Example #1
0
 def get(self, *patterns):
     res = dnf.util.Bunch()
     res.environments = []
     res.groups = []
     for pat in patterns:
         envs = grps = []
         if self.kinds & self.ENVIRONMENTS:
             available = self.comps.environments_by_pattern(pat)
             installed = self.prst.environments_by_pattern(pat)
             envs = self._get(available,
                              installed)
             res.environments.extend(envs)
         if self.kinds & self.GROUPS:
             available = self.comps.groups_by_pattern(pat)
             installed = self.prst.groups_by_pattern(pat)
             grps = self._get(available,
                              installed)
             res.groups.extend(grps)
         if not envs and not grps:
             if self.status == self.INSTALLED:
                 msg = _("Group '%s' is not installed.") % ucd(pat)
             else:
                 msg = _("Group '%s' does not exist.") % ucd(pat)
             raise CompsError(msg)
     return res
Example #2
0
    def _hcmd_redo(self, extcmds):
        old = self.base.history_get_transaction(extcmds)
        if old is None:
            return 1, ['Failed history redo']
        tm = dnf.util.normalize_time(old.beg_timestamp)
        print('Repeating transaction %u, from %s' % (old.tid, tm))
        self.output.historyInfoCmdPkgsAltered(old)

        converter = dnf.history.TransactionConverter(self.base.sack)
        history = dnf.history.open_history(self.base.history)
        operations = history.transaction_nevra_ops(old.tid)

        # FIXME this is wrong. Will be fixed in new swdb design.
        #   Reason of a package installed in the original transaction is lost in the
        #   operation above and replaced by reason USER (in the operation below).
        #   (dependencies are promoted to user installed packages)

        try:
            self.base.transaction = converter.convert(operations, SwdbReason.USER)
        except dnf.exceptions.PackagesNotInstalledError as err:
            logger.info(_('No package %s installed.'),
                        self.output.term.bold(ucd(err.pkg_spec)))
            return 1, ['An operation cannot be redone']
        except dnf.exceptions.PackagesNotAvailableError as err:
            logger.info(_('No package %s available.'),
                        self.output.term.bold(ucd(err.pkg_spec)))
            return 1, ['An operation cannot be redone']
        else:
            return 2, ['Repeating transaction %u' % (old.tid,)]
Example #3
0
    def _hcmd_redo(self, extcmds):
        old = self.base.history_get_transaction(extcmds)
        if old is None:
            return 1, ['Failed history redo']
        tm = time.ctime(old.beg_timestamp)
        print('Repeating transaction %u, from %s' % (old.tid, tm))
        self.output.historyInfoCmdPkgsAltered(old)

        converter = dnf.history.TransactionConverter(self.base.sack)
        history = dnf.history.open_history(self.base.history)
        operations = history.transaction_nevra_ops(old.tid)

        hibeg = self.output.term.MODE['bold']
        hiend = self.output.term.MODE['normal']
        try:
            self.base.transaction = converter.convert(operations, 'history')
        except dnf.exceptions.PackagesNotInstalledError as err:
            logger.info(_('No package %s%s%s installed.'),
                        hibeg, ucd(err.pkg_spec), hiend)
            return 1, ['An operation cannot be redone']
        except dnf.exceptions.PackagesNotAvailableError as err:
            logger.info(_('No package %s%s%s available.'),
                        hibeg, ucd(err.pkg_spec), hiend)
            return 1, ['An operation cannot be redone']
        else:
            return 2, ['Repeating transaction %u' % (old.tid,)]
Example #4
0
File: cli.py Project: mscherer/dnf
    def history_undo_transaction(self, extcmd):
        """Undo given transaction."""
        old = self.history_get_transaction((extcmd,))
        if old is None:
            return 1, ['Failed history undo']

        tm = dnf.util.normalize_time(old.beg_timestamp)
        msg = _("Undoing transaction {}, from {}").format(old.tid, ucd(tm))
        logger.info(msg)
        self.output.historyInfoCmdPkgsAltered(old)  # :todo

        history = dnf.history.open_history(self.history)  # :todo

        try:
            self._history_undo_operations(
                history.transaction_nevra_ops(old.tid),
                old.tid)
        except dnf.exceptions.PackagesNotInstalledError as err:
            logger.info(_('No package %s installed.'),
                        self.output.term.bold(ucd(err.pkg_spec)))
            return 1, ['An operation cannot be undone']
        except dnf.exceptions.PackagesNotAvailableError as err:
            logger.info(_('No package %s available.'),
                        self.output.term.bold(ucd(err.pkg_spec)))
            return 1, ['An operation cannot be undone']
        except dnf.exceptions.MarkingError:
            assert False
        else:
            return 2, ["Undoing transaction %u" % (old.tid,)]
Example #5
0
File: group.py Project: edynox/dnf
    def _mark_install(self, patterns):
        prst = self.base.history.group
        q = CompsQuery(self.base.comps, prst,
                       CompsQuery.GROUPS | CompsQuery.ENVIRONMENTS,
                       CompsQuery.AVAILABLE | CompsQuery.INSTALLED)
        solver = self.base._build_comps_solver()
        res = q.get(*patterns)
        types = dnf.comps.DEFAULT | dnf.comps.MANDATORY | dnf.comps.OPTIONAL

        for env_id in res.environments:
            if not dnf.comps.install_or_skip(solver._environment_install,
                                             env_id, types):
                res.environments.remove(env_id)
        for group_id in res.groups:
            if not dnf.comps.install_or_skip(solver._group_install,
                                             group_id, types):
                res.groups.remove(group_id)

        if res.environments:
            logger.info(_('Environments marked installed: %s'),
                        ','.join([ucd(prst.environment(g).ui_name)
                                  for g in res.environments]))
        if res.groups:
            logger.info(_('Groups marked installed: %s'),
                        ','.join([ucd(prst.group(g).ui_name)
                                  for g in res.groups]))
        prst.commit()
 def _resolve_specs_enable_update_sack(self, module_specs):
     no_match_specs = []
     error_spec = []
     module_dicts = {}
     for spec in module_specs:
         module_list, nsvcap = self._get_modules(spec)
         if not module_list:
             no_match_specs.append(spec)
             continue
         try:
             module_dict = self._create_module_dict_and_enable(module_list, True)
             module_dicts[spec] = (nsvcap, module_dict)
         except (RuntimeError, EnableMultipleStreamsException) as e:
             error_spec.append(spec)
             logger.error(ucd(e))
             logger.error(_("Unable to resolve argument {}").format(spec))
     hot_fix_repos = [i.id for i in self.base.repos.iter_enabled() if i.module_hotfixes]
     try:
         solver_errors = self.base.sack.filter_modules(
             self.base._moduleContainer, hot_fix_repos, self.base.conf.installroot,
             self.base.conf.module_platform_id,
             self.base.conf.debug_solver)
     except hawkey.Exception as e:
         raise dnf.exceptions.Error(ucd(e))
     for spec, (nsvcap, moduleDict) in module_dicts.items():
         for streamDict in moduleDict.values():
             for modules in streamDict.values():
                 try:
                     self.base._moduleContainer.enableDependencyTree(
                         libdnf.module.VectorModulePackagePtr(modules))
                 except RuntimeError as e:
                     error_spec.append(spec)
                     logger.error(ucd(e))
                     logger.error(_("Unable to resolve argument {}").format(spec))
     return no_match_specs, error_spec, solver_errors, module_dicts
Example #7
0
    def _hcmd_redo(self, extcmds):
        try:
            extcmd, = extcmds
        except ValueError:
            if not extcmds:
                logger.critical(_("No transaction ID given"))
            elif len(extcmds) > 1:
                logger.critical(_("Found more than one transaction ID!"))
            return 1, ["Failed history redo"]

        old = self.base.history_get_transaction((extcmd,))
        if old is None:
            return 1, ["Failed history redo"]
        tm = time.ctime(old.beg_timestamp)
        print("Repeating transaction %u, from %s" % (old.tid, tm))
        self.output.historyInfoCmdPkgsAltered(old)

        converter = dnf.history.TransactionConverter(self.base.sack)
        history = dnf.history.open_history(self.base.history)
        operations = history.transaction_nevra_ops(old.tid)

        hibeg = self.output.term.MODE["bold"]
        hiend = self.output.term.MODE["normal"]
        try:
            self.base.transaction = converter.convert(operations, "history")
        except dnf.exceptions.PackagesNotInstalledError as err:
            logger.info(_("No package %s%s%s installed."), hibeg, ucd(err.pkg_spec), hiend)
            return 1, ["An operation cannot be redone"]
        except dnf.exceptions.PackagesNotAvailableError as err:
            logger.info(_("No package %s%s%s available."), hibeg, ucd(err.pkg_spec), hiend)
            return 1, ["An operation cannot be redone"]
        else:
            return 2, ["Repeating transaction %u" % (old.tid,)]
Example #8
0
File: config.py Project: edynox/dnf
    def _configure_from_options(self, opts):
        """Configure parts of CLI from the opts """
        config_args = ['plugins', 'version', 'config_file_path',
                       'debuglevel', 'errorlevel', 'installroot',
                       'best', 'assumeyes', 'assumeno', 'clean_requirements_on_remove', 'gpgcheck',
                       'showdupesfromrepos', 'plugins', 'ip_resolve',
                       'rpmverbosity', 'disable_excludes', 'color',
                       'downloadonly', 'exclude', 'excludepkgs', 'skip_broken',
                       'tsflags', 'arch', 'basearch', 'ignorearch', 'cacheonly', 'comment']

        for name in config_args:
            value = getattr(opts, name, None)
            if value is not None and value != []:
                confopt = self._get_option(name)
                if confopt:
                    confopt._set(value, dnf.conf.PRIO_COMMANDLINE)
                elif hasattr(self, name):
                    setattr(self, name, value)
                else:
                    logger.warning(_('Unknown configuration option: %s = %s'),
                                   ucd(name), ucd(value))

        if hasattr(opts, 'main_setopts'):
            # now set all the non-first-start opts from main from our setopts
            # pylint: disable=W0212
            for name, val in opts.main_setopts._get_kwargs():
                opt = self._get_option(name)
                if opt:
                    opt._set(val, dnf.conf.PRIO_COMMANDLINE)
                elif hasattr(self, name):
                    setattr(self, name, val)
                else:
                    msg = "Main config did not have a %s attr. before setopt"
                    logger.warning(msg, name)
