diff --git a/SOURCES/0006-Add-default-colors-to-documentation.patch b/SOURCES/0006-Add-default-colors-to-documentation.patch
new file mode 100644
index 0000000..aa773c2
--- /dev/null
+++ b/SOURCES/0006-Add-default-colors-to-documentation.patch
@@ -0,0 +1,200 @@
+From 6766d3af1993d48f5548746e68268e674e52bd1d Mon Sep 17 00:00:00 2001
+From: Gary Leydon <gary.leydon@yale.edu>
+Date: Fri, 21 May 2021 14:13:59 -0400
+Subject: [PATCH 1/3] add default colors to documentation
+
+---
+ doc/conf_ref.rst | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
+index ec5bac2ab..fcaa0319f 100644
+--- a/doc/conf_ref.rst
++++ b/doc/conf_ref.rst
+@@ -498,72 +498,72 @@ configuration file by your distribution to override the DNF defaults.
+     :ref:`color <color-label>`
+ 
+     Color of available packages that are older than installed packages.
+-    The option is used during list operations.
++    The option is used during list operations. Default is dim,cyan.
+ 
+ ``color_list_available_install``
+     :ref:`color <color-label>`
+ 
+     Color of packages that are available for installation and none of their versions in installed.
+-    The option is used during list operations.
++    The option is used during list operations. Default is normal.
+ 
+ ``color_list_available_reinstall``
+     :ref:`color <color-label>`
+ 
+-    Color of available packages that are identical to installed versions and are available for reinstalls.
++    Color of available packages that are identical to installed versions and are available for reinstalls. Default is bold,underline,green.
+     The option is used during list operations.
+ 
+ ``color_list_available_upgrade``
+     :ref:`color <color-label>`
+ 
+-    Color of available packages that are newer than installed packages.
++    Color of available packages that are newer than installed packages. Default is bold,blue.
+     The option is used during list operations.
+ 
+ ``color_list_installed_extra``
+     :ref:`color <color-label>`
+ 
+     Color of installed packages that do not have any version among available packages.
+-    The option is used during list operations.
++    The option is used during list operations. Default is bold,red.
+ 
+ ``color_list_installed_newer``
+     :ref:`color <color-label>`
+ 
+     Color of installed packages that are newer than any version among available packages.
+-    The option is used during list operations.
++    The option is used during list operations. Default is bold,yellow.
+ 
+ ``color_list_installed_older``
+     :ref:`color <color-label>`
+ 
+     Color of installed packages that are older than any version among available packages.
+-    The option is used during list operations.
++    The option is used during list operations. Default is bold.
+ 
+ ``color_list_installed_reinstall``
+     :ref:`color <color-label>`
+ 
+     Color of installed packages that are among available packages and can be reinstalled.
+-    The option is used during list operations.
++    The option is used during list operations. Default is normal.
+ 
+ ``color_search_match``
+     :ref:`color <color-label>`
+ 
+-    Color of patterns matched in search output.
++    Color of patterns matched in search output. Default is bold.
+ 
+ ``color_update_installed``
+     :ref:`color <color-label>`
+ 
+-    Color of removed packages.
++    Color of removed packages. Default is normal.
+     This option is used during displaying transactions.
+ 
+ ``color_update_local``
+     :ref:`color <color-label>`
+ 
+     Color of local packages that are installed from the @commandline repository.
+-    This option is used during displaying transactions.
++    This option is used during displaying transactions. Default is bold.
+ 
+ ``color_update_remote``
+     :ref:`color <color-label>`
+ 
+     Color of packages that are installed/upgraded/downgraded from remote repositories.
+-    This option is used during displaying transactions.
++    This option is used during displaying transactions. Default is normal.
+ 
+ 
+ ==============
+-- 
+2.31.1
+
+
+From 276e3b1d19bfad2a72f75ecbcce478e4f1e575db Mon Sep 17 00:00:00 2001
+From: Gary Leydon <gary.leydon@yale.edu>
+Date: Fri, 21 May 2021 14:16:21 -0400
+Subject: [PATCH 2/3] add author
+
+---
+ AUTHORS | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/AUTHORS b/AUTHORS
+index 1981dc4e7..f8c9eb832 100644
+--- a/AUTHORS
++++ b/AUTHORS
+@@ -95,3 +95,4 @@ DNF CONTRIBUTORS
+     Vladan Kudlac <vladankudlac@gmail.com>
+     Will Woods <wwoods@redhat.com>
+     Furkan Karcıoğlu <krc440002@gmail.com>
++    Gary Leydon <gary.leydon@yale.edu>
+-- 
+2.31.1
+
+
+From 5cfe87de2ecd645c2aa8b210bd98171e8dd72fe5 Mon Sep 17 00:00:00 2001
+From: Gary Leydon <gary.leydon@yale.edu>
+Date: Thu, 27 May 2021 11:52:42 -0400
+Subject: [PATCH 3/3] update colors according to
+ libdnf/libdnf/conf/ConfigMain.cpp
+
+---
+ doc/conf_ref.rst | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
+index fcaa0319f..016bd00c2 100644
+--- a/doc/conf_ref.rst
++++ b/doc/conf_ref.rst
+@@ -498,13 +498,13 @@ configuration file by your distribution to override the DNF defaults.
+     :ref:`color <color-label>`
+ 
+     Color of available packages that are older than installed packages.
+-    The option is used during list operations. Default is dim,cyan.
++    The option is used during list operations. Default is magenta.
+ 
+ ``color_list_available_install``
+     :ref:`color <color-label>`
+ 
+     Color of packages that are available for installation and none of their versions in installed.
+-    The option is used during list operations. Default is normal.
++    The option is used during list operations. Default is bold,cyan.
+ 
+ ``color_list_available_reinstall``
+     :ref:`color <color-label>`
+@@ -534,36 +534,36 @@ configuration file by your distribution to override the DNF defaults.
+     :ref:`color <color-label>`
+ 
+     Color of installed packages that are older than any version among available packages.
+-    The option is used during list operations. Default is bold.
++    The option is used during list operations. Default is yellow.
+ 
+ ``color_list_installed_reinstall``
+     :ref:`color <color-label>`
+ 
+     Color of installed packages that are among available packages and can be reinstalled.
+-    The option is used during list operations. Default is normal.
++    The option is used during list operations. Default is cyan.
+ 
+ ``color_search_match``
+     :ref:`color <color-label>`
+ 
+-    Color of patterns matched in search output. Default is bold.
++    Color of patterns matched in search output. Default is bold,magenta.
+ 
+ ``color_update_installed``
+     :ref:`color <color-label>`
+ 
+-    Color of removed packages. Default is normal.
++    Color of removed packages. Default is red. 
+     This option is used during displaying transactions.
+ 
+ ``color_update_local``
+     :ref:`color <color-label>`
+ 
+     Color of local packages that are installed from the @commandline repository.
+-    This option is used during displaying transactions. Default is bold.
++    This option is used during displaying transactions. Default is green.
+ 
+ ``color_update_remote``
+     :ref:`color <color-label>`
+ 
+     Color of packages that are installed/upgraded/downgraded from remote repositories.
+-    This option is used during displaying transactions. Default is normal.
++    This option is used during displaying transactions. Default is bold,green.
+ 
+ 
+ ==============
+-- 
+2.31.1
+
diff --git a/SOURCES/0007-Fix-reporting-irrecoverable-errors-on-packages-download.patch b/SOURCES/0007-Fix-reporting-irrecoverable-errors-on-packages-download.patch
new file mode 100644
index 0000000..12f3972
--- /dev/null
+++ b/SOURCES/0007-Fix-reporting-irrecoverable-errors-on-packages-download.patch
@@ -0,0 +1,81 @@
+From f5cb86b83aedaa18fd784d06d8f1479b9127c6f5 Mon Sep 17 00:00:00 2001
+From: Marek Blaha <mblaha@redhat.com>
+Date: Wed, 6 Oct 2021 09:43:37 +0200
+Subject: [PATCH] Fix reporting irrecoverable errors on packages download
+
+The original _irrecoverable property returns random dictionary - either
+packages irrecoverable errors, or global fatal error or even new empty
+dictionary. This makes it prone to programmer errors like:
+
+errs._irrecoverable[pkg] = [err]
+
+which may lead to setting the error into the newly created empty
+dictionary instead of packages errors dictionary as intended.
+
+I turned the property to method which I consider more clear.
+---
+ dnf/base.py |  8 ++++----
+ dnf/repo.py |  9 ++++-----
+ 2 files changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/dnf/base.py b/dnf/base.py
+index 0949ddf..b0a378c 100644
+--- a/dnf/base.py
++++ b/dnf/base.py
+@@ -1165,8 +1165,8 @@ class Base(object):
+                 progress.start(len(payloads), est_remote_size)
+             errors = dnf.repo._download_payloads(payloads, drpm)
+ 
+-            if errors._irrecoverable:
+-                raise dnf.exceptions.DownloadError(errors._irrecoverable)
++            if errors._irrecoverable():
++                raise dnf.exceptions.DownloadError(errors._irrecoverable())
+ 
+             remote_size = sum(errors._bandwidth_used(pload)
+                               for pload in payloads)
+@@ -1191,8 +1191,8 @@ class Base(object):
+                 progress.start(len(payloads), est_remote_size)
+                 errors = dnf.repo._download_payloads(payloads, drpm)
+ 
+-                if errors._irrecoverable:
+-                    raise dnf.exceptions.DownloadError(errors._irrecoverable)
++                if errors._irrecoverable():
++                    raise dnf.exceptions.DownloadError(errors._irrecoverable())
+ 
+                 remote_size += \
+                     sum(errors._bandwidth_used(pload) for pload in payloads)
+diff --git a/dnf/repo.py b/dnf/repo.py
+index b5c9849..b454e98 100644
+--- a/dnf/repo.py
++++ b/dnf/repo.py
+@@ -112,7 +112,7 @@ def _download_payloads(payloads, drpm):
+             errs._skipped.add(pkg)
+             continue
+         pkg.repo._repo.expire()
+-        errs._irrecoverable[pkg] = [err]
++        errs._pkg_irrecoverable[pkg] = [err]
+ 
+     return errs
+ 
+@@ -131,15 +131,14 @@ def _update_saving(saving, payloads, errs):
+ 
+ class _DownloadErrors(object):
+     def __init__(self):
+-        self._val_irrecoverable = {}
++        self._pkg_irrecoverable = {}
+         self._val_recoverable = {}
+         self._fatal = None
+         self._skipped = set()
+ 
+-    @property
+     def _irrecoverable(self):
+-        if self._val_irrecoverable:
+-            return self._val_irrecoverable
++        if self._pkg_irrecoverable:
++            return self._pkg_irrecoverable
+         if self._fatal:
+             return {'': [self._fatal]}
+         return {}
+--
+libgit2 1.0.1
+
diff --git a/SOURCES/0008-Add-fail_fast-parameter-to-download_payloads-methods.patch b/SOURCES/0008-Add-fail_fast-parameter-to-download_payloads-methods.patch
new file mode 100644
index 0000000..6c01254
--- /dev/null
+++ b/SOURCES/0008-Add-fail_fast-parameter-to-download_payloads-methods.patch
@@ -0,0 +1,70 @@
+From ca3d7f06c8f4c1c901dc853ac33c06976b46c61e Mon Sep 17 00:00:00 2001
+From: Marek Blaha <mblaha@redhat.com>
+Date: Wed, 6 Oct 2021 09:56:05 +0200
+Subject: [PATCH] Add fail_fast parameter to download_payloads methods
+
+Unlike in the rpm transaction, reposync needs to switch the fail_fast
+off to download as much packages from repository as possible.
+---
+ dnf/base.py | 6 +++---
+ dnf/repo.py | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/dnf/base.py b/dnf/base.py
+index b0a378c..c258a5a 100644
+--- a/dnf/base.py
++++ b/dnf/base.py
+@@ -1151,7 +1151,7 @@ class Base(object):
+         timer()
+         self._trans_success = True
+ 
+-    def _download_remote_payloads(self, payloads, drpm, progress, callback_total):
++    def _download_remote_payloads(self, payloads, drpm, progress, callback_total, fail_fast=True):
+         lock = dnf.lock.build_download_lock(self.conf.cachedir, self.conf.exit_on_lock)
+         with lock:
+             beg_download = time.time()
+@@ -1163,7 +1163,7 @@ class Base(object):
+                 progress.start(len(payloads), est_remote_size, total_drpms=total_drpm)
+             else:
+                 progress.start(len(payloads), est_remote_size)
+-            errors = dnf.repo._download_payloads(payloads, drpm)
++            errors = dnf.repo._download_payloads(payloads, drpm, fail_fast)
+ 
+             if errors._irrecoverable():
+                 raise dnf.exceptions.DownloadError(errors._irrecoverable())
+@@ -1189,7 +1189,7 @@ class Base(object):
+                 est_remote_size = sum(pload.download_size
+                                       for pload in payloads)
+                 progress.start(len(payloads), est_remote_size)
+-                errors = dnf.repo._download_payloads(payloads, drpm)
++                errors = dnf.repo._download_payloads(payloads, drpm, fail_fast)
+ 
+                 if errors._irrecoverable():
+                     raise dnf.exceptions.DownloadError(errors._irrecoverable())
+diff --git a/dnf/repo.py b/dnf/repo.py
+index b454e98..bb42230 100644
+--- a/dnf/repo.py
++++ b/dnf/repo.py
+@@ -84,17 +84,17 @@ def _pkg2payload(pkg, progress, *factories):
+     raise ValueError(_('no matching payload factory for %s') % pkg)
+ 
+ 
+-def _download_payloads(payloads, drpm):
++def _download_payloads(payloads, drpm, fail_fast=True):
+     # download packages
+     def _download_sort_key(payload):
+         return not hasattr(payload, 'delta')
+ 
+     drpm.err.clear()
+     targets = [pload._librepo_target()
+                for pload in sorted(payloads, key=_download_sort_key)]
+     errs = _DownloadErrors()
+     try:
+-        libdnf.repo.PackageTarget.downloadPackages(libdnf.repo.VectorPPackageTarget(targets), True)
++        libdnf.repo.PackageTarget.downloadPackages(libdnf.repo.VectorPPackageTarget(targets), fail_fast)
+     except RuntimeError as e:
+         errs._fatal = str(e)
+     drpm.wait()
+--
+libgit2 1.0.1
+
diff --git a/SOURCES/0009-comps-Make-the-install_or_skip-method-not-catch-CompsError-anymore.patch b/SOURCES/0009-comps-Make-the-install_or_skip-method-not-catch-CompsError-anymore.patch
new file mode 100644
index 0000000..42a06db
--- /dev/null
+++ b/SOURCES/0009-comps-Make-the-install_or_skip-method-not-catch-CompsError-anymore.patch
@@ -0,0 +1,138 @@
+From f0f037db8219b1e74be4ed86f5eea53b63ca1d88 Mon Sep 17 00:00:00 2001
+From: Lukáš Hrázký <lhrazky@redhat.com>
+Date: Tue, 20 Jul 2021 15:29:59 +0200
+Subject: [PATCH] comps: Make the install_or_skip() method not catch CompsError anymore
+
+According to its docstring, the original intention of the method was to
+not fail on installing an already installed group/environment.
+
+However, the CompsError is no longer thrown when attempting to install
+an already installed group or environment. It was changed to logging a
+warning directly in 5210b9dc and then the check was removed completely
+in 217ca0fa.
+
+For the other case for which an instance of CompsError can be thrown
+from the install_group() and install_environment() methods, which is
+when a group or environment is not found, we certainly want to throw an
+error (see the linked bugs), therefore there's no reason to catch the
+exception anymore.
+
+The install_or_skip() method is preserved as part of the API so as not
+to break compatibility any more than necessary.
+
+msg: API: Raise CompsError when group/env not found in install_group and install_environment
+type: bugfix
+resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1947958
+related: https://bugzilla.redhat.com/show_bug.cgi?id=1943206
+---
+ dnf/base.py               |  8 ++------
+ dnf/cli/commands/group.py |  4 ++--
+ dnf/comps.py              | 20 ++++++++++----------
+ doc/api_base.rst          |  4 ++--
+ 4 files changed, 16 insertions(+), 20 deletions(-)
+
+diff --git a/dnf/base.py b/dnf/base.py
+index c258a5a..babca31 100644
+--- a/dnf/base.py
++++ b/dnf/base.py
+@@ -1668,9 +1668,7 @@ class Base(object):
+         if not isinstance(types, int):
+             types = libdnf.transaction.listToCompsPackageType(types)
+ 
+-        trans = dnf.comps.install_or_skip(solver._environment_install,
+-                                          env_id, types, exclude or set(),
+-                                          strict, exclude_groups)
++        trans = solver._environment_install(env_id, types, exclude or set(), strict, exclude_groups)
+         if not trans:
+             return 0
+         return self._add_comps_trans(trans)
+@@ -1713,9 +1711,7 @@ class Base(object):
+         if not isinstance(pkg_types, int):
+             pkg_types = libdnf.transaction.listToCompsPackageType(pkg_types)
+ 
+-        trans = dnf.comps.install_or_skip(solver._group_install,
+-                                          grp_id, pkg_types, exclude_pkgnames,
+-                                          strict)
++        trans = solver._group_install(grp_id, pkg_types, exclude_pkgnames, strict)
+         if not trans:
+             return 0
+         if strict:
+diff --git a/dnf/cli/commands/group.py b/dnf/cli/commands/group.py
+index cf54279..fd723c4 100644
+--- a/dnf/cli/commands/group.py
++++ b/dnf/cli/commands/group.py
+@@ -244,9 +244,9 @@ class GroupCommand(commands.Command):
+             types = tuple(self.base.conf.group_package_types)
+         pkg_types = libdnf.transaction.listToCompsPackageType(types)
+         for env_id in res.environments:
+-            dnf.comps.install_or_skip(solver._environment_install, env_id, pkg_types)
++            solver._environment_install(env_id, pkg_types)
+         for group_id in res.groups:
+-            dnf.comps.install_or_skip(solver._group_install, group_id, pkg_types)
++            solver._group_install(group_id, pkg_types)
+ 
+     def _mark_remove(self, patterns):
+         q = CompsQuery(self.base.comps, self.base.history,
+diff --git a/dnf/comps.py b/dnf/comps.py
+index 8976533..461eb27 100644
+--- a/dnf/comps.py
++++ b/dnf/comps.py
+@@ -93,15 +93,15 @@ def _fn_display_order(group):
+ 
+ def install_or_skip(install_fnc, grp_or_env_id, types, exclude=None,
+                     strict=True, exclude_groups=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_id, types, exclude, strict, exclude_groups)
+-    except dnf.comps.CompsError as e:
+-        logger.warning("%s, %s", ucd(e)[:-1], _("skipping."))
++    """
++    Installs a group or an environment identified by grp_or_env_id.
++    This method is preserved for API compatibility. It used to catch an
++    exception thrown when a gorup or env was already installed, which is no
++    longer thrown.
++    `install_fnc` has to be Solver._group_install or
++    Solver._environment_install.
++    """
++    return install_fnc(grp_or_env_id, types, exclude, strict, exclude_groups)
+ 
+ 
+ class _Langs(object):
+@@ -592,7 +592,7 @@ class Solver(object):
+         assert dnf.util.is_string_type(group_id)
+         return self.history.env.is_removable_group(group_id)
+ 
+-    def _environment_install(self, env_id, pkg_types, exclude, strict=True, exclude_groups=None):
++    def _environment_install(self, env_id, pkg_types, exclude=None, strict=True, exclude_groups=None):
+         assert dnf.util.is_string_type(env_id)
+         comps_env = self.comps._environment_by_id(env_id)
+         if not comps_env:
+diff --git a/doc/api_base.rst b/doc/api_base.rst
+index 20d7945..03396b6 100644
+--- a/doc/api_base.rst
++++ b/doc/api_base.rst
+@@ -179,7 +179,7 @@
+ 
+   .. method:: group_install(group_id, pkg_types, exclude=None, strict=True)
+ 
+-    Mark group with corresponding `group_id` installed and mark the packages in the group for installation. Return the number of packages that the operation has marked for installation. `pkg_types` is a sequence of strings determining the kinds of packages to be installed, where the respective groups can be selected by including ``"mandatory"``, ``"default"`` or ``"optional"`` in it. If `exclude` is given, it has to be an iterable of package name glob patterns: :meth:`.group_install` will then not mark the respective packages for installation whenever possible. Parameter `strict` is a 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).
++    Mark group with corresponding `group_id` installed and mark the packages in the group for installation. Return the number of packages that the operation has marked for installation. `pkg_types` is a sequence of strings determining the kinds of packages to be installed, where the respective groups can be selected by including ``"mandatory"``, ``"default"`` or ``"optional"`` in it. If `exclude` is given, it has to be an iterable of package name glob patterns: :meth:`.group_install` will then not mark the respective packages for installation whenever possible. Parameter `strict` is a 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).  Raises :exc:`dnf.exceptions.CompsError` in case the group doesn't exist.
+ 
+   .. method:: group_remove(group_id)
+ 
+@@ -191,7 +191,7 @@
+ 
+   .. method:: environment_install(env_id, types, exclude=None, strict=True, exclude_groups=None)
+ 
+-    Similar to :meth:`.group_install` but operates on environmental groups. `exclude_groups` is an iterable of group IDs that will not be marked as installed.
++    Similar to :meth:`.group_install` but operates on environmental groups. `exclude_groups` is an iterable of group IDs that will not be marked as installed.  Raises :exc:`dnf.exceptions.CompsError` in case the group doesn't exist.
+ 
+   .. method:: environment_remove(env_id)
+ 
+--
+libgit2 1.0.1
+
diff --git a/SOURCES/0010-doc-Improve-description-of-multilib_policyall-RhBug19966811995630.patch b/SOURCES/0010-doc-Improve-description-of-multilib_policyall-RhBug19966811995630.patch
new file mode 100644
index 0000000..c9abef0
--- /dev/null
+++ b/SOURCES/0010-doc-Improve-description-of-multilib_policyall-RhBug19966811995630.patch
@@ -0,0 +1,29 @@
+From 683b92811abcb6cbbc00353010ec18e2cf655912 Mon Sep 17 00:00:00 2001
+From: Jaroslav Mracek <jmracek@redhat.com>
+Date: Mon, 6 Sep 2021 12:40:59 +0200
+Subject: [PATCH] [doc] Improve description of multilib_policy=all (RhBug:1996681,1995630)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1996681
+https://bugzilla.redhat.com/show_bug.cgi?id=1995630
+---
+ doc/conf_ref.rst | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
+index 016bd00..83b14ec 100644
+--- a/doc/conf_ref.rst
++++ b/doc/conf_ref.rst
+@@ -351,7 +351,9 @@ configuration file by your distribution to override the DNF defaults.
+ ``multilib_policy``
+     :ref:`string <string-label>`
+ 
+-    Controls how multilib packages are treated during install operations. Can either be ``"best"`` (the default) for the depsolver to prefer packages which best match the system's architecture, or ``"all"`` to install all available packages with compatible architectures.
++    Controls how multilib packages are treated during install operations. Can either be ``"best"`` (the default) for
++    the depsolver to prefer packages which best match the system's architecture, or ``"all"`` to install packages for
++    all available architectures.
+ 
+ .. _obsoletes_conf_option-label:
+ 
+--
+libgit2 1.0.1
+
diff --git a/SOURCES/0011-Fix-Python-dnf-API-does-not-respect-cacheonly-RhBug1862970.patch b/SOURCES/0011-Fix-Python-dnf-API-does-not-respect-cacheonly-RhBug1862970.patch
new file mode 100644
index 0000000..b1f2b86
--- /dev/null
+++ b/SOURCES/0011-Fix-Python-dnf-API-does-not-respect-cacheonly-RhBug1862970.patch
@@ -0,0 +1,33 @@
+From db52d259645daf8ca0ae06e829787d36171f2d5b Mon Sep 17 00:00:00 2001
+From: Jaroslav Rohel <jrohel@redhat.com>
+Date: Wed, 20 Oct 2021 09:20:03 +0200
+Subject: [PATCH] Fix: Python dnf API does not respect cacheonly (RhBug:1862970)
+
+`Repo` object has always been constructed with default synchronization
+strategy. The configuration option `cacheonly` was ignored. DNF
+application set synchronization strategy later in the `Cli` object
+during processing demands.
+
+The fix takes into account the `cacheonly` option during the construction
+of the `Repo` object. Synchronization strategy may still be overriden
+during demand processing.
+---
+ dnf/repo.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/dnf/repo.py b/dnf/repo.py
+index bb42230..1822cf0 100644
+--- a/dnf/repo.py
++++ b/dnf/repo.py
+@@ -434,7 +434,7 @@ class Repo(dnf.conf.RepoConf):
+         self._pkgdir = None
+         self._key_import = _NullKeyImport()
+         self.metadata = None  # :api
+-        self._repo.setSyncStrategy(self.DEFAULT_SYNC)
++        self._repo.setSyncStrategy(SYNC_ONLY_CACHE if parent_conf and parent_conf.cacheonly else self.DEFAULT_SYNC)
+         if parent_conf:
+             self._repo.setSubstitutions(parent_conf.substitutions)
+         self._substitutions = dnf.conf.substitutions.Substitutions()
+--
+libgit2 1.0.1
+
diff --git a/SOURCES/0012-Documentation-API-notes-for-cacheonly.patch b/SOURCES/0012-Documentation-API-notes-for-cacheonly.patch
new file mode 100644
index 0000000..8c3cef0
--- /dev/null
+++ b/SOURCES/0012-Documentation-API-notes-for-cacheonly.patch
@@ -0,0 +1,26 @@
+From f8025df597685a0bd0c347b1a60c280f03bdca6f Mon Sep 17 00:00:00 2001
+From: Jaroslav Rohel <jrohel@redhat.com>
+Date: Fri, 5 Nov 2021 08:52:56 +0100
+Subject: [PATCH] Documentation: API notes for cacheonly
+
+---
+ doc/conf_ref.rst | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
+index 83b14ec..75bcdf7 100644
+--- a/doc/conf_ref.rst
++++ b/doc/conf_ref.rst
+@@ -129,6 +129,9 @@ configuration file by your distribution to override the DNF defaults.
+     If set to ``True`` DNF will run entirely from system cache, will not update
+     the cache and will use it even in case it is expired. Default is ``False``.
+ 
++    API Notes: Must be set before repository objects are created. Plugins must set
++    this in the pre_config hook. Later changes are ignored.
++
+ .. _check_config_file_age-label:
+ 
+ ``check_config_file_age``
+--
+libgit2 1.0.1
+
diff --git a/SOURCES/0013-Allow-destdir-option-with-modulesync-command.patch b/SOURCES/0013-Allow-destdir-option-with-modulesync-command.patch
new file mode 100644
index 0000000..d859553
--- /dev/null
+++ b/SOURCES/0013-Allow-destdir-option-with-modulesync-command.patch
@@ -0,0 +1,39 @@
+From 6af9938c87cf409f886f21b59ec45c54eda6c8b2 Mon Sep 17 00:00:00 2001
+From: Jaroslav Mracek <jmracek@redhat.com>
+Date: Tue, 2 Nov 2021 14:23:22 +0100
+Subject: [PATCH] Allow destdir option with modulesync command
+
+---
+ dnf/cli/cli.py      | 2 +-
+ doc/command_ref.rst | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py
+index 6576997..a315201 100644
+--- a/dnf/cli/cli.py
++++ b/dnf/cli/cli.py
+@@ -810,7 +810,7 @@ class Cli(object):
+         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'):
++                    'download', 'system-upgrade', 'reposync', 'modulesync'):
+                 logger.critical(_('--destdir or --downloaddir must be used with --downloadonly '
+                                   'or download or system-upgrade command.')
+                 )
+diff --git a/doc/command_ref.rst b/doc/command_ref.rst
+index f96c0ea..42aec72 100644
+--- a/doc/command_ref.rst
++++ b/doc/command_ref.rst
+@@ -182,7 +182,7 @@ Options
+ ``--downloaddir=<path>, --destdir=<path>``
+     Redirect downloaded packages to provided directory. The option has to be used together with the \-\
+     :ref:`-downloadonly <downloadonly-label>` command line option, with the
+-    ``download`` command (dnf-plugins-core) or with the ``system-upgrade`` command
++    ``download``, ``modulesync`` or ``reposync`` commands (dnf-plugins-core) or with the ``system-upgrade`` command
+     (dnf-plugins-extras).
+ 
+ .. _downloadonly-label:
+--
+libgit2 1.1.0
+
diff --git a/SPECS/dnf.spec b/SPECS/dnf.spec
index 4820e9d..345c013 100644
--- a/SPECS/dnf.spec
+++ b/SPECS/dnf.spec
@@ -66,7 +66,7 @@ It supports RPMs, modules and comps groups & environments.
 
 Name:           dnf
 Version:        4.7.0
