]> scripts.mit.edu Git - wizard.git/blob - bin/wizard
Fix bugs in scripts-specific installation code.
[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
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     configure       Configures an autoinstall (database, etc) to work
40     prepare-pristine    Downloads and extracts pristine upstream files
41     prepare-new     Prepares a new repository
42     prepare-config  Prepares configuration files for versioning
43
44 See '%prog help COMMAND' for more information on a specific command."""
45
46     parser = optparse.OptionParser(usage)
47     parser.disable_interspersed_args()
48     _, args = parser.parse_args() # no global options
49     rest_argv = args[1:]
50     baton = command.OptionBaton()
51     baton.add("--versions-path", dest="versions_path", metavar="PATH",
52         default=getenvpath("WIZARD_VERSIONS_PATH") or "/afs/athena.mit.edu/contrib/scripts/sec-tools/store/versions",
53         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.")
54     baton.add("--srv-path", dest="srv_path", metavar="PATH",
55         default=getenvpath("WIZARD_SRV_PATH") or "/afs/athena.mit.edu/contrib/scripts/git/autoinstalls",
56         help="Location of autoinstall Git repositories, such that $REPO_PATH/$APP.git is a repository (for development work).  Environment variable is WIZARD_SRV_PATH.")
57     baton.add("--dry-run", dest="dry_run", action="store_true",
58             default=False, help="Performs the operation without actually modifying any files.  Use in combination with --verbose to see commands that will be run.")
59     # common variables for mass commands
60     baton.add("--seen", dest="seen",
61             default=None, help="File to read/write paths of successfully modified installs;"
62             "these will be skipped on re-runs.  If --log-dir is specified, this is automatically enabled.")
63     baton.add("--no-parallelize", dest="no_parallelize", action="store_true",
64             default=False, help="Turn off parallelization")
65     baton.add("--max-processes", dest="max_processes", type="int", metavar="N",
66             default=10, help="Maximum subprocesses to run concurrently")
67     baton.add("--limit", dest="limit", type="int",
68             default=None, help="Limit the number of autoinstalls to look at.")
69     baton.add("--user", "-u", dest="user",
70             default=None, help="Only mass migrate a certain user's installs.  No effect if versions_path is a file.")
71     try:
72         command_name = args[0]
73     except IndexError:
74         parser.print_help()
75         sys.exit(1)
76     baton.add("--log-dir", dest="log_dir",
77         default=getenvpath("WIZARD_LOG_DIR") or "/tmp/wizard-%s" % command_name,
78         help="Log files for Wizard children processes are placed here.")
79     if command_name == "help":
80         try:
81             help_module = get_command(rest_argv[0])
82         except ImportError:
83             parser.error("invalid action")
84         except IndexError:
85             parser.print_help()
86             sys.exit(1)
87         help_module.main(['--help'], baton)
88     # Dispatch commands
89     command_module = get_command(command_name)
90     try:
91         command_module.main(rest_argv, baton)
92     except Exception as e:
93         # log the exception
94         msg = traceback.format_exc()
95         if command.logging_setup:
96             logging.error(msg)
97         else:
98             sys.stderr.write(msg)
99         if isinstance(e, wizard.Error):
100             sys.exit(e.exitcode)
101         else:
102             sys.exit(1)
103
104 def get_command(name):
105     name = name.replace("-", "_")
106     __import__("wizard.command." + name)
107     return getattr(wizard.command, name)
108
109 def getenvpath(name):
110     val = os.getenv(name)
111     if val:
112         val = os.path.abspath(val)
113     return val
114
115 if __name__ == "__main__":
116     main()
117