Example #9
0
File: cli.py Project: StefDev/dnf
    def history_undo_transaction(self, extcmd):
        """Undo given transaction."""
        old = self.history_get_transaction((extcmd,))
        if old is None:
            return 1, ['Failed history undo']

        tm = time.ctime(old.beg_timestamp)
        print("Undoing transaction %u, from %s" % (old.tid, tm))
        self.output.historyInfoCmdPkgsAltered(old)  # :todo

        history = dnf.history.open_history(self.history)  # :todo

        hibeg = self.output.term.MODE['bold']
        hiend = self.output.term.MODE['normal']
        try:
            self.history_undo_operations(history.transaction_nevra_ops(old.tid))
        except dnf.exceptions.PackagesNotInstalledError as err:
            logger.info(_('No package %s%s%s installed.'),
                             hibeg, ucd(err.pkg_spec), hiend)
            return 1, ['An operation cannot be undone']
        except dnf.exceptions.PackagesNotAvailableError as err:
            logger.info(_('No package %s%s%s available.'),
                             hibeg, ucd(err.pkg_spec), hiend)
            return 1, ['An operation cannot be undone']
        except dnf.exceptions.MarkingError:
            assert False
        else:
            return 2, ["Undoing transaction %u" % (old.tid,)]
Example #10
0
 def dump_rpm_problems(self):
     self.write("%%%%RPMDB PROBLEMS\n")
     (missing, conflicts) = rpm_problems(self.base)
     self.write("".join(["Package %s requires %s\n" % (ucd(pkg), ucd(req))
                         for (req, pkg) in missing]))
     self.write("".join(["Package %s conflicts with %s\n" % (ucd(pkg),
                                                             ucd(conf))
                         for (conf, pkg) in conflicts]))
Example #11
0
File: cli.py Project: hnk/dnf
    def history_rollback_transaction(self, extcmd):
        """Rollback given transaction."""
        old = self.history_get_transaction((extcmd, ))
        if old is None:
            return 1, ['Failed history rollback, no transaction']
        last = self.history.last()
        if last is None:
            return 1, ['Failed history rollback, no last?']
        if old.tid == last.tid:
            return 0, ['Rollback to current, nothing to do']

        mobj = None
        for tid in self.history.old(list(range(old.tid + 1, last.tid + 1))):
            if tid.altered_lt_rpmdb:
                logger.warning(
                    _('Transaction history is incomplete, before %u.'),
                    tid.tid)
            elif tid.altered_gt_rpmdb:
                logger.warning(
                    _('Transaction history is incomplete, after %u.'), tid.tid)

            if mobj is None:
                mobj = dnf.yum.history.YumMergedHistoryTransaction(tid)
            else:
                mobj.merge(tid)

        tm = time.ctime(old.beg_timestamp)
        print("Rollback to transaction %u, from %s" % (old.tid, tm))
        print(self.output.fmtKeyValFill(
            "  Undoing the following transactions: ", ", ".join(
                (str(x) for x in mobj.tid))))
        self.output.historyInfoCmdPkgsAltered(mobj)  # :todo

        history = dnf.history.open_history(self.history)  # :todo
        operations = dnf.history.NEVRAOperations()
        for id_ in range(old.tid + 1, last.tid + 1):
            operations += history.transaction_nevra_ops(id_)

        hibeg = self.output.term.MODE['bold']
        hiend = self.output.term.MODE['normal']
        try:
            self.history_undo_operations(operations)
        except dnf.exceptions.PackagesNotInstalledError as err:
            logger.info(
                _('No package %s%s%s installed.'), hibeg, ucd(err.pkg_spec),
                hiend)
            return 1, ['A transaction cannot be undone']
        except dnf.exceptions.PackagesNotAvailableError as err:
            logger.info(
                _('No package %s%s%s available.'), hibeg, ucd(err.pkg_spec),
                hiend)
            return 1, ['A transaction cannot be undone']
        except dnf.exceptions.MarkingError:
            assert False
        else:
            return 2, ["Rollback to transaction %u" % (old.tid, )]
Example #12
0
    def exclude_pkgs(self, pkgs):
        # :api
        name = "excludepkgs"

        if pkgs is not None and pkgs != []:
            if self._has_option(name):
                self._set_value(name, pkgs, dnf.conf.PRIO_COMMANDLINE)
            else:
                logger.warning(_('Unknown configuration option: %s = %s'),
                               ucd(name), ucd(pkgs))
Example #13
0
    def history_rollback_transaction(self, extcmd):
        """Rollback given transaction."""
        old = self.history_get_transaction((extcmd,))
        if old is None:
            return 1, ['Failed history rollback, no transaction']
        last = self.history.last()
        if last is None:
            return 1, ['Failed history rollback, no last?']
        if old.tid == last.tid:
            return 0, ['Rollback to current, nothing to do']

        mobj = None
        for trans in self.history.old(list(range(old.tid + 1, last.tid + 1))):
            if trans.altered_lt_rpmdb:
                logger.warning(_('Transaction history is incomplete, before %u.'), trans.tid)
            elif trans.altered_gt_rpmdb:
                logger.warning(_('Transaction history is incomplete, after %u.'), trans.tid)

            if mobj is None:
                mobj = dnf.db.history.MergedTransactionWrapper(trans)
            else:
                mobj.merge(trans)

        tm = dnf.util.normalize_time(old.beg_timestamp)
        print("Rollback to transaction %u, from %s" % (old.tid, tm))
        print(self.output.fmtKeyValFill("  Undoing the following transactions: ",
                                        ", ".join((str(x) for x in mobj.tids()))))
        self.output.historyInfoCmdPkgsAltered(mobj)  # :todo

#        history = dnf.history.open_history(self.history)  # :todo
#        m = libdnf.transaction.MergedTransaction()

#        return

#        operations = dnf.history.NEVRAOperations()
#        for id_ in range(old.tid + 1, last.tid + 1):
#            operations += history.transaction_nevra_ops(id_)

        try:
            self._history_undo_operations(mobj, old.tid + 1, True, strict=self.conf.strict)
        except dnf.exceptions.PackagesNotInstalledError as err:
            raise
            logger.info(_('No package %s installed.'),
                        self.output.term.bold(ucd(err.pkg_spec)))
            return 1, ['A transaction cannot be undone']
        except dnf.exceptions.PackagesNotAvailableError as err:
            raise
            logger.info(_('No package %s available.'),
                        self.output.term.bold(ucd(err.pkg_spec)))
            return 1, ['A transaction cannot be undone']
        except dnf.exceptions.MarkingError:
            raise
            assert False
        else:
            return 2, ["Rollback to transaction %u" % (old.tid,)]
Example #14
0
File: config.py Project: edynox/dnf
    def exclude_pkgs(self, pkgs):
        # :api
        name = "excludepkgs"

        if pkgs is not None and pkgs != []:
            confopt = self._get_option(name)
            if confopt:
                confopt._set(pkgs, dnf.conf.PRIO_COMMANDLINE)
            else:
                logger.warning(_('Unknown configuration option: %s = %s'),
                               ucd(name), ucd(pkgs))
Example #15
0
 def _populate(self, parser, section, priority=PRIO_DEFAULT):
     """Set option values from an INI file section."""
     if parser.has_section(section):
         for name in parser.options(section):
             value = parser.get(section, name)
             opt = self._get_option(name)
             if opt and not opt._is_runtimeonly():
                 opt._set(value, priority)
             else:
                 logger.warning(_('Unknown configuration option: %s = %s'),
                                ucd(name), ucd(value))
Example #16
0
    def _hcmd_redo(self, extcmds):
        old = self.base.history_get_transaction(extcmds)
        if old is None:
            return 1, ['Failed history redo']
        tm = dnf.util.normalize_time(old.beg_timestamp)
        print('Repeating transaction %u, from %s' % (old.tid, tm))
        self.output.historyInfoCmdPkgsAltered(old)

        for i in old.packages():
            pkgs = list(self.base.sack.query().filter(nevra=str(i), reponame=i.from_repo))
            if i.action in dnf.transaction.FORWARD_ACTIONS:
                if not pkgs:
                    logger.info(_('No package %s available.'),
                    self.output.term.bold(ucd(str(i))))
                    return 1, ['An operation cannot be redone']
                pkg = pkgs[0]
                self.base.install(str(pkg))
            elif i.action == libdnf.transaction.TransactionItemAction_REMOVE:
                if not pkgs:
                    # package was removed already, we can skip removing it again
                    continue
                pkg = pkgs[0]
                self.base.remove(str(pkg))

        self.base.resolve()
        self.base.do_transaction()
Example #17
0
 def callback(self, what, amount, total, key, client_data):
     if isinstance(key, str):
         key = ucd(key)
     if what == rpm.RPMCALLBACK_TRANS_START:
         self._transStart(total)
     elif what == rpm.RPMCALLBACK_TRANS_STOP:
         self._transStop()
     elif what == rpm.RPMCALLBACK_ELEM_PROGRESS:
         # This callback type is issued every time the next transaction
         # element is about to be processed by RPM, before any other
         # callbacks are issued.  "amount" carries the index of the element.
         self._elemProgress(amount)
     elif what == rpm.RPMCALLBACK_INST_OPEN_FILE:
         return self._instOpenFile(key)
     elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
         self._instCloseFile(key)
     elif what == rpm.RPMCALLBACK_INST_PROGRESS:
         self._instProgress(amount, total, key)
     elif what == rpm.RPMCALLBACK_UNINST_STOP:
         self._unInstStop(key)
     elif what == rpm.RPMCALLBACK_CPIO_ERROR:
         self._cpioError(key)
     elif what == rpm.RPMCALLBACK_UNPACK_ERROR:
         self._unpackError(key)
     elif what == rpm.RPMCALLBACK_SCRIPT_ERROR:
         self._scriptError(amount, total, key)
     elif what == rpm.RPMCALLBACK_SCRIPT_STOP:
         self._scriptStop()
Example #18
0
File: comps.py Project: mluscon/dnf
    def _group_install(self, group_id, pkg_types, exclude, strict=True):
        group = self.comps._group_by_id(group_id)
        if not group:
            raise ValueError(_("Group_id '%s' does not exist.") % ucd(group_id))
        p_grp = self.persistor.group(group_id)
        if p_grp.installed:
            raise CompsError(_("Group '%s' is already installed.") %
                             group.ui_name)

        exclude = set() if exclude is None else set(exclude)
        p_grp.name = group.name
        p_grp.ui_name = group.ui_name
        p_grp.pkg_exclude.extend(exclude)
        p_grp.pkg_types = pkg_types
        p_grp.full_list.extend(self._full_package_set(group))

        trans = TransactionBunch()
        types = pkg_types & MANDATORY
        mandatory = self._pkgs_of_type(group, types, exclude)
        types = pkg_types & (DEFAULT | OPTIONAL)
        trans.install_opt = self._pkgs_of_type(group, types, exclude)

        if strict:
            trans.install = mandatory
        else:
            trans.install_opt.update(mandatory)
        return trans
