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 instance_setup(instance_name): "When Bombardier is first getting set up, this method is called." progress_path = get_progress_path(instance_name) status_dict = None if os.path.isfile(progress_path): try: status_dict = json.loads(open(progress_path).read()) except: msg = "Unable to load existing json from %s" % progress_path Logger.warning(msg) if type(status_dict) != type({}): status_dict = {"install-progress": {}} status_dict["client_version"] = CLIENT_VERSION status_dict["core_version"] = CORE_VERSION status_dict["clientVersion"] = CLIENT_VERSION status_dict["coreVersion"] = CORE_VERSION pkg_dir = make_path(get_spkg_path(), instance_name, "packages") repos_dir = make_path(get_spkg_path(), "repos") tmp_dir = make_path(get_spkg_path(), "tmp") if not os.path.isdir(pkg_dir): os.makedirs(pkg_dir) if not os.path.isdir(repos_dir): os.makedirs(repos_dir) if not os.path.isdir(tmp_dir): os.makedirs(tmp_dir) open(progress_path, 'w').write(json.dumps(status_dict))
def execute_maint_script(self, script_name): ''' execute a user-defined function script_name -- name of the function to run ''' Package.execute_maint_script(self) script_path = "%s/%s.py" % (self.maint_dir, script_name) start_dir = get_slash_cwd() os.chdir(self.maint_dir) if not os.path.isfile(script_path): msg = "%s does not exist" % script_path raise BadPackage, (self.name, msg) sys.path.append(self.maint_dir ) import_string = 'import %s' % script_name cmd = 'status = %s.execute(self.config, Logger)' % script_name job = Job(import_string, cmd, self.config) status = job.execute() sys.path.remove(self.maint_dir) os.chdir(start_dir) if status == None: status = OK if type(status) != type(1): msg = "Invalid status type (%s: '%s')" Logger.warning(msg % (type(status), status)) status = FAIL return status
def add_dependency_error(self, dependency_name): ''' Record the fact that the system has a dependency error. This is used when uninstalling packages later. dependency_name -- name of the dependency that is missing ''' errmsg = "BOM file is incomplete: should contain %s" % dependency_name Logger.warning(errmsg) self.dependency_errors.append(dependency_name)
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 _eval_priority(self): 'determine priority of this package' if not self.priority: self.priority = AVERAGE else: try: self.priority = int(self.priority) except ValueError: Logger.warning(ermsg) self.priority = AVERAGE
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 _gather_dependencies(self): 'determine what packages must be installed before this package' self.dependencies = self.meta_data.data.get("dependencies") if type(self.dependencies) == type(None): self.dependencies = [] elif type(self.dependencies) == type('string'): self.dependencies = [self.dependencies] elif type(self.dependencies) == type([]): pass else: errmsg = "Unsupported dependencies data for %s. "\ "Must be a list. [%s] instead." Logger.warning(errmsg % (self.name, self.dependencies)) self.dependencies = []
def _get_del_pkd(self, del_pkns): """ create a dictionary of package objects based on a list of names that we know we're supposed to remove del_pkns -- the names of packages that we should be removing """ pkd = {} for pkn in del_pkns: try: pkg = self._get_new_pkg(pkn) pkg.action = UNINSTALL pkd[pkn] = pkg except Exceptions.BadPackage, err: errmsg = "Skipping Bad package: %s" % err Logger.warning(errmsg)
def _get_add_pkd(self, add_pkns): """ create a pkd for package names that should be installed add_pkns -- the names of packages that we should be installing """ pkd = {} for pkn in add_pkns: try: pkg = self._get_new_pkg(pkn) self._check_configuration(pkg) pkd[pkn] = pkg except Exceptions.BadPackage, err: errmsg = "Skipping bad package %s: %s" % (err.pkn, err.errmsg) self.operation_output.append(errmsg) Logger.warning(errmsg)
def _filter_bad_pkgs(self): """ Go through my chain of packages, and if there are any 'bad' packages in the list of dependencies, cut off the package chain at that point """ index = 0 for index in range(0, len(self.chain)): pkn = self.chain[index] if pkn in self.broken_pkns: index -= 1 msg = "Omitting packages %s due to bad package" msg = msg % self.chain[index:] Logger.warning(msg) break self.chain = self.chain[: index + 1]
def _ck_inst_stat(self, bom_pkns): """ Given a list of packages that are supposed to be on this machine, we will look at the installation status and (1) make a decision on what packages should be removed (and in what order) and (2) decide which packages should be added. bom_pkns -- A list of package names that are intended to be installed on the machine (i.e. the 'bill of materials' """ if bom_pkns == []: bom_pkns = self.config.get_bom_pkns() if bom_pkns == []: Logger.warning("Empty Bill of Materials") add_pkns, del_pkns = self._check_bom(bom_pkns) add_pkd = self._get_add_pkd(add_pkns) del_pkd, uninstall_order = self._get_pkd_to_remove(del_pkns) return add_pkd, del_pkd, uninstall_order
def _check_configuration(self, pkg): """ Check to see if we have sufficient configuration data to mess around with a given package pkg -- a package object that we need to do something with """ if pkg.get_configuration(): required_configs = pkg.get_configuration() diff = diff_dicts(required_configs, self.config.data) if diff != {}: self.operation_status = FAIL errmsg = "This machine does not have sufficient " "configuration data to install %s " % pkg.name diff_txt = "" for key in diff: diff_txt += "key: %s; value: %s" % (key, diff[key]) Logger.warning(errmsg) Logger.warning(diff_txt) raise Exceptions.BadPackage(pkg.name, "Bad Config")
def _create_pkg_chains(self, pkd): """ Create package chains based on current set of packages pkd -- dictionary of package objects """ chains = [] pkg_data = self.progress.get_progress_data(False) installed_pkns, broken_pkns = Progress.get_installed(pkg_data) for pkn in pkd.keys(): if pkn in broken_pkns: Logger.warning("Skipping broken package %s" % pkn) continue if pkn not in installed_pkns: chain_priority = pkd[pkn].priority else: chain_priority = 0 try: new_chain = PackageChain( chain_priority, pkn, pkd, installed_pkns, broken_pkns, self.repository, self.config, self.instance_name, self.record_errors, ) except Exceptions.BadPackage, err: errmsg = "Package %s will not be installed because it is " "dependent upon one or more broken packages" Logger.warning(errmsg % pkn) Logger.warning(str(err)) continue chains.append([new_chain.priority, new_chain.chain])