-Release:        3%{?dist}
+Release:        7%{?dist}
 Summary:        %{pkg_summary}
 # For a breakdown of the licensing, see PACKAGE-LICENSING
 License:        GPLv2+
@@ -77,6 +77,14 @@ Patch2:         0002-dnfrpmmiscutilspy-fix-usage-of-_.patch
 Patch3:         0003-Pass-the-package-to-rpmkeys-stdin.patch
 Patch4:         0004-Use-rpmkeys-alone-to-verify-signature.patch
 Patch5:         0005-Lower-_pkgverify_level-to-signature-for-signature-checking-with-rpmkeys.patch
+Patch6:         0006-Add-default-colors-to-documentation.patch
+Patch7:         0007-Fix-reporting-irrecoverable-errors-on-packages-download.patch
+Patch8:         0008-Add-fail_fast-parameter-to-download_payloads-methods.patch
+Patch9:         0009-comps-Make-the-install_or_skip-method-not-catch-CompsError-anymore.patch
+Patch10:        0010-doc-Improve-description-of-multilib_policyall-RhBug19966811995630.patch
+Patch11:        0011-Fix-Python-dnf-API-does-not-respect-cacheonly-RhBug1862970.patch
+Patch12:        0012-Documentation-API-notes-for-cacheonly.patch
+Patch13:        0013-Allow-destdir-option-with-modulesync-command.patch
 
 BuildArch:      noarch
 BuildRequires:  cmake
@@ -376,6 +384,22 @@ popd
 %{python3_sitelib}/%{name}/automatic/
 
 %changelog
+* Fri Jan 14 2022 Pavla Kratochvilova <pkratoch@redhat.com> - 4.7.0-7
+- Rebuild with new release number
+
+* Tue Jan 11 2022 Pavla Kratochvilova <pkratoch@redhat.com> - 4.7.0-6
+- Allow destdir option with modulesync command
+
+* Tue Nov 09 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.7.0-5
+- Bump release number because of conflicting version of 8.5 build
+
+* Tue Nov 09 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.7.0-4
+- Add fail_fast parameter to _download_remote_payloads() method
+- Throw CompsError when a group or environment is not found for the install methods
+- Respect cacheonly in python dnf API (RhBug:1862970)
+- [doc] Improve description of multilib_policy=all (RhBug:1996681,1995630)
+- [doc] Document default colors
+
 * Mon Aug 16 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.7.0-3
 - Improve signature checking using rpmkeys (RhBug:1967454)