Example #19
0
File: comps.py Project: edynox/dnf
    def _group_install(self, group_id, pkg_types, exclude, strict=True):
        if isinstance(group_id, SwdbGroup):
            group_id = group_id.name_id
        group = self.comps._group_by_id(group_id)
        if not group:
            raise ValueError(_("Group_id '%s' does not exist.") %
                             ucd(group_id))
        # this will return DnfSwdbGroup object
        p_grp = self.persistor.group(group_id)
        if p_grp and p_grp.installed:
            logger.warning(_("Group '%s' is already installed.") %
                           group.ui_name)
        else:
            p_grp = self.persistor.new_group(group_id, group.name,
                                             group.ui_name, 0, pkg_types)
            self.persistor.add_group(p_grp)
            self.persistor.install_group(p_grp)

        exclude = list() if exclude is None else list(exclude)
        p_grp.add_exclude(exclude)
        p_grp.add_package(list(self._full_package_set(group)))

        trans = TransactionBunch()
        trans.install.update(self._pkgs_of_type(group, pkg_types, exclude))
        return trans
    def sack(self):
        ''' Generate cache of available packages '''
        # We generate this cache only if the repos were just freshed or if the
        # cache file doesn't exist

        fresh = False
        for repo in self.base.repos.iter_enabled():
            if repo.metadata is not None and repo.metadata.fresh:
                # One fresh repo is enough to cause a regen of the cache
                fresh = True
                break

        if not os.path.exists(self.cache_file) or fresh:
            try:
                with sqlite3.connect(self.cache_file) as conn:
                    self._out('Generating completion cache...')
                    cur = conn.cursor()
                    cur.execute(
                        "create table if not exists available (pkg TEXT)")
                    cur.execute(
                        "create unique index if not exists "
                        "pkg_available ON available(pkg)")
                    cur.execute("delete from available")
                    avail_pkgs = self.base.sack.query().available()
                    avail_pkgs_insert = [["{}.{}".format(x.name, x.arch)]
                                         for x in avail_pkgs if x.arch != "src"]
                    cur.executemany("insert or ignore into available values (?)",
                                    avail_pkgs_insert)
                    conn.commit()
            except sqlite3.OperationalError as e:
                self._out("Can't write completion cache: %s" % ucd(e))
Example #21
0
 def callback( self, what, bytes, total, h, user ):
     if isinstance(h, str):
         h = ucd(h)
     if what == rpm.RPMCALLBACK_TRANS_START:
         self._transStart( bytes, total, h )
     elif what == rpm.RPMCALLBACK_TRANS_PROGRESS:
         self._transProgress( bytes, total, h )
     elif what == rpm.RPMCALLBACK_TRANS_STOP:
         self._transStop( bytes, total, h )
     elif what == rpm.RPMCALLBACK_INST_OPEN_FILE:
         return self._instOpenFile( bytes, total, h )
     elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
         self._instCloseFile(  bytes, total, h )
     elif what == rpm.RPMCALLBACK_INST_PROGRESS:
         self._instProgress( bytes, total, h )
     elif what == rpm.RPMCALLBACK_UNINST_START:
         self._unInstStart( bytes, total, h )
     elif what == rpm.RPMCALLBACK_UNINST_PROGRESS:
         self._unInstProgress( bytes, total, h )
     elif what == rpm.RPMCALLBACK_UNINST_STOP:
         self._unInstStop( bytes, total, h )
     elif what == rpm.RPMCALLBACK_CPIO_ERROR:
         self._cpioError(bytes, total, h)
     elif what == rpm.RPMCALLBACK_UNPACK_ERROR:
         self._unpackError(bytes, total, h)
     elif what == rpm.RPMCALLBACK_SCRIPT_ERROR:
         self._scriptError(bytes, total, h)
     elif what == rpm.RPMCALLBACK_SCRIPT_START:
         self._scriptStart(bytes, total, h)
     elif what == rpm.RPMCALLBACK_SCRIPT_STOP:
         self._scriptStop(bytes, total, h);
    def _modules_reset_or_disable(self, module_specs, to_state):
        no_match_specs = []
        for spec in module_specs:
            module_list, nsvcap = self._get_modules(spec)
            if not module_list:
                logger.error(_("Unable to resolve argument {}").format(spec))
                no_match_specs.append(spec)
                continue
            if nsvcap.stream or nsvcap.version or nsvcap.context or nsvcap.arch or nsvcap.profile:
                logger.info(_("Only module name is required. "
                              "Ignoring unneeded information in argument: '{}'").format(spec))
            module_names = set()
            for module in module_list:
                module_names.add(module.getName())
            for name in module_names:
                if to_state == STATE_UNKNOWN:
                    self.base._moduleContainer.reset(name)
                if to_state == STATE_DISABLED:
                    self.base._moduleContainer.disable(name)

        hot_fix_repos = [i.id for i in self.base.repos.iter_enabled() if i.module_hotfixes]
        try:
            solver_errors = self.base.sack.filter_modules(
                self.base._moduleContainer, hot_fix_repos, self.base.conf.installroot,
                self.base.conf.module_platform_id, update_only=True,
                debugsolver=self.base.conf.debug_solver)
        except hawkey.Exception as e:
            raise dnf.exceptions.Error(ucd(e))
        return no_match_specs, solver_errors
Example #23
0
File: main.py Project: AdamWill/dnf
def resolving(cli, base):
    """Perform the depsolve, download and RPM transaction stage."""

    if base.transaction is None:
        base.resolve(cli.demands.allow_erasing)
        logger.info(_('Dependencies resolved.'))

    # Run the transaction
    displays = []
    if cli.demands.transaction_display is not None:
        displays.append(cli.demands.transaction_display)
    try:
        base.do_transaction(display=displays)
    except dnf.cli.CliError as exc:
        logger.error(ucd(exc))
        return 1
    except dnf.exceptions.TransactionCheckError as err:
        for msg in cli.command.get_error_output(err):
            logger.critical(msg)
        return 1
    except IOError as e:
        return ex_IOError(e)
    else:
        logger.info(_('Complete!'))
    return 0
Example #24
0
    def read_dump_file(filename):
        if filename.endswith(".gz"):
            fobj = gzip.GzipFile(filename)
        else:
            fobj = open(filename)

        if ucd(fobj.readline()) != DEBUG_VERSION:
            dnfpluginsextras.logger.error(_("Bad dnf debug file: %s"), filename)
            raise dnf.exceptions.Error

        skip = True
        pkgs = {}
        for line in fobj:
            line = ucd(line)
            if skip:
                if line == "%%%%RPMDB\n":
                    skip = False
                continue

            if not line or line[0] != " ":
                break

            pkg_spec = line.strip()
            nevra = hawkey.split_nevra(pkg_spec)
            pkgs[(nevra.name, nevra.arch)] = ["install", ucd(nevra.name),
                                              ucd(nevra.arch),
                                              ucd(nevra.epoch),
                                              ucd(nevra.version),
                                              ucd(nevra.release)]

        return pkgs
Example #25
0
 def test_dump(self):
     dump = self.repo.dump()
     f = io.StringIO(ucd(dump))
     parser = iniparse.compat.ConfigParser()
     parser.readfp(f)
     self.assertIn('r', parser.sections())
     opts = parser.options('r')
     self.assertIn('bandwidth', opts)
     self.assertIn('gpgkey', opts)
 def transaction(self):
     ''' Generate cache of installed packages '''
     try:
         with open(self.installed_cache_file, 'w') as cache_file:
             installed_packages = self.base.sack.query().installed()
             self._out('Generating completion cache...')
             for package in installed_packages:
                 cache_file.write(package.name + '\n')
     except Exception as e:
         self._out("Can't write completion cache: %s" % ucd(e))
Example #27
0
File: comps.py Project: refnode/dnf
def install_or_skip(install_fnc, grp_or_env, types, exclude=None):
    """Either mark in persistor as installed given `grp_or_env` (group
       or environment) or skip it (if it's already installed).
       `install_fnc` has to be Solver.group_install
       or Solver.environment_install.
       """
    try:
        return install_fnc(grp_or_env, types, exclude)
    except dnf.comps.CompsError as e:
        logger.warning("%s, %s", ucd(e)[:-1], _("skipping."))
Example #28
0
File: group.py Project: edynox/dnf
    def _mark_remove(self, patterns):
        prst = self.base.history.group
        q = CompsQuery(self.base.comps, prst,
                       CompsQuery.GROUPS | CompsQuery.ENVIRONMENTS,
                       CompsQuery.INSTALLED)
        solver = self.base._build_comps_solver()
        res = q.get(*patterns)
        for env_id in res.environments:
            solver._environment_remove(env_id)
        for grp_id in res.groups:
            solver._group_remove(grp_id)

        if res.environments:
            logger.info(_('Environments marked removed: %s'),
                        ','.join([ucd(prst.environment(e_id).ui_name)
                                  for e_id in res.environments]))
        if res.groups:
            logger.info(_('Groups marked removed: %s'),
                        ','.join([ucd(prst.group(g_id).ui_name)
                                  for g_id in res.groups]))
        prst.commit()
Example #29
0
 def __getattr__(self, name):
     if "_config" not in self.__dict__:
         raise AttributeError("'{}' object has no attribute '{}'".format(self.__class__, name))
     option = getattr(self._config, name)
     if option is None:
         return None
     try:
         value = option().getValue()
     except Exception as ex:
         return None
     if isinstance(value, str):
         return ucd(value)
     return value
Example #30
0
    def transaction(self):
        main, crepo = self.main, self.crepo

        if not main["enabled"]:
            return

        repodir = main["repodir"]
        if not os.path.exists(repodir):
            try:
                os.makedirs(repodir, mode=0o755)
            except OSError as e:
                self.logger.error("local: " + _(
                    "Unable to create a directory '{}' due to '{}'").format(repodir, ucd(e)))
                return
        elif not os.path.isdir(repodir):
            self.logger.error(
                "local: " + _("'{}' is not a directory").format(repodir))
            return

        needs_rebuild = False
        for pkg in self.base.transaction.install_set:
            path = pkg.localPkg()
            if os.path.dirname(path) == repodir:
                continue
            self.logger.debug(
                "local: " + _("Copying '{}' to local repo").format(path))
            try:
                shutil.copy2(path, repodir)
                needs_rebuild = True
            except IOError:
                self.logger.error(
                    "local: " + _("Can't write file '{}'").format(os.path.join(
                        repodir, os.path.basename(path))))

        if not crepo["enabled"] or not needs_rebuild:
            return

        args = ["createrepo_c", "--update", "--unique-md-filenames"]
        if crepo["verbose"]:
            args.append("--verbose")
        elif crepo["quiet"]:
            args.append("--quiet")
        if crepo["cachedir"] is not None:
            args.append("--cachedir")
            args.append(crepo["cachedir"])
        args.append(repodir)
        self.logger.debug("local: " + _("Rebuilding local repo"))
        p = subprocess.Popen(args, stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)
        for line in p.stdout:
            print(line.decode().rstrip("\n"))
Example #31
0
 def _log_errors(self, errors):
     for error in errors:
         error = ucd(error)
         self.swdb.log_error(self._tid, error)
