Ejemplo n.º 1
0
    def test_history_undo_operations_erase_twoavailable(self):
        """Test history_undo_operations with an erase available in two repos."""
        base = Base()
        base._sack = mock_sack('main', 'search')
        operations = NEVRAOperations()
        operations.add('Erase', 'lotus-3-16.x86_64')

        with base:
            base.history_undo_operations(operations)

        transaction_it = iter(base.transaction)
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             INSTALL, installed='lotus-3-16.x86_64',
                             reason='history'))
        self.assertRaises(StopIteration, next, transaction_it)
Ejemplo n.º 2
0
def repo_baseurl_make_native(base: dnf.Base) -> dnf.Base:
    """Ensure that baseurl in each repository is a list of Python strings.

    Workaround: rhbz#1649284 -- Package.remote_location fails with AttributeError
    """

    class BaseurlRepoProxy:
        def __init__(self, repo):
            self.__repo = repo

        def __getattr__(self, name):
            return getattr(self.__repo, name)

        @property
        def baseurl(self):
            return list(map(str, self.__repo.baseurl))

    for name, repo in base.repos.items():
        base.repos[name] = BaseurlRepoProxy(repo)

    return base
Ejemplo n.º 3
0
 def setUp(self):
     """Prepare the test fixture."""
     self._base = Base()
     self._base._sack = mock_sack('main', 'updates')
