diff --git a/.dnf.metadata b/.dnf.metadata
index cb4f5fb..1a71a98 100644
--- a/.dnf.metadata
+++ b/.dnf.metadata
@@ -1 +1 @@
-2b22746950312972466fb32d74c79ca42a367cf7 SOURCES/dnf-2.7.5-modularity-6.tar.gz
+0696a20c11d7e9d6f45726ffad7ae0b40e5b500c SOURCES/dnf-4.0.9.2.tar.gz
diff --git a/.gitignore b/.gitignore
index 20da192..83a534e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/dnf-2.7.5-modularity-6.tar.gz
+SOURCES/dnf-4.0.9.2.tar.gz
diff --git a/SOURCES/0001-Allow-to-set-cacheonly-from-commands-and-conf-RhBug-.patch b/SOURCES/0001-Allow-to-set-cacheonly-from-commands-and-conf-RhBug-.patch
deleted file mode 100644
index 703ad04..0000000
--- a/SOURCES/0001-Allow-to-set-cacheonly-from-commands-and-conf-RhBug-.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From bc11bf599ce3102656fa42b0ad0a6c7270822f30 Mon Sep 17 00:00:00 2001
-From: Jaroslav Mracek <jmracek@redhat.com>
-Date: Mon, 27 Nov 2017 14:35:32 +0100
-Subject: [PATCH 1/3] Allow to set cacheonly from commands and conf
- (RhBug:1492036)
-
-The formal code reacts only to --cacheonly option.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1492036
----
- dnf/cli/cli.py | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py
-index f60cdced..11fbed31 100644
---- a/dnf/cli/cli.py
-+++ b/dnf/cli/cli.py
-@@ -741,7 +741,10 @@ class Cli(object):
-             if not os.getegid() == 0:
-                 raise dnf.exceptions.Error(_('This command has to be run under the root user.'))
- 
--        if not demands.cacheonly:
-+        if demands.cacheonly or self.base.conf.cacheonly:
-+            self.base.conf.cacheonly = True
-+            repos.all()._md_only_cached = True
-+        else:
-             if demands.freshest_metadata:
-                 for repo in repos.iter_enabled():
-                     repo._md_expire_cache()
--- 
-2.13.6
-
diff --git a/SOURCES/0002-Remove-redundant-conf-option-cacheonly.patch b/SOURCES/0002-Remove-redundant-conf-option-cacheonly.patch
deleted file mode 100644
index 8005180..0000000
--- a/SOURCES/0002-Remove-redundant-conf-option-cacheonly.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 777df1098f4215edb8339a56c1807c9217715142 Mon Sep 17 00:00:00 2001
-From: Jaroslav Mracek <jmracek@redhat.com>
-Date: Mon, 27 Nov 2017 14:38:08 +0100
-Subject: [PATCH 2/3] Remove redundant conf option cacheonly
-
-The option was defined twice in "dnf.conf".
----
- dnf/conf/config.py | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/dnf/conf/config.py b/dnf/conf/config.py
-index f0c39665..f2098fc6 100644
---- a/dnf/conf/config.py
-+++ b/dnf/conf/config.py
-@@ -778,7 +778,6 @@ class MainConf(BaseConfig):
-         # runtime only options
-         self._add_option('downloadonly', BoolOption(False, runtimeonly=True))
-         self._add_option('ignorearch', BoolOption(False))
--        self._add_option('cacheonly', BoolOption(False))
- 
-     @property
-     def get_reposdir(self):
--- 
-2.13.6
-
diff --git a/SOURCES/0003-Remove-unnecessary-code-for-set-cacheonly.patch b/SOURCES/0003-Remove-unnecessary-code-for-set-cacheonly.patch
deleted file mode 100644
index 2be79b0..0000000
--- a/SOURCES/0003-Remove-unnecessary-code-for-set-cacheonly.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From aebbc222b85a7949a705360ea51b7c987126c2d8 Mon Sep 17 00:00:00 2001
-From: Jaroslav Mracek <jmracek@redhat.com>
-Date: Tue, 28 Nov 2017 09:21:40 +0100
-Subject: [PATCH 3/3] Remove unnecessary code for set cacheonly
-
-Attribute repo._md_only_cached is set on different place during
-_progress_demands().
----
- dnf/repo.py       | 5 -----
- tests/test_cli.py | 2 --
- 2 files changed, 7 deletions(-)
-
-diff --git a/dnf/repo.py b/dnf/repo.py
-index e9ce597e..75a11a47 100644
---- a/dnf/repo.py
-+++ b/dnf/repo.py
-@@ -858,11 +858,6 @@ class Repo(dnf.conf.RepoConf):
-         else:
-             return self._try_revive_by_repomd()
- 
--    def _configure_from_options(self, opts):
--        if getattr(opts, 'cacheonly', None):
--            self._md_only_cached = True
--        super(Repo, self)._configure_from_options(opts)
--
-     def disable(self):
-         # :api
-         self.enabled = False
-diff --git a/tests/test_cli.py b/tests/test_cli.py
-index f4ea27ee..8963783a 100644
---- a/tests/test_cli.py
-+++ b/tests/test_cli.py
-@@ -136,8 +136,6 @@ class CliTest(TestCase):
-         self.assertTrue(self.base.repos['comb'].enabled)
-         self.assertFalse(self.base.repos["comb"].gpgcheck)
-         self.assertFalse(self.base.repos["comb"].repo_gpgcheck)
--        self.assertEqual(self.base.repos["comb"]._sync_strategy,
--                         dnf.repo.SYNC_ONLY_CACHE)
- 
-     def test_configure_repos_expired(self, _):
-         """Ensure that --cacheonly beats the expired status."""
--- 
-2.13.6
-
diff --git a/SOURCES/0005-compatibility-gpgme.patch b/SOURCES/0005-compatibility-gpgme.patch
deleted file mode 100644
index 3f7d402..0000000
--- a/SOURCES/0005-compatibility-gpgme.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-diff --git a/dnf/crypto.py b/dnf/crypto.py
-index a1839eefe..24a13ed6f 100644
---- a/dnf/crypto.py
-+++ b/dnf/crypto.py
-@@ -26,12 +26,64 @@
- import dnf.pycomp
- import dnf.util
- import dnf.yum.misc
--import gpg
- import io
- import logging
- import os
- import tempfile
- 
-+try:
-+    from gpg import Context
-+    from gpg import Data
-+except ImportError:
-+    import gpgme
-+
-+
-+    class Context(object):
-+        def __init__(self):
-+            self.__dict__["ctx"] = gpgme.Context()
-+
-+        def __enter__(self):
-+            return self
-+
-+        def __exit__(self, type, value, tb):
-+            pass
-+
-+        @property
-+        def armor(self):
-+            return self.ctx.armor
-+
-+        @armor.setter
-+        def armor(self, value):
-+            self.ctx.armor = value
-+
-+        def op_import(self, key_fo):
-+            if isinstance(key_fo, basestring):
-+                key_fo = io.BytesIO(key_fo)
-+            self.ctx.import_(key_fo)
-+
-+        def op_export(self, pattern, mode, keydata):
-+            self.ctx.export(pattern, keydata)
-+
-+        def __getattr__(self, name):
-+            return getattr(self.ctx, name)
-+
-+
-+    class Data(object):
-+        def __init__(self):
-+            self.__dict__["buf"] = io.BytesIO()
-+
-+        def __enter__(self):
-+            return self
-+
-+        def __exit__(self, type, value, tb):
-+            pass
-+
-+        def read(self):
-+            return self.buf.getvalue()
-+
-+        def __getattr__(self, name):
-+            return getattr(self.buf, name)
-+
- 
- GPG_HOME_ENV = 'GNUPGHOME'
- logger = logging.getLogger('dnf')
-@@ -67,7 +119,7 @@ def keyids_from_pubring(gpgdir):
-     if not os.path.exists(gpgdir):
-         return []
- 
--    with pubring_dir(gpgdir), gpg.Context() as ctx:
-+    with pubring_dir(gpgdir), Context() as ctx:
-         keyids = []
-         for k in ctx.keylist():
-             subkey = _extract_signing_subkey(k)
-@@ -101,7 +153,7 @@ def pubring_dir(pubring_dir):
- def rawkey2infos(key_fo):
-     pb_dir = tempfile.mkdtemp()
-     keyinfos = []
--    with pubring_dir(pb_dir), gpg.Context() as ctx:
-+    with pubring_dir(pb_dir), Context() as ctx:
-         ctx.op_import(key_fo)
-         for key in ctx.keylist():
-             subkey = _extract_signing_subkey(key)
-@@ -110,7 +162,7 @@ def rawkey2infos(key_fo):
-             keyinfos.append(Key(key, subkey))
-         ctx.armor = True
-         for info in keyinfos:
--            with gpg.Data() as sink:
-+            with Data() as sink:
-                 ctx.op_export(info.id_, 0, sink)
-                 sink.seek(0, os.SEEK_SET)
-                 info.raw_key = sink.read()
-diff --git a/dnf/yum/misc.py b/dnf/yum/misc.py
-index 97f8be94d..248bff884 100644
---- a/dnf/yum/misc.py
-+++ b/dnf/yum/misc.py
-@@ -32,7 +32,6 @@
- import dnf.i18n
- import errno
- import glob
--import gpg
- import gzip
- import hashlib
- import io
-@@ -278,7 +277,7 @@ def import_key_to_pubring(rawkey, keyid, gpgdir=None, make_ro_copy=True):
-     if not os.path.exists(gpgdir):
-         os.makedirs(gpgdir)
- 
--    with dnf.crypto.pubring_dir(gpgdir), gpg.Context() as ctx:
-+    with dnf.crypto.pubring_dir(gpgdir), dnf.crypto.Context() as ctx:
-         # import the key
-         with open(os.path.join(gpgdir, 'gpg.conf'), 'wb') as fp:
-             fp.write(b'')
diff --git a/SOURCES/0006-util-Correctly-source-errno.EEXIST.patch b/SOURCES/0006-util-Correctly-source-errno.EEXIST.patch
deleted file mode 100644
index 20b5437..0000000
--- a/SOURCES/0006-util-Correctly-source-errno.EEXIST.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 199fc9cb11ff004fc752b58b7177aaf8d7fcedfd Mon Sep 17 00:00:00 2001
-From: Neal Gompa <ngompa13@gmail.com>
-Date: Sat, 3 Mar 2018 12:44:54 -0500
-Subject: [PATCH] util: Correctly source errno.EEXIST
-
----
- dnf/util.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/dnf/util.py b/dnf/util.py
-index ab7fd279..d0f1a4f2 100644
---- a/dnf/util.py
-+++ b/dnf/util.py
-@@ -28,6 +28,7 @@ from functools import reduce
- import dnf
- import dnf.const
- import dnf.pycomp
-+import errno
- import itertools
- import librepo
- import locale
-@@ -120,7 +121,7 @@ def ensure_dir(dname):
-     try:
-         os.makedirs(dname, mode=0o755)
-     except OSError as e:
--        if e.errno != os.errno.EEXIST or not os.path.isdir(dname):
-+        if e.errno != errno.EEXIST or not os.path.isdir(dname):
-             raise e
- 
- def empty(iterable):
--- 
-2.17.0
-
diff --git a/SOURCES/0007-fix-tests.patch b/SOURCES/0007-fix-tests.patch
deleted file mode 100644
index 3ce9a76..0000000
--- a/SOURCES/0007-fix-tests.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/tests/test_history_undo.py b/tests/test_history_undo.py
-index 5c7e423c..a551336b 100644
---- a/tests/test_history_undo.py
-+++ b/tests/test_history_undo.py
-@@ -30,6 +30,7 @@ from dnf.transaction import (ERASE, DOWNGRADE, INSTALL, REINSTALL,
- from hawkey import split_nevra
- from tests.support import mock_sack, Base, ObjectMatcher
- from unittest import TestCase
-+import tempfile
- 
- class BaseTest(TestCase):
-     """Unit tests of dnf.Base."""
-@@ -60,6 +61,7 @@ class BaseTest(TestCase):
-     def setUp(self):
-         """Prepare the test fixture."""
-         self._base = Base()
-+        self._base.conf.persistdir = tempfile.mkdtemp()
-         self._base._sack = mock_sack('main', 'updates')
- 
-     def test_history_undo_operations_downgrade(self):
-@@ -113,6 +115,7 @@ class BaseTest(TestCase):
-     def test_history_undo_operations_erase_twoavailable(self):
-         """Test history_undo_operations with an erase available in two repos."""
-         base = Base()
-+        base.conf.persistdir = tempfile.mkdtemp()
-         base._sack = mock_sack('main', 'search')
-         operations = NEVRAOperations()
-         operations.add('Erase', 'lotus-3-16.x86_64')
diff --git a/SOURCES/0008-system-and-cmdline-repos-hotfixes.patch b/SOURCES/0008-system-and-cmdline-repos-hotfixes.patch
deleted file mode 100644
index c56456e..0000000
--- a/SOURCES/0008-system-and-cmdline-repos-hotfixes.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-commit 805859f4a75d5d8118d9a307ee296efe1d9cff2f
-Author: Jaroslav Mracek <jmracek@redhat.com>
-Date:   Mon Sep 24 14:31:26 2018 +0200
-
-    Exclude system and commandline pkg from filtering (RhBug:1630226)
-    
-    https://bugzilla.redhat.com/show_bug.cgi?id=1630226
-
-diff --git a/dnf/base.py b/dnf/base.py
-index 1c41af7a..34ea864e 100644
---- a/dnf/base.py
-+++ b/dnf/base.py
-@@ -294,6 +294,8 @@ class Base(object):
- 
-         # collect all hotfix repo repoids - we don't filter them at all
-         hotfix_repos = [i.id for i in self.repos.iter_enabled() if i.hotfixes]
-+        hotfix_repos.append(hawkey.SYSTEM_REPO_NAME)
-+        hotfix_repos.append(hawkey.CMDLINE_REPO_NAME)
- 
-         # collect all RPM $names for bare RPMs filtering
-         names = {hawkey.split_nevra(i).name for i in include_nevras_set}
diff --git a/SOURCES/0009-Allow-usage-of--C-and-with-modified-cachedir-RhBug1643129.patch b/SOURCES/0009-Allow-usage-of--C-and-with-modified-cachedir-RhBug1643129.patch
deleted file mode 100644
index 36a66a3..0000000
--- a/SOURCES/0009-Allow-usage-of--C-and-with-modified-cachedir-RhBug1643129.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 487b68b0aed495c7154a6b91ffef4452f4333cf7 Mon Sep 17 00:00:00 2001
-From: Jaroslav Mracek <jmracek@redhat.com>
-Date: Mon, 29 Oct 2018 16:53:53 +0100
-Subject: [PATCH] Allow usage of -C and with modified cachedir (RhBug:1643129)
-
----
- dnf/cli/cli.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py
-index 521b3f3..ff7d80d 100644
---- a/dnf/cli/cli.py
-+++ b/dnf/cli/cli.py
-@@ -810,10 +810,10 @@ class Cli(object):
- 
-         # Read up configuration options and initialize plugins
-         try:
--            self.base.conf._configure_from_options(opts)
-             if opts.cacheonly:
-                 self.base.conf.cachedir = self.base.conf.system_cachedir
-                 self.demands.cacheonly = True
-+            self.base.conf._configure_from_options(opts)
-             self._read_conf_file(opts.releasever)
-             self.base.conf._adjust_conf_options()
-         except (dnf.exceptions.ConfigError, ValueError) as e:
---
-libgit2 0.26.7
-
diff --git a/SOURCES/0010-Fix-priority-cachedir-priority-with---cacheonly.patch b/SOURCES/0010-Fix-priority-cachedir-priority-with---cacheonly.patch
deleted file mode 100644
index e3046eb..0000000
--- a/SOURCES/0010-Fix-priority-cachedir-priority-with---cacheonly.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 5e8a1723a7c93f7f2a564d12a62b52d00d33c446 Mon Sep 17 00:00:00 2001
-From: Jaroslav Mracek <jmracek@redhat.com>
-Date: Tue, 30 Oct 2018 12:53:07 +0100
-Subject: [PATCH] Fix priority cachedir priority with --cacheonly
-
----
- dnf/cli/cli.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py
-index ff7d80d..17a31fc 100644
---- a/dnf/cli/cli.py
-+++ b/dnf/cli/cli.py
-@@ -811,7 +811,8 @@ class Cli(object):
-         # Read up configuration options and initialize plugins
-         try:
-             if opts.cacheonly:
--                self.base.conf.cachedir = self.base.conf.system_cachedir
-+                opt = self.base.conf._get_option("cachedir")
-+                opt._set(self.base.conf.system_cachedir, dnf.conf.PRIO_COMMANDLINE)
-                 self.demands.cacheonly = True
-             self.base.conf._configure_from_options(opts)
-             self._read_conf_file(opts.releasever)
---
-libgit2 0.26.7
-
diff --git a/SOURCES/1293.patch b/SOURCES/1293.patch
new file mode 100644
index 0000000..36ba762
--- /dev/null
+++ b/SOURCES/1293.patch
@@ -0,0 +1,114 @@
+From 7f6d223078599c3a6a2f26bf89ba8a91afd4cb88 Mon Sep 17 00:00:00 2001
+From: Michal Domonkos <mdomonko@redhat.com>
+Date: Mon, 17 Dec 2018 14:38:22 +0100
+Subject: [PATCH] Add basic integration with %_pkgverify_level
+
+RPM 4.14.2 introduced a new low-level security policy for package
+verification configured with the %_pkgverify_level macro:
+
+http://rpm.org/wiki/Releases/4.14.2
+
+In DNF, signature verification is done via RPM but in a separate step
+that precedes the transaction itself (BaseCli.gpgsigcheck()).  We can
+make use of that to catch signature errors and/or import public keys the
+same way as if gpgcheck was enabled from the start.  To that end, this
+commit forces the gpgcheck and localpkg_gpgcheck options to True if the
+policy would result in signature verification anyway.
+
+Resolves RHEL-8 bug:
+https://bugzilla.redhat.com/show_bug.cgi?id=1614351
+---
+ dnf/cli/cli.py           | 18 ++++++++++++++++++
+ dnf/cli/option_parser.py |  2 +-
+ doc/command_ref.rst      |  2 +-
+ doc/conf_ref.rst         | 12 ++++++++++--
+ 4 files changed, 30 insertions(+), 4 deletions(-)
+
+diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py
+index ea328702f4..522a2ad936 100644
+--- a/dnf/cli/cli.py
++++ b/dnf/cli/cli.py
+@@ -972,6 +972,24 @@ def configure(self, args, option_parser=None):
+         if self.base.conf.color != 'auto':
+             self.base.output.term.reinit(color=self.base.conf.color)
+ 
++        if rpm.expandMacro('%_pkgverify_level') in ('signature', 'all'):
++            forcing = False
++            for repo in self.base.repos.iter_enabled():
++                if repo.gpgcheck:
++                    continue
++                repo.gpgcheck = True
++                forcing = True
++            if not self.base.conf.localpkg_gpgcheck:
++                self.base.conf.localpkg_gpgcheck = True
++                forcing = True
++            if forcing:
++                logger.warning(
++                    _("Warning: Enforcing GPG signature check globally "
++                      "as per active RPM security policy (see 'gpgcheck' in "
++                      "dnf.conf(5) for how to squelch this message)"
++                      )
++                )
++
+     def _read_conf_file(self, releasever=None):
+         timer = dnf.logging.Timer('config')
+         conf = self.base.conf
+diff --git a/dnf/cli/option_parser.py b/dnf/cli/option_parser.py
+index e60179cfac..ba5a316c79 100644
+--- a/dnf/cli/option_parser.py
++++ b/dnf/cli/option_parser.py
+@@ -274,7 +274,7 @@ def _main_parser(self):
+                                  help=_("disable removal of dependencies that are no longer used"))
+         main_parser.add_argument("--nogpgcheck", action="store_false",
+                                  default=None, dest='gpgcheck',
+-                                 help=_("disable gpg signature checking"))
++                                 help=_("disable gpg signature checking (if RPM policy allows)"))
+         main_parser.add_argument("--color", dest="color", default=None,
+                                  help=_("control whether color is used"))
+         main_parser.add_argument("--refresh", dest="freshest_metadata",
+diff --git a/doc/command_ref.rst b/doc/command_ref.rst
+index 6ba31ff9be..70659e6560 100644
+--- a/doc/command_ref.rst
++++ b/doc/command_ref.rst
+@@ -275,7 +275,7 @@ Options
+     do not install documentation by using rpm flag 'RPMTRANS_FLAG_NODOCS'
+ 
+ ``--nogpgcheck``
+-    skip checking GPG signatures on packages
++    skip checking GPG signatures on packages (if RPM policy allows)
+ 
+ ``--noplugins``
+     Disable all plugins.
+diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
+index 979e2d18c6..6bbcbda9c0 100644
+--- a/doc/conf_ref.rst
++++ b/doc/conf_ref.rst
+@@ -452,7 +452,11 @@ configuration.
+ ``gpgcheck``
+     :ref:`boolean <boolean-label>`
+ 
+-    Whether to perform GPG signature check on packages found in this repository. The default is False.
++    Whether to perform GPG signature check on packages found in this repository.
++    The default is False.
++    This option can only be used to strengthen the active RPM security policy set with the `%_pkgverify_level` macro (see /usr/lib/rpm/macros for details).
++    That means, if the macro is set to `signature` or `all` and this option is False, it will be overridden to True when DNF runs and a warning will be printed.
++    To squelch the warning, make sure this option is True on every enabled repository and also enable :ref:`localpkg_gpgcheck <localpkg_gpgcheck-label>`.
+ 
+ .. _include-label:
+ 
+@@ -470,10 +474,14 @@ configuration.
+ 
+     Determines how DNF resolves host names. Set this to '4'/'IPv4' or '6'/'IPv6' to resolve to IPv4 or IPv6 addresses only. By default, DNF resolves to either addresses.
+ 
++.. _localpkg_gpgcheck-label:
++
+ ``localpkg_gpgcheck``
+     :ref:`boolean <boolean-label>`
+ 
+-    Whether to perform a GPG signature check on local packages (packages in a file, not in a repositoy). The default is False.
++    Whether to perform a GPG signature check on local packages (packages in a file, not in a repository).
++    The default is False.
++    This option is subject to the active RPM security policy (see :ref:`gpgcheck <gpgcheck-label>` for more details).
+ 
+ ``max_parallel_downloads``
+     :ref:`integer <integer-label>`
diff --git a/SPECS/dnf.spec b/SPECS/dnf.spec
index 1d75e65..1fcb177 100644
--- a/SPECS/dnf.spec
+++ b/SPECS/dnf.spec
@@ -1,13 +1,13 @@
 # default dependencies
-%global hawkey_version 0.11.1
-%global librepo_version 1.8.1
+%global hawkey_version 0.22.5
 %global libcomps_version 0.1.8
 %global libmodulemd_version 1.4.0
-%global python_smartcols_version 0.3.0
 %global rpm_version 4.14.0
 
 # conflicts
-%global conflicts_dnf_plugins_core_version 2.1.3
+%global conflicts_dnf_plugins_core_version 4.0.2
+%global conflicts_dnf_plugins_extras_version 3.0.2
+%global conflicts_dnfdaemon_version 0.3.19
 
 # override dependencies for rhel 7
 %if 0%{?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,7 +40,7 @@
 # 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 nextgen-yum4
 %endif
@@ -71,22 +72,14 @@
 It supports RPMs, modules and comps groups & environments.
 
 Name:           dnf
-Version:        2.7.5
-Release:        19%{?dist}
+Version:        4.0.9.2
+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}-modularity-6/%{name}-%{version}-modularity-6.tar.gz
-Patch0:         0001-Allow-to-set-cacheonly-from-commands-and-conf-RhBug-.patch
-Patch1:         0002-Remove-redundant-conf-option-cacheonly.patch
-Patch2:         0003-Remove-unnecessary-code-for-set-cacheonly.patch
-Patch3:         0005-compatibility-gpgme.patch
-Patch4:         0006-util-Correctly-source-errno.EEXIST.patch
-Patch5:         0007-fix-tests.patch
-Patch6:         0008-system-and-cmdline-repos-hotfixes.patch
-Patch7:         0009-Allow-usage-of--C-and-with-modified-cachedir-RhBug1643129.patch
-Patch8:         0010-Fix-priority-cachedir-priority-with---cacheonly.patch
+Source0:        %{url}/archive/%{version}/%{name}-%{version}.tar.gz
+Patch0:         1293.patch
 
 BuildArch:      noarch
 BuildRequires:  cmake
@@ -112,6 +105,7 @@ Recommends:     (python2-dbus if NetworkManager)
 Recommends:     (%{_bindir}/sqlite3 if bash-completion)
 %endif
 %{?systemd_requires}
+Provides:       dnf-command(alias)
 Provides:       dnf-command(autoremove)
 Provides:       dnf-command(check-update)
 Provides:       dnf-command(clean)
@@ -136,6 +130,8 @@ Provides:       dnf-command(upgrade)
 Provides:       dnf-command(upgrade-to)
 Conflicts:      python2-dnf-plugins-core < %{conflicts_dnf_plugins_core_version}
 Conflicts:      python3-dnf-plugins-core < %{conflicts_dnf_plugins_core_version}
+Conflicts:      python2-dnf-plugins-extras < %{conflicts_dnf_plugins_extras_version}
+Conflicts:      python3-dnf-plugins-extras < %{conflicts_dnf_plugins_extras_version}
 
 %description
 %{pkg_description}
@@ -153,7 +149,11 @@ Common data and configuration files for DNF
 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}
