Esempio n. 1
0
 def updateBaseRepo(self, fallback=True, root=None):
     logger.info("updating base repo")
     # start with a fresh YumBase instance
     self.reset(root=root)
     # see if we can get a usable base repo from self.data.method
     self._configureBaseRepo()
     self._yumCacheDirHack()
Esempio n. 2
0
 def updateBaseRepo(self, fallback=True, root=None):
     logger.info("updating base repo")
     # start with a fresh YumBase instance
     self.reset(root=root)
     # see if we can get a usable base repo from self.data.method
     self._configureBaseRepo()
     self._yumCacheDirHack()
Esempio n. 3
0
    def gatherRepoMetadata(self):
        # now go through and get metadata for all enabled repos
        logger.info("gathering repo metadata")
        for repo_id in self.repos:
            repo = self._yum.repos.getRepo(repo_id)
            if repo.enabled:
                try:
                    self._getRepoMetadata(repo)
                except PayloadError as e:
                    logger.error("failed to grab repo metadata for %s: %s"
                              % (repo_id, e))
                    self.disableRepo(repo_id)

        logger.info("metadata retrieval complete")
Esempio n. 4
0
    def gatherRepoMetadata(self):
        # now go through and get metadata for all enabled repos
        logger.info("gathering repo metadata")
        for repo_id in self.repos:
            repo = self._yum.repos.getRepo(repo_id)
            if repo.enabled:
                try:
                    self._getRepoMetadata(repo)
                except PayloadError as e:
                    logger.error("failed to grab repo metadata for %s: %s" %
                                 (repo_id, e))
                    self.disableRepo(repo_id)

        logger.info("metadata retrieval complete")
Esempio n. 5
0
    def _configureBaseRepo(self):
        logger.info("configuring base repo")
        if CF.S.BASE_REPO_URL.startswith('/'):
            url = "file://" + CF.S.BASE_REPO_URL
        else:
            url = CF.S.BASE_REPO_URL

        with _yum_lock:
            self._yum.preconf.releasever = self._getReleaseVersion(url)
            self._yumCacheDirHack()
        try:
            self._addYumRepo(CF.S.BASE_REPO_NAME, url)
        except:
            logger.error("base repo (%s) not valid -- removing it" % (url, ))
            self._removeYumRepo(CF.S.BASE_REPO_NAME)
            raise
Esempio n. 6
0
 def _configureBaseRepo(self):
     logger.info("configuring base repo")
     if CF.S.BASE_REPO_URL.startswith('/'):
         url = "file://" + CF.S.BASE_REPO_URL
     else:
         url = CF.S.BASE_REPO_URL
     
     with _yum_lock:
         self._yum.preconf.releasever = self._getReleaseVersion(url)
         self._yumCacheDirHack()
     try:
         self._addYumRepo(CF.S.BASE_REPO_NAME, url)
     except:
         logger.error("base repo (%s) not valid -- removing it"
                   % (url, ))
         self._removeYumRepo(CF.S.BASE_REPO_NAME)
         raise
Esempio n. 7
0
    def selectKernelPackage(self):
        kernels = self.kernelPackages
        selected = None
        # XXX This is optimistic. I'm curious if yum will DTRT if I just say
        #     "select this kernel" without jumping through hoops to figure out
        #     which arch it should use.
        for kernel in kernels:
            try:
                # XXX might need explicit arch specification
                self._selectYumPackage(kernel)
            except NoSuchPackage as e:
                logger.info("no %s package" % kernel)
                continue
            else:
                logger.info("selected %s" % kernel)
                selected = kernel
                # select module packages for this kernel

                # select the devel package if gcc will be installed
                if self._yum.tsInfo.matchNaevr(name="gcc"):
                    logger.info("selecting %s-devel" % kernel)
                    # XXX might need explicit arch specification
                    self._selectYumPackage("%s-devel" % kernel)

                break

        if not selected:
            logger.error("failed to select a kernel from %s" % kernels)
Esempio n. 8
0
    def selectKernelPackage(self):
        kernels = self.kernelPackages
        selected = None
        # XXX This is optimistic. I'm curious if yum will DTRT if I just say
        #     "select this kernel" without jumping through hoops to figure out
        #     which arch it should use.
        for kernel in kernels:
            try:
                # XXX might need explicit arch specification
                self._selectYumPackage(kernel)
            except NoSuchPackage as e:
                logger.info("no %s package" % kernel)
                continue
            else:
                logger.info("selected %s" % kernel)
                selected = kernel
                # select module packages for this kernel

                # select the devel package if gcc will be installed
                if self._yum.tsInfo.matchNaevr(name="gcc"):
                    logger.info("selecting %s-devel" % kernel)
                    # XXX might need explicit arch specification
                    self._selectYumPackage("%s-devel" % kernel)

                break

        if not selected:
            logger.error("failed to select a kernel from %s" % kernels)