Ejemplo n.º 4
0
class BaseTest(TestCase):
    """Unit tests of dnf.Base."""

    def _create_item_matcher(self, op_type, installed=None, erased=None,
                             obsoleted=[], reason='unknown'):
        """Create a new instance of dnf.transaction.TransactionItem matcher."""
        attrs = {'op_type': op_type,
                 'installed': self._create_package_matcher(installed)
                              if installed else installed,
                 'erased': self._create_package_matcher(erased)
                           if erased else erased,
                 'obsoleted': [self._create_package_matcher(nevra)
                               for nevra in obsoleted],
                 'reason': reason}
        return ObjectMatcher(TransactionItem, attrs)

    def _create_package_matcher(self, nevra_str):
        """Create a new instance of dnf.package.Package matcher."""
        nevra = split_nevra(nevra_str)
        attrs = {'name': nevra.name,
                 'epoch': nevra.epoch,
                 'version': nevra.version,
                 'release': nevra.release,
                 'arch': nevra.arch}
        return ObjectMatcher(Package, attrs)

    def setUp(self):
        """Prepare the test fixture."""
        self._base = Base()
        self._base._sack = mock_sack('main', 'updates')

    def test_history_undo_operations_downgrade(self):
        """Test history_undo_operations with a downgrade."""
        operations = NEVRAOperations()
        operations.add('Downgrade', 'pepper-20-0.x86_64', 'pepper-20-1.x86_64', ('lotus-3-16.x86_64',))

        with self._base:
            self._base.history_undo_operations(operations)

        transaction_it = iter(self._base.transaction)
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             UPGRADE, installed='pepper-20-1.x86_64',
                             erased='pepper-20-0.x86_64'))
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                            INSTALL, installed='lotus-3-16.x86_64',
                            reason='history'))
        self.assertRaises(StopIteration, next, transaction_it)

    def test_history_undo_operations_downgrade_notavailable(self):
        """Test history_undo_operations with an unavailable downgrade."""
        operations = NEVRAOperations()
        operations.add('Downgrade', 'pepper-20-0.x86_64', 'pepper-20-2.x86_64')

        with self._base, self.assertRaises(PackagesNotAvailableError) as context:
            self._base.history_undo_operations(operations)

        self.assertEqual(context.exception.pkg_spec, 'pepper-20-2.x86_64')

    def test_history_undo_operations_downgrade_notinstalled(self):
        """Test history_undo_operations with a not installed downgrade."""
        operations = NEVRAOperations()
        operations.add('Downgrade', 'lotus-3-0.x86_64', 'lotus-3-16.x86_64')

        with self._base, self.assertRaises(PackagesNotInstalledError) as context:
            self._base.history_undo_operations(operations)

        self.assertEqual(context.exception.pkg_spec, 'lotus-3-0.x86_64')

    def test_history_undo_operations_erase(self):
        """Test history_undo_operations with an erase."""
        operations = NEVRAOperations()
        operations.add('Erase', 'lotus-3-16.x86_64')

        with self._base:
            self._base.history_undo_operations(operations)

        transaction_it = iter(self._base.transaction)
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             INSTALL, installed='lotus-3-16.x86_64',
                             reason='history'))
        self.assertRaises(StopIteration, next, transaction_it)

    def test_history_undo_operations_erase_twoavailable(self):
        """Test history_undo_operations with an erase available in two repos."""
        base = Base()
        base._sack = mock_sack('main', 'search')
        operations = NEVRAOperations()
        operations.add('Erase', 'lotus-3-16.x86_64')

        with base:
            base.history_undo_operations(operations)

        transaction_it = iter(base.transaction)
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             INSTALL, installed='lotus-3-16.x86_64',
                             reason='history'))
        self.assertRaises(StopIteration, next, transaction_it)

    def test_history_undo_operations_erase_notavailable(self):
        """Test history_undo_operations with an unavailable erase."""
        operations = NEVRAOperations()
        operations.add('Erase', 'hole-1-1.x86_64')

        with self._base, self.assertRaises(PackagesNotAvailableError) as context:
            self._base.history_undo_operations(operations)

        self.assertEqual(context.exception.pkg_spec, 'hole-1-1.x86_64')

    def test_history_undo_operations_install(self):
        """Test history_undo_operations with an install."""
        operations = NEVRAOperations()
        operations.add('Install', 'pepper-20-0.x86_64', obsoleted_nevras=('lotus-3-16.x86_64',))

        with self._base:
            self._base.history_undo_operations(operations)

        transaction_it = iter(self._base.transaction)
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             ERASE, erased='pepper-20-0.x86_64'))
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             INSTALL, installed='lotus-3-16.x86_64',
                             reason='history'))
        self.assertRaises(StopIteration, next, transaction_it)

    def test_history_undo_operations_install_notinstalled(self):
        """Test history_undo_operations with a not installed install."""
        operations = NEVRAOperations()
        operations.add('Install', 'mrkite-2-0.x86_64')

        with self._base, self.assertRaises(PackagesNotInstalledError) as context:
            self._base.history_undo_operations(operations)

        self.assertEqual(context.exception.pkg_spec, 'mrkite-2-0.x86_64')

    def test_history_undo_operations_reinstall(self):
        """Test history_undo_operations with a reinstall."""
        operations = NEVRAOperations()
        operations.add('Reinstall', 'pepper-20-0.x86_64', 'pepper-20-0.x86_64', ('hole-1-1.x86_64',))

        with self._base:
            self._base.history_undo_operations(operations)

        transaction_it = iter(self._base.transaction)
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             REINSTALL, installed='pepper-20-0.x86_64',
                             erased='pepper-20-0.x86_64',
                             obsoleted=('hole-1-1.x86_64',)))
        self.assertRaises(StopIteration, next, transaction_it)

    def test_history_undo_operations_reinstall_notavailable(self):
        """Test history_undo_operations with an unvailable reinstall."""
        operations = NEVRAOperations()
        operations.add('Reinstall', 'mrkite-2-0.x86_64', 'mrkite-2-0.x86_64')

        with self._base, self.assertRaises(PackagesNotInstalledError) as context:
            self._base.history_undo_operations(operations)

        self.assertEqual(context.exception.pkg_spec, 'mrkite-2-0.x86_64')

    def test_history_undo_operations_reinstall_notinstalled(self):
        """Test history_undo_operations with a not installed reinstall."""
        operations = NEVRAOperations()
        operations.add('Reinstall', 'hole-1-1.x86_64', 'hole-1-1.x86_64')

        with self._base, self.assertRaises(PackagesNotAvailableError) as context:
            self._base.history_undo_operations(operations)

        self.assertEqual(context.exception.pkg_spec, 'hole-1-1.x86_64')

    def test_history_undo_operations_reinstall_notinstalled_obsoleted(self):
        """Test history_undo_operations with a not installed obsoleted of a reinstall."""
        operations = NEVRAOperations()
        operations.add('Reinstall', 'pepper-20-0.x86_64', 'pepper-20-0.x86_64', ('lotus-3-16.x86_64',))

        with self._base:
            self._base.history_undo_operations(operations)

        transaction_it = iter(self._base.transaction)
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             REINSTALL, installed='pepper-20-0.x86_64',
                             erased='pepper-20-0.x86_64', obsoleted=()))
        self.assertRaises(StopIteration, next, transaction_it)

    def test_history_undo_operations_update(self):
        """Test history_undo_operations with an update."""
        operations = NEVRAOperations()
        operations.add('Update', 'tour-5-0.noarch', 'tour-4.6-1.noarch', ('lotus-3-16.x86_64',))

        with self._base:
            self._base.history_undo_operations(operations)

        transaction_it = iter(self._base.transaction)
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             DOWNGRADE, installed='tour-4.6-1.noarch',
                             erased='tour-5-0.noarch'))
        self.assertEqual(next(transaction_it),
                         self._create_item_matcher(
                             INSTALL, installed='lotus-3-16.x86_64',
                             reason='history'))
        self.assertRaises(StopIteration, next, transaction_it)

    def test_history_undo_operations_update_notavailable(self):
        """Test history_undo_operations with an unavailable update."""
        operations = NEVRAOperations()
        operations.add('Update', 'tour-5-0.noarch', 'tour-4.6-2.noarch')

        with self._base, self.assertRaises(PackagesNotAvailableError) as context:
            self._base.history_undo_operations(operations)

        self.assertEqual(context.exception.pkg_spec, 'tour-4.6-2.noarch')

    def test_history_undo_operations_update_notinstalled(self):
        """Test history_undo_operations with a not installed update."""
        operations = NEVRAOperations()
        operations.add('Update', 'lotus-4-0.x86_64', 'lotus-3-16.x86_64')

        with self._base, self.assertRaises(PackagesNotInstalledError) as context:
            self._base.history_undo_operations(operations)

        self.assertEqual(context.exception.pkg_spec, 'lotus-4-0.x86_64')