@@ -165,45 +165,50 @@ Summary:        Python 2 interface to DNF
 %{?python_provide:%python_provide python2-%{name}}
 BuildRequires:  python2-devel
 BuildRequires:  python2-hawkey >= %{hawkey_version}
+BuildRequires:  python2-libdnf >= %{hawkey_version}
 BuildRequires:  python2-libcomps >= %{libcomps_version}
-BuildRequires:  python-librepo >= %{librepo_version}
+BuildRequires:  python2-libdnf
 BuildRequires:  python2-nose
+BuildRequires:  libmodulemd >= %{libmodulemd_version}
+Requires:       libmodulemd >= %{libmodulemd_version}
 %if (0%{?rhel} && 0%{?rhel} <= 7)
 BuildRequires:  pygpgme
 Requires:       pygpgme
+BuildRequires:  python-enum34
+Requires:       python-enum34
 %else
 BuildRequires:  python2-gpg
 Requires:       python2-gpg
+BuildRequires:  python2-enum34
+Requires:       python2-enum34
 %endif
 BuildRequires:  pyliblzma
 Requires:       pyliblzma
 Requires:       %{name}-data = %{version}-%{release}
-%if 0%{?fedora} || 0%{?centos}
+%if 0%{?fedora}
+Recommends:     deltarpm
+Recommends:     python2-unbound
+%endif
+%if 0%{?centos}
 Requires:       deltarpm
 %endif
 Requires:       python2-hawkey >= %{hawkey_version}