Esempio n. 9
0
    def checkSoftwareSelection(self):
        logger.info("checking software selection")
        self.txID = time.time()

        self.release()

        with _yum_lock:
            self._yum._undoDepInstalls()

        self._applyYumSelections()

        with _yum_lock:
            # doPostSelection
            # select kernel packages
            # select packages needed for storage, bootloader

            # check dependencies
            logger.info("checking dependencies")
            (code, msgs) = self._yum.buildTransaction(
                unfinished_transactions_check=False)
            self._removeTxSaveFile()
            if code == 0:
                # empty transaction?
                logger.debug("empty transaction")
            elif code == 2:
                # success
                logger.debug("success")


#            elif self.data.packages.handleMissing == KS_MISSING_IGNORE:
#                logger.debug("ignoring missing due to ks config")
#            elif self.data.upgrade.upgrade:
#                logger.debug("ignoring unresolved deps on upgrade")
            else:
                for msg in msgs:
                    logger.warning(msg)

                raise DependencyError(msgs)

        self.calculateSpaceNeeds()
        logger.info("%d packages selected totalling %s" %
                    (len(self._yum.tsInfo.getMembers()), self.spaceRequired))
Esempio n. 10
0
    def checkSoftwareSelection(self):
        logger.info("checking software selection")
        self.txID = time.time()

        self.release()

        with _yum_lock:
            self._yum._undoDepInstalls()

        self._applyYumSelections()

        with _yum_lock:
            # doPostSelection
            # select kernel packages
            # select packages needed for storage, bootloader

            # check dependencies
            logger.info("checking dependencies")
            (code, msgs) = self._yum.buildTransaction(unfinished_transactions_check=False)
            self._removeTxSaveFile()
            if code == 0:
                # empty transaction?
                logger.debug("empty transaction")
            elif code == 2:
                # success
                logger.debug("success")
#            elif self.data.packages.handleMissing == KS_MISSING_IGNORE:
#                logger.debug("ignoring missing due to ks config")
#            elif self.data.upgrade.upgrade:
#                logger.debug("ignoring unresolved deps on upgrade")
            else:
                for msg in msgs:
                    logger.warning(msg)

                raise DependencyError(msgs)

        self.calculateSpaceNeeds()
        logger.info("%d packages selected totalling %s"
                 % (len(self._yum.tsInfo.getMembers()), self.spaceRequired))
