def _check_bom(self, bom_pkns):
        """ Check through what should be installed on the system and what
        is installed on the system and determine what packages aren't
        installed that should be and what packages are installed that
        shouldn't be.
        bom_pkns -- A list of package names that are intended to be
                    installed on the machine (i.e. the 'bill of
                    materials'
        """
        should_be_installed = []
        shouldnt_be_installed = []
        pdat = self.progress.get_progress_data(False)
        installed_pkns, broken_pkns = Progress.get_installed(pdat)

        all_pkns = set(installed_pkns).union(broken_pkns)
        all_plus_missing_pkns = self._examine_dependencies(all_pkns)
        missing_pkns = list(all_plus_missing_pkns - all_pkns)
        bom_pkns = bom_pkns + missing_pkns

        dependency_errors = self._get_dependency_errors(bom_pkns, pdat)
        if dependency_errors:
            errmsg = "The following packages are installed as " "dependencies %s" % dependency_errors
            Logger.debug(errmsg)
        bom_pkns += dependency_errors
        for pkn in installed_pkns:
            if pkn not in bom_pkns:
                shouldnt_be_installed.append(pkn)
        for pkn in bom_pkns:
            if pkn not in installed_pkns:
                should_be_installed.append(pkn)
        return should_be_installed, shouldnt_be_installed
Exemple #2
0
 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
Exemple #3
0
 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 _get_uninst_pkg_dep(self, pkd, del_pkns, installed_pkns):
        """Add any packages that are installed already which are dependent
        upon those to the list as well
        pkd -- The dictionary of package objects
        del_pkns -- names of packages we want to remove
        installed_pkns -- names of packages that are installed already
        """
        msg = "Checking dependencies of packages to be uninstalled %s..."
        msg = msg % del_pkns
        Logger.info(msg)
        v_pkgs = VirtualPackages(self.repository.pkg_data)
        uninstall_order = copy.deepcopy(del_pkns)
        while del_pkns:
            new_dependency_names = []
            del_pkns = []
            for pkn in installed_pkns:
                if pkn in pkd.keys():
                    Logger.debug("Package %s will already be deleted -- " "ignoring" % pkn)
                    continue
                pkg = self._get_new_pkg(pkn)
                pkg.action = UNINSTALL
                for tombstoned_pkns in pkd.keys():
                    vpn = v_pkgs.get_vpn_from_pkn(tombstoned_pkns)
                    if vpn in pkg.dependencies:
                        erstr = "Adding to package removal list: %s" " (depends on %s)"
                        uninstall_order.insert(0, pkn)
                        Logger.info(erstr % (pkn, tombstoned_pkns))
                        pkd[tombstoned_pkns].depends_on_me.append(pkn)
                        if pkn not in pkd.keys():
                            if pkn not in new_dependency_names:
                                pkd[pkn] = pkg
                                new_dependency_names.append(pkn)
                del_pkns = new_dependency_names

        proper_order = self._sort_uninstalled_pkgs(uninstall_order)
        return pkd, proper_order
Exemple #5
0
    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()
Exemple #6
0
    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)
Exemple #7
0
 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)