+Requires:       python2-libdnf >= %{hawkey_version}
 Requires:       python2-libcomps >= %{libcomps_version}
-Requires:       python-librepo >= %{librepo_version}
-BuildRequires:  libmodulemd >= %{libmodulemd_version}
-Requires:       libmodulemd >= %{libmodulemd_version}
-BuildRequires:  python2-smartcols >= %{python_smartcols_version}
-Requires:       python2-smartcols >= %{python_smartcols_version}
+Requires:       python2-libdnf
 %if 0%{?rhel} && 0%{?rhel} <= 7
 BuildRequires:  python-iniparse
 Requires:       python-iniparse
 BuildRequires:  rpm-python >= %{rpm_version}
 Requires:       rpm-python >= %{rpm_version}
-BuildRequires:  python-gobject-base
-Requires:       python-gobject-base
 %else
 BuildRequires:  python2-iniparse
 Requires:       python2-iniparse
 BuildRequires:  python2-rpm >= %{rpm_version}
 Requires:       python2-rpm >= %{rpm_version}
 Recommends:     rpm-plugin-systemd-inhibit
-BuildRequires:  python2-gobject-base
-Requires:       python2-gobject-base
 %endif
+Conflicts:      dnfdaemon < %{conflicts_dnfdaemon_version}
 
 %description -n python2-%{name}
 Python 2 interface to DNF.