Example #32
0
    def configure(self, args, option_parser=None):
        """Parse command line arguments, and set up :attr:`self.base.conf` and
        :attr:`self.cmds`, as well as logger objects in base instance.

        :param args: a list of command line arguments
        :param option_parser: a class for parsing cli options
        """
        self.optparser = dnf.cli.option_parser.OptionParser() \
            if option_parser is None else option_parser
        opts = self.optparser.parse_main_args(args)

        # Just print out the version if that's what the user wanted
        if opts.version:
            print(dnf.const.VERSION)
            print_versions(self.base.conf.history_record_packages, self.base,
                           self.base.output)
            sys.exit(0)

        if opts.quiet:
            opts.debuglevel = 0
            opts.errorlevel = 0
        if opts.verbose:
            opts.debuglevel = opts.errorlevel = dnf.const.VERBOSE_LEVEL

        # Read up configuration options and initialize plugins
        try:
            self.base.conf._configure_from_options(opts)
            self._read_conf_file(opts.releasever)
        except (dnf.exceptions.ConfigError, ValueError) as e:
            logger.critical(_('Config error: %s'), e)
            sys.exit(1)
        except IOError as e:
            e = '%s: %s' % (ucd(e.args[1]), repr(e.filename))
            logger.critical(_('Config error: %s'), e)
            sys.exit(1)

        # store the main commands & summaries, before plugins are loaded
        self.optparser.add_commands(self.cli_commands, 'main')
        # store the plugin commands & summaries
        self.base.init_plugins(opts.disableplugins, self)
        self.optparser.add_commands(self.cli_commands, 'plugin')

        # show help if no command specified
        # this is done here, because we first have the full
        # usage info after the plugins are loaded.
        if not opts.command:
            self.optparser.print_help()
            sys.exit(0)

        # save our original args out
        self.base.args = args
        # save out as a nice command string
        self.cmdstring = dnf.const.PROGRAM_NAME + ' '
        for arg in self.base.args:
            self.cmdstring += '%s ' % arg

        self._log_essentials()
        try:
            self._parse_commands(opts, args)
        except CliError:
            sys.exit(1)

        # show help for dnf <command> --help / --help-cmd
        if opts.help:
            self.optparser.print_help(self.command)
            sys.exit(0)

        opts = self.optparser.parse_command_args(self.command, args)

        if opts.allowerasing:
            self.demands.allow_erasing = opts.allowerasing
        if opts.freshest_metadata:
            self.demands.freshest_metadata = opts.freshest_metadata
        if opts.debugsolver:
            self.base.conf.debug_solver = True
        if opts.cacheonly:
            self.demands.cacheonly = True

        # with cachedir in place we can configure stuff depending on it:
        self.base._activate_persistor()

        self._configure_repos(opts)

        self.base.configure_plugins()

        self.base.conf._configure_from_options(opts)

        self.command.configure()

        if self.base.conf.color != 'auto':
            self.base.output.term.reinit(color=self.base.conf.color)
Example #33
0
    def __init__(self, section='main', parser=None):
        # pylint: disable=R0915
        super(MainConf, self).__init__(section, parser)
        self.substitutions = dnf.conf.substitutions.Substitutions()
        # setup different cache and log for non-priviledged users
        if dnf.util.am_i_root():
            cachedir = dnf.const.SYSTEM_CACHEDIR
            logdir = '/var/log'
        else:
            try:
                cachedir = logdir = misc.getCacheDir()
            except (IOError, OSError) as e:
                logger.critical(_('Could not set cachedir: %s'), ucd(e))

        self._add_option('debuglevel',
                         IntOption(2, range_min=0, range_max=10)) # :api
        self._add_option('errorlevel', IntOption(2, range_min=0, range_max=10))

        self._add_option('installroot', PathOption('/', abspath=True)) # :api
        self._add_option('config_file_path',
                         PathOption(dnf.const.CONF_FILENAME)) # :api
        self._add_option('plugins', BoolOption(True))
        self._add_option('pluginpath', ListOption([dnf.const.PLUGINPATH])) # :api
        self._add_option('pluginconfpath',
                         ListOption([dnf.const.PLUGINCONFPATH])) # :api
        self._add_option('persistdir', PathOption(dnf.const.PERSISTDIR)) # :api
        self._add_option('recent', IntOption(7, range_min=0))
        self._add_option('retries', PositiveIntOption(10, names_of_0=["0"]))
        self._add_option('reset_nice', BoolOption(True))

        self._add_option('cachedir', PathOption(cachedir)) # :api
        self._add_option('system_cachedir',
                         PathOption(dnf.const.SYSTEM_CACHEDIR)) # :api

        self._add_option('keepcache', BoolOption(False))
        self._add_option('logdir', Option(logdir)) # :api
        self._add_option('reposdir', ListOption(['/etc/yum.repos.d',
                                                 '/etc/yum/repos.d',
                                                 '/etc/distro.repos.d'])) # :api

        self._add_option('debug_solver', BoolOption(False))

        self._add_option('excludepkgs', ListAppendOption())
        self._add_option('includepkgs', ListAppendOption())
        self._add_option('exclude', self._get_option('excludepkgs'))
            # ^ compatibility with yum
        self._add_option('fastestmirror', BoolOption(False))
        self._add_option('proxy', UrlOption(schemes=('http', 'ftp', 'https',
                                                     'socks5', 'socks5h',
                                                     'socks4', 'socks4a'),
                                            allow_none=True)) # :api
        self._add_option('proxy_username', Option()) # :api
        self._add_option('proxy_password', Option()) # :api
        self._add_option('protected_packages',
                         ListOption("dnf glob:/etc/yum/protected.d/*.conf " \
                                    "glob:/etc/dnf/protected.d/*.conf")) #:api
        self._add_option('username', Option()) # :api
        self._add_option('password', Option()) # :api
        self._add_option('installonlypkgs', ListAppendOption(dnf.const.INSTALLONLYPKGS))
        self._add_option('group_package_types', ListOption(dnf.const.GROUP_PACKAGE_TYPES))
            # NOTE: If you set this to 2, then because it keeps the current
            # kernel it means if you ever install an "old" kernel it'll get rid
            # of the newest one so you probably want to use 3 as a minimum
            # ... if you turn it on.
        self._add_option('installonly_limit',
                         PositiveIntOption(0, range_min=2,
                                           names_of_0=["0", "<off>"])) # :api
        self._add_option('tsflags', ListAppendOption())  # :api

        self._add_option('assumeyes', BoolOption(False)) # :api
        self._add_option('assumeno', BoolOption(False))
        self._add_option('check_config_file_age', BoolOption(True))
        self._add_option('defaultyes', BoolOption(False))
        self._add_option('alwaysprompt', BoolOption(True))
        self._add_option('diskspacecheck', BoolOption(True))
        self._add_option('gpgcheck', BoolOption(False))
        self._add_option('repo_gpgcheck', BoolOption(False))
        self._add_option('localpkg_gpgcheck', BoolOption(False))
        self._add_option('obsoletes', BoolOption(True))
        self._add_option('showdupesfromrepos', BoolOption(False))
        self._add_option('enabled', BoolOption(True))
        self._add_option('enablegroups', BoolOption(True))
        self._add_option('exit_on_lock', BoolOption(False))

        self._add_option('bandwidth', BytesOption(0))
        self._add_option('minrate', BytesOption(1000))
        self._add_option('ip_resolve',
                         CaselessSelectionOption(choices=('ipv4', 'ipv6',
                                                          'whatever'),
                                                 mapper={'4': 'ipv4',
                                                         '6': 'ipv6'}))
        self._add_option('throttle', ThrottleOption(0))
        self._add_option('timeout', SecondsOption(120))
        self._add_option('max_parallel_downloads', IntOption(None, range_min=1))

        self._add_option('metadata_expire',
                         SecondsOption(60 * 60 * 48))    # 48 hours
        self._add_option('metadata_timer_sync',
                         SecondsOption(60 * 60 * 3)) #  3 hours
        self._add_option('disable_excludes', ListOption())
        self._add_option('multilib_policy',
                         SelectionOption('best', choices=('best', 'all'))) # :api
        self._add_option('best', BoolOption(False)) # :api
        self._add_option('install_weak_deps', BoolOption(True))
        self._add_option('bugtracker_url', Option(dnf.const.BUGTRACKER))

        self._add_option('color',
                         SelectionOption('auto',
                                         choices=('auto', 'never', 'always'),
                                         mapper={'on': 'always', 'yes' : 'always',
                                                 '1' : 'always', 'true': 'always',
                                                 'off': 'never', 'no':   'never',
                                                 '0':   'never', 'false': 'never',
                                                 'tty': 'auto', 'if-tty': 'auto'})
                        )
        self._add_option('color_list_installed_older', Option('bold'))
        self._add_option('color_list_installed_newer', Option('bold,yellow'))
        self._add_option('color_list_installed_reinstall', Option('normal'))
        self._add_option('color_list_installed_extra', Option('bold,red'))
        self._add_option('color_list_available_upgrade', Option('bold,blue'))
        self._add_option('color_list_available_downgrade', Option('dim,cyan'))
        self._add_option('color_list_available_reinstall',
                         Option('bold,underline,green'))
        self._add_option('color_list_available_install', Option('normal'))
        self._add_option('color_update_installed', Option('normal'))
        self._add_option('color_update_local', Option('bold'))
        self._add_option('color_update_remote', Option('normal'))
        self._add_option('color_search_match', Option('bold'))

        self._add_option('sslcacert', PathOption()) # :api
        self._add_option('sslverify', BoolOption(True)) # :api
        self._add_option('sslclientcert', Option()) # :api
        self._add_option('sslclientkey', Option()) # :api
        self._add_option('deltarpm', BoolOption(True))
        self._add_option('deltarpm_percentage',
                         PositiveIntOption(75, names_of_0=["0", "<off>"]))

        self._add_option('history_record', BoolOption(True))
        self._add_option('history_record_packages', ListOption(['dnf', 'rpm']))

        self._add_option('rpmverbosity', Option('info'))
        self._add_option('strict', BoolOption(True)) # :api
        self._add_option('skip_broken', BoolOption(False))  # :yum-compatibility
        self._add_option('clean_requirements_on_remove', BoolOption(True))
        self._add_option('history_list_view',
                         SelectionOption('commands',
                                         choices=('single-user-commands',
                                                  'users', 'commands'),
                                         mapper={'cmds': 'commands',
                                                 'default': 'commands'}))
        self._add_option('upgrade_group_objects_upgrade',
                         BoolOption(True))  # :api

        # runtime only options
        self._add_option('downloadonly', BoolOption(False, runtimeonly=True))
Example #34
0
 def log_scriptlet_output(self, msg):
     if msg is None or not hasattr(self, '_tid'):
         return  # Not configured to run
     for error in msg.splitlines():
         error = ucd(error)
         self.swdb.log_output(self._tid, error)
