예제 #1
0
파일: bc.py 프로젝트: psbanka/bombardier
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))
예제 #2
0
    def reconcile_system(self, action):
        """
        Figure out everything that needs to happen to get this machine into
        compliance with its stated configuration and do it
        action -- DRY_RUN or RECONCILE
        """

        self.operation_status = OK
        self.operation_output = []
        pkns = []
        dry_run = False

        if action == DRY_RUN:
            msg = "Reconcile dry-run starting..."
            Logger.info(msg)
            dry_run = True
        else:
            msg = "Reconcile starting..."
            Logger.info(msg)

        add_pkd, del_pkd, uninstall_order = self._ck_inst_stat(pkns)
        # Logger.info("uninstall_order: %s" % uninstall_order)
        status = self._uninstall_pkgs(del_pkd, uninstall_order, dry_run)
        if status == FAIL:
            msg = "Uninstallation failed. Aborting reconcile."
            self.operation_output.append(msg)
            self.operation_status = FAIL
            return self._cleanup()

        add_pkd, del_pkd, uninstall_order = self._ck_inst_stat(pkns)
        status = self._install_pkgs(add_pkd, dry_run)
        if status != OK:
            self.operation_status = FAIL
        self.operation_output.append("Finished installing")
        return self._cleanup()
예제 #3
0
 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
예제 #4
0
파일: bc.py 프로젝트: psbanka/bombardier
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)
예제 #5
0
    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
예제 #6
0
 def _uninstall_pkgs(self, del_pkd, uninstall_order, dry_run=False):
     """
     Given a dictionary of packages and an uninstall order, make some
     changes on this machine
     del_pkd -- A dictionary of package objects that are to
                be uninstalled
     uninstall_order -- the order with which to uninstall packages
     dry_run -- boolean flag indicating if we're serious about this or not
     """
     status = OK
     remove_full_pkns = []
     # Logger.info("UninstallOrder: %s" % uninstall_order)
     for name in uninstall_order:
         if del_pkd[name].full_name:
             name_str = del_pkd[name].full_name
         else:
             name_str = name
         remove_full_pkns.append(name_str)
     msg = "Packages to remove: %s" % remove_full_pkns
     Logger.info(msg)
     for pkn in uninstall_order:
         uninstall_status = del_pkd[pkn].uninstall(dry_run)
         if uninstall_status == FAIL:
             return FAIL
     return status
예제 #7
0
 def unzip_type_4(self, pkg_path, full_name):
     '''
     Perform untar/ungzip operations. (NOTE: NOT RELIABLE IN Python)
     pkg_path -- full path to package file, minus extension
     full_name -- name of the package, including version
     '''
     Logger.info("Unzipping %s" % full_name)
     self.untargz(pkg_path + ".spkg")
     return OK
예제 #8
0
 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)
예제 #9
0
 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
예제 #10
0
 def execute_maint_script(self, script_name, arguments):
     '''
     execute a user-defined function
     script_name -- name of the function to run
     arguments -- arguments to the script to be run
     '''
     Package.execute_maint_script(self, script_name)
     self.status = self._find_cmd(script_name, arguments=arguments)
     msg = "%s result for %s : %s"
     Logger.info(msg % (script_name, self.full_name, self.status))
     return self.status
예제 #11
0
파일: bc.py 프로젝트: psbanka/bombardier
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
예제 #12
0
 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
예제 #13
0
 def verify(self, dry_run=False): 
     '''
     Perform a verification action on this package
     dry_run -- whether to actually perform the action
     '''
     self._download()
     message = "Verifying package %s" % self.full_name
     Logger.info(message)
     self.status = self._find_cmd(VERIFY, dry_run=dry_run)
     if self.action != INSTALL:
         self._write_progress()
     Logger.info("Verify result for %s : %s" % (self.full_name, self.status))
     return self.status
예제 #14
0
 def execute_maint_script(self, script_name):
     '''
     execute a user-defined function
     script_name -- name of the function to run
     '''
     self._download()
     # remove old history
     output_path = make_path(get_spkg_path(), self.instance_name,
                               "output", "%s-output.yml" % script_name)
     if os.path.isfile(output_path):
         os.unlink(output_path)
     message = "Executing (%s) inside package (%s)"
     Logger.info(message % (script_name, self.full_name))
예제 #15
0
파일: bc.py 프로젝트: psbanka/bombardier
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
예제 #16
0
파일: Job.py 프로젝트: psbanka/bombardier
 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
예제 #17
0
 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 = []
예제 #18
0
 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)