@@ -215,32 +220,34 @@ Summary:        Python 3 interface to DNF
 %{?python_provide:%python_provide python3-%{name}}
 BuildRequires:  python3-devel
 BuildRequires:  python3-hawkey >= %{hawkey_version}
+BuildRequires:  python3-libdnf >= %{hawkey_version}
 BuildRequires:  python3-iniparse
 BuildRequires:  python3-libcomps >= %{libcomps_version}
-BuildRequires:  python3-librepo >= %{librepo_version}
+BuildRequires:  python3-libdnf
+BuildRequires:  libmodulemd >= %{libmodulemd_version}
+Requires:       libmodulemd >= %{libmodulemd_version}
 BuildRequires:  python3-nose
 BuildRequires:  python3-gpg
 Requires:       python3-gpg
 Requires:       %{name}-data = %{version}-%{release}
-%if 0%{?fedora} || 0%{?centos}
+%if 0%{?fedora}
+Recommends:     deltarpm
+%endif
+%if 0%{?centos}
 Requires:       deltarpm
 %endif
 Requires:       python3-hawkey >= %{hawkey_version}
+Requires:       python3-libdnf >= %{hawkey_version}
 Requires:       python3-iniparse
 Requires:       python3-libcomps >= %{libcomps_version}
-Requires:       python3-librepo >= %{librepo_version}
+Requires:       python3-libdnf
 BuildRequires:  python3-rpm >= %{rpm_version}
 Requires:       python3-rpm >= %{rpm_version}