Example #35
0
    def do_transaction(self, display=()):
        """Take care of package downloading, checking, user
        confirmation and actually running the transaction.

        :param display: `TransactionDisplay` object(s)
        :return: a numeric return code, and optionally a list of
           errors.  A negative return code indicates that errors
           occurred in the pre-transaction checks
        """

        grp_diff = self._groups_diff()
        grp_str = self.output.list_group_transaction(self.comps, grp_diff)
        if grp_str:
            logger.info(grp_str)
        trans = self.transaction
        pkg_str = self.output.list_transaction(trans)
        if pkg_str:
            logger.info(pkg_str)

        if trans:
            # Check which packages have to be downloaded
            downloadpkgs = []
            rmpkgs = []
            stuff_to_download = False
            install_only = True
            for tsi in trans:
                installed = tsi.installed
                if installed is not None:
                    stuff_to_download = True
                    downloadpkgs.append(installed)
                erased = tsi.erased
                if erased is not None:
                    install_only = False
                    rmpkgs.append(erased)

            # Close the connection to the rpmdb so that rpm doesn't hold the
            # SIGINT handler during the downloads.
            del self.ts

            # report the total download size to the user
            if not stuff_to_download:
                self.output.reportRemoveSize(rmpkgs)
            else:
                self.output.reportDownloadSize(downloadpkgs, install_only)

        if trans or (grp_diff and not grp_diff.empty()):
            # confirm with user
            if self._promptWanted():
                if self.conf.assumeno or not self.output.userconfirm():
                    raise CliError(_("Operation aborted."))
        else:
            logger.info(_('Nothing to do.'))
            return

        if trans:
            if downloadpkgs:
                logger.info(_('Downloading Packages:'))
            try:
                total_cb = self.output.download_callback_total_cb
                self.download_packages(downloadpkgs, self.output.progress,
                                       total_cb)
            except dnf.exceptions.DownloadError as e:
                specific = dnf.cli.format.indent_block(ucd(e))
                errstring = _('Error downloading packages:\n%s') % specific
                raise dnf.exceptions.Error(errstring)
            # Check GPG signatures
            self.gpgsigcheck(downloadpkgs)

        if not isinstance(display, collections.Sequence):
            display = [display]
        display = [output.CliTransactionDisplay()] + list(display)
        super(BaseCli, self).do_transaction(display)
        if trans:
            msg = self.output.post_transaction_output(trans)
            logger.info(msg)
Example #36
0
    def configure(self, args, option_parser=None):
        """Parse command line arguments, and set up :attr:`self.base.conf` and
        :attr:`self.cmds`, as well as logger objects in base instance.

        :param args: a list of command line arguments
        :param option_parser: a class for parsing cli options
        """
        aliases = dnf.cli.aliases.Aliases()
        args = aliases.resolve(args)

        self.optparser = dnf.cli.option_parser.OptionParser() \
            if option_parser is None else option_parser
        opts = self.optparser.parse_main_args(args)

        # Just print out the version if that's what the user wanted
        if opts.version:
            print(dnf.const.VERSION)
            print_versions(self.base.conf.history_record_packages, self.base,
                           self.base.output)
            sys.exit(0)

        if opts.quiet:
            opts.debuglevel = 0
            opts.errorlevel = 2
        if opts.verbose:
            opts.debuglevel = opts.errorlevel = dnf.const.VERBOSE_LEVEL

        # Read up configuration options and initialize plugins
        try:
            if opts.cacheonly:
                opt = self.base.conf._get_option("cachedir")
                opt._set(self.base.conf.system_cachedir, dnf.conf.PRIO_DEFAULT)
                self.demands.cacheonly = True
            self.base.conf._configure_from_options(opts)
            self._read_conf_file(opts.releasever)
            if 'arch' in opts:
                self.base.conf.arch = opts.arch
            self.base.conf._adjust_conf_options()
        except (dnf.exceptions.ConfigError, ValueError) as e:
            logger.critical(_('Config error: %s'), e)
            sys.exit(1)
        except IOError as e:
            e = '%s: %s' % (ucd(str(e)), repr(e.filename))
            logger.critical(_('Config error: %s'), e)
            sys.exit(1)
        if opts.destdir is not None:
            self.base.conf.destdir = opts.destdir
            if not self.base.conf.downloadonly and opts.command not in (
                    'download', 'system-upgrade', 'reposync'):
                logger.critical(
                    _('--destdir or --downloaddir must be used with --downloadonly '
                      'or download or system-upgrade command.'))
                sys.exit(1)
        if (opts.set_enabled
                or opts.set_disabled) and opts.command != 'config-manager':
            logger.critical(
                _('--enable, --set-enabled and --disable, --set-disabled '
                  'must be used with config-manager command.'))
            sys.exit(1)

        if opts.sleeptime is not None:
            time.sleep(random.randrange(opts.sleeptime * 60))

        # store the main commands & summaries, before plugins are loaded
        self.optparser.add_commands(self.cli_commands, 'main')
        # store the plugin commands & summaries
        self.base.init_plugins(opts.disableplugin, opts.enableplugin, self)
        self.optparser.add_commands(self.cli_commands, 'plugin')

        # show help if no command specified
        # this is done here, because we first have the full
        # usage info after the plugins are loaded.
        if not opts.command:
            self.optparser.print_help()
            sys.exit(0)

        # save our original args out
        self.base.args = args
        # save out as a nice command string
        self.cmdstring = dnf.const.PROGRAM_NAME + ' '
        for arg in self.base.args:
            self.cmdstring += '%s ' % arg

        self._log_essentials()
        try:
            self._parse_commands(opts, args)
        except CliError:
            sys.exit(1)

        # show help for dnf <command> --help / --help-cmd
        if opts.help:
            self.optparser.print_help(self.command)
            sys.exit(0)

        opts = self.optparser.parse_command_args(self.command, args)

        if opts.allowerasing:
            self.demands.allow_erasing = opts.allowerasing
            self.base._allow_erasing = True
        if opts.freshest_metadata:
            self.demands.freshest_metadata = opts.freshest_metadata
        if opts.debugsolver:
            self.base.conf.debug_solver = True
        if opts.obsoletes:
            self.base.conf.obsoletes = True
        self.command.pre_configure()
        self.base.pre_configure_plugins()

        # with cachedir in place we can configure stuff depending on it:
        self.base._activate_persistor()

        self._configure_repos(opts)

        self.base.configure_plugins()

        self.base.conf._configure_from_options(opts)

        self.command.configure()

        if self.base.conf.destdir:
            dnf.util.ensure_dir(self.base.conf.destdir)
            self.base.repos.all().pkgdir = self.base.conf.destdir

        if self.base.conf.color != 'auto':
            self.base.output.term.reinit(color=self.base.conf.color)
Example #37
0
    def history_rollback_transaction(self, extcmd):
        """Rollback given transaction."""
        old = self.history_get_transaction((extcmd, ))
        if old is None:
            return 1, ['Failed history rollback, no transaction']
        last = self.history.last()
        if last is None:
            return 1, ['Failed history rollback, no last?']
        if old.tid == last.tid:
            return 0, ['Rollback to current, nothing to do']

        mobj = None
        for trans in self.history.old(list(range(old.tid + 1, last.tid + 1))):
            if trans.altered_lt_rpmdb:
                logger.warning(
                    _('Transaction history is incomplete, before %u.'),
                    trans.tid)
            elif trans.altered_gt_rpmdb:
                logger.warning(
                    _('Transaction history is incomplete, after %u.'),
                    trans.tid)

            if mobj is None:
                mobj = dnf.db.history.MergedTransactionWrapper(trans)
            else:
                mobj.merge(trans)

        tm = dnf.util.normalize_time(old.beg_timestamp)
        print("Rollback to transaction %u, from %s" % (old.tid, tm))
        print(
            self.output.fmtKeyValFill("  Undoing the following transactions: ",
                                      ", ".join(
                                          (str(x) for x in mobj.tids()))))
        self.output.historyInfoCmdPkgsAltered(mobj)  # :todo

        #        history = dnf.history.open_history(self.history)  # :todo
        #        m = libdnf.transaction.MergedTransaction()

        #        return

        #        operations = dnf.history.NEVRAOperations()
        #        for id_ in range(old.tid + 1, last.tid + 1):
        #            operations += history.transaction_nevra_ops(id_)

        try:
            self._history_undo_operations(mobj,
                                          old.tid + 1,
                                          True,
                                          strict=self.conf.strict)
        except dnf.exceptions.PackagesNotInstalledError as err:
            raise
            logger.info(_('No package %s installed.'),
                        self.output.term.bold(ucd(err.pkg_spec)))
            return 1, ['A transaction cannot be undone']
        except dnf.exceptions.PackagesNotAvailableError as err:
            raise
            logger.info(_('No package %s available.'),
                        self.output.term.bold(ucd(err.pkg_spec)))
            return 1, ['A transaction cannot be undone']
        except dnf.exceptions.MarkingError:
            raise
            assert False
        else:
            return 2, ["Rollback to transaction %u" % (old.tid, )]
Example #38
0
    def _configure_from_options(self, opts):
        """Configure parts of CLI from the opts """
        config_args = [
            'plugins', 'version', 'config_file_path', 'debuglevel',
            'errorlevel', 'installroot', 'best', 'assumeyes', 'assumeno',
            'clean_requirements_on_remove', 'gpgcheck', 'showdupesfromrepos',
            'plugins', 'ip_resolve', 'rpmverbosity', 'disable_excludes',
            'color', 'downloadonly', 'exclude', 'excludepkgs', 'skip_broken',
            'tsflags', 'arch', 'basearch', 'ignorearch', 'cacheonly', 'comment'
        ]

        for name in config_args:
            value = getattr(opts, name, None)
            if value is not None and value != []:
                opt = self._get_option(name)
                if opt is not None:
                    appendValue = False
                    if self._config:
                        try:
                            appendValue = self._config.optBinds().at(
                                name).getAddValue()
                        except RuntimeError:
                            # fails if option with "name" does not exist in _config (libdnf)
                            pass
                    if appendValue:
                        add_priority = dnf.conf.PRIO_COMMANDLINE
                        if add_priority < opt._get_priority():
                            add_priority = opt._get_priority()
                        for item in value:
                            if item:
                                opt._set(opt._get() + [item], add_priority)
                            else:
                                opt._set([], dnf.conf.PRIO_COMMANDLINE)
                    else:
                        opt._set(value, dnf.conf.PRIO_COMMANDLINE)
                elif hasattr(self, name):
                    setattr(self, name, value)
                else:
                    logger.warning(_('Unknown configuration option: %s = %s'),
                                   ucd(name), ucd(value))

        if getattr(opts, 'gpgcheck', None) is False:
            opt = self._get_option("localpkg_gpgcheck")
            opt._set(False, dnf.conf.PRIO_COMMANDLINE)

        if hasattr(opts, 'main_setopts'):
            # now set all the non-first-start opts from main from our setopts
            # pylint: disable=W0212
            for name, values in opts.main_setopts.items():
                for val in values:
                    if hasattr(self._config, name):
                        try:
                            # values in main_setopts are strings, try to parse it using newString()
                            self._config.optBinds().at(name).newString(
                                PRIO_COMMANDLINE, val)
                        except RuntimeError as e:
                            raise dnf.exceptions.ConfigError(_(
                                "Error parsing --setopt with key '%s', value '%s': %s"
                            ) % (name, val, str(e)),
                                                             raw_error=str(e))
                    else:
                        # if config option with "name" doesn't exist in _config, it could be defined
                        # only in Python layer
                        if hasattr(self, name):
                            setattr(self, name, val)
                        else:
                            msg = _(
                                "Main config did not have a %s attr. before setopt"
                            )
                            logger.warning(msg, name)