예제 #19
0
 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]
예제 #20
0
 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)
예제 #21
0
 def _install(self, future_pkns, dry_run=False):
     '''
     perform an installation operation
     future_pkns -- package names to be installed after this one
     dry_run -- whether or not to actuall perform the installation
     '''
     dry_run_string = ""
     if dry_run:
         dry_run_string = " --DRY_RUN-- "
     self._download()
     message = "Beginning installation of (%s)%s"
     Logger.info(message % (self.full_name, dry_run_string))
     self.status = self._find_cmd(INSTALL, future_pkns=future_pkns, dry_run=dry_run)
     msg = "Install result for %s%s : %s"
     Logger.info(msg % (self.full_name, dry_run_string, self.status))
     return self.status
예제 #22
0
    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
예제 #23
0
 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
예제 #24
0
 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")
예제 #25
0
 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
예제 #26
0
 def uninstall(self, dry_run=False):
     '''
     Perform an uninstall action on this package
     dry_run -- whether to actually perform the action
     '''
     self.action = UNINSTALL
     self._download()
     if self.status != OK:
         return self.status
     dry_run_string = ""
     if dry_run:
         dry_run_string = " --DRY_RUN-- "
     msg = "Uninstalling package %s%s" % (self.name, dry_run_string)
     Logger.info(msg)
     self.status = self._find_cmd(UNINSTALL, dry_run=dry_run)
     if not dry_run:
         self._write_progress()
     msg = "Uninstall result for %s%s : %s"
     Logger.info(msg % (self.full_name, dry_run_string, self.status))
     return self.status
예제 #27
0
 def check_system(self):
     """
     After a system has had all of its packages installed and it's in
     stable-state, this is a method we can use to verify that everything
     is still kosher
     """
     Logger.info("System-check starting...")
     bom_pkns = self.config.get_bom_pkns()
     pdat = self.progress.get_progress_data()
     full_pdat = self.progress.get_progress_data(False)
     full_installed_pkns, _full_bpkns = Progress.get_installed(full_pdat)
     msg = "Packages that are installed: %s"
     Logger.info(msg % " ".join(full_installed_pkns))
     installed_pkns, broken_pkns = Progress.get_installed(pdat)
     should_be_installed, shouldnt_be_installed = self._check_bom(bom_pkns)
     # check the configuration for each installed package
     pkg_info = {
         "Packages installed properly": installed_pkns,
         "Packages to be RECONFIGURED": {},
         "Packages to be INSTALLED": should_be_installed,
         "Packages to be REMOVED": shouldnt_be_installed,
         "Packages that are BROKEN": broken_pkns,
     }
     for pkn in shouldnt_be_installed:
         pkg_info["Packages installed properly"].remove(pkn)
     for pkn in installed_pkns:
         differences = self._check_configuration_hash(pkn)
         if differences:
             if pkn in pkg_info["Packages installed properly"]:
                 pkg_info["Packages to be RECONFIGURED"][pkn] = differences
                 pkg_info["Packages installed properly"].remove(pkn)
     for key in pkg_info:
         Logger.info("==OUTPUT==:%s: %s" % (key, pkg_info[key]))
     return pkg_info
예제 #28
0
 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])
예제 #29
0
    def _sort_uninstalled_pkgs(self, uninstall_order):
        """Make sure packages get uninstalled in the right order, paying
        attention to dependencies.
        uninstall_order -- a list of package names the order of which indicates
                           which should be uninstalled first, second...
        """
        dependency_dict = {}
        if len(uninstall_order) > 1:
            Logger.info("Determining uninstallation order...")
            for pkn in uninstall_order:
                dependency_dict[pkn] = []

            for pkn in uninstall_order:
                pkg = self._get_new_pkg(pkn)
                for other_pkn in uninstall_order:
                    if other_pkn in pkg.dependencies:
                        dependency_dict[other_pkn].append(pkn)
        else:
            return uninstall_order

        new_proper_order = copy.deepcopy(uninstall_order)
        swapped = True

        while swapped:
            proper_order = copy.deepcopy(new_proper_order)
            swapped = False
            for pkn in proper_order:
                dependency_list = dependency_dict[pkn]
                for dependency in dependency_list:
                    index1 = proper_order.index(dependency)
                    index2 = proper_order.index(pkn)
                    if index1 > index2:
                        new_proper_order = swap(proper_order, index1, index2)
                        swapped = True
                        break
                if swapped:
                    break

        Logger.info("Uninstallation Order: %s" % new_proper_order)
        return new_proper_order
예제 #30
0
 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