def exit_with_return_code(value): "Provide proper output to the CNM server" if type(value) != type(0): Logger.error("Invalid exit code, not an integer: %s" % value) value = FAIL Logger.warning("==EXIT-CODE==:%s" % value) sys.exit(value)
def fix_spkg(instance_name, pkn, action, package_factory): """A user is requesting to take a package that is currently flagged as 'broken' and set it to be 'installed'. Perhaps they have manually fixed the package on the system.""" progress_file = get_progress_path(instance_name) status_data = open(progress_file, 'r').read() try: status = json.loads(status_data) except ValueError: Logger.error("Data in %s is not parsable by json" % progress_file) return FAIL if status.get("install-progress") == None: status["install-progress"] = {} Logger.warning( "Status file is empty." ) now = time.asctime() if action == FIX: fix_name = [] base_names = re.compile("(\s+)\-\d+").findall(pkn) if base_names: base_name = base_names[0] else: base_name = pkn for possible_pkn in status["install-progress"]: if base_name in possible_pkn: fix_name.append(possible_pkn) if len(fix_name) > 1: msg = "Package name %s is ambigious. (possible %s)" msg = msg % (pkn, ' '.join(fix_name)) Logger.error(msg) return FAIL elif len(fix_name) == 1: pkn = fix_name[0] elif len(fix_name) == 0: new_package = package_factory.get_me_one(pkn) pkn = new_package.full_name Logger.info("Selecting previously UNINSTALLED package: %s" % pkn) status["install-progress"]["%s" % pkn] = {"INSTALLED": now, "UNINSTALLED": "NA", "VERIFIED": now} Logger.info("==OUTPUT==:%s has been set to INSTALLED." % pkn ) elif action == PURGE: if status["install-progress"].get(pkn): del status["install-progress"][pkn] msg = "==OUTPUT==:%s has been removed from %s status" msg = msg % (pkn, instance_name) Logger.info(msg) else: Logger.info("==OUTPUT==:%s is not in the status file" % pkn) pkns = status["install-progress"] possible_names = [x for x in pkns if pkn in x] msg = "==OUTPUT==:Maybe you want one of these: %s" msg = msg % str(possible_names) Logger.info(msg) return FAIL open(get_progress_path(instance_name), 'w').write(json.dumps(status)) return OK
def use_pkg(self, pkn, action, script_name, arguments): """ Main entry point to the class. Performs an action using a package pkn -- name of the package to use action -- STATUS, INSTALL, UNINSTALL, CONFIGURE, VERIFY, or EXEC script_name -- the name of a method to run within the package arguments -- arguments to the executable, typically a restore target """ try: pkg = self._get_new_pkg(pkn) if pkg.status == FAIL: self.operation_status = FAIL return self._cleanup() if action == INSTALL: pdat = self.progress.get_progress_data(False) installed_pkns, broken_pkns = Progress.get_installed(pdat) if pkn in [installed_pkns + broken_pkns]: Logger.error("Package %s cannot be installed." % pkn) self.operation_status = FAIL return FAIL add_pkd = {pkn: pkg} status = self._install_pkgs(add_pkd) if action == UNINSTALL: pdat = self.progress.get_progress_data(False) installed_pkns, broken_pkns = Progress.get_installed(pdat) bom_pkns = installed_pkns if pkn in bom_pkns: bom_pkns.remove(pkn) self.config.set_bom_pkgs(bom_pkns) add_pkd, del_pkd, uninstall_order = self._ck_inst_stat([]) status = self._uninstall_pkgs(del_pkd, uninstall_order) if action == VERIFY: status = pkg.verify() if action == CONFIGURE: self._check_configuration(pkg) status = pkg.configure() hash_path = make_path(pkg.get_path(), HASH_FILE) msg = "Writing configuration fingerprint to %s" % hash_path Logger.info(msg) self.config.save_hash(hash_path) if action in [EXECUTE, BACKUP, RESTORE]: status = pkg.execute_maint_script(script_name, arguments) if status == FAIL: self.operation_status = FAIL msg = "Finished %s for %s." msg = msg % (ACTION_REVERSE_LOOKUP[action], pkn) self.operation_output.append(msg) status = self._cleanup() return self._cleanup() except Exceptions.BadPackage, err: errmsg = "Cannot perform action %s on package %s: %s" errmsg = errmsg % (ACTION_REVERSE_LOOKUP[action], err.pkn, err.errmsg) Logger.warning(errmsg) Logger.info("RETURN FAIL 1") return FAIL
def initialize(self): '''Evaluate the package meta-data for consistency and initialize parameters. Verify that data on the disk for this package is consistent. ''' try: self.meta_data = self.repository.get_meta_data(self.name) except BadPackage, bpe: Logger.error("initialize INVALIDATING") self._invalidate(bpe) return
def process_action(action, instance_name, pkn, method_name, arguments, package_factory): """ Performs a Bombardier action on this system action -- either INIT, INSTALL, UNINSTALL, VERIFY, CONFIGURE, EXECUTE, RECONCILE, CHECK_STATUS, FIX, or PURGE instance_name -- the name of the machine pkn -- the package name to operate on. Could be none for actions that operate on the whole machine, such as RECONCILE, CHECK_STATUS, or INIT method_name -- Only applicable for the EXECUTE action, runs a named method within a package. package_factory -- provides packages we may need """ if action == INIT: instance_setup(instance_name) return OK if action in [ UNINSTALL, VERIFY, CONFIGURE, EXECUTE, BACKUP ]: try: pkn = find_likely_pkn(instance_name, pkn) except ValueError: return FAIL status = FAIL try: if action in [ FIX, PURGE ]: status = fix_spkg(instance_name, pkn, action, package_factory) return status bc_obj = get_bc(instance_name, package_factory.env) if action == CHECK_STATUS: status_dict = bc_obj.check_system() if type(status_dict) == type({}): if not status_dict["Packages that are BROKEN"]: status = OK else: status = FAIL elif action in [ RECONCILE, DRY_RUN ]: bc_obj.record_errors = True status = bc_obj.reconcile_system(action) else: # INSTALL, UNINSTALL, VERIFY, BACKUP, CONFIGURE, EXECUTE, RESTORE bc_obj.record_errors = False status = bc_obj.use_pkg(pkn, action, method_name, arguments) except: err = StringIO.StringIO() traceback.print_exc(file = err) err.seek(0) data = err.read() ermsg = '' for line in data.split('\n'): ermsg += "\n||>>>%s" % line Logger.error(ermsg) return FAIL return status
def is_running(self): 'ability to check if the job is finished' if self.job_thread: if self.job_thread.isAlive(): return True if type(self.job_thread.cmd_status) == type(0) \ or type(self.job_thread.cmd_status) == type('str'): Logger.debug("-- status: %s" % (self.job_thread.cmd_status)) self.job_status = self.job_thread.cmd_status else: msg = "Invalid return status (type: %s)" Logger.error(msg % (type(self.job_thread.cmd_status))) self.job_status = FAIL return False
def run(self): 'Thread interface' Logger.debug("Running %s..." % self.cmd) try: exec(self.import_string) exec("self.cmd_status = %s" % self.cmd) except StandardError, err: Logger.error("Failed to run %s (%s)" % (self.cmd, err)) sio = StringIO.StringIO() traceback.print_exc(file=sio) sio.seek(0) data = sio.read() ermsg = '' for line in data.split('\n'): ermsg += "\n||>>>%s" % line Logger.error(ermsg) self.cmd_status = FAIL
def _find_cmd(self, action, arguments=[], future_pkns=[], dry_run=False): ''' Perform the action on the system, importing modules from the package and running the appropriate method on the class within. action -- INSTALL, UNINSTALL, CONFIGURE, VERIFY future_pkns -- future package names. Some packages want to know about the packages that will come after them dry_run -- boolean flag to see if we're really going to do this ''' ret_val = None if type(action) == type(1): action = ACTION_REVERSE_LOOKUP[action] cwd = get_slash_cwd() obj, rand_string = self._get_object(future_pkns) try: if not hasattr(obj, action): msg = "Class %s does not have a %s method." raise BadPackage(self.name, msg % (self.class_name, action)) if not dry_run: if arguments: if ACTION_LOOKUP.get(action) == RESTORE: if len(arguments) != 1: Logger.error("Incorrect number of arguments passed to restore") return FAIL restore_path = make_path(get_spkg_path(), "archive", self.name, str(arguments[0])) if not os.path.isdir(restore_path): msg = "Cannot execute restore: archive data does not "\ "exist in %s" % (restore_path) Logger.error(msg) return FAIL self._prepare_restore(obj, restore_path) exec("ret_val = obj.%s('%s')" % (action, restore_path)) else: exec("ret_val = obj.%s()" % (action)) else: ret_val = OK self._cleanup(obj) del rand_string except SystemExit, err: if err.code: ret_val = err.code else: ret_val = OK del rand_string
def execute(self): 'starts a job and waits for it to finish' self.start_time = time.time() status = FAIL if self.is_running(): msg = "Refusing to run %s; it is already running" % self.cmd Logger.error(msg) return FAIL self.job_thread = JobThread(self.import_string, self.cmd, self.config) self.job_thread.start() Logger.info("Started job...") counter = 1 while self.is_running(): time.sleep(1) counter += 1 if not counter % 100: msg = "Waiting for completion (%s)..." Logger.info(msg % time.strftime(time.ctime())) counter = 1 status = self.job_thread.cmd_status return status
def find_likely_pkn(instance_name, pkn): """Sometimes an ambiguous package name is requested. This attempts to help a guy out.""" progress_file = get_progress_path(instance_name) try: status_yml = json.loads(open(progress_file).read()) except ValueError: Logger.error("Progress data in %s is not parsable." % progress_file) raise pkns = [] status_packages = status_yml['install-progress'] for name in status_packages: if status_packages[name]['INSTALLED'] in [ 'NA', 'BROKEN' ]: continue if pkn.lower() in name.lower(): pkns.append(name) if len(pkns) > 1: msg = 'Ambiguous package name: %s could be any of %s' % (pkn, str(pkns)) Logger.error( msg ) exit_with_return_code(FAIL) if len(pkns) == 0: Logger.error( 'Package not found: %s' %pkn ) exit_with_return_code(FAIL) else: pkn = '-'.join(pkns[0].split('-')[:-1]) Logger.info( 'Using %s' %pkn) return pkn
def get_type_4(self, full_name): ''' Get a type-4 package from the filesystem, and process it full_name -- name of package (with version) ''' pkg_dir = get_package_path(self.instance_name) os.system('bash -c "mkdir -p %s"' % pkg_dir) pkg_path = make_path(pkg_dir, full_name) if not os.path.isfile(pkg_path + ".spkg"): erstr = "No package file in %s." % (pkg_path + ".spkg") Logger.error(erstr) raise Exceptions.BadPackage(full_name, erstr) if sys.platform != 'win32': cmd = 'bash -c "cd %s && tar -mxzf %s.spkg"' % (pkg_dir, full_name) Logger.info("Untarring with command: %s" %cmd) if not os.system(cmd) == OK: raise Exceptions.BadPackage(full_name, "Could not unpack") return OK if self.unzip_type_5(pkg_path, full_name) == FAIL: raise Exceptions.BadPackage(full_name, "could not unzip") # tar = tarfile.open(pkg_path + ".tar", "r") # tar.errorlevel = 2 cwd = get_slash_cwd() os.chdir(pkg_dir) # for tarinfo in tar: # try: # tar.extract(tarinfo) # except tarfile.ExtractError, err: # Logger.warning("Error with package %s,%s: "\ # "%s" % (full_name, tarinfo.name, err)) # tar.close() if not os.path.isdir(make_path(pkg_path, full_name)): erstr = "Package %s is malformed." % (full_name) os.chdir(cwd) raise Exceptions.BadPackage(full_name, erstr) os.chdir(cwd) # os.unlink(pkg_path + ".tar") return OK
def _install_pkgs(self, add_pkd, dry_run=False): """ Provided a dictionary of packages, we will install those that need to be installed. add_pkd -- a dictionary of packages that need to be added dry_run -- whether or not to just 'fake it' """ status = OK making_progress = True pkns_left = ["initialize"] while making_progress and pkns_left: making_progress = False install_order = self._find_install_order(add_pkd) pkns_left = list(install_order) for pkn in install_order: msg = "Packages remaining to install (in order):" Logger.info(msg) for tpkn in pkns_left: Logger.info(" + %s" % tpkn) pkns_left.remove(pkn) pkg = add_pkd[pkn] erstr = "Currently installing package priority %s [%s]" Logger.info(erstr % (pkg.get_priority(), pkn)) pkg_status = pkg.install_and_verify(pkns_left) if not dry_run: hash_path = make_path(pkg.get_path(), HASH_FILE) self.config.save_hash(hash_path) if pkg_status == FAIL: status = FAIL erstr = "Package installation failure -- re-calculating" " package installation order" Logger.error(erstr) break else: making_progress = True if status != OK: msg = "There are packages that are broken, and we have done all" " we can do. ; ;" Logger.error(msg) return status
def _get_object(self, future_pkns): ''' Import modules from the package in order to run an appropriate method on the class within. future_pkns -- future package names. Some packages want to know about the packages that will come after them ''' lib_path = self._get_lib_path() sys.path.insert(0, lib_path) Logger.info("Adding %s to our path..." % lib_path) obj = None try: class_name = '.'.join(self.class_name.split('.')[1:]) obj = Spkg.SpkgV5(self.config) os.chdir(self.working_dir) Logger.info("CHANGING TO: %s" % self.working_dir) letters = [ chr( x ) for x in range(65, 91) ] random.shuffle(letters) rand_string = ''.join(letters) exec("import %s as %s" % (self.class_name, rand_string)) self.config["__FUTURE_PACKAGES__"] = future_pkns self.config["__INSTANCE__"] = self.instance_name cmd_str = "obj = %s.%s(self.config)" exec(cmd_str % (rand_string, class_name)) except ImportError, ie: tb_str = StringIO.StringIO() traceback.print_exc(file=tb_str) tb_str.seek(0) data = tb_str.read() ermsg = '' for line in data.split('\n'): Logger.error(line) self.status = FAIL msg = "Class %s is not importable." % self.class_name raise BadPackage(self.name, msg)
def _dump_error(cls, err, file_name): ''' perform a traceback for logging purposes err -- an exception object file_name -- the module that was running ''' Logger.error("Error detected in %s (%s)." % (file_name, err)) sio = StringIO.StringIO() traceback.print_exc(file=sio) sio.seek(0) data = sio.read() ermsg = '' for line in data.split('\n'): ermsg += "\n||>>>%s" % line Logger.error(ermsg) Logger.error("Error ocurred in %s" % file_name)
def _prepare_restore(self, obj, restore_path): """ Command to deal with setting up the environment prior to a restore action obj -- package object which owns methods for restoring, etc. restore_path -- place where restore files have been dropped """ if hasattr(obj, "pre_restore_cmd"): pre_backup_cmd = obj.pre_backup_cmd status = self._find_cmd(obj.pre_restore_cmd) if status != OK: erstr = "%s: restore FAILED because %s failed." Logger.error(erstr % (self.full_name, pre_backup_cmd)) return FAIL backup_data = yaml_load(open(make_path(restore_path, "backup_info.yml")).read()) for backup_target in backup_data: if backup_target.startswith("__"): continue md5_data = backup_data[backup_target].get("md5", {}) backup_file_name = backup_data[backup_target].get("backup_file", '') if not md5_data or not backup_file_name: Logger.error("Corrupted backup data for %s, aborting." % (backup_target)) return FAIL source_file = make_path(restore_path, rpartition(backup_target, os.path.sep)[0][1:], backup_file_name) destination_file = make_path(restore_path, backup_target[1:]) Logger.debug("=================================") Logger.debug("backup_target: %s..." % (backup_target)) Logger.debug("current directory: %s" % (restore_path)) Logger.debug("backup_file_name: %s..." % (backup_file_name)) Logger.debug("destination_file: %s..." % (destination_file)) Logger.debug("source_file: %s" % (source_file)) Logger.debug("=================================") if not os.path.isfile(source_file): Logger.error("Restore file %s does not exist, aborting" % (source_file)) return FAIL rfp = ReversePluggableFileProcessor(source_file, destination_file, md5_data, Logger) rfp.process_all()
self._prepare_restore(obj, restore_path) exec("ret_val = obj.%s('%s')" % (action, restore_path)) else: exec("ret_val = obj.%s()" % (action)) else: ret_val = OK self._cleanup(obj) del rand_string except SystemExit, err: if err.code: ret_val = err.code else: ret_val = OK del rand_string except KeyboardInterrupt: Logger.error("Keyboard interrupt detected. Exiting...") ret_val = FAIL sys.exit(10) # FIXME: Literal except SyntaxError, err: self._dump_error(err, self.class_name) ret_val = FAIL del rand_string except StandardError, err: self._dump_error(err, self.class_name) ret_val = FAIL del rand_string os.chdir(cwd) if ACTION_LOOKUP.get(action) == BACKUP: if type(ret_val) != type({}): erstr = "%s: backup method did not return a "\
def _backup(self, obj, backup_data, future_pkns, dry_run): "Perform basic backup functions for a package" pre_backup_cmd = obj.pre_backup post_backup_cmd = obj.post_backup if pre_backup_cmd: status = self._find_cmd(pre_backup_cmd, future_pkns=future_pkns, dry_run=dry_run) if status != OK: erstr = "%s: backup FAILED because pre-backup command failed." Logger.error(erstr % self.full_name) return FAIL file_names = backup_data.get("file_names") if type(file_names) != type([]): errmsg = "Package %s did not define its backup data correctly."\ " '%s' should be a list." Logger.error(errmsg % (self.full_name, file_names)) return FAIL options = backup_data.get("options", [COMPRESS]) if type(options) != type([]): errmsg = "Package %s did not define its backup data correctly."\ " '%s' should be a list." Logger.error(errmsg % (self.full_name, options)) return FAIL backup_dir = tempfile.mkdtemp() Logger.info("Temporary backup dir: %s" % backup_dir) start_time = time.time() backup_data = {"__START_TIME__": start_time} for file_name in file_names: backup_data[file_name] = {} current_start = time.time() if file_name.startswith(os.path.sep): backup_destination = make_path(backup_dir, file_name[1:]) fpf = ForwardPluggableFileProcessor(file_name, backup_destination, options, Logger) backup_file_name, md5_dict = fpf.process_all() if not os.path.isfile(backup_file_name): Logger.error("Backup file not created.") return FAIL backup_data[file_name]["md5"] = md5_dict backup_data[file_name]["backup_file"] = rpartition(backup_file_name, os.path.sep)[-1] elapsed_time = time.time() - current_start backup_data[file_name]["elapsed_time"] = elapsed_time size = os.stat(file_name)[stat.ST_SIZE] backup_data[file_name]["size"] = size backup_data[file_name]["status"] = OK if post_backup_cmd: status = self._find_cmd(post_backup_cmd, future_pkns=future_pkns, dry_run=dry_run) if status != OK: erstr = "%s: backup FAILED because post-backup command failed." Logger.error(erstr % self.full_name) return FAIL backup_data["__BACKUP_DIR__"] = backup_dir dump_string = yaml_dump(backup_data) for line in dump_string.split('\n'): Logger.info("==REPORT==:%s" % line) return OK
def _find_cmd(self, action, argument='', future_pkns=[], dry_run=False): ''' Perform the action on the system, importing modules from the package and running the appropriate method on the class within. action -- INSTALL, UNINSTALL, CONFIGURE, VERIFY future_pkns -- future package names. Some packages want to know about the packages that will come after them dry_run -- boolean flag to see if we're really going to do this ''' cwd = get_slash_cwd() sys.path.insert(0, self.scripts_dir) os.chdir(self.scripts_dir) files = self._get_possible_module_files() status = FAIL file_found = False for file_name in files: try: obj = Spkg.SpkgV4(self.config, logger=Logger) os.chdir(self.working_dir) letters = [ chr( x ) for x in range(65, 91) ] random.shuffle(letters) rand_string = ''.join(letters) exec("import %s as %s" % (file_name, rand_string)) self.config["__FUTURE_PACKAGES__"] = future_pkns self.config["__INSTANCE__"] = self.instance_name cmd_str = "obj = %s.%s(self.config, Logger)" exec(cmd_str % (rand_string, file_name)) file_found = True if not dry_run: if action == INSTALL: status = obj.installer() elif action == VERIFY: status = obj.verify() elif action == UNINSTALL: status = obj.uninstaller() elif action == CONFIGURE: status = obj.configure() else: raise FeatureRemovedException(action) else: status = OK del rand_string if file_name in sys.modules: sys.modules.pop(file_name) while self.scripts_dir in sys.path: sys.path.remove(self.scripts_dir) break except ImportError: msg = "File %s is not runnable. Looking for others" % file_name Logger.debug(msg) continue except SystemExit, err: if err.code: status = err.code else: status = 0 file_found = True break except KeyboardInterrupt: Logger.error("Keyboard interrupt detected. Exiting...") sys.exit(10)
def data_request(self): "Obtain configuration data from the server" b64_data = [] while True: #Logger.info( "STARTING READ" ) chunk = sys.stdin.read(STREAM_BLOCK_SIZE).strip() #Logger.info( "READ FROM SERVER: [%s]" % chunk) if not chunk or chunk[0] == ' ' or chunk.endswith("-"): chunk = chunk[:-1] b64_data.append(chunk) break b64_data.append(chunk) sys.stdout.write(">\n") sys.stdout.flush() #Logger.info("FINISHED INPUT LOOP") #print "b64_data: ", b64_data json_data = '' #json_data = zlib.decompress(base64.decodestring(''.join(b64_data))) json_data = base64.decodestring(''.join(b64_data)) #print "json_dataa", json_data Logger.debug("Received %s lines of json" % len(json_data.split('\n'))) try: input_data = json.loads(json_data) #print "input_dataa", input_data except: ermsg = "Configuration data not YAML-parseable: %s" % (repr(json_data)) file_number, filename = tempfile.mkstemp(suffix=".yml") fh = open(filename, 'w') Logger.error("Writing bad data to %s" % filename) for line in json_data.split('\n'): fh.write("[%s]" % line) fh.flush() fh.close() raise ConfigurationException(ermsg) if type(input_data) == type("string"): ermsg = "Configuration data not YAML-parseable: %s" % (repr(json_data)) raise ConfigurationException(ermsg) if type(input_data) != type({}) and type(input_data) != type([]): input_data = input_data.next() config_key = input_data.get("config_key", None) if config_key: try: from bombardier_core.Cipher import Cipher except ImportError: msg = "This machine cannot accept an encrypted configuration" raise ConfigurationException(msg) enc_json_file = make_path(get_spkg_path(), self.instance_name, 'client.yml.enc') if not os.path.isfile(enc_json_file): msg = "%s file doesn't exist" % enc_json_file raise ConfigurationException(msg) enc_data = open(enc_json_file).read() cipher = Cipher(config_key) plain_json_str = cipher.decrypt_string(enc_data) try: input_data = json.loads(plain_json_str) except: ermsg = "Received bad YAML file: %s" % enc_json_file raise ConfigurationException(ermsg) config_data = input_data.get("config_data") if not config_data: raise ConfigurationException("No configuration data received") package_data = input_data.get("package_data", {}) self.config = Config(self.instance_name, config_data) self.repository = Repository(self.instance_name, package_data)
def main(): Logger.add_std_err_logging() parser = optparse.OptionParser('\n'.join(USAGE)) parser.add_option("-s", "--status", dest="action", action="store_const", const=CHECK_STATUS, help="display the status of the system") parser.add_option("-c", "--configure", dest="action", action="store_const", const=CONFIGURE, help="configure a package") parser.add_option("-v", "--verify", dest="action", action="store_const", const=VERIFY, help="verify a package") parser.add_option("-i", "--install", dest="action", action="store_const", const=INSTALL, help="install a package") parser.add_option("-r", "--reconcile", dest="action", action="store_const", const=RECONCILE, help="reconcile the system") parser.add_option("-x", "--execute", dest="action", action="store_const", const=EXECUTE, help="Execute a maintenance script") parser.add_option("-u", "--uninstall", dest="action", action="store_const", const=UNINSTALL, help="uninstall a package") parser.add_option("-f", "--fix", dest="action", action="store_const", const=FIX, help="set a package status to INSTALLED without doing anything") parser.add_option("-p", "--purge", dest="action", action="store_const", const=PURGE, help="Remove a package from the status") parser.add_option("-d", "--dry-run", dest="action", action="store_const", const=DRY_RUN, help="Do a test reconcile") parser.add_option("-n", "--init", dest="action", action="store_const", const=INIT, help="Initialize the client after installation") parser.add_option("-B", "--backup", dest="action", action="store_const", const=BACKUP, help="Tell a package to back itself up") parser.add_option("-R", "--restore", dest="action", action="store_const", const=RESTORE, help="Tell a package to restore itself") (options, args) = parser.parse_args() Logger.info("options: (%s) / args: (%s)" % (options, args)) if options.action: Logger.info("Action: %s" % (ACTION_REVERSE_LOOKUP[options.action])) if len(args) < 1: print "CMD: %s" % ' '.join(sys.argv) print "This command requires an instance name." parser.print_help() exit_with_return_code(1) instance_name = args[0] env = BombardierEnvironment(instance_name) env.data_request() package_factory = PackageFactory(env) arguments = [] if options.action in [ RECONCILE, CHECK_STATUS, DRY_RUN, INIT ]: status = process_action(options.action, instance_name, '', '', '', package_factory) else: method_name = "" if len(args) < 2: print "CMD: %s" % ' '.join(sys.argv) print "This command requires a package name as an argument." Logger.error("This command requires a package name as an argument.") parser.print_help() exit_with_return_code( 1 ) package_name = args[1] if options.action == BACKUP: method_name = "backup" if options.action == RESTORE: method_name = "restore" arguments = args[2:] if options.action == EXECUTE: if len(args) < 3: print "CMD: %s" % ' '.join(sys.argv) print "This command requires a package name and a script name." Logger.error("This command requires a package name and a script name.") parser.print_help() exit_with_return_code( 1 ) package_name = args[1] method_name = args[2] if len(args) > 3: arguments = args[3:] status = process_action(options.action, instance_name, package_name, method_name, arguments, package_factory) if status != OK: exit_with_return_code(status) exit_with_return_code(status)
def _invalidate(self, exception_object): 'set the package as not operable' erstr = "INVALID PACKAGE: %s" % self.name Logger.error(erstr) Logger.error(str(exception_object)) self.status = FAIL
else: status = 0 file_found = True break except KeyboardInterrupt: Logger.error("Keyboard interrupt detected. Exiting...") sys.exit(10) except SyntaxError, err: self._dump_error(err, file_name) file_found = False break except StandardError, err: self._dump_error(err, file_name) file_found = True status = FAIL break os.chdir(cwd) if not file_found: msg = "Unable to find a suitable script to install." raise BadPackage(self.name, msg) if status == None: status = OK if status == REBOOT: raise RebootRequiredException(self.name) if status != OK: erstr = "%s: failed with status %s" % (self.full_name, status) Logger.error(erstr) return FAIL return OK