diff --git a/.gitignore b/.gitignore index 023ca79..3e9a7ad 100644 --- a/.gitignore +++ b/.gitignore @@ -120,3 +120,4 @@ /dnf-3.3.0.tar.gz /dnf-3.5.0.tar.gz /dnf-3.5.1.tar.gz +/dnf-3.6.1.tar.gz diff --git a/0001-Restore-strict-choice-for-group-installs-1461539.patch b/0001-Restore-strict-choice-for-group-installs-1461539.patch deleted file mode 100644 index 7041feb..0000000 --- a/0001-Restore-strict-choice-for-group-installs-1461539.patch +++ /dev/null @@ -1,421 +0,0 @@ -From c9c10a0f479954c9e829ce8b604ceb1d29746317 Mon Sep 17 00:00:00 2001 -From: Adam Williamson -Date: Tue, 13 Mar 2018 15:33:24 -0700 -Subject: [PATCH] Restore 'strict' choice for group installs (#1461539) - -This makes the `strict` parameter to `group_install` mean -something again. - -When it is set `True`, DNF will behave as yum previously did, -which has been a request for several years now. See: - -https://bugzilla.redhat.com/show_bug.cgi?id=1292892 -https://bugzilla.redhat.com/show_bug.cgi?id=1337731 -https://bugzilla.redhat.com/show_bug.cgi?id=1427365 -https://bugzilla.redhat.com/show_bug.cgi?id=1461539 - -And commits: - -91f9ce98dbb630800017f44180d636af395435cd -1e1901822748b754d038dd396655c997281a7201 - -We have been around the houses on this multiple times. @mikem23 -actually got things right way way back in #1292892: - -"yum-deprecated behaves more sanely here. - -In case 1 [package exists but has dependency issues], it reports -the missing dependency and exits with an error - -... - -In case 2 [package cannot be found at all], it exits cleanly, but -prints a warning." - -Note that this applies to yum's *default* behaviour: it had an -option, --skip-broken, which caused it to skip packages with -dependency errors. - -That's exactly what we've wanted all along, and it's also what -1461539 requests. Unfortunately, the initial commit intended to -fix #1292892 - that's 91f9ce9 - did not quite behave as Mike -requested. It treated any 'mandatory' package having dependency -errors *or* not existing at all as fatal errors, while not -treating non-existence *or* errors on the part of a 'default' -or 'optional' package as a fatal error. This introduced *two* -differences from yum's behaviour (making the comps 'type' matter, -which it never did to yum, and failing on non-existence), which -I think was the source of quite a lot of confusion. - -We then wound up filing bugs on this - like #1337731 - and the -response to that was 1e19018, which causes dnf to treat *neither* -case as a fatal error for *any* package, which is where we stand -at present. - -When resolving a transaction, currently, if it cannot find a -package corresponding to an entry in a group, dnf will log a -warning and carry on. This is good and fine and just what we want -it to do. However, when a package is available but cannot be -installed, it does the wrong thing. The various forks of this -`trans_install` internal function all wind up passing -`optional=True` to the Goal, which tells it that it's fine to -just leave the package out if its dependencies can't be resolved. -Additionally, if this happens, `resolve()` itself does not log -anything. - -If you try a group install through the CLI, it will tell you -about packages that have been left out due to dependency errors, -via the `_skipped_packages` function in `dnf/output.py` which -actually sucks them out of the Goal instance itself. But that's -no use to anything besides the CLI. Other things which use -`resolve()`, like anaconda, have no means of accessing this -information, so when this happens to them, the omission of the -package is not logged in any way at all, and they have no way to -find out about it. - -If `strict` is set to `False`, the current behaviour described -above will be used: non-installable packages will be skipped. We -implement this by restoring the old separation between `install` -and `install_opt` which was removed in 1e19018. When group_install -is called with `strict=True` we add the packages to the `install` -set; when it's called with `strict=False` we add the packages to -the `install_opt` set. Then `_finalize_comps_trans` requests -strict behaviour for `install` and non-strict for `install_opt`. - -It continues to be the case that the comps 'type' - mandatory, -default, or optional - does not matter; the same behaviour will be -used for all three. Again, this is how yum behaved (in the -absence of --skip-broken) - -The comps 'types' were *never* intended to dictate yum/dnf -behaviour in terms of whether it should fail on error or not, as I -understand it; they were in fact related to installer UI behaviour. -In the old installer UI, after you selected a group, you would see -all the packages in the group listed. 'mandatory' packages would -be pre-checked for installation and the check would be greyed out -- you couldn't unselect them. 'default' packages would be -pre-checked for installation, but you *could* de-select them if you -wanted. 'optional' packages would not be pre-checked for -installation, but you could *select* them if you wanted. This was -the intent of the comps 'type', as I understand it. - -Importantly, a package not existing at all will continue to *not* -be a fatal error whatever `strict` is set to. as this is handled -*before* we reach the `trans_install` function. - -Signed-off-by: Adam Williamson ---- - dnf/base.py | 21 ++++-- - dnf/comps.py | 27 +++++++- - tests/repos/broken_group.repo | 4 ++ - tests/repos/main_comps.xml | 4 +- - tests/test_groups.py | 122 +++++++++++++++++++++++++++------- - 5 files changed, 145 insertions(+), 33 deletions(-) - create mode 100644 tests/repos/broken_group.repo - -diff --git a/dnf/base.py b/dnf/base.py -index 96c1aab7..60c60779 100644 ---- a/dnf/base.py -+++ b/dnf/base.py -@@ -1438,10 +1438,10 @@ class Base(object): - self._goal.upgrade(select=sltr) - return remove_query - -- def trans_install(query, remove_query, comps_pkg): -+ def trans_install(query, remove_query, comps_pkg, strict): - if self.conf.multilib_policy == "all": - if not comps_pkg.requires: -- self._install_multiarch(query, strict=False) -+ self._install_multiarch(query, strict=strict) - else: - # it installs only one arch for conditional packages - installed_query = query.installed().apply() -@@ -1450,7 +1450,7 @@ class Base(object): - _msg_installed(pkg) - sltr = dnf.selector.Selector(self.sack) - sltr.set(provides="({} if {})".format(comps_pkg.name, comps_pkg.requires)) -- self._goal.install(select=sltr, optional=True) -+ self._goal.install(select=sltr, optional=not strict) - - else: - sltr = dnf.selector.Selector(self.sack) -@@ -1458,7 +1458,7 @@ class Base(object): - sltr.set(provides="({} if {})".format(comps_pkg.name, comps_pkg.requires)) - else: - sltr.set(pkg=query) -- self._goal.install(select=sltr, optional=True) -+ self._goal.install(select=sltr, optional=not strict) - return remove_query - - def trans_remove(query, remove_query, comps_pkg): -@@ -1466,7 +1466,8 @@ class Base(object): - return remove_query - - remove_query = self.sack.query().filterm(empty=True) -- attr_fn = ((trans.install, trans_install), -+ attr_fn = ((trans.install, functools.partial(trans_install, strict=True)), -+ (trans.install_opt, functools.partial(trans_install, strict=False)), - (trans.upgrade, trans_upgrade), - (trans.remove, trans_remove)) - -@@ -1537,6 +1538,10 @@ class Base(object): - """Installs packages of selected group - :param exclude: list of package name glob patterns - that will be excluded from install set -+ :param strict: boolean indicating whether group packages that -+ exist but are non-installable due to e.g. dependency -+ issues should be skipped (False) or cause transaction to -+ fail to resolve (True) - """ - def _pattern_to_pkgname(pattern): - if dnf.util.is_glob_pattern(pattern): -@@ -1558,8 +1563,12 @@ class Base(object): - strict) - if not trans: - return 0 -+ if strict: -+ instlog = trans.install -+ else: -+ instlog = trans.install_opt - logger.debug(_("Adding packages from group '%s': %s"), -- grp_id, trans.install) -+ grp_id, instlog) - return self._add_comps_trans(trans) - - def env_group_install(self, patterns, types, strict=True, exclude=None, exclude_groups=None): -diff --git a/dnf/comps.py b/dnf/comps.py -index 079d21be..8743812a 100644 ---- a/dnf/comps.py -+++ b/dnf/comps.py -@@ -476,18 +476,20 @@ class CompsTransPkg(object): - class TransactionBunch(object): - def __init__(self): - self._install = set() -+ self._install_opt = set() - self._remove = set() - self._upgrade = set() - - def __iadd__(self, other): - self._install.update(other._install) -+ self._install_opt.update(other._install_opt) - self._upgrade.update(other._upgrade) - self._remove = (self._remove | other._remove) - \ -- self._install - self._upgrade -+ self._install - self._install_opt - self._upgrade - return self - - def __len__(self): -- return len(self.install) + len(self.upgrade) + len(self.remove) -+ return len(self.install) + len(self.install_opt) + len(self.upgrade) + len(self.remove) - - @staticmethod - def _set_value(param, val): -@@ -499,12 +501,28 @@ class TransactionBunch(object): - - @property - def install(self): -+ """ -+ Packages to be installed with strict=True - transaction will -+ fail if they cannot be installed due to dependency errors etc. -+ """ - return self._install - - @install.setter - def install(self, value): - self._set_value(self._install, value) - -+ @property -+ def install_opt(self): -+ """ -+ Packages to be installed with strict=False - they will be -+ skipped if they cannot be installed -+ """ -+ return self._install_opt -+ -+ @install_opt.setter -+ def install_opt(self, value): -+ self._set_value(self._install_opt, value) -+ - @property - def remove(self): - return self._remove -@@ -641,7 +659,10 @@ class Solver(object): - - trans = TransactionBunch() - # TODO: remove exclude -- trans.install.update(self._pkgs_of_type(comps_group, pkg_types, exclude=[])) -+ if strict: -+ trans.install.update(self._pkgs_of_type(comps_group, pkg_types, exclude=[])) -+ else: -+ trans.install_opt.update(self._pkgs_of_type(comps_group, pkg_types, exclude=[])) - return trans - - def _group_remove(self, group_id): -diff --git a/tests/repos/broken_group.repo b/tests/repos/broken_group.repo -new file mode 100644 -index 00000000..7f151971 ---- /dev/null -+++ b/tests/repos/broken_group.repo -@@ -0,0 +1,4 @@ -+=Ver: 2.0 -+# -+=Pkg: brokendeps 20 2 x86_64 -+=Req: nosuchpackage >= 1.2-0 -diff --git a/tests/repos/main_comps.xml b/tests/repos/main_comps.xml -index 3cf8faa5..9e694d13 100644 ---- a/tests/repos/main_comps.xml -+++ b/tests/repos/main_comps.xml -@@ -44,7 +44,9 @@ - Broken Group - - meaning-of-life -- lotus -+ lotus -+ librita -+ brokendeps - - - -diff --git a/tests/test_groups.py b/tests/test_groups.py -index ec10a619..fe388f96 100644 ---- a/tests/test_groups.py -+++ b/tests/test_groups.py -@@ -183,29 +183,6 @@ class PresetPersistorTest(tests.support.ResultTestCase): - swdb_group = self.history.group.get(comps_group.id) - self.assertIsNotNone(swdb_group) - -- """ -- this should be reconsidered once relengs document comps -- def test_group_install_broken(self): -- grp = self.base.comps.group_by_pattern('Broken Group') -- p_grp = self.history.group.get('broken-group') -- self.assertFalse(p_grp.installed) -- -- self.assertRaises(dnf.exceptions.MarkingError, -- self.base.group_install, grp.id, -- ('mandatory', 'default')) -- p_grp = self.history.group.get('broken-group') -- self.assertFalse(p_grp.installed) -- -- self.assertEqual(self.base.group_install(grp.id, -- ('mandatory', 'default'), -- strict=False), 1) -- inst, removed = self.installed_removed(self.base) -- self.assertLength(inst, 1) -- self.assertEmpty(removed) -- p_grp = self.history.group.get('broken-group') -- self.assertTrue(p_grp.installed) -- """ -- - def test_group_remove(self): - self._install_test_group() - group_id = 'somerset' -@@ -220,6 +197,105 @@ class PresetPersistorTest(tests.support.ResultTestCase): - self._swdb_end() - - -+class ProblemGroupTest(tests.support.ResultTestCase): -+ """Test some cases involving problems in groups: packages that -+ don't exist, and packages that exist but cannot be installed. The -+ "broken" group lists three packages. "meaning-of-life", explicitly -+ 'default', does not exist. "lotus", implicitly 'mandatory' (no -+ explicit type), exists and is installable. "brokendeps", -+ explicitly 'optional', exists but has broken dependencies. See -+ https://bugzilla.redhat.com/show_bug.cgi?id=1292892, -+ https://bugzilla.redhat.com/show_bug.cgi?id=1337731, -+ https://bugzilla.redhat.com/show_bug.cgi?id=1427365, and -+ https://bugzilla.redhat.com/show_bug.cgi?id=1461539 for some of -+ the background on this. -+ """ -+ -+ REPOS = ['main', 'broken_group'] -+ COMPS = True -+ COMPS_SEED_PERSISTOR = True -+ -+ def test_group_install_broken_mandatory(self): -+ """Here we will test installing the group with only mandatory -+ packages. We expect this to succeed, leaving out the -+ non-existent 'meaning-of-life': it should also log a warning, -+ but we don't test that. -+ """ -+ comps_group = self.base.comps.group_by_pattern('Broken Group') -+ swdb_group = self.history.group.get(comps_group.id) -+ self.assertIsNone(swdb_group) -+ -+ cnt = self.base.group_install(comps_group.id, ('mandatory')) -+ self._swdb_commit() -+ self.base.resolve() -+ # this counts packages *listed* in the group, so 2 -+ self.assertEqual(cnt, 2) -+ -+ inst, removed = self.installed_removed(self.base) -+ # the above should work, but only 'lotus' actually installed -+ self.assertLength(inst, 1) -+ self.assertEmpty(removed) -+ -+ def test_group_install_broken_default(self): -+ """Here we will test installing the group with only mandatory -+ and default packages. Again we expect this to succeed: the new -+ factor is an entry pulling in librita if no-such-package is -+ also included or installed. We expect this not to actually -+ pull in librita (as no-such-package obviously *isn't* there), -+ but also not to cause a fatal error. -+ """ -+ comps_group = self.base.comps.group_by_pattern('Broken Group') -+ swdb_group = self.history.group.get(comps_group.id) -+ self.assertIsNone(swdb_group) -+ -+ cnt = self.base.group_install(comps_group.id, ('mandatory', 'default')) -+ self._swdb_commit() -+ self.base.resolve() -+ # this counts packages *listed* in the group, so 3 -+ self.assertEqual(cnt, 3) -+ -+ inst, removed = self.installed_removed(self.base) -+ # the above should work, but only 'lotus' actually installed -+ self.assertLength(inst, 1) -+ self.assertEmpty(removed) -+ -+ def test_group_install_broken_optional(self): -+ """Here we test installing the group with optional packages -+ included. We expect this to fail, as a package that exists but -+ has broken dependencies is now included. -+ """ -+ comps_group = self.base.comps.group_by_pattern('Broken Group') -+ swdb_group = self.history.group.get(comps_group.id) -+ self.assertIsNone(swdb_group) -+ -+ cnt = self.base.group_install(comps_group.id, ('mandatory', 'default', 'optional')) -+ self.assertEqual(cnt, 4) -+ -+ self._swdb_commit() -+ # this should fail, as optional 'brokendeps' is now pulled in -+ self.assertRaises(dnf.exceptions.DepsolveError, self.base.resolve) -+ -+ def test_group_install_broken_optional_nonstrict(self): -+ """Here we test installing the group with optional packages -+ included, but with strict=False. We expect this to succeed, -+ skipping the package with broken dependencies. -+ """ -+ comps_group = self.base.comps.group_by_pattern('Broken Group') -+ swdb_group = self.history.group.get(comps_group.id) -+ self.assertIsNone(swdb_group) -+ -+ cnt = self.base.group_install(comps_group.id, ('mandatory', 'default', 'optional'), -+ strict=False) -+ self._swdb_commit() -+ self.base.resolve() -+ self.assertEqual(cnt, 4) -+ -+ inst, removed = self.installed_removed(self.base) -+ # the above should work, but only 'lotus' actually installed -+ self.assertLength(inst, 1) -+ self.assertEmpty(removed) -+ -+ - class EnvironmentInstallTest(tests.support.ResultTestCase): - """Set up a test where sugar is considered not installed.""" - --- -2.19.0 - diff --git a/dnf.spec b/dnf.spec index e2b761e..125c999 100644 --- a/dnf.spec +++ b/dnf.spec @@ -1,12 +1,12 @@ # default dependencies -%global hawkey_version 0.19.0 +%global hawkey_version 0.20.0 %global libcomps_version 0.1.8 %global libmodulemd_version 1.4.0 %global rpm_version 4.14.0 # conflicts -%global conflicts_dnf_plugins_core_version 3.0.1 -%global conflicts_dnf_plugins_extras_version 3.0.0 +%global conflicts_dnf_plugins_core_version 3.0.4 +%global conflicts_dnf_plugins_extras_version 3.0.2 %global conflicts_dnfdaemon_version 0.3.19 # override dependencies for rhel 7 @@ -30,7 +30,8 @@ %bcond_without python3 %endif -%if 0%{?rhel} >= 8 +%if 0%{?rhel} >= 8 || 0%{?fedora} > 29 +# Disable python2 build %bcond_with python2 %else %bcond_without python2 @@ -39,9 +40,9 @@ # configurable name for the compat yum package %global yum_subpackage_name %{name}-yum -# provide yum4 on rhel <= 7 to avoid conflict with existing yum +# provide nextgen-yum4 on rhel <= 7 to avoid conflict with existing yum %if 0%{?rhel} && 0%{?rhel} <= 7 - %global yum_subpackage_name yum4 + %global yum_subpackage_name nextgen-yum4 %endif # provide yum on rhel >= 8, it replaces old yum @@ -71,16 +72,13 @@ It supports RPMs, modules and comps groups & environments. Name: dnf -Version: 3.5.1 -Release: 2%{?dist} +Version: 3.6.1 +Release: 1%{?dist} Summary: %{pkg_summary} # For a breakdown of the licensing, see PACKAGE-LICENSING License: GPLv2+ and GPLv2 and GPL URL: https://github.com/rpm-software-management/dnf Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz -# Backport of https://github.com/rpm-software-management/dnf/pull/1038 -# Should make compose fail on missing group packages again -Patch0: 0001-Restore-strict-choice-for-group-installs-1461539.patch BuildArch: noarch BuildRequires: cmake BuildRequires: gettext @@ -153,7 +151,11 @@ Version: 4.0.%{version} Requires: %{name} = %{version}-%{release} Summary: %{pkg_summary} %if 0%{?fedora} +%if 0%{?fedora} >= 30 Conflicts: yum +%else +Conflicts: yum < 3.4.3-505 +%endif %endif %description -n %{yum_subpackage_name} @@ -399,8 +401,6 @@ ln -sr %{buildroot}%{confdir}/vars %{buildroot}%{_sysconfdir}/yum/vars %dir %{confdir}/modules.d %dir %{confdir}/modules.defaults.d %dir %{pluginconfpath} -%dir %{_sysconfdir}/%{name}/modules.d -%dir %{_sysconfdir}/%{name}/modules.defaults.d %dir %{confdir}/protected.d %dir %{confdir}/vars %config(noreplace) %{confdir}/%{name}.conf @@ -439,7 +439,7 @@ ln -sr %{buildroot}%{confdir}/vars %{buildroot}%{_sysconfdir}/yum/vars %exclude %{_sysconfdir}/yum/vars %endif -%if "%{yum_subpackage_name}" == "yum4" +%if "%{yum_subpackage_name}" == "nextgen-yum4" %{_bindir}/yum4 %{_mandir}/man8/yum4.8* %exclude %{_sysconfdir}/yum.conf @@ -449,9 +449,14 @@ ln -sr %{buildroot}%{confdir}/vars %{buildroot}%{_sysconfdir}/yum/vars %if "%{yum_subpackage_name}" == "%{name}-yum" %{_bindir}/yum +%{_mandir}/man8/yum.8* +%if 0%{?fedora} >= 30 %{_sysconfdir}/yum.conf %{_mandir}/man5/yum.conf.5* -%{_mandir}/man8/yum.8* +%else +%exclude %{_sysconfdir}/yum.conf +%exclude %{_mandir}/man5/yum.conf.5* +%endif %endif %if %{with python2} @@ -490,6 +495,26 @@ ln -sr %{buildroot}%{confdir}/vars %{buildroot}%{_sysconfdir}/yum/vars %endif %changelog +* Tue Sep 25 2018 Jaroslav Mracek - 3.6.1-1 +- [module] Improved module commands list, info +- [module] Reports error from module solver +- Fix: Error detected when calling 'RepoCB.fastestMirror' (RhBug:1628056) +- Preserve packages from other installed mod profiles (RhBug:1629841) +- [spec] Postpone conflict with yum to Fedora 30+ (RhBug:1600444) +- [cli] Install command recommends alternative packages (RhBug:1625586) +- [cli] Fix case insensitive hint (1628514) +- Fix installed profiles for module info (RhBug:1629689) +- Fix module provides not having consistent output (RhBug:1623866) +- Enhance label for transaction table (RhBug:1609919) +- Implement C_, the gettext function with a context (RhBug:1305340) +- Actually disambiguate some messages using C_ (RhBug:1305340) +- Restore 'strict' choice for group installs (#1461539) +- [repoquery] More strict queryformat parsing (RhBug:1631458) +- Redirect repo progress to std error (RhBug:1626011) +- Unify behavior of remove and module remove (RhBug:1629848) +- Change behavior of disabled module for module install (RhBug:1629711) +- Allow enablement on disabled plugin (RhBug:1614539) + * Thu Sep 20 2018 Adam Williamson - 3.5.1-2 - Backport PR #1038 to make compose fail on missing group packages again diff --git a/sources b/sources index 807b1f8..ca8129d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (dnf-3.5.1.tar.gz) = 3acdfca43c644b163fbd054f1ceda73a312c709c42427a747e3d8bfcc7be200a765ece9373f640a176dd57549c1a9b8995b7c69b0713a6382d34bf5af3f6eb33 +SHA512 (dnf-3.6.1.tar.gz) = ba253b8c37b594f5be62cc0f7a6ec26b70b2b54e53bbcc0a869c17b41da138839c08252af9a4553976b2b0ffc1f20ae4664bd0e688229fbbb0669d27474aba54