+Recommends:     python3-unbound
 %if 0%{?rhel} && 0%{?rhel} <= 7
 Requires:       rpm-plugin-systemd-inhibit
 %else
 Recommends:     rpm-plugin-systemd-inhibit
-BuildRequires:  libmodulemd >= %{libmodulemd_version}
-Requires:       libmodulemd >= %{libmodulemd_version}
-BuildRequires:  python3-gobject-base
-Requires:       python3-gobject-base
-BuildRequires:  python3-smartcols >= %{python_smartcols_version}
-Requires:       python3-smartcols >= %{python_smartcols_version}
 %endif
 
 %description -n python3-%{name}
@@ -258,7 +265,7 @@ Systemd units that can periodically download package upgrades and apply them.
 
 
 %prep
-%autosetup -p1 -n %{name}-%{version}-modularity-6
+%autosetup -p1
 mkdir build-py2
 mkdir build-py3
 
@@ -266,7 +273,7 @@ mkdir build-py3
 %build
 %if %{with python2}
     pushd build-py2
-    %cmake .. -DPYTHON_DESIRED:str=2
+    %cmake .. -DPYTHON_DESIRED:FILEPATH=%{__python2}
     %make_build
     make doc-man
     popd
@@ -274,7 +281,7 @@ mkdir build-py3
 
 %if %{with python3}
     pushd build-py3
