def process_standard_options(options, parser, precreated_file_layout=None, installer_name=None, allow_overrides_of_dh=False, rotate_logfiles=True): if precreated_file_layout: file_layout = precreated_file_layout else: file_layout = get_engine_layout_mgr(installer_name) dh = get_deployment_home(options, parser, file_layout, allow_overrides=allow_overrides_of_dh) log_setup.parse_log_options(options, file_layout.get_log_directory(), rotate_logfiles=rotate_logfiles) if hasattr(options, "master_password_file") and \ options.master_password_file and \ (not os.path.exists(options.master_password_file)): parser.error("Master password file %s does not exist" % options.master_password_file) return (file_layout, dh)
def process_args(self, argv): usage = "usage: %prog [options] deployment_home" parser = OptionParser(usage=usage) add_log_option(parser) parser.add_option("--application-archive", "-a", dest="application_archive", action="store", default=None, help="If specified, override the application_archive property in config choices file with this value") parser.add_option("-s", "--subproc", action="store_true", dest="subproc", default=False, help="Run in subprocess mode, getting master password from standard input") parser.add_option("-x", "--python", default=None, help="Use the specified python executable as basis for Python virtual environments", dest="python_exe") parser.add_option("-p", "--master-password-file", default=None, help="File containing master password (if not specified, will prompt from console if needed)") (self.options, args) = parser.parse_args(args=argv) if len(args) != 1: parser.error("Expecting exactly one argument, the deployment's home directory") self.deployment_home = os.path.abspath(os.path.expanduser(args[0])) if not os.path.exists(self.deployment_home): parser.error("Deployment home %s not found" % self.deployment_home) self.config_dir = os.path.join(self.deployment_home, "config") if not os.path.exists(self.config_dir): parser.error("Configuration directory %s does not exist" % self.config_dir) log_directory_file = os.path.join(self.config_dir, "log_directory.txt") if not os.path.exists(log_directory_file): parser.error("Log directory pointer file %s does not exit" % log_directory_file) with open(log_directory_file, "r") as f: self.log_directory = f.read().rstrip() parse_log_options(self.options, self.log_directory) if self.options.python_exe: if not os.path.exists(self.options.python_exe): parser.error("Python executable %s does not exist" % self.options.python_exe) if self.options.master_password_file: if not os.path.exists(self.options.master_password_file): parser.error("Master password file %s not found" % self.options.master_password_file) self.engage_home = os.path.join(self.deployment_home, "engage") if not os.path.isdir(self.engage_home): parser.error("Engage home %s does not exist" % self.engage_home) self.engage_bin_dir = os.path.join(self.engage_home, "bin") if not os.path.isdir(self.engage_bin_dir): parser.error("Engage binary directory %s does not exist" % self.engage_bin_dir) if self.options.application_archive: self.application_archive = os.path.abspath(os.path.expanduser(self.options.application_archive)) if not os.path.exists(self.application_archive): parser.error("Application archive file %s does not exist" % self.application_archive) if os.path.exists(os.path.join(self.config_dir, "pw_repository")): if self.options.master_password_file: with open(self.options.master_password_file, "rb") as f: self.master_pw = f.read().rstrip() elif self.options.subproc: self.master_pw = sys.stdin.read().rstrip() else: while True: self.master_pw = getpass.getpass("Master password:"******"Re-enter Master password:"******"Passwords do not match, try again."
def main(argv): usage = "usage: %prog [options] deployment_home" parser = OptionParser(usage=usage) add_log_option(parser) parser.add_option("-d", "--logdir", action="store", type="string", help="master log directory for deployment (defaults to <deployment_home>/log)", dest="logdir", default=None) parser.add_option("-c", "--create-dist-archive", action="store_true", help="create a distribution archive", dest="create_dist_archive", default=False) parser.add_option("-x", "--python", default=None, help="Use the specified python executable as basis for Python virtual environments", dest="python_exe") parser.add_option("--never-download", default=False, action="store_true", help="If specified, never try to download packages during bootstrap. If a package is required, exit with an error.", dest="never_download") parser.add_option("--include-test-data", default=False, action="store_true", help="If specified, copy test data into the deployment home. Otherwise, tests requiring data will be skipped.") (options, args) = parser.parse_args(args=argv) if len(args) != 1: parser.error("Expecting exactly one argument, the deployment's home directory") logger = setup_logger("Bootstrap", __name__) if options.python_exe: options.python_exe = os.path.abspath(os.path.expanduser(options.python_exe)) if not os.path.exists(options.python_exe): parser.error("Python executable %s does not exist" % options.python_exe) if not os.access(options.python_exe, os.X_OK): parser.error("Python executable file %s is not an executable" % options.python_exe) test_data_src = os.path.join(base_src_dir, "test_data") if options.include_test_data and not os.path.isdir(test_data_src): parser.error("--include-test-data specified, but test data directory %s does not exist" % test_data_src) deployment_home = os.path.abspath(os.path.expanduser(args[0])) if os.path.exists(deployment_home): sentry_file = os.path.join(deployment_home, "config/installed_resources.json") if os.path.exists(sentry_file): raise Exception("Deployment home directory %s exists and contains the file %s. Cannot overwrite an existing install." % (deployment_home, sentry_file)) else: os.makedirs(deployment_home) if options.logdir: log_dir = os.path.abspath(os.path.expanduser(options.logdir)) else: log_dir = os.path.join(deployment_home, "log") if not os.path.exists(log_dir): os.makedirs(log_dir) parse_log_options(options, log_dir) logger.info("Running bootstrap under Python executable %s" % sys.executable) # the engage home is just a python virtual environment engage_home = os.path.join(deployment_home, "engage") sw_packages_src_loc = os.path.join(base_src_dir, "sw_packages") sw_packages_dst_loc = os.path.join(engage_home, "sw_packages") create_virtualenv(engage_home, logger, sw_packages_src_loc, base_python_exe=options.python_exe, never_download=options.never_download) logger.info("Created python virtualenv for engage") # copy this bootstrap script and the upgrade script bootstrap_py_dst = os.path.join(engage_home, "bootstrap.py") shutil.copyfile(os.path.join(base_src_dir, "bootstrap.py"), bootstrap_py_dst) os.chmod(bootstrap_py_dst, 0755) upgrade_py_src = os.path.join(base_src_dir, "upgrade.py") upgrade_py_dst = os.path.join(engage_home, "upgrade.py") shutil.copyfile(upgrade_py_src, upgrade_py_dst) os.chmod(upgrade_py_dst, 0755) # we also copy the python_pkg directory to the distribution home for use in creating # future distributions python_pkg_dst_dir = os.path.join(engage_home, "python_pkg") copy_tree(python_pkg_dir, python_pkg_dst_dir, logger) # we need to run the setup.py script for the python_pkg engage_bin_dir = os.path.join(engage_home, "bin") engage_python_exe = os.path.join(engage_bin_dir, "python") assert os.path.exists(engage_python_exe), "Python executable at %s missing" % engage_python_exe setup_py_file = os.path.join(python_pkg_dir, "setup.py") assert os.path.exists(setup_py_file), "Missing %s" % setup_py_file cmd = "%s %s install" % (engage_python_exe, setup_py_file) rc = system(cmd, logger, cwd=python_pkg_dir) if rc != 0: raise Exception("Install of engage python packages failed: '%s' failed, rc was %d" % (cmd, rc)) logger.info("Installed python packages") platform = get_platform() # copy the configurator binary config_exe_src_loc = os.path.join(base_src_dir, "bin/configurator-%s" % platform) assert os.path.exists(config_exe_src_loc), "Configurator executable missing at %s" % config_exe_src_loc config_exe_dst_loc = os.path.join(engage_bin_dir, "configurator-%s" % platform) logger.action("cp %s %s" % (config_exe_src_loc, config_exe_dst_loc)) shutil.copyfile(config_exe_src_loc, config_exe_dst_loc) os.chmod(config_exe_dst_loc, 0755) symlink_loc = os.path.join(engage_bin_dir, "configurator") logger.action("ln -s %s %s" % (config_exe_dst_loc, symlink_loc)) os.symlink(config_exe_dst_loc, symlink_loc) # copy the metadata files metadata_files_src_loc = os.path.join(base_src_dir, "metadata") metadata_files_dst_loc = os.path.join(engage_home, "metadata") copy_tree(metadata_files_src_loc, metadata_files_dst_loc, logger) # copy the sw_packages directory copy_tree(sw_packages_src_loc, sw_packages_dst_loc, logger) if not is_package_installed(engage_bin_dir, "Crypto.Cipher.AES", logger): if get_platform()=="linux64" and (not options.never_download): run_apt_install("python-crypto", logger) else: # Pycrypto may be preinstalled on the machine. # If so, we don't install our local copy, as installation # can be expensive (involves a g++ compile). run_install(engage_bin_dir, sw_packages_src_loc, ["pycrypto-2.3-%s.tar.gz" % platform, "pycrypto-2.3.tar.gz"], logger, "pycrypto", never_download=options.never_download) bootstrap_packages = [# JF 2012-05-11: Don't install provision and its # dependencies - moving down to DJM level. #(["paramiko-1.7.6.zip"], "paramiko"), #(["apache-libcloud-0.6.2.tar.bz2"], None), #(["argparse-1.2.1.tar.gz"], "argparse"), #(["provision-0.9.3-dev.tar.gz"], None), (["nose-1.0.0.tar.gz"], "nose"), (["engage_utils-1.0.tar.gz"], "git+git://github.com/genforma/engage-utils.git")] # run install for all of the bootstrap packages for (package_file_list, alternate) in bootstrap_packages: run_install(engage_bin_dir, sw_packages_src_loc, package_file_list, logger, alternate, never_download=options.never_download) # create a virtualenv for the deployed apps deployed_virtualenv = os.path.join(deployment_home, "python") create_virtualenv(deployed_virtualenv, logger, sw_packages_src_loc, base_python_exe=options.python_exe, never_download=options.never_download) logger.info("Created a virtualenv for deployed apps") deployed_config_dir = os.path.join(deployment_home, "config") os.makedirs(deployed_config_dir) # don't use "with" as this should be python 2.5 compatible f = open(os.path.join(deployed_config_dir, "log_directory.txt"), "wb") try: f.write(log_dir) finally: f.close() # copy the test data if requested if options.include_test_data: test_data_dest = os.path.join(engage_home, "test_data") copy_tree(test_data_src, test_data_dest, logger) if options.create_dist_archive: logger.info("Creating a distribution") import engage.engine.create_distribution engage.engine.create_distribution.create_distribution_from_deployment_home(deployment_home, include_test_data=options.include_test_data) logger.info("Engage environment bootstrapped successfully") return 0