From 2cd080d0bb04cf42f72aeccc182df1b8b90db5a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Wed, 6 Mar 2019 16:25:01 +0100 Subject: [PATCH] Follow up fix for zypper compat link Move the code handling the compat setup of the rpm database to the correct method of the repository API. Call the import of the signing keys only if there are signing keys --- kiwi/repository/apt.py | 5 +- kiwi/repository/dnf.py | 7 ++- kiwi/repository/zypper.py | 77 ++++++++++++++--------------- kiwi/system/prepare.py | 3 +- test/unit/repository_zypper_test.py | 31 ++++++------ 5 files changed, 59 insertions(+), 64 deletions(-) diff --git a/kiwi/repository/apt.py b/kiwi/repository/apt.py index 7a8f5c2d..26238587 100644 --- a/kiwi/repository/apt.py +++ b/kiwi/repository/apt.py @@ -205,9 +205,8 @@ class RepositoryApt(RepositoryBase): :param list signing_keys: list of the key files to import """ - if signing_keys: - for key in signing_keys: - self.signing_keys.append(key) + for key in signing_keys: + self.signing_keys.append(key) def delete_repo(self, name): """ diff --git a/kiwi/repository/dnf.py b/kiwi/repository/dnf.py index 75cf5402..90cf123e 100644 --- a/kiwi/repository/dnf.py +++ b/kiwi/repository/dnf.py @@ -199,10 +199,9 @@ class RepositoryDnf(RepositoryBase): :param list signing_keys: list of the key files to import """ - if signing_keys: - rpmdb = RpmDataBase(self.root_dir) - for key in signing_keys: - rpmdb.import_signing_key_to_image(key) + rpmdb = RpmDataBase(self.root_dir) + for key in signing_keys: + rpmdb.import_signing_key_to_image(key) def delete_repo(self, name): """ diff --git a/kiwi/repository/zypper.py b/kiwi/repository/zypper.py index af15fe66..5f432ac1 100644 --- a/kiwi/repository/zypper.py +++ b/kiwi/repository/zypper.py @@ -155,6 +155,7 @@ class RepositoryZypper(RepositoryBase): 2. Create the rpm bootstrap macro to make sure for bootstrapping the rpm database location matches the host rpm database setup. This macro only persists during the bootstrap phase + 3. Create zypper compat link """ rpmdb = RpmDataBase( self.root_dir, Defaults.get_custom_rpm_image_macro_name() @@ -164,6 +165,41 @@ class RepositoryZypper(RepositoryBase): rpmdb.write_config() RpmDataBase(self.root_dir).set_database_to_host_path() + # Zypper compat code: + # + # Manually adding the compat link /var/lib/rpm that points to the + # rpmdb location as it is configured in the host rpm setup. The + # host rpm setup is taken into account because import_trusted_keys + # is called during the bootstrap phase where rpm (respectively zypper) + # is called from the host + # + # Usually it is expected that the package manager reads the + # signing keys from the rpm database setup provisioned by rpm + # itself (macro level) but zypper doesn't take the rpm macro + # setup into account and relies on a hard coded path which we + # can only provide as a symlink. + # + # That symlink is usually created by the rpm package when it gets + # installed. However at that early phase when we import the + # signing keys no rpm is installed yet nor any symlink exists. + # Thus we have to create it here and hope to get rid of it in the + # future. + # + # For further details on the motivation in zypper please + # refer to bsc#1112357 + rpmdb.init_database() + Path.create( + os.sep.join([self.root_dir, 'var', 'lib']) + ) + Command.run( + [ + 'ln', '-s', ''.join( + ['../..', rpmdb.rpmdb_host.expand_query('%_dbpath')] + ), os.sep.join( + [self.root_dir, 'var', 'lib', 'rpm'] + ) + ], raise_on_error=False + ) def use_default_location(self): """ @@ -286,45 +322,8 @@ class RepositoryZypper(RepositoryBase): :param list signing_keys: list of the key files to import """ rpmdb = RpmDataBase(self.root_dir) - if signing_keys: - for key in signing_keys: - rpmdb.import_signing_key_to_image(key) - else: - rpmdb.init_database() - # Zypper compat code: - # - # Manually adding the compat link /var/lib/rpm that points to the - # rpmdb location as it is configured in the host rpm setup. The - # host rpm setup is taken into account because import_trusted_keys - # is called during the bootstrap phase where rpm (respectively zypper) - # is called from the host - # - # Usually it is expected that the package manager reads the - # signing keys from the rpm database setup provisioned by rpm - # itself (macro level) but zypper doesn't take the rpm macro - # setup into account and relies on a hard coded path which we - # can only provide as a symlink. - # - # That symlink is usually created by the rpm package when it gets - # installed. However at that early phase when we import the - # signing keys no rpm is installed yet nor any symlink exists. - # Thus we have to create it here and hope to get rid of it in the - # future. - # - # For further details on the motivation in zypper please - # refer to bsc#1112357 - Path.create( - os.sep.join([self.root_dir, 'var', 'lib']) - ) - Command.run( - [ - 'ln', '-s', ''.join( - ['../..', rpmdb.rpmdb_host.expand_query('%_dbpath')] - ), os.sep.join( - [self.root_dir, 'var', 'lib', 'rpm'] - ) - ], raise_on_error=False - ) + for key in signing_keys: + rpmdb.import_signing_key_to_image(key) def delete_repo(self, name): """ diff --git a/kiwi/system/prepare.py b/kiwi/system/prepare.py index 097b2a0f..b19969a0 100644 --- a/kiwi/system/prepare.py +++ b/kiwi/system/prepare.py @@ -112,7 +112,8 @@ class SystemPrepare(object): self.root_bind, package_manager, repository_options ) repo.setup_package_database_configuration() - repo.import_trusted_keys(signing_keys) + if signing_keys: + repo.import_trusted_keys(signing_keys) for xml_repo in repository_sections: repo_type = xml_repo.get_type() repo_source = xml_repo.get_source().get_path() diff --git a/test/unit/repository_zypper_test.py b/test/unit/repository_zypper_test.py index f98252fe..33e3a5ca 100644 --- a/test/unit/repository_zypper_test.py +++ b/test/unit/repository_zypper_test.py @@ -224,8 +224,13 @@ class TestRepositoryZypper(object): ) @patch('kiwi.repository.zypper.RpmDataBase') - def test_setup_package_database_configuration(self, mock_RpmDataBase): + @patch('kiwi.command.Command.run') + @patch('kiwi.repository.zypper.Path.create') + def test_setup_package_database_configuration( + self, mock_Path_create, mock_Command_run, mock_RpmDataBase + ): rpmdb = mock.Mock() + rpmdb.rpmdb_host.expand_query.return_value = '/usr/lib/sysimage/rpm' mock_RpmDataBase.return_value = rpmdb self.repo.setup_package_database_configuration() assert mock_RpmDataBase.call_args_list == [ @@ -237,15 +242,17 @@ class TestRepositoryZypper(object): ) rpmdb.write_config.assert_called_once_with() rpmdb.set_database_to_host_path.assert_called_once_with() + rpmdb.init_database.assert_called_once_with() + mock_Path_create.assert_called_once_with('../data/var/lib') + mock_Command_run.assert_called_once_with( + [ + 'ln', '-s', '../../usr/lib/sysimage/rpm', '../data/var/lib/rpm' + ], raise_on_error=False + ) @patch('kiwi.repository.zypper.RpmDataBase') - @patch('kiwi.command.Command.run') - @patch('kiwi.repository.zypper.Path.create') - def test_import_trusted_keys( - self, mock_Path_create, mock_Command_run, mock_RpmDataBase - ): + def test_import_trusted_keys(self, mock_RpmDataBase): rpmdb = mock.Mock() - rpmdb.rpmdb_host.expand_query.return_value = '/usr/lib/sysimage/rpm' mock_RpmDataBase.return_value = rpmdb signing_keys = ['key-file-a.asc', 'key-file-b.asc'] self.repo.import_trusted_keys(signing_keys) @@ -253,16 +260,6 @@ class TestRepositoryZypper(object): call('key-file-a.asc'), call('key-file-b.asc') ] - mock_Path_create.assert_called_once_with('../data/var/lib') - mock_Command_run.assert_called_once_with( - [ - 'ln', '-s', '../../usr/lib/sysimage/rpm', '../data/var/lib/rpm' - ], raise_on_error=False - ) - signing_keys = None - rpmdb.reset_mock() - self.repo.import_trusted_keys(signing_keys) - rpmdb.init_database.assert_called_once_with() @patch('kiwi.command.Command.run') @patch('kiwi.repository.zypper.Path.wipe')