]> scripts.mit.edu Git - wizard.git/blob - bin/wizard
Make some exceptions quiet.
[wizard.git] / bin / wizard
1 #!/usr/bin/env python
2
3 import os
4 import optparse
5 import sys
6 import logging
7 import traceback
8
9 # import some non-standard modules to make it fail out early
10 import decorator
11
12 sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
13
14 import wizard
15 from wizard import command, prompt
16
17 def main():
18     usage = """usage: %prog COMMAND [ARGS]
19
20 Wizard is a Git-based autoinstall management system for scripts.
21
22 User commands:
23     backup          Backup data not on filesystem (database, etc)
24     install         Installs an application
25     migrate         Migrate autoinstalls from old format to Git-based format
26     restore         Restores files and database to previous version
27     upgrade         Upgrades an autoinstall to the latest version
28
29 Administrative commands:
30     blacklist       Marks an autoinstall to not try upgrades
31     errors          Lists all broken autoinstall metadata
32     list            Lists autoinstalls, with optional filtering
33     mass-migrate    Performs mass migration of autoinstalls of an application
34     mass-upgrade    Performs mass upgrade of autoinstalls of an application
35     research        Print statistics about a possible upgrade
36     summary         Generate statistics (see help for subcommands)
37
38 Utility commands:
39     prepare-pristine    Downloads and extracts pristine upstream files
40     prepare-new     Prepares a new repository
41     prepare-config  Prepares configuration files for versioning
42
43 See '%prog help COMMAND' for more information on a specific command."""
44
45     parser = optparse.OptionParser(usage)
46     parser.disable_interspersed_args()
47     _, args = parser.parse_args() # no global options
48     rest_argv = args[1:]
49     baton = command.OptionBaton()
50     baton.add("--versions-path", dest="versions_path", metavar="PATH",
51         default=getenvpath("WIZARD_VERSIONS_PATH") or "/afs/athena.mit.edu/contrib/scripts/sec-tools/store/versions",
52         help="Location of parallel-find output directory, or a file containing a newline separated list of 'all autoinstalls' (for development work).  Environment variable is WIZARD_VERSIONS_PATH.")
53     baton.add("--srv-path", dest="srv_path", metavar="PATH",
54         default=getenvpath("WIZARD_SRV_PATH") or "/afs/athena.mit.edu/contrib/scripts/git/autoinstalls",
55         help="Location of autoinstall Git repositories, such that $REPO_PATH/$APP.git is a repository (for development work).  Environment variable is WIZARD_SRV_PATH.")
56     baton.add("--dry-run", dest="dry_run", action="store_true",
57             default=False, help="Performs the operation without actually modifying any files.  Use in combination with --verbose to see commands that will be run.")
58     # common variables for mass commands
59     baton.add("--seen", dest="seen",
60             default=None, help="File to read/write paths of successfully modified installs;"
61             "these will be skipped on re-runs.  If --log-dir is specified, this is automatically enabled.")
62     baton.add("--no-parallelize", dest="no_parallelize", action="store_true",
63             default=False, help="Turn off parallelization")
64     baton.add("--max-processes", dest="max_processes", type="int", metavar="N",
65             default=10, help="Maximum subprocesses to run concurrently")
66     baton.add("--limit", dest="limit", type="int",
67             default=None, help="Limit the number of autoinstalls to look at.")
68     baton.add("--user", "-u", dest="user",
69             default=None, help="Only mass migrate a certain user's installs.  No effect if versions_path is a file.")
70     try:
71         command_name = args[0]
72     except IndexError:
73         parser.print_help()
74         sys.exit(1)
75     baton.add("--log-dir", dest="log_dir",
76         default=getenvpath("WIZARD_LOG_DIR") or "/tmp/wizard-%s" % command_name,
77         help="Log files for Wizard children processes are placed here.")
78     if command_name == "help":
79         try:
80             help_module = get_command(rest_argv[0])
81         except ImportError:
82             parser.error("invalid action")
83         except IndexError:
84             parser.print_help()
85             sys.exit(1)
86         help_module.main(['--help'], baton)
87     # Dispatch commands
88     command_module = get_command(command_name)
89     try:
90         command_module.main(rest_argv, baton)
91     except prompt.UserCancel as e:
92         print str(e)
93         sys.exit(1)
94     except Exception as e:
95         # log the exception
96         msg = traceback.format_exc()
97         if command.logging_setup:
98             outfun = logging.error
99         else:
100             outfun = sys.stderr.write
101         if isinstance(e, wizard.Error):
102             if e.quiet and not command.debug:
103                 msg = str(e)
104                 if command.logging_setup:
105                     msg = msg.replace("ERROR: ", "")
106             outfun(msg)
107             sys.exit(e.exitcode)
108         else:
109             outfun(msg)
110             sys.exit(1)
111
112 def get_command(name):
113     name = name.replace("-", "_")
114     __import__("wizard.command." + name)
115     return getattr(wizard.command, name)
116
117 def getenvpath(name):
118     val = os.getenv(name)
119     if val:
120         val = os.path.abspath(val)
121     return val
122
123 if __name__ == "__main__":
124     main()
125