-    %cmake .. -DPYTHON_DESIRED:str=3
+    %cmake .. -DPYTHON_DESIRED:FILEPATH=%{__python3}
     %make_build
     make doc-man
     popd
@@ -296,15 +303,16 @@ mkdir build-py3
 
 %find_lang %{name}
 mkdir -p %{buildroot}%{confdir}/vars
+mkdir -p %{buildroot}%{confdir}/aliases.d
 mkdir -p %{buildroot}%{pluginconfpath}/
+mkdir -p %{buildroot}%{_sysconfdir}/%{name}/modules.d
+mkdir -p %{buildroot}%{_sysconfdir}/%{name}/modules.defaults.d
 %if %{with python2}
 mkdir -p %{buildroot}%{py2pluginpath}/
 %endif
 %if %{with python3}
 mkdir -p %{buildroot}%{py3pluginpath}/__pycache__/
 %endif
-mkdir -p %{buildroot}%{confdir}/modules.d
-mkdir -p %{buildroot}%{confdir}/modules.defaults.d
 ln -sr  %{buildroot}%{confdir}/%{name}.conf %{buildroot}%{_sysconfdir}/yum.conf
 mkdir -p %{buildroot}%{_localstatedir}/log/
 mkdir -p %{buildroot}%{_var}/cache/dnf/