Ejemplo n.º 5
0
def dnf_base():
    base = Base()
    base.read_all_repos()
    base.fill_sack()
    base.sack.query()
    return base.sack.query()
Ejemplo n.º 6
0
    def setup(self):
        """
        Setup DNF builder.
        """
        dnf_conf = Conf()

        dnf_conf.debuglevel = 10
        dnf_conf.logdir = self.log_path

        dnf_conf.assumeyes = True

        dnf_conf.installroot = self.image_path
        pdir = os.path.join(self.image_path, "var", "lib", "dnf")
        dnf_conf.persistdir = pdir
        dnf_conf.cachedir = os.path.join(pdir, "cache")
        dnf_conf.keepcache = not self.cleanall

        dnf_conf.releasever = str(self.config["releasever"])

        for arch in ("arch", "basearch"):
            dnf_conf.substitutions[arch] = self.config["architecture"]

        for conf in ("proxy", "proxy_username", "proxy_password"):
            if conf in self.runtime:
                setattr(dnf_conf, conf, self.runtime[conf])

        self.dnf_builder = Base(dnf_conf)
        self.dnf_builder.read_all_repos()

        all_repos = self.config["repo"].get("*", False)
        runtime_all_repos = self.runtime["repo"].get("*", False)

        for repo_name, repo in self.dnf_builder.repos.items():
            repo_conf = None
            if all_repos or runtime_all_repos:
                repo_conf = configfile.merge(self.config["repo"].get("*", {}),
                                             self.runtime["repo"].get("*", {}))

                if repo_conf.get("baseurl"):
                    del repo_conf["baseurl"]

            if (repo_name in self.config["repo"] or
                    repo_name in self.runtime["repo"]):
                merge_conf = configfile.merge(
                    self.config["repo"].get(repo_name, {}),
                    self.runtime["repo"].get(repo_name, {}))

                if not merge_conf:
                    continue

                if repo_conf:
                    repo_conf = configfile.merge(merge_conf, repo_conf)
                else:
                    repo_conf = merge_conf

            if repo_conf:
                if "baseurl" in repo_conf:
                    repo.baseurl = repo_conf["baseurl"]
                    # Explicitly remove these as
                    # they can override the baseurl settings
                    repo.mirrorlist = None
                    repo.metalink = None
                if "enabled" in repo_conf:
                    if not repo_conf["enabled"]:
                        repo.disable()
                    else:
                        repo.enable()
                else:
                    repo.enable()

        # If the RPM DBs aren't initialised,
        # hawkey doesn't fill the sack correctly and fails.
        # But we don't want to overwrite any already setup RPM DBs.
        rpm_path = os.path.join(self.image_path, "var", "lib", "rpm")
        if not os.path.exists(rpm_path):
            self.dnf_builder.ts.ts.initDB()

        self.dnf_builder.fill_sack()