Esempio n. 11
0
    def callback(self, event, amount, total, key, userdata):
        """ Yum install callback. """
        if event == rpm.RPMCALLBACK_TRANS_START: #@UndefinedVariable
            if amount == 6:
                self.progress.send_message(_("Preparing transaction from installation source"))
            self.total_actions = total
            self.completed_actions = 0
        elif event == rpm.RPMCALLBACK_TRANS_PROGRESS: #@UndefinedVariable
            # amount / total complete
            pass
        elif event == rpm.RPMCALLBACK_TRANS_STOP: #@UndefinedVariable
            # we are done
            pass
        elif event == rpm.RPMCALLBACK_INST_OPEN_FILE: #@UndefinedVariable
            # update status that we're installing/upgrading %h
            # return an open fd to the file
            txmbr = self._get_txmbr(key)[1]

            # If self.completed_actions is still None, that means this package
            # is being opened to retrieve a %pretrans script. Don't log that
            # we're installing the package unless we've been called with a
            # TRANS_START event.
            if self.completed_actions is not None:
                if self.upgrade:
                    mode = _("Upgrading")
                else:
                    mode = _("Installing")

                self.completed_actions += 1
                msg_format = "%s %s (%d/%d)"
                progress_package = txmbr.name
                if txmbr.arch not in ["noarch", self.base_arch]:
                    progress_package = "%s.%s" % (txmbr.name, txmbr.arch)

                progress_msg =  msg_format % (mode, progress_package,
                                              self.completed_actions,
                                              self.total_actions)
                log_msg = msg_format % (mode, txmbr.po,
                                        self.completed_actions,
                                        self.total_actions)
                logger.info(log_msg)
                self.install_log.write(log_msg+"\n")
                self.install_log.flush()

                self.progress.send_message(progress_msg)

            self.package_file = None
            repo = self._yum.repos.getRepo(txmbr.po.repoid)
            while self.package_file is None:
                try:
                    # checkfunc gets passed to yum's use of URLGrabber which
                    # then calls it with the file being fetched. verifyPkg
                    # makes sure the checksum matches the one in the metadata.
                    #
                    # From the URLGrab documents:
                    # checkfunc=(function, ('arg1', 2), {'kwarg': 3})
                    # results in a callback like:
                    #   function(obj, 'arg1', 2, kwarg=3)
                    #     obj.filename = '/tmp/stuff'
                    #     obj.url = 'http://foo.com/stuff'
                    checkfunc = (self._yum.verifyPkg, (txmbr.po, 1), {})
                    package_path = repo.getPackage(txmbr.po, checkfunc=checkfunc)
                except yum.URLGrabError as e:
                    logger.error("URLGrabError: %s" % (e,))
                    exn = PayloadInstallError("failed to get package")
                    #if errorHandler.cb(exn, txmbr.po) == ERROR_RAISE:
                    raise exn
                except (yum.Errors.NoMoreMirrorsRepoError, IOError):
                    if os.path.exists(txmbr.po.localPkg()):
                        os.unlink(txmbr.po.localPkg())
                        logger.debug("retrying download of %s" % txmbr.po)
                        continue
                    exn = PayloadInstallError("failed to open package")
                    #if errorHandler.cb(exn, txmbr.po) == ERROR_RAISE:
                    raise exn
                except yum.Errors.RepoError:
                    continue

                self.package_file = open(package_path)

            return self.package_file.fileno()
        elif event == rpm.RPMCALLBACK_INST_PROGRESS: #@UndefinedVariable
            txmbr = self._get_txmbr(key)[1]
            progress_package = txmbr.name
            if txmbr.arch not in ["noarch", self.base_arch]:
                progress_package = "%s.%s" % (txmbr.name, txmbr.arch)
            #self.progress.send_message('%s (%s/%s)' % (progress_package, amount, total))
        elif event == rpm.RPMCALLBACK_INST_CLOSE_FILE: #@UndefinedVariable
            # close and remove the last opened file
            # update count of installed/upgraded packages
            package_path = self.package_file.name
            self.package_file.close()
            self.package_file = None

            if package_path.startswith(_yum_cache_dir):
                try:
                    os.unlink(package_path)
                except OSError as e:
                    logger.debug("unable to remove file %s" % e.strerror)

            # rpm doesn't tell us when it's started post-trans stuff which can
            # take a very long time.  So when it closes the last package, just
            # display the message.
            if self.completed_actions == self.total_actions:
                self.progress.send_message(_("Performing post-install setup tasks"))
        elif event == rpm.RPMCALLBACK_UNINST_START: #@UndefinedVariable
            # update status that we're cleaning up %key
            #self.progress.set_text(_("Cleaning up %s" % key))
            pass
        elif event in (rpm.RPMCALLBACK_CPIO_ERROR, #@UndefinedVariable
                       rpm.RPMCALLBACK_UNPACK_ERROR, #@UndefinedVariable
                       rpm.RPMCALLBACK_SCRIPT_ERROR): #@UndefinedVariable
            name = self._get_txmbr(key)[0]

            # Script errors store whether or not they're fatal in "total".  So,
            # we should only error out for fatal script errors or the cpio and
            # unpack problems.
            if event != rpm.RPMCALLBACK_SCRIPT_ERROR or total: #@UndefinedVariable
                exn = PayloadInstallError("cpio, unpack, or fatal script error")
                #if errorHandler.cb(exn, name) == ERROR_RAISE:
                raise exn