Example #39
0
    def configure(self, args):
        """Parse command line arguments, and set up :attr:`self.base.conf` and
        :attr:`self.cmds`, as well as logger objects in base instance.

        :param args: a list of command line arguments
        """
        self.optparser = dnf.cli.option_parser.OptionParser()
        opts, cmds = self.optparser.parse_known_args(args)

        # Just print out the version if that's what the user wanted
        if opts.version:
            print(dnf.const.VERSION)
            opts.quiet = True
            opts.verbose = False

        # go through all the setopts and set the global ones
        bad_setopt_tm, bad_setopt_ne = self._parse_setopts(opts.setopts)

        if self.main_setopts:
            for opt in self.main_setopts.items:
                setattr(opts, opt, getattr(self.main_setopts, opt))

        # get the install root to use
        self.optparser._checkAbsInstallRoot(opts.installroot)
        (root,
         opts.conffile) = self._root_and_conffile(opts.installroot,
                                                  opts.conffile)
        # the conffile is solid now
        assert (opts.conffile is not None)
        if opts.quiet:
            opts.debuglevel = 0
        if opts.verbose:
            opts.debuglevel = opts.errorlevel = dnf.const.VERBOSE_LEVEL

        # Read up configuration options and initialize plugins
        overrides = self.optparser._non_nones2dict(
            self._get_first_config(opts))
        releasever = opts.releasever
        try:
            self.read_conf_file(opts.conffile, root, releasever, overrides)

            # now set all the non-first-start opts from main from our setopts
            if self.main_setopts:
                for opt in self.main_setopts.items:
                    if not hasattr(self.base.conf, opt):
                        msg = "Main config did not have a %s attr. before setopt"
                        logger.warning(msg % opt)
                    setattr(self.base.conf, opt,
                            getattr(self.main_setopts, opt))

        except (dnf.exceptions.ConfigError, ValueError) as e:
            logger.critical(_('Config error: %s'), e)
            sys.exit(1)
        except IOError as e:
            e = '%s: %s' % (ucd(e.args[1]), repr(e.filename))
            logger.critical(_('Config error: %s'), e)
            sys.exit(1)
        for item in bad_setopt_tm:
            msg = "Setopt argument has multiple values: %s"
            logger.warning(msg % item)
        for item in bad_setopt_ne:
            msg = "Setopt argument has no value: %s"
            logger.warning(msg % item)

        self.optparser.configure_from_options(opts, self.base.conf,
                                              self.demands, self.base.output)
        self.base.cmds = cmds

        if opts.version:
            opts.quiet = True
            opts.verbose = False
        if opts.quiet:
            opts.debuglevel = 0
        if opts.verbose:
            opts.debuglevel = opts.errorlevel = dnf.const.VERBOSE_LEVEL
        self.nogpgcheck = opts.nogpgcheck

        # the configuration reading phase is now concluded, finish the init
        self._configure_cachedir()
        # with cachedir in place we can configure stuff depending on it:
        self.base.activate_persistor()
        self._configure_repos(opts)

        if opts.version:
            print_versions(self.base.conf.history_record_packages, self.base,
                           self.base.output)
            sys.exit(0)

        # store the main commands & summaries, before plugins are loaded
        self.optparser.add_commands(self.cli_commands, 'main')
        if self.base.conf.plugins:
            self.base.plugins.load(self.base.conf.pluginpath,
                                   opts.disableplugins)
        self.base.plugins.run_init(self.base, self)
        # store the plugin commands & summaries
        self.optparser.add_commands(self.cli_commands, 'plugin')

        # build the usage info and put it into the optparser.
        self.optparser.usage = self.optparser.get_usage()

        # show help if the user requests it
        # this is done here, because we first have the full
        # usage info after the plugins are loaded.
        if opts.help:
            self.optparser.print_help()
            sys.exit(0)

        # save our original args out
        self.base.args = args
        # save out as a nice command string
        self.cmdstring = dnf.const.PROGRAM_NAME + ' '
        for arg in self.base.args:
            self.cmdstring += '%s ' % arg

        self._log_essentials()
        try:
            self._parse_commands(
            )  # before we return check over the base command
            # + args make sure they match/make sense
        except CliError:
            sys.exit(1)
        self.command.configure(self.base.extcmds)

        if opts.debugsolver:
            self.base.conf.debug_solver = True

        self.base.plugins.run_config()
Example #40
0
def _per_nevra_dict(pkg_list):
    return {ucd(pkg): pkg for pkg in pkg_list}
Example #41
0
 def __unicode__(self):
     return ucd(self.__str__())
Example #42
0
 def __init__(self, value=None, raw_error=None):
     super(ConfigError, self).__init__(value)
     self.raw_error = ucd(raw_error) if raw_error is not None else None
Example #43
0
 def __init__(self, value=None):
     super(Error, self).__init__()
     self.value = None if value is None else ucd(value)
Example #44
0
 def six_digits(num):
     return ucd(dnf.pycomp.format("%6d", num, True))
Example #45
0
 def messages(self):
     messages = self._scriptOutput()
     if messages:
         for line in messages.splitlines():
             yield ucd(line)
Example #46
0
 def __init__(self, value=None, pkg_spec=None):
     """Initialize the marking error instance."""
     super(MarkingError, self).__init__(value)
     self.pkg_spec = None if pkg_spec is None else ucd(pkg_spec)
Example #47
0
def _num2ui_num(num):
    return ucd(dnf.pycomp.format("%d", num, True))
Example #48
0
File: main.py Project: rcutmore/dnf
def ex_Error(e):
    logger.log(dnf.logging.SUBDEBUG, '', exc_info=True)
    if e.value is not None:
        logger.critical(_('Error: %s'), ucd(e))
    return 1
Example #49
0
    def do_transaction(self, display=()):
        """Take care of package downloading, checking, user
        confirmation and actually running the transaction.

        :param display: `rpm.callback.TransactionProgress` object(s)
        :return: history database transaction ID or None
        """
        if dnf.base.WITH_MODULES:
            if not self.conf.module_stream_switch:
                switchedModules = dict(
                    self._moduleContainer.getSwitchedStreams())
                if switchedModules:
                    report_module_switch(switchedModules)
                    msg = _(
                        "It is not possible to switch enabled streams of a module unless explicitly "
                        "enabled via configuration option module_stream_switch.\n"
                        "It is recommended to rather remove all installed content from the module, and "
                        "reset the module using '{prog} module reset <module_name>' command. After "
                        "you reset the module, you can install the other stream."
                    ).format(prog=dnf.util.MAIN_PROG)
                    raise dnf.exceptions.Error(msg)

        trans = self.transaction
        pkg_str = self.output.list_transaction(trans)
        if pkg_str:
            logger.info(pkg_str)

        if trans:
            # Check which packages have to be downloaded
            install_pkgs = []
            rmpkgs = []
            install_only = True
            for tsi in trans:
                if tsi.action in dnf.transaction.FORWARD_ACTIONS:
                    install_pkgs.append(tsi.pkg)
                elif tsi.action in dnf.transaction.BACKWARD_ACTIONS:
                    install_only = False
                    rmpkgs.append(tsi.pkg)

            # Close the connection to the rpmdb so that rpm doesn't hold the
            # SIGINT handler during the downloads.
            del self._ts

            # report the total download size to the user
            if not install_pkgs:
                self.output.reportRemoveSize(rmpkgs)
            else:
                self.output.reportDownloadSize(install_pkgs, install_only)

        if trans or self._moduleContainer.isChanged() or \
                (self._history and (self._history.group or self._history.env)):
            # confirm with user
            if self.conf.downloadonly:
                logger.info(
                    _("{prog} will only download packages for the transaction."
                      ).format(prog=dnf.util.MAIN_PROG_UPPER))
            elif 'test' in self.conf.tsflags:
                logger.info(
                    _("{prog} will only download packages, install gpg keys, and check the "
                      "transaction.").format(prog=dnf.util.MAIN_PROG_UPPER))
            if self._promptWanted():
                if self.conf.assumeno or not self.output.userconfirm():
                    raise CliError(_("Operation aborted."))
        else:
            logger.info(_('Nothing to do.'))
            return

        if trans:
            if install_pkgs:
                logger.info(_('Downloading Packages:'))
                try:
                    total_cb = self.output.download_callback_total_cb
                    self.download_packages(install_pkgs, self.output.progress,
                                           total_cb)
                except dnf.exceptions.DownloadError as e:
                    specific = dnf.cli.format.indent_block(ucd(e))
                    errstr = _(
                        'Error downloading packages:') + '\n%s' % specific
                    # setting the new line to prevent next chars being eaten up
                    # by carriage returns
                    print()
                    raise dnf.exceptions.Error(errstr)
            # Check GPG signatures
            self.gpgsigcheck(install_pkgs)

        if self.conf.downloadonly:
            return

        if not isinstance(display, Sequence):
            display = [display]
        display = [output.CliTransactionDisplay()] + list(display)
        tid = super(BaseCli, self).do_transaction(display)

        # display last transaction (which was closed during do_transaction())
        if tid is not None:
            trans = self.history.old([tid])[0]
            trans = dnf.db.group.RPMTransaction(self.history, trans._trans)
        else:
            trans = None

        if trans:
            # the post transaction summary is already written to log during
            # Base.do_transaction() so here only print the messages to the
            # user arranged in columns
            print()
            print('\n'.join(self.output.post_transaction_output(trans)))
            print()
            for tsi in trans:
                if tsi.state == libdnf.transaction.TransactionItemState_ERROR:
                    raise dnf.exceptions.Error(_('Transaction failed'))

        return tid