Ejemplo n.º 7
0
class DNFBuilder(object):
    """
    DNF wrapper.
    """
    def __init__(self, image_path, log_path, architecture, config, runtime):
        """
        Create DNF builder.

        :param image_path: image base path
        :type image_path: str
        :param log_path: logging path
        :type log_path: str
        :param architecture: architecture to run on
        :type architecture: str
        :param config: configuration options
        :type config: dict
        :param runtime: runtime configuration options
        :type runtime: dict or None
        """
        self.dnf_builder = None
        self.image_path = image_path
        self.log_path = log_path

        self.cleanall = config.pop("cleanall", True)

        arch = "i686" if architecture == "x86" else "x86_64"
        self.config = {
            "releasever": detect_releasever("/"),
            "architecture": arch,
            "repo": {}
        }
        self.config.update(config)

        self.runtime = {"repo": {}}
        if runtime:
            self.runtime.update(runtime)

    def setup(self):
        """
        Setup DNF builder.
        """
        dnf_conf = Conf()

        dnf_conf.debuglevel = 10
        dnf_conf.logdir = self.log_path

        dnf_conf.assumeyes = True

        dnf_conf.installroot = self.image_path
        pdir = os.path.join(self.image_path, "var", "lib", "dnf")
        dnf_conf.persistdir = pdir
        dnf_conf.cachedir = os.path.join(pdir, "cache")
        dnf_conf.keepcache = not self.cleanall

        dnf_conf.releasever = str(self.config["releasever"])

        for arch in ("arch", "basearch"):
            dnf_conf.substitutions[arch] = self.config["architecture"]

        for conf in ("proxy", "proxy_username", "proxy_password"):
            if conf in self.runtime:
                setattr(dnf_conf, conf, self.runtime[conf])

        self.dnf_builder = Base(dnf_conf)
        self.dnf_builder.read_all_repos()

        all_repos = self.config["repo"].get("*", False)
        runtime_all_repos = self.runtime["repo"].get("*", False)

        for repo_name, repo in self.dnf_builder.repos.items():
            repo_conf = None
            if all_repos or runtime_all_repos:
                repo_conf = configfile.merge(self.config["repo"].get("*", {}),
                                             self.runtime["repo"].get("*", {}))

                if repo_conf.get("baseurl"):
                    del repo_conf["baseurl"]

            if (repo_name in self.config["repo"] or
                    repo_name in self.runtime["repo"]):
                merge_conf = configfile.merge(
                    self.config["repo"].get(repo_name, {}),
                    self.runtime["repo"].get(repo_name, {}))

                if not merge_conf:
                    continue

                if repo_conf:
                    repo_conf = configfile.merge(merge_conf, repo_conf)
                else:
                    repo_conf = merge_conf

            if repo_conf:
                if "baseurl" in repo_conf:
                    repo.baseurl = repo_conf["baseurl"]
                    # Explicitly remove these as
                    # they can override the baseurl settings
                    repo.mirrorlist = None
                    repo.metalink = None
                if "enabled" in repo_conf:
                    if not repo_conf["enabled"]:
                        repo.disable()
                    else:
                        repo.enable()
                else:
                    repo.enable()

        # If the RPM DBs aren't initialised,
        # hawkey doesn't fill the sack correctly and fails.
        # But we don't want to overwrite any already setup RPM DBs.
        rpm_path = os.path.join(self.image_path, "var", "lib", "rpm")
        if not os.path.exists(rpm_path):
            self.dnf_builder.ts.ts.initDB()

        self.dnf_builder.fill_sack()

    def install(self, pkgs):
        """
        Install the list of provided packages.

        :param pkgs: list of packages to install
        :type pkgs: list
        """
        if not self.dnf_builder:
            self.setup()

        for pkg in pkgs:
            try:
                self.dnf_builder.install(pkg)
            except dnf.exceptions.MarkingError:
                raise DNFError("Cannot install package '{}'".format(pkg))

        try:
            self.dnf_builder.resolve()
        except dnf.exceptions.DepsolveError:
            raise DNFError("Cannot resolve package dependencies")

        try:
            self.dnf_builder.download_packages(
                self.dnf_builder.transaction.install_set)
        except dnf.exceptions.DownloadError:
            raise DNFError("Cannot download packages for installation")

        self.dnf_builder.do_transaction()

    def finish(self):
        """
        Run any cleanup steps.
        """
        if self.dnf_builder:
            self.dnf_builder.close()
            if self.cleanall:
                shutil.rmtree(self.dnf_builder.conf.cachedir, True)