Esempio n. 12
0
    def install(self):
        """ Install the payload. """
        from yum.Errors import PackageSackError, RepoError, YumBaseError

        logger.info("preparing transaction")
        logger.debug("initialize transaction set")
        with _yum_lock:
            self._yum.initActionTs()
            if rpmUtils and rpmUtils.arch.isMultiLibArch():
                self._yum.ts.ts.setColor(3)

            logger.debug("populate transaction set")
            try:
                # uses dsCallback.transactionPopulation
                self._yum.populateTs(keepold=0)
            except RepoError as e:
                logger.error("error populating transaction: %s" % e)
                exn = PayloadInstallError(str(e))
                #if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

            logger.debug("check transaction set")
            self._yum.ts.check()
            logger.debug("order transaction set")
            self._yum.ts.order()
            self._yum.ts.clean()

            # Write scriptlet output to a file to be logged later
            script_log = tempfile.NamedTemporaryFile(delete=False)
            self._yum.ts.ts.scriptFd = script_log.fileno()
            rpm.setLogFile(script_log) #@UndefinedVariable

            # create the install callback
            rpmcb = RPMCallback(self._yum, script_log, self.progress,
                                upgrade=False)

            if self.flags.testing:
                self._yum.ts.setFlags(rpm.RPMTRANS_FLAG_TEST) #@UndefinedVariable

            logger.info("running transaction")
            self.progress.send_step()
            try:
                self._yum.runTransaction(cb=rpmcb)
            except PackageSackError as e:
                logger.error("error running transaction: %s" % e)
                exn = PayloadInstallError(str(e))
                #if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
            except YumBaseError as e:
                logger.error("error [2] running transaction: %s" % e)
                for error in e.errors:
                    logger.error("%s" % error[0])
                exn = PayloadInstallError(str(e))
                #if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
            else:
                logger.info("transaction complete")
                self.progress.send_step()
            finally:
                self._yum.ts.close()
                iutil.resetRpmDb()
                script_log.close()

                # log the contents of the scriptlet logfile
                logger.info("==== start rpm scriptlet logs ====")
                with open(script_log.name) as f:
                    for l in f:
                        logger.info(l)
                logger.info("==== end rpm scriptlet logs ====")
                os.unlink(script_log.name)
Esempio n. 13
0
    def install(self):
        """ Install the payload. """
        from yum.Errors import PackageSackError, RepoError, YumBaseError

        logger.info("preparing transaction")
        logger.debug("initialize transaction set")
        with _yum_lock:
            self._yum.initActionTs()
            if rpmUtils and rpmUtils.arch.isMultiLibArch():
                self._yum.ts.ts.setColor(3)

            logger.debug("populate transaction set")
            try:
                # uses dsCallback.transactionPopulation
                self._yum.populateTs(keepold=0)
            except RepoError as e:
                logger.error("error populating transaction: %s" % e)
                exn = PayloadInstallError(str(e))
                #if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

            logger.debug("check transaction set")
            self._yum.ts.check()
            logger.debug("order transaction set")
            self._yum.ts.order()
            self._yum.ts.clean()

            # Write scriptlet output to a file to be logged later
            script_log = tempfile.NamedTemporaryFile(delete=False)
            self._yum.ts.ts.scriptFd = script_log.fileno()
            rpm.setLogFile(script_log)  #@UndefinedVariable

            # create the install callback
            rpmcb = RPMCallback(self._yum,
                                script_log,
                                self.progress,
                                upgrade=False)

            if self.flags.testing:
                self._yum.ts.setFlags(
                    rpm.RPMTRANS_FLAG_TEST)  #@UndefinedVariable

            logger.info("running transaction")
            self.progress.send_step()
            try:
                self._yum.runTransaction(cb=rpmcb)
            except PackageSackError as e:
                logger.error("error running transaction: %s" % e)
                exn = PayloadInstallError(str(e))
                #if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
            except YumBaseError as e:
                logger.error("error [2] running transaction: %s" % e)
                for error in e.errors:
                    logger.error("%s" % error[0])
                exn = PayloadInstallError(str(e))
                #if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
            else:
                logger.info("transaction complete")
                self.progress.send_step()
            finally:
                self._yum.ts.close()
                iutil.resetRpmDb()
                script_log.close()

                # log the contents of the scriptlet logfile
                logger.info("==== start rpm scriptlet logs ====")
                with open(script_log.name) as f:
                    for l in f:
                        logger.info(l)
                logger.info("==== end rpm scriptlet logs ====")
                os.unlink(script_log.name)