Example #50
0
    def _get_key_for_package(self, po, askcb=None, fullaskcb=None):
        """Retrieve a key for a package. If needed, use the given
        callback to prompt whether the key should be imported.

        :param po: the package object to retrieve the key of
        :param askcb: Callback function to use to ask permission to
           import a key.  The arguments *askck* should take are the
           package object, the userid of the key, and the keyid
        :param fullaskcb: Callback function to use to ask permission to
           import a key.  This differs from *askcb* in that it gets
           passed a dictionary so that we can expand the values passed.
        :raises: :class:`dnf.exceptions.Error` if there are errors
           retrieving the keys
        """
        repo = self.repos[po.repoid]
        keyurls = repo.gpgkey
        key_installed = False

        def _prov_key_data(msg):
            msg += _('Failing package is: %s') % (po) + '\n '
            msg += _('GPG Keys are configured as: %s') % \
                    (', '.join(repo.gpgkey) + '\n')
            return '\n\n\n' + msg

        user_cb_fail = False
        for keyurl in keyurls:
            keys = dnf.crypto.retrieve(keyurl, repo)

            for info in keys:
                ts = self._rpmconn.readonly_ts
                # Check if key is already installed
                if misc.keyInstalled(ts, info.rpm_id, info.timestamp) >= 0:
                    msg = _('GPG key at %s (0x%s) is already installed')
                    logger.info(msg, keyurl, info.short_id)
                    continue

                # Try installing/updating GPG key
                info.url = keyurl
                dnf.crypto.log_key_import(info)
                rc = False
                if self.conf.assumeno:
                    rc = False
                elif self.conf.assumeyes:
                    rc = True

                # grab the .sig/.asc for the keyurl, if it exists if it
                # does check the signature on the key if it is signed by
                # one of our ca-keys for this repo or the global one then
                # rc = True else ask as normal.

                elif fullaskcb:
                    rc = fullaskcb({
                        "po": po,
                        "userid": info.userid,
                        "hexkeyid": info.short_id,
                        "keyurl": keyurl,
                        "fingerprint": info.fingerprint,
                        "timestamp": info.timestamp
                    })
                elif askcb:
                    rc = askcb(po, info.userid, info.short_id)

                if not rc:
                    user_cb_fail = True
                    continue

                # Import the key
                result = ts.pgpImportPubkey(misc.procgpgkey(info.raw_key))
                if result != 0:
                    msg = _('Key import failed (code %d)') % result
                    raise dnf.exceptions.Error(_prov_key_data(msg))
                logger.info(_('Key imported successfully'))
                key_installed = True

        if not key_installed and user_cb_fail:
            raise dnf.exceptions.Error(_("Didn't install any keys"))

        if not key_installed:
            msg = _('The GPG keys listed for the "%s" repository are '
                    'already installed but they are not correct for this '
                    'package.\n'
                    'Check that the correct key URLs are configured for '
                    'this repository.') % repo.name
            raise dnf.exceptions.Error(_prov_key_data(msg))

        # Check if the newly installed keys helped
        result, errmsg = self._sig_check_pkg(po)
        if result != 0:
            msg = _("Import of key(s) didn't help, wrong key(s)?")
            logger.info(msg)
            errmsg = ucd(errmsg)
            raise dnf.exceptions.Error(_prov_key_data(errmsg))
Example #51
0
 def _print_match_section(text, keys):
     # Print them in the order they were passed
     used_keys = [arg for arg in args if arg in keys]
     formatted = self.base.output.fmtSection(text %
                                             ", ".join(used_keys))
     print(ucd(formatted))
Example #52
0
    def do_transaction(self, display=()):
        """Take care of package downloading, checking, user
        confirmation and actually running the transaction.

        :param display: `rpm.callback.TransactionProgress` object(s)
        :return: history database transaction ID or None
        """

        trans = self.transaction
        pkg_str = self.output.list_transaction(trans)
        if pkg_str:
            logger.info(pkg_str)

        if trans:
            # Check which packages have to be downloaded
            install_pkgs = []
            rmpkgs = []
            install_only = True
            for tsi in trans:
                if tsi.action in dnf.transaction.FORWARD_ACTIONS:
                    install_pkgs.append(tsi.pkg)
                elif tsi.action in dnf.transaction.BACKWARD_ACTIONS:
                    install_only = False
                    rmpkgs.append(tsi.pkg)

            # Close the connection to the rpmdb so that rpm doesn't hold the
            # SIGINT handler during the downloads.
            del self._ts

            # report the total download size to the user
            if not install_pkgs:
                self.output.reportRemoveSize(rmpkgs)
            else:
                self.output.reportDownloadSize(install_pkgs, install_only)

        if trans or self._moduleContainer.isChanged() or \
                (self._history and (self._history.group or self._history.env)):
            # confirm with user
            if self.conf.downloadonly:
                logger.info(
                    _("DNF will only download packages for the transaction."))
            elif 'test' in self.conf.tsflags:
                logger.info(
                    _("DNF will only download packages, install gpg keys, and check the "
                      "transaction."))
            if self._promptWanted():
                if self.conf.assumeno or not self.output.userconfirm():
                    raise CliError(_("Operation aborted."))
        else:
            logger.info(_('Nothing to do.'))
            return

        if trans:
            if install_pkgs:
                logger.info(_('Downloading Packages:'))
                try:
                    total_cb = self.output.download_callback_total_cb
                    self.download_packages(install_pkgs, self.output.progress,
                                           total_cb)
                except dnf.exceptions.DownloadError as e:
                    specific = dnf.cli.format.indent_block(ucd(e))
                    errstr = _(
                        'Error downloading packages:') + '\n%s' % specific
                    # setting the new line to prevent next chars being eaten up
                    # by carriage returns
                    print()
                    raise dnf.exceptions.Error(errstr)
            # Check GPG signatures
            self.gpgsigcheck(install_pkgs)

        if self.conf.downloadonly:
            return

        if not isinstance(display, Sequence):
            display = [display]
        display = [output.CliTransactionDisplay()] + list(display)
        tid = super(BaseCli, self).do_transaction(display)

        # display last transaction (which was closed during do_transaction())
        if tid is not None:
            trans = self.history.old([tid])[0]
            trans = dnf.db.group.RPMTransaction(self.history, trans._trans)
        else:
            trans = None

        if trans:
            msg = self.output.post_transaction_output(trans)
            logger.info(msg)
            for tsi in trans:
                if tsi.state == libdnf.transaction.TransactionItemState_ERROR:
                    raise dnf.exceptions.Error(_('Transaction failed'))

        return tid
