4 Wizard is a next-generation autoinstall management system with an
5 eye towards flexibility and scalability.
7 Copyright (c) 2009-2010 the Wizard development team
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice shall be included
18 in all copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 # import some non-standard modules to make it fail out early
38 _root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
39 sys.path.insert(0, _root_dir)
40 sys.path.insert(0, os.path.join(_root_dir, "plugins/scripts")) # hack to load scripts plugins for now
43 from wizard import command, prompt
46 usage = """usage: %prog COMMAND [ARGS]
48 Wizard is a Git-based autoinstall management system for scripts.
51 backup Backup data not on filesystem (database, etc)
52 install Installs an application
53 migrate Migrate autoinstalls from old format to Git-based format
54 remove Removes an autoinstall, databases and other files
55 restore Restores files and database to previous version
56 upgrade Upgrades an autoinstall to the latest version
58 Administrative commands:
59 blacklist Marks an autoinstall to not try upgrades
60 errors Lists all broken autoinstall metadata
61 list Lists autoinstalls, with optional filtering
62 mass-migrate Performs mass migration of autoinstalls of an application
63 mass-upgrade Performs mass upgrade of autoinstalls of an application
64 research Print statistics about a possible upgrade
65 summary Generate statistics (see help for subcommands)
68 prepare-pristine Downloads and extracts pristine upstream files
69 prepare-new Prepares a new repository
70 prepare-config Prepares configuration files for versioning
71 quota Prints the usage and available quota of a directory
73 See '%prog help COMMAND' for more information on a specific command."""
75 parser = optparse.OptionParser(usage)
76 parser.disable_interspersed_args()
77 _, args = parser.parse_args() # no global options
79 baton = command.OptionBaton()
80 baton.add("--versions-path", dest="versions_path", metavar="PATH",
81 default=getenvpath("WIZARD_VERSIONS_PATH") or "/afs/athena.mit.edu/contrib/scripts/sec-tools/store/versions",
82 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.")
83 baton.add("--srv-path", dest="srv_path", metavar="PATH",
84 default=getenvpath("WIZARD_SRV_PATH") or "/afs/athena.mit.edu/contrib/scripts/git/autoinstalls",
85 help="Location of autoinstall Git repositories, such that $REPO_PATH/$APP.git is a repository (for development work). Environment variable is WIZARD_SRV_PATH.")
86 baton.add("--dry-run", dest="dry_run", action="store_true",
87 default=False, help="Performs the operation without actually modifying any files. Use in combination with --verbose to see commands that will be run.")
88 # common variables for mass commands
89 baton.add("--seen", dest="seen",
90 default=None, help="File to read/write paths of successfully modified installs;"
91 "these will be skipped on re-runs. If --log-dir is specified, this is automatically enabled.")
92 baton.add("--no-parallelize", dest="no_parallelize", action="store_true",
93 default=False, help="Turn off parallelization")
94 baton.add("--max-processes", dest="max_processes", type="int", metavar="N",
95 default=5, help="Maximum subprocesses to run concurrently")
96 baton.add("--limit", dest="limit", type="int",
97 default=None, help="Limit the number of autoinstalls to look at.")
98 baton.add("--user", "-u", dest="user",
99 default=None, help="Only mass migrate a certain user's installs. No effect if versions_path is a file.")
101 command_name = args[0]
105 baton.add("--log-dir", dest="log_dir",
106 default=getenvpath("WIZARD_LOG_DIR") or "/tmp/wizard-%s" % command_name,
107 help="Log files for Wizard children processes are placed here.")
108 if command_name == "help":
110 help_module = get_command(rest_argv[0])
112 parser.error("invalid action")
116 help_module.main(['--help'], baton)
118 command_module = get_command(command_name)
120 command_module.main(rest_argv, baton)
121 except prompt.UserCancel as e:
124 except Exception as e:
126 msg = traceback.format_exc()
127 if command.logging_setup:
128 outfun = logging.error
130 outfun = sys.stderr.write
131 if isinstance(e, wizard.Error):
132 if e.quiet and not command.debug:
134 if command.logging_setup:
135 msg = msg.replace("ERROR: ", "")
142 def get_command(name):
143 name = name.replace("-", "_")
144 __import__("wizard.command." + name)
145 return getattr(wizard.command, name)
147 def getenvpath(name):
148 val = os.getenv(name)
150 val = os.path.abspath(val)
153 if __name__ == "__main__":