From ad2ca8d2aad741be805d70fa9a22c1ca02c0331d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Tue, 14 Mar 2017 10:22:59 +0100 Subject: [PATCH] Refactor ContainerBuilder Use Checksum instance to run a checksum match Check for existence of base image at earliest opportunity when constructing a ContainerBuilder --- kiwi/builder/container.py | 31 ++++++----- test/unit/builder_container_test.py | 80 +++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 34 deletions(-) diff --git a/kiwi/builder/container.py b/kiwi/builder/container.py index 8c01aa12..fd3f06db 100644 --- a/kiwi/builder/container.py +++ b/kiwi/builder/container.py @@ -66,10 +66,9 @@ class ContainerBuilder(object): if self.base_image_uri: base_image_origin = self.base_image_uri.translate() - - # we expect the base image to be unpacked by the kiwi prepare step - # and stored inside of the root_dir/image directory. In addition - # a md5 file of the image is expected there too + # The base image is expected to be unpacked by the kiwi + # prepare step and stored inside of the root_dir/image directory. + # In addition a md5 file of the image is expected too self.base_image = os.path.normpath( os.sep.join( [ @@ -78,7 +77,20 @@ class ContainerBuilder(object): ] ) ) + if not os.path.exists(self.base_image): + raise KiwiContainerBuilderError( + 'Unpacked Base image {0} not found'.format( + self.base_image + ) + ) + self.base_image_md5 = ''.join([self.base_image, '.md5']) + if not os.path.exists(self.base_image_md5): + raise KiwiContainerBuilderError( + 'Base image MD5 sum {0} not found at'.format( + self.base_image_md5 + ) + ) self.system_setup = SystemSetup( xml_state=xml_state, root_dir=self.root_dir @@ -113,15 +125,8 @@ class ContainerBuilder(object): ) container_setup.setup() else: - try: - checksum = Checksum(self.base_image) - with open(self.base_image_md5) as md5_file: - base_image_md5 = md5_file.read() - except Exception as e: - raise KiwiContainerBuilderError( - '%s: %s' % (type(e).__name__, format(e)) - ) - if base_image_md5.split(' ')[0] != checksum.md5(): + checksum = Checksum(self.base_image) + if not checksum.matches(checksum.md5(), self.base_image_md5): raise KiwiContainerBuilderError( 'base image file {0} checksum validation failed'.format( self.base_image diff --git a/test/unit/builder_container_test.py b/test/unit/builder_container_test.py index 0512912c..1c1f6677 100644 --- a/test/unit/builder_container_test.py +++ b/test/unit/builder_container_test.py @@ -12,7 +12,9 @@ from kiwi.exceptions import KiwiContainerBuilderError class TestContainerBuilder(object): @patch('platform.machine') - def setup(self, mock_machine): + @patch('os.path.exists') + def setup(self, mock_exists, mock_machine): + mock_exists.return_value = True mock_machine.return_value = 'x86_64' self.uri = Uri('file:///image_file.tar.xz') self.xml_state = mock.Mock() @@ -42,12 +44,55 @@ class TestContainerBuilder(object): ) self.container.result = mock.Mock() - def test_init_derived(self): + @patch('os.path.exists') + def test_init_derived(self, mock_exists): + mock_exists.return_value = True builder = ContainerBuilder( self.xml_state, 'target_dir', 'root_dir' ) assert builder.base_image == 'root_dir/image/image_file' + @patch('os.path.exists') + @raises(KiwiContainerBuilderError) + def test_init_derived_base_image_not_existing(self, mock_exists): + mock_exists.return_value = False + ContainerBuilder( + self.xml_state, 'target_dir', 'root_dir' + ) + + @patch('os.path.exists') + @raises(KiwiContainerBuilderError) + def test_init_derived_base_image_md5_not_existing(self, mock_exists): + exists_results = [False, True] + + def side_effect(self): + return exists_results.pop() + + mock_exists.side_effect = side_effect + ContainerBuilder( + self.xml_state, 'target_dir', 'root_dir' + ) + + @patch('kiwi.builder.container.Checksum') + @patch('kiwi.builder.container.ContainerImage') + @patch('os.path.exists') + @raises(KiwiContainerBuilderError) + def test_create_derived_checksum_match_failed( + self, mock_exists, mock_image, mock_checksum + ): + mock_exists.return_value = True + container = ContainerBuilder( + self.xml_state, 'target_dir', 'root_dir' + ) + container.result = mock.Mock() + + checksum = mock.Mock() + checksum.matches = mock.Mock( + return_value=False + ) + mock_checksum.return_value = checksum + container.create() + @patch('kiwi.builder.container.ContainerSetup') @patch('kiwi.builder.container.ContainerImage') def test_create(self, mock_image, mock_setup): @@ -99,28 +144,21 @@ class TestContainerBuilder(object): 'target_dir' ) - @patch_open @patch('kiwi.builder.container.Checksum') @patch('kiwi.builder.container.ContainerImage') - def test_create_derived(self, mock_image, mock_md5, mock_open): + @patch('os.path.exists') + def test_create_derived(self, mock_exists, mock_image, mock_checksum): + mock_exists.return_value = True container = ContainerBuilder( self.xml_state, 'target_dir', 'root_dir' ) container.result = mock.Mock() - md5 = mock.Mock() - md5.md5.return_value = 'checksumvalue' - mock_md5.return_value = md5 - - context_manager_mock = mock.Mock() - file_mock = mock.Mock() - file_mock.read.return_value = 'checksumvalue and someotherstuff\n' - enter_mock = mock.Mock() - exit_mock = mock.Mock() - enter_mock.return_value = file_mock - setattr(context_manager_mock, '__enter__', enter_mock) - setattr(context_manager_mock, '__exit__', exit_mock) - mock_open.return_value = context_manager_mock + checksum = mock.Mock() + checksum.md5 = mock.Mock( + return_value='checksumvalue' + ) + mock_checksum.return_value = checksum container_image = mock.Mock() mock_image.return_value = container_image @@ -129,10 +167,10 @@ class TestContainerBuilder(object): container.create() - mock_open.assert_called_once_with('root_dir/image/image_file.md5') - file_mock.read.assert_called_once_with() - mock_md5.assert_called_once_with('root_dir/image/image_file') - md5.md5.assert_called_once_with() + mock_checksum.assert_called_once_with('root_dir/image/image_file') + checksum.matches.assert_called_once_with( + 'checksumvalue', 'root_dir/image/image_file.md5' + ) mock_image.assert_called_once_with( 'docker', 'root_dir', self.container_config