Example #53
0
    def run(self):
        arg = self.opts.repos_action
        extcmds = [x.lower() for x in self.opts.repos]

        verbose = self.base.conf.verbose

        repos = list(self.base.repos.values())
        repos.sort(key=operator.attrgetter('id'))
        term = self.output.term
        on_ehibeg = term.FG_COLOR['green'] + term.MODE['bold']
        on_dhibeg = term.FG_COLOR['red']
        on_hiend = term.MODE['normal']
        tot_num = 0
        cols = []
        if not repos:
            logger.warning(_('No repositories available'))
            return
        include_status = arg == 'all' or (arg == 'enabled-default' and extcmds)
        repoinfo_output = []
        for repo in repos:
            if len(extcmds) and not _repo_match(repo, extcmds):
                continue
            (ehibeg, dhibeg, hiend) = '', '', ''
            ui_enabled = ''
            ui_endis_wid = 0
            ui_excludes_num = ''
            if include_status:
                (ehibeg, dhibeg, hiend) = (on_ehibeg, on_dhibeg, on_hiend)
            if repo.enabled:
                enabled = True
                if arg == 'disabled':
                    continue
                if include_status or verbose or self.opts.command == 'repoinfo':
                    ui_enabled = ehibeg + _('enabled') + hiend
                    ui_endis_wid = exact_width(_('enabled'))
                if verbose or self.opts.command == 'repoinfo':
                    ui_size = _repo_size(self.base.sack, repo)
            else:
                enabled = False
                if arg == 'enabled' or (arg == 'enabled-default'
                                        and not extcmds):
                    continue
                ui_enabled = dhibeg + _('disabled') + hiend
                ui_endis_wid = exact_width(_('disabled'))

            if not (verbose or self.opts.command == 'repoinfo'):
                rid = ucd(repo.id)
                cols.append((rid, repo.name, (ui_enabled, ui_endis_wid)))
            else:
                if enabled:
                    md = repo.metadata
                else:
                    md = None
                out = [
                    self.output.fmtKeyValFill(_("Repo-id            : "),
                                              repo.id),
                    self.output.fmtKeyValFill(_("Repo-name          : "),
                                              repo.name)
                ]

                if include_status:
                    out += [
                        self.output.fmtKeyValFill(_("Repo-status        : "),
                                                  ui_enabled)
                    ]
                if md and repo._repo.getRevision():
                    out += [
                        self.output.fmtKeyValFill(_("Repo-revision      : "),
                                                  repo._repo.getRevision())
                    ]
                if md and repo._repo.getContentTags():
                    tags = repo._repo.getContentTags()
                    out += [
                        self.output.fmtKeyValFill(_("Repo-tags          : "),
                                                  ", ".join(sorted(tags)))
                    ]

                if md and repo._repo.getDistroTags():
                    distroTagsDict = {
                        k: v
                        for (k, v) in repo._repo.getDistroTags()
                    }
                    for (distro, tags) in distroTagsDict.items():
                        out += [
                            self.output.fmtKeyValFill(
                                _("Repo-distro-tags      : "),
                                "[%s]: %s" % (distro, ", ".join(sorted(tags))))
                        ]

                if md:
                    num = len(
                        self.base.sack.query(
                            flags=hawkey.IGNORE_EXCLUDES).filterm(
                                reponame__eq=repo.id))
                    num_available = len(
                        self.base.sack.query().filterm(reponame__eq=repo.id))
                    ui_num = _num2ui_num(num)
                    ui_num_available = _num2ui_num(num_available)
                    tot_num += num
                    out += [
                        self.output.fmtKeyValFill(
                            _("Repo-updated       : "),
                            dnf.util.normalize_time(
                                repo._repo.getMaxTimestamp())),
                        self.output.fmtKeyValFill(_("Repo-pkgs          : "),
                                                  ui_num),
                        self.output.fmtKeyValFill(_("Repo-available-pkgs: "),
                                                  ui_num_available),
                        self.output.fmtKeyValFill(_("Repo-size          : "),
                                                  ui_size)
                    ]

                if repo.metalink:
                    out += [
                        self.output.fmtKeyValFill(_("Repo-metalink      : "),
                                                  repo.metalink)
                    ]
                    if enabled:
                        ts = repo._repo.getTimestamp()
                        out += [
                            self.output.fmtKeyValFill(
                                _("  Updated          : "),
                                dnf.util.normalize_time(ts))
                        ]
                elif repo.mirrorlist:
                    out += [
                        self.output.fmtKeyValFill(_("Repo-mirrors       : "),
                                                  repo.mirrorlist)
                    ]
                baseurls = repo.baseurl
                if baseurls:
                    out += [
                        self.output.fmtKeyValFill(_("Repo-baseurl       : "),
                                                  ", ".join(baseurls))
                    ]
                elif enabled:
                    mirrors = repo._repo.getMirrors()
                    if mirrors:
                        url = "%s (%d more)" % (mirrors[0], len(mirrors) - 1)
                        out += [
                            self.output.fmtKeyValFill(
                                _("Repo-baseurl       : "), url)
                        ]

                expire = _expire_str(repo, md)
                out += [
                    self.output.fmtKeyValFill(_("Repo-expire        : "),
                                              expire)
                ]

                if repo.excludepkgs:
                    # TRANSLATORS: Packages that are excluded - their names like (dnf systemd)
                    out += [
                        self.output.fmtKeyValFill(_("Repo-exclude       : "),
                                                  ", ".join(repo.excludepkgs))
                    ]

                if repo.includepkgs:
                    out += [
                        self.output.fmtKeyValFill(_("Repo-include       : "),
                                                  ", ".join(repo.includepkgs))
                    ]

                if ui_excludes_num:
                    # TRANSLATORS: Number of packages that where excluded (5)
                    out += [
                        self.output.fmtKeyValFill(_("Repo-excluded      : "),
                                                  ui_excludes_num)
                    ]

                if repo.repofile:
                    out += [
                        self.output.fmtKeyValFill(_("Repo-filename      : "),
                                                  repo.repofile)
                    ]
                repoinfo_output.append("\n".join(map(ucd, out)))

        if repoinfo_output:
            print("\n\n".join(repoinfo_output))
        if not verbose and cols:
            #  Work out the first (id) and last (enabled/disabled/count),
            # then chop the middle (name)...

            id_len = exact_width(_('repo id'))
            nm_len = 0
            st_len = 0

            for (rid, rname, (ui_enabled, ui_endis_wid)) in cols:
                if id_len < exact_width(rid):
                    id_len = exact_width(rid)
                if nm_len < exact_width(rname):
                    nm_len = exact_width(rname)
                if st_len < ui_endis_wid:
                    st_len = ui_endis_wid
                # Need this as well as above for: fill_exact_width()
            if include_status:
                if exact_width(_('status')) > st_len:
                    left = term.columns - (id_len + len(_('status')) + 2)
                else:
                    left = term.columns - (id_len + st_len + 2)
            else:  # Don't output a status column.
                left = term.columns - (id_len + 1)

            if left < nm_len:  # Name gets chopped
                nm_len = left
            else:  # Share the extra...
                left -= nm_len
                id_len += left // 2
                nm_len += left - (left // 2)

            txt_rid = fill_exact_width(_('repo id'), id_len)
            if include_status:
                txt_rnam = fill_exact_width(_('repo name'), nm_len, nm_len)
            else:
                txt_rnam = _('repo name')
            if not include_status:  # Don't output a status column.
                print("%s %s" % (txt_rid, txt_rnam))
            else:
                print("%s %s %s" % (txt_rid, txt_rnam, _('status')))
            for (rid, rname, (ui_enabled, ui_endis_wid)) in cols:
                if not include_status:  # Don't output a status column.
                    print("%s %s" % (fill_exact_width(rid, id_len), rname))
                    continue

                print("%s %s %s" %
                      (fill_exact_width(rid, id_len),
                       fill_exact_width(rname, nm_len, nm_len), ui_enabled))
        if verbose or self.opts.command == 'repoinfo':
            msg = _('Total packages: {}')
            print(msg.format(_num2ui_num(tot_num)))
Example #54
0
    def do_transaction(self, display=()):
        """Take care of package downloading, checking, user
        confirmation and actually running the transaction.

        :param display: `rpm.callback.TransactionProgress` object(s)
        :return: a numeric return code, and optionally a list of
           errors.  A negative return code indicates that errors
           occurred in the pre-transaction checks
        """

        # Reports about excludes and includes (but not from plugins)
        if self.conf.excludepkgs:
            logger.debug('Excludes in dnf.conf: ' +
                         ", ".join(sorted(set(self.conf.excludepkgs))))
        if self.conf.includepkgs:
            logger.debug('Includes in dnf.conf: ' +
                         ", ".join(sorted(set(self.conf.includepkgs))))
        for repo in self.repos.iter_enabled():
            if repo.excludepkgs:
                logger.debug('Excludes in repo ' + repo.id + ": " +
                             ", ".join(sorted(set(repo.excludepkgs))))
            if repo.includepkgs:
                logger.debug('Includes in repo ' + repo.id + ": " +
                             ", ".join(sorted(set(repo.includepkgs))))

        trans = self.transaction
        pkg_str = self.output.list_transaction(trans)
        if pkg_str:
            logger.info(pkg_str)

        if trans:
            # Check which packages have to be downloaded
            install_pkgs = []
            rmpkgs = []
            install_only = True
            for tsi in trans:
                installed = tsi.installed
                if installed is not None:
                    install_pkgs.append(installed)
                erased = tsi.erased
                if erased is not None:
                    install_only = False
                    rmpkgs.append(erased)

            # Close the connection to the rpmdb so that rpm doesn't hold the
            # SIGINT handler during the downloads.
            del self._ts

            # report the total download size to the user
            if not install_pkgs:
                self.output.reportRemoveSize(rmpkgs)
            else:
                self.output.reportDownloadSize(install_pkgs, install_only)

        if trans:
            # confirm with user
            if self.conf.downloadonly:
                logger.info(
                    _("DNF will only download packages for the transaction."))
            elif 'test' in self.conf.tsflags:
                logger.info(
                    _("DNF will only download packages, install gpg keys, and check the "
                      "transaction."))
            if self._promptWanted():
                if self.conf.assumeno or not self.output.userconfirm():
                    raise CliError(_("Operation aborted."))
        else:
            logger.info(_('Nothing to do.'))
            return

        if trans:
            if install_pkgs:
                logger.info(_('Downloading Packages:'))
                try:
                    total_cb = self.output.download_callback_total_cb
                    self.download_packages(install_pkgs, self.output.progress,
                                           total_cb)
                except dnf.exceptions.DownloadError as e:
                    specific = dnf.cli.format.indent_block(ucd(e))
                    errstr = _(
                        'Error downloading packages:') + '\n%s' % specific
                    # setting the new line to prevent next chars being eaten up
                    # by carriage returns
                    print()
                    raise dnf.exceptions.Error(errstr)
            # Check GPG signatures
            self.gpgsigcheck(install_pkgs)

        if self.conf.downloadonly:
            return

        if not isinstance(display, collections.Sequence):
            display = [display]
        display = [output.CliTransactionDisplay()] + list(display)
        super(BaseCli, self).do_transaction(display)
        if trans:
            msg = self.output.post_transaction_output(trans)
            logger.info(msg)
            for tsi in trans:
                if tsi.op_type == dnf.transaction.FAIL:
                    raise dnf.exceptions.Error(_('Transaction failed'))
Example #55
0
    def run(self, extcmds):
        try:
            subcommand = extcmds[0]
        except (ValueError, IndexError):
            dnf.cli.commands.err_mini_usage(self.cli, self.cli.base.basecmd)
            return 0
        if subcommand == "help":
            dnf.cli.commands.err_mini_usage(self.cli, self.cli.base.basecmd)
            return 0
        try:
            project_name = extcmds[1]
        except (ValueError, IndexError):
            logger.critical(
                _('Error: ') + _('exactly two additional parameters to '
                                 'copr command are required'))
            dnf.cli.commands.err_mini_usage(self.cli, self.cli.base.basecmd)
            raise dnf.cli.CliError(
                _('exactly two additional parameters to '
                  'copr command are required'))
        try:
            chroot = extcmds[2]
        except IndexError:
            chroot = self._guess_chroot()
        repo_filename = "/etc/yum.repos.d/_copr_{}.repo" \
                        .format(project_name.replace("/", "-"))
        if subcommand == "enable":
            self._need_root()
            self._ask_user("""
You are about to enable a Copr repository. Please note that this
repository is not part of the main Fedora distribution, and quality
may vary.

The Fedora Project does not exercise any power over the contents of
this repository beyond the rules outlined in the Copr FAQ at
<https://fedorahosted.org/copr/wiki/UserDocs#WhatIcanbuildinCopr>, and
packages are not held to any quality or security level.

Please do not file bug reports about these packages in Fedora
Bugzilla. In case of problems, contact the owner of this repository.

Do you want to continue? [y/N]: """)
            self._download_repo(project_name, repo_filename, chroot)
            logger.info(_("Repository successfully enabled."))
        elif subcommand == "disable":
            self._need_root()
            self._remove_repo(repo_filename)
            logger.info(_("Repository successfully disabled."))
        elif subcommand == "list":
            #http://copr.fedoraproject.org/api/coprs/ignatenkobrain/
            api_path = "/api/coprs/{}/".format(project_name)

            res = dnfpluginscore.lib.urlopen(self, None,
                                             self.copr_url + api_path, 'w+')
            try:
                json_parse = json.loads(res.read())
            except ValueError:
                raise dnf.exceptions.Error(
                    _("Can't parse repositories for username '{}'.").format(
                        project_name))
            self._check_json_output(json_parse)
            section_text = _("List of {} coprs").format(project_name)
            self._print_match_section(section_text)
            i = 0
            while i < len(json_parse["repos"]):
                msg = "{0}/{1} : ".format(project_name,
                                          json_parse["repos"][i]["name"])
                desc = json_parse["repos"][i]["description"]
                if not desc:
                    desc = _("No description given")
                msg = self.base.output.fmtKeyValFill(ucd(msg), desc)
                print(msg)
                i += 1
        elif subcommand == "search":
            #http://copr.fedoraproject.org/api/coprs/search/tests/
            api_path = "/api/coprs/search/{}/".format(project_name)

            res = dnfpluginscore.lib.urlopen(self, None,
                                             self.copr_url + api_path, 'w+')
            try:
                json_parse = json.loads(res.read())
            except ValueError:
                raise dnf.exceptions.Error(
                    _("Can't parse search for '{}'.").format(project_name))
            self._check_json_output(json_parse)
            section_text = _("Matched: {}").format(project_name)
            self._print_match_section(section_text)
            i = 0
            while i < len(json_parse["repos"]):
                msg = "{0}/{1} : ".format(json_parse["repos"][i]["username"],
                                          json_parse["repos"][i]["coprname"])
                desc = json_parse["repos"][i]["description"]
                if not desc:
                    desc = _("No description given.")
                msg = self.base.output.fmtKeyValFill(ucd(msg), desc)
                print(msg)
                i += 1
        else:
            raise dnf.exceptions.Error(
                _('Unknown subcommand {}.').format(subcommand))
Example #56
0
File: main.py Project: rcutmore/dnf
def ex_IOError(e):
    logger.log(dnf.logging.SUBDEBUG, '', exc_info=True)
    logger.critical(ucd(e))
    return 1
Example #57
0
 def _file_timestamp(self, what):
     try:
         return dnf.util.file_timestamp(self._repo_dct[what])
     except OSError as e:
         raise dnf.exceptions.MetadataError(ucd(e))
Example #58
0
 def scriptout(self, msgs):
     if msgs:
         self.rpm_logger.info(ucd(msgs))