Esempio n. 14
0
    def callback(self, event, amount, total, key, userdata):
        """ Yum install callback. """
        if event == rpm.RPMCALLBACK_TRANS_START:  #@UndefinedVariable
            if amount == 6:
                self.progress.send_message(
                    _("Preparing transaction from installation source"))
            self.total_actions = total
            self.completed_actions = 0
        elif event == rpm.RPMCALLBACK_TRANS_PROGRESS:  #@UndefinedVariable
            # amount / total complete
            pass
        elif event == rpm.RPMCALLBACK_TRANS_STOP:  #@UndefinedVariable
            # we are done
            pass
        elif event == rpm.RPMCALLBACK_INST_OPEN_FILE:  #@UndefinedVariable
            # update status that we're installing/upgrading %h
            # return an open fd to the file
            txmbr = self._get_txmbr(key)[1]

            # If self.completed_actions is still None, that means this package
            # is being opened to retrieve a %pretrans script. Don't log that
            # we're installing the package unless we've been called with a
            # TRANS_START event.
            if self.completed_actions is not None:
                if self.upgrade:
                    mode = _("Upgrading")
                else:
                    mode = _("Installing")

                self.completed_actions += 1
                msg_format = "%s %s (%d/%d)"
                progress_package = txmbr.name
                if txmbr.arch not in ["noarch", self.base_arch]:
                    progress_package = "%s.%s" % (txmbr.name, txmbr.arch)

                progress_msg = msg_format % (mode, progress_package,
                                             self.completed_actions,
                                             self.total_actions)
                log_msg = msg_format % (mode, txmbr.po, self.completed_actions,
                                        self.total_actions)
                logger.info(log_msg)
                self.install_log.write(log_msg + "\n")
                self.install_log.flush()

                self.progress.send_message(progress_msg)

            self.package_file = None
            repo = self._yum.repos.getRepo(txmbr.po.repoid)
            while self.package_file is None:
                try:
                    # checkfunc gets passed to yum's use of URLGrabber which
                    # then calls it with the file being fetched. verifyPkg
                    # makes sure the checksum matches the one in the metadata.
                    #
                    # From the URLGrab documents:
                    # checkfunc=(function, ('arg1', 2), {'kwarg': 3})
                    # results in a callback like:
                    #   function(obj, 'arg1', 2, kwarg=3)
                    #     obj.filename = '/tmp/stuff'
                    #     obj.url = 'http://foo.com/stuff'
                    checkfunc = (self._yum.verifyPkg, (txmbr.po, 1), {})
                    package_path = repo.getPackage(txmbr.po,
                                                   checkfunc=checkfunc)
                except yum.URLGrabError as e:
                    logger.error("URLGrabError: %s" % (e, ))
                    exn = PayloadInstallError("failed to get package")
                    #if errorHandler.cb(exn, txmbr.po) == ERROR_RAISE:
                    raise exn
                except (yum.Errors.NoMoreMirrorsRepoError, IOError):
                    if os.path.exists(txmbr.po.localPkg()):
                        os.unlink(txmbr.po.localPkg())
                        logger.debug("retrying download of %s" % txmbr.po)
                        continue
                    exn = PayloadInstallError("failed to open package")
                    #if errorHandler.cb(exn, txmbr.po) == ERROR_RAISE:
                    raise exn
                except yum.Errors.RepoError:
                    continue

                self.package_file = open(package_path)

            return self.package_file.fileno()
        elif event == rpm.RPMCALLBACK_INST_PROGRESS:  #@UndefinedVariable
            txmbr = self._get_txmbr(key)[1]
            progress_package = txmbr.name
            if txmbr.arch not in ["noarch", self.base_arch]:
                progress_package = "%s.%s" % (txmbr.name, txmbr.arch)
            #self.progress.send_message('%s (%s/%s)' % (progress_package, amount, total))
        elif event == rpm.RPMCALLBACK_INST_CLOSE_FILE:  #@UndefinedVariable
            # close and remove the last opened file
            # update count of installed/upgraded packages
            package_path = self.package_file.name
            self.package_file.close()
            self.package_file = None

            if package_path.startswith(_yum_cache_dir):
                try:
                    os.unlink(package_path)
                except OSError as e:
                    logger.debug("unable to remove file %s" % e.strerror)

            # rpm doesn't tell us when it's started post-trans stuff which can
            # take a very long time.  So when it closes the last package, just
            # display the message.
            if self.completed_actions == self.total_actions:
                self.progress.send_message(
                    _("Performing post-install setup tasks"))
        elif event == rpm.RPMCALLBACK_UNINST_START:  #@UndefinedVariable
            # update status that we're cleaning up %key
            #self.progress.set_text(_("Cleaning up %s" % key))
            pass
        elif event in (
                rpm.RPMCALLBACK_CPIO_ERROR,  #@UndefinedVariable
                rpm.RPMCALLBACK_UNPACK_ERROR,  #@UndefinedVariable
                rpm.RPMCALLBACK_SCRIPT_ERROR):  #@UndefinedVariable
            name = self._get_txmbr(key)[0]

            # Script errors store whether or not they're fatal in "total".  So,
            # we should only error out for fatal script errors or the cpio and
            # unpack problems.
            if event != rpm.RPMCALLBACK_SCRIPT_ERROR or total:  #@UndefinedVariable
                exn = PayloadInstallError(
                    "cpio, unpack, or fatal script error")
                #if errorHandler.cb(exn, name) == ERROR_RAISE:
                raise exn