@@ -325,6 +333,12 @@ ln -sr  %{buildroot}%{_bindir}/dnf-2 %{buildroot}%{_bindir}/yum
 %endif
 %endif
 rm -vf %{buildroot}%{_bindir}/dnf-automatic-*
+%if "%{yum_subpackage_name}" == "yum"
+mkdir -p %{buildroot}%{_sysconfdir}/yum
+ln -sr  %{buildroot}%{pluginconfpath} %{buildroot}%{_sysconfdir}/yum/pluginconf.d
+ln -sr  %{buildroot}%{confdir}/protected.d %{buildroot}%{_sysconfdir}/yum/protected.d
+ln -sr  %{buildroot}%{confdir}/vars %{buildroot}%{_sysconfdir}/yum/vars
+%endif
 
 
 %check
@@ -394,18 +408,19 @@ rm -vf %{buildroot}%{_bindir}/dnf-automatic-*
 %dir %{pluginconfpath}
 %dir %{confdir}/protected.d
 %dir %{confdir}/vars
+%dir %{confdir}/aliases.d
 %config(noreplace) %{confdir}/%{name}.conf
 %config(noreplace) %{confdir}/protected.d/%{name}.conf
 %config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
-%ghost %{_localstatedir}/log/hawkey.log
-%ghost %{_localstatedir}/log/%{name}.log
-%ghost %{_localstatedir}/log/%{name}.librepo.log
-%ghost %{_localstatedir}/log/%{name}.rpm.log
-%ghost %{_localstatedir}/log/%{name}.plugin.log
-%ghost %{_sharedstatedir}/%{name}
-%ghost %{_sharedstatedir}/%{name}/groups.json
-%ghost %{_sharedstatedir}/%{name}/yumdb
-%ghost %{_sharedstatedir}/%{name}/history
+%ghost %attr(644,-,-) %{_localstatedir}/log/hawkey.log
+%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.log
+%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.librepo.log
+%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.rpm.log
+%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.plugin.log
+%ghost %attr(755,-,-) %dir %{_sharedstatedir}/%{name}
+%ghost %attr(644,-,-) %{_sharedstatedir}/%{name}/groups.json
+%ghost %attr(755,-,-) %dir %{_sharedstatedir}/%{name}/yumdb
+%ghost %attr(755,-,-) %dir %{_sharedstatedir}/%{name}/history
 %{_mandir}/man5/%{name}.conf.5*
 %{_tmpfilesdir}/%{name}.conf
 %{_sysconfdir}/libreport/events.d/collect_dnf.conf
@@ -413,9 +428,21 @@ rm -vf %{buildroot}%{_bindir}/dnf-automatic-*
 %files -n %{yum_subpackage_name}
 %if "%{yum_subpackage_name}" == "yum"
 %{_bindir}/yum
+%{_mandir}/man8/yum.8*
 %{_sysconfdir}/yum.conf
+%{_sysconfdir}/yum/pluginconf.d
+%{_sysconfdir}/yum/protected.d
+%{_sysconfdir}/yum/vars
 %{_mandir}/man5/yum.conf.5.*
 %{_mandir}/man8/yum.8*
+%{_mandir}/man8/yum-shell.8*
+%{_mandir}/man1/yum-aliases.1*
+%else
+%exclude %{_mandir}/man8/yum-shell.8*
+%exclude %{_mandir}/man1/yum-aliases.1*
+%exclude %{_sysconfdir}/yum/pluginconf.d
+%exclude %{_sysconfdir}/yum/protected.d
+%exclude %{_sysconfdir}/yum/vars
 %endif
 
 %if "%{yum_subpackage_name}" == "nextgen-yum4"
@@ -427,10 +454,15 @@ rm -vf %{buildroot}%{_bindir}/dnf-automatic-*
 %endif
 
 %if "%{yum_subpackage_name}" == "%{name}-yum"
-%{_sysconfdir}/yum.conf
 %{_bindir}/yum
-%{_mandir}/man5/yum.conf.5*
 %{_mandir}/man8/yum.8*
+%if 0%{?fedora} >= 30
+%{_sysconfdir}/yum.conf
+%{_mandir}/man5/yum.conf.5*
+%else
+%exclude %{_sysconfdir}/yum.conf
+%exclude %{_mandir}/man5/yum.conf.5*
+%endif
 %endif
 
 %if %{with python2}
@@ -469,6 +501,9 @@ rm -vf %{buildroot}%{_bindir}/dnf-automatic-*
 %endif
 
 %changelog
+* Tue Jan 08 2019 Daniel Mach <dmach@redhat.com> - 4.0.9.2-1
+- Update to 4.0.9.2
+
 * Thu Nov 08 2018 Jaroslav Mracek <jmracek@redhat.com> - 2.7.5-19
 - Backport patches for RHBZ#1643129 from upstream dnf-2-modularity