Example #1
0
    def create(self, filename, base_image):
        """
        Create compressed oci system container tar archive

        :param string filename: archive file name
        :param string base_image: archive used as a base image
        """
        exclude_list = Defaults.get_exclude_list_for_root_data_sync()
        exclude_list.append('boot')
        exclude_list.append('dev')
        exclude_list.append('sys')
        exclude_list.append('proc')

        if base_image:
            Path.create(self.oci.container_dir)
            image_tar = ArchiveTar(base_image)
            image_tar.extract(self.oci.container_dir)

        self.oci.init_layout(bool(base_image))

        self.oci.unpack()
        self.oci.sync_rootfs(''.join([self.root_dir, os.sep]), exclude_list)
        self.oci.repack(self.oci_config)

        if 'additional_tags' in self.oci_config:
            for tag in self.oci_config['additional_tags']:
                self.oci.add_tag(tag)

        self.oci.set_config(self.oci_config, bool(base_image))

        self.oci.garbage_collect()

        return self.pack_image_to_file(filename)
Example #2
0
    def import_overlay_files(self,
                             follow_links=False,
                             preserve_owner_group=False):
        """
        Copy overlay files from the image description to
        the image root tree. Supported are a root/ directory
        or a root.tar.gz tarball. The root/ directory takes
        precedence over the tarball

        :param bool follow_links: follow symlinks true|false
        :param bool preserve_owner_group: preserve permissions true|false
        """
        overlay_directory = self.description_dir + '/root/'
        overlay_archive = self.description_dir + '/root.tar.gz'
        if os.path.exists(overlay_directory):
            log.info('Copying user defined files to image tree')
            sync_options = [
                '-r', '-p', '-t', '-D', '-H', '-X', '-A', '--one-file-system'
            ]
            if follow_links:
                sync_options.append('--copy-links')
            else:
                sync_options.append('--links')
            if preserve_owner_group:
                sync_options.append('-o')
                sync_options.append('-g')
            data = DataSync(overlay_directory, self.root_dir)
            data.sync_data(options=sync_options)
        elif os.path.exists(overlay_archive):
            log.info(
                'Extracting user defined files from archive to image tree')
            archive = ArchiveTar(overlay_archive)
            archive.extract(self.root_dir)
Example #3
0
class TestArchiveTar(object):
    def setup(self):
        self.archive = ArchiveTar('foo.tar')

    @patch('kiwi.archive.tar.Command.run')
    def test_extract(self, mock_command):
        self.archive.extract('destination')
        mock_command.assert_called_once_with(
            ['tar', '-C', 'destination', '-x', '-v', '-f', 'foo.tar'])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        self.archive.create('source-dir')
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*', '-c',
            '-f', 'foo.tar', 'foo', 'bar'
        ])

    @patch('kiwi.archive.tar.Command.run')
    def test_create_from_dir_with_excludes(self, mock_command):
        archive = ArchiveTar('foo.tar', False)
        archive.create('source-dir', ['foo', 'bar'])
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*', '-c',
            '-f', 'foo.tar', '.', '--exclude', './foo', '--exclude', './bar'
        ])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_xz_compressed(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        self.archive.create_xz_compressed('source-dir')
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*', '-c',
            '-J', '-f', 'foo.tar.xz', 'foo', 'bar'
        ])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_gnu_gzip_compressed(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        self.archive.create_gnu_gzip_compressed('source-dir')
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '--format=gnu', '-cSz', '-f',
            'foo.tar.gz', 'foo', 'bar'
        ])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_exclude(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        self.archive.create('source-dir', ['foo'])
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*', '-c',
            '-f', 'foo.tar', 'bar'
        ])
Example #4
0
File: oci.py Project: eduardoj/kiwi
    def create(self, filename, base_image):
        """
        Create compressed oci system container tar archive

        :param string filename: archive file name
        :param string base_image: archive used as a base image
        """
        exclude_list = Defaults.get_exclude_list_for_root_data_sync()
        exclude_list.append('boot')
        exclude_list.append('dev')
        exclude_list.append('sys')
        exclude_list.append('proc')

        self.oci_dir = mkdtemp(prefix='kiwi_oci_dir.')
        self.oci_root_dir = mkdtemp(prefix='kiwi_oci_root_dir.')

        container_dir = os.sep.join([self.oci_dir, 'umoci_layout'])
        container_name = ':'.join([container_dir, self.container_tag])

        if base_image:
            Path.create(container_dir)
            image_tar = ArchiveTar(base_image)
            image_tar.extract(container_dir)
            Command.run([
                'umoci', 'config', '--image',
                '{0}:base_layer'.format(container_dir), '--tag',
                self.container_tag
            ])
        else:
            Command.run(['umoci', 'init', '--layout', container_dir])
            Command.run(['umoci', 'new', '--image', container_name])

        Command.run(
            ['umoci', 'unpack', '--image', container_name, self.oci_root_dir])
        oci_root = DataSync(''.join([self.root_dir, os.sep]),
                            os.sep.join([self.oci_root_dir, 'rootfs']))
        oci_root.sync_data(options=['-a', '-H', '-X', '-A', '--delete'],
                           exclude=exclude_list)
        Command.run(
            ['umoci', 'repack', '--image', container_name, self.oci_root_dir])
        for tag in self.additional_tags:
            Command.run(
                ['umoci', 'config', '--image', container_name, '--tag', tag])
        Command.run(['umoci', 'config'] + self.maintainer + self.user +
                    self.workingdir + self.entry_command +
                    self.entry_subcommand + self.expose_ports + self.volumes +
                    self.environment + self.labels + [
                        '--image', container_name, '--created',
                        datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S+00:00')
                    ])
        Command.run(['umoci', 'gc', '--layout', container_dir])

        return self.pack_image_to_file(filename)
Example #5
0
    def import_cdroot_files(self, target_dir):
        """
        Copy cdroot files from the image description to the
        specified target directory. Supported is a tar
        archive named config-cdroot.tar[.compression-postfix]

        :param str target_dir: directory to unpack archive to
        """
        glob_match = self.description_dir + '/config-cdroot.tar*'
        for cdroot_archive in sorted(glob.iglob(glob_match)):
            log.info('Extracting ISO user config archive: {0} to: {1}'.format(
                cdroot_archive, target_dir))
            archive = ArchiveTar(cdroot_archive)
            archive.extract(target_dir)
            break
Example #6
0
 def _install_archives(self, archive_list):
     log.info("Installing archives")
     for archive in archive_list:
         log.info("--> archive: %s", archive)
         description_dir = \
             self.xml_state.xml_data.description_dir
         derived_description_dir = \
             self.xml_state.xml_data.derived_description_dir
         archive_is_absolute = archive.startswith('/')
         if archive_is_absolute:
             archive_file = archive
         else:
             archive_file = '/'.join([description_dir, archive])
         archive_exists = os.path.exists(archive_file)
         if not archive_is_absolute and not archive_exists and derived_description_dir:
             archive_file = '/'.join([derived_description_dir, archive])
         tar = ArchiveTar(archive_file)
         tar.extract(self.root_bind.root_dir)
Example #7
0
    def import_overlay_files(
        self, follow_links: bool = False, preserve_owner_group: bool = False
    ) -> None:
        """
        Copy overlay files from the image description to
        the image root tree. Supported are a root/ directory
        or a root.tar.gz tarball. The root/ directory takes
        precedence over the tarball.

        In addition the method also supports profile specific
        overlay files which are searched in a directory of the
        same name as the profile name.

        The overall order for including overlay files is as
        follows:

        1. root/ dir or root.tar.gz
        2. PROFILE_NAME/ dir(s) in the order of the selected
           profiles

        :param bool follow_links: follow symlinks true|false
        :param bool preserve_owner_group: preserve permissions true|false
        """
        overlay_directory = self.description_dir + '/root/'
        overlay_archive = self.description_dir + '/root.tar.gz'
        if os.path.exists(overlay_directory):
            self._sync_overlay_files(
                overlay_directory, follow_links, preserve_owner_group
            )
        elif os.path.exists(overlay_archive):
            log.info('Extracting user defined files from archive to image tree')
            archive = ArchiveTar(overlay_archive)
            archive.extract(self.root_dir)

        for profile in self.xml_state.profiles:
            overlay_directory = os.path.join(
                self.description_dir, profile
            ) + os.sep
            if os.path.exists(overlay_directory):
                self._sync_overlay_files(
                    overlay_directory, follow_links, preserve_owner_group,
                    profile
                )
Example #8
0
    def extract_oci_image(self):
        """
        Extract the image from the provided image file to a temporary
        location to KIWI can work with it.
        """
        if not self.unknown_uri:
            tar = ArchiveTar(self.image_file)
            self.uncompressed_image = mkdtemp(prefix='kiwi_uncompressed.')
            tar.extract(self.uncompressed_image)
            if self.tag:
                skopeo_uri = 'oci:{0}:{1}'.format(self.uncompressed_image,
                                                  self.tag)
            else:
                skopeo_uri = 'oci:{0}'.format(self.uncompressed_image)
        else:
            log.warning('Bypassing base image URI to skopeo tool')
            skopeo_uri = self.unknown_uri

        Command.run([
            'skopeo', 'copy', skopeo_uri, 'oci:{0}'.format(self.oci_layout_dir)
        ])
Example #9
0
 def _install_archives(self, archive_list):
     log.info("Installing archives")
     for archive in archive_list:
         log.info("--> archive: %s", archive)
         description_dir = \
             self.xml_state.xml_data.description_dir
         derived_description_dir = \
             self.xml_state.xml_data.derived_description_dir
         archive_is_absolute = archive.startswith('/')
         if archive_is_absolute:
             archive_file = archive
         else:
             archive_file = '/'.join(
                 [description_dir, archive]
             )
         archive_exists = os.path.exists(archive_file)
         if not archive_is_absolute and not archive_exists and derived_description_dir:
             archive_file = '/'.join(
                 [derived_description_dir, archive]
             )
         tar = ArchiveTar(archive_file)
         tar.extract(self.root_bind.root_dir)
Example #10
0
    def extract_oci_image(self):
        """
        Extract the contents from the provided image file to a temporary
        location KIWI can work with.
        """
        if not self.unknown_uri:
            tar = ArchiveTar(self.image_file)
            self.uncompressed_image = mkdtemp(prefix='kiwi_uncompressed.')
            tar.extract(self.uncompressed_image)
            if self.tag:
                skopeo_uri = 'oci:{0}:{1}'.format(
                    self.uncompressed_image, self.tag
                )
            else:
                skopeo_uri = 'oci:{0}'.format(self.uncompressed_image)
        else:
            log.warning('Bypassing base image URI to skopeo tool')
            skopeo_uri = self.unknown_uri

        Command.run([
            'skopeo', 'copy', skopeo_uri,
            'oci:{0}:base_layer'.format(self.oci_layout_dir)
        ])
Example #11
0
    def import_overlay_files(
        self, follow_links=False, preserve_owner_group=False
    ):
        """
        Copy overlay files from the image description to
        the image root tree. Supported are a root/ directory
        or a root.tar.gz tarball. The root/ directory takes
        precedence over the tarball

        :param bool follow_links: follow symlinks true|false
        :param bool preserve_owner_group: preserve permissions true|false
        """
        overlay_directory = self.description_dir + '/root/'
        overlay_archive = self.description_dir + '/root.tar.gz'
        if os.path.exists(overlay_directory):
            log.info('Copying user defined files to image tree')
            sync_options = [
                '-r', '-p', '-t', '-D', '-H', '-X', '-A', '--one-file-system'
            ]
            if follow_links:
                sync_options.append('--copy-links')
            else:
                sync_options.append('--links')
            if preserve_owner_group:
                sync_options.append('-o')
                sync_options.append('-g')
            data = DataSync(
                overlay_directory, self.root_dir
            )
            data.sync_data(
                options=sync_options
            )
        elif os.path.exists(overlay_archive):
            log.info('Extracting user defined files from archive to image tree')
            archive = ArchiveTar(overlay_archive)
            archive.extract(self.root_dir)
Example #12
0
class TestArchiveTar(object):
    @patch('kiwi.archive.tar.Command.run')
    def setup(self, mock_command):
        command = mock.Mock()
        command.output = 'version 1.27.0'
        mock_command.return_value = command
        self.archive = ArchiveTar('foo.tar')

    @raises(KiwiCommandCapabilitiesError)
    @patch('kiwi.archive.tar.Command.run')
    def test_invalid_tar_command_version(self, mock_command):
        command = mock.Mock()
        command.output = 'version cannot be parsed'
        mock_command.return_value = command
        self.archive = ArchiveTar('foo.tar')

    @patch('kiwi.archive.tar.Command.run')
    def test_extract(self, mock_command):
        self.archive.extract('destination')
        mock_command.assert_called_once_with(
            ['tar', '-C', 'destination', '-x', '-v', '-f', 'foo.tar'])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create('source-dir') == 'foo.tar'
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*', '-c',
            '-f', 'foo.tar', 'foo', 'bar'
        ])

    @patch('kiwi.archive.tar.Command.run')
    def test_append_files(self, mock_command):
        assert self.archive.append_files('source-dir', ['foo', 'bar']) \
            == 'foo.tar'
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '-r', '--file=' + self.archive.filename,
            '--xattrs', '--xattrs-include=*', 'foo', 'bar'
        ])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_with_options(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create('source-dir',
                                   options=['--fake-option',
                                            'fake_arg']) == 'foo.tar'
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '--fake-option', 'fake_arg', '--xattrs',
            '--xattrs-include=*', '-c', '-f', 'foo.tar', 'foo', 'bar'
        ])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_with_old_tar_version(self, mock_os_dir, mock_command):
        command = mock.Mock()
        command.output = 'version 1.26.1'
        mock_command.return_value = command
        archive = ArchiveTar('foo.tar')
        mock_os_dir.return_value = ['foo', 'bar']
        assert archive.create('source-dir') == 'foo.tar'
        calls = [
            call(['tar', '--version']),
            call([
                'tar', '-C', 'source-dir', '-c', '-f', 'foo.tar', 'foo', 'bar'
            ])
        ]
        mock_command.assert_has_calls(calls)
        assert mock_command.call_count == 2

    @patch('kiwi.archive.tar.Command.run')
    def test_create_from_dir_with_excludes(self, mock_command):
        command = mock.Mock()
        command.output = 'version 1.27.0'
        mock_command.return_value = command
        archive = ArchiveTar('foo.tar', False)
        assert archive.create('source-dir', ['foo', 'bar']) == 'foo.tar'
        calls = [
            call(['tar', '--version']),
            call([
                'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*',
                '-c', '-f', 'foo.tar', '.', '--exclude', './foo', '--exclude',
                './bar'
            ])
        ]
        mock_command.assert_has_calls(calls)
        assert mock_command.call_count == 2

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_xz_compressed(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create_xz_compressed('source-dir') == 'foo.tar.xz'
        mock_command.assert_called_once_with([
            'bash', '-c', ' '.join([
                'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*',
                '-c', '--to-stdout', 'foo', 'bar', '|', 'xz', '-f',
                '--threads=0', '>', 'foo.tar.xz'
            ])
        ])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_xz_compressed_with_custom_xz_options(
            self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create_xz_compressed('source-dir',
                                                 xz_options=['-a', '-b'
                                                             ]) == 'foo.tar.xz'
        mock_command.assert_called_once_with([
            'bash', '-c', ' '.join([
                'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*',
                '-c', '--to-stdout', 'foo', 'bar', '|', 'xz', '-f', '-a', '-b',
                '>', 'foo.tar.xz'
            ])
        ])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_gnu_gzip_compressed(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create_gnu_gzip_compressed('source-dir') \
            == 'foo.tar.gz'
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '--format=gnu', '-cSz', '-f',
            'foo.tar.gz', 'foo', 'bar'
        ])

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_exclude(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create('source-dir', ['foo']) == 'foo.tar'
        mock_command.assert_called_once_with([
            'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*', '-c',
            '-f', 'foo.tar', 'bar'
        ])
Example #13
0
class TestArchiveTar(object):
    @patch('kiwi.archive.tar.Command.run')
    def setup(self, mock_command):
        command = mock.Mock()
        command.output = 'version 1.27.0'
        mock_command.return_value = command
        self.archive = ArchiveTar('foo.tar')

    @raises(KiwiCommandCapabilitiesError)
    @patch('kiwi.archive.tar.Command.run')
    def test_invalid_tar_command_version(self, mock_command):
        command = mock.Mock()
        command.output = 'version cannot be parsed'
        mock_command.return_value = command
        self.archive = ArchiveTar('foo.tar')

    @patch('kiwi.archive.tar.Command.run')
    def test_extract(self, mock_command):
        self.archive.extract('destination')
        mock_command.assert_called_once_with(
            ['tar', '-C', 'destination', '-x', '-v', '-f', 'foo.tar']
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create('source-dir') == 'foo.tar'
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir',
                '--xattrs', '--xattrs-include=*',
                '-c', '-f', 'foo.tar', 'foo', 'bar'
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    def test_append_files(self, mock_command):
        assert self.archive.append_files('source-dir', ['foo', 'bar']) \
            == 'foo.tar'
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir', '-r',
                '--file=' + self.archive.filename,
                '--xattrs', '--xattrs-include=*',
                'foo', 'bar'
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_with_options(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create('source-dir', options=[
            '--fake-option', 'fake_arg'
        ]) == 'foo.tar'
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir',
                '--fake-option', 'fake_arg',
                '--xattrs', '--xattrs-include=*',
                '-c', '-f', 'foo.tar', 'foo', 'bar'
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_with_old_tar_version(self, mock_os_dir, mock_command):
        command = mock.Mock()
        command.output = 'version 1.26.1'
        mock_command.return_value = command
        archive = ArchiveTar('foo.tar')
        mock_os_dir.return_value = ['foo', 'bar']
        assert archive.create('source-dir') == 'foo.tar'
        calls = [
            call(['tar', '--version']),
            call(
                [
                    'tar', '-C', 'source-dir',
                    '-c', '-f', 'foo.tar', 'foo', 'bar'
                ]
            )
        ]
        mock_command.assert_has_calls(calls)
        assert mock_command.call_count == 2

    @patch('kiwi.archive.tar.Command.run')
    def test_create_from_dir_with_excludes(self, mock_command):
        command = mock.Mock()
        command.output = 'version 1.27.0'
        mock_command.return_value = command
        archive = ArchiveTar('foo.tar', False)
        assert archive.create('source-dir', ['foo', 'bar']) == 'foo.tar'
        calls = [
            call(['tar', '--version']),
            call(
                [
                    'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*',
                    '-c', '-f', 'foo.tar', '.',
                    '--exclude', './foo', '--exclude', './bar'
                ]
            )
        ]
        mock_command.assert_has_calls(calls)
        assert mock_command.call_count == 2

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_xz_compressed(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create_xz_compressed('source-dir') == 'foo.tar.xz'
        mock_command.assert_called_once_with(
            [
                'bash', '-c',
                ' '.join([
                    'tar', '-C', 'source-dir', '--xattrs',
                    '--xattrs-include=*', '-c', '--to-stdout',
                    'foo', 'bar', '|', 'xz', '-f', '--threads=0',
                    '>', 'foo.tar.xz'
                ])
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_xz_compressed_with_custom_xz_options(
        self, mock_os_dir, mock_command
    ):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create_xz_compressed(
            'source-dir', xz_options=['-a', '-b']
        ) == 'foo.tar.xz'
        mock_command.assert_called_once_with(
            [
                'bash', '-c',
                ' '.join([
                    'tar', '-C', 'source-dir', '--xattrs',
                    '--xattrs-include=*', '-c', '--to-stdout',
                    'foo', 'bar', '|', 'xz', '-f', '-a', '-b',
                    '>', 'foo.tar.xz'
                ])
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_gnu_gzip_compressed(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create_gnu_gzip_compressed('source-dir') \
            == 'foo.tar.gz'
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir',
                '--format=gnu', '-cSz', '-f', 'foo.tar.gz', 'foo', 'bar'
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_exclude(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        assert self.archive.create('source-dir', ['foo']) == 'foo.tar'
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*',
                '-c', '-f', 'foo.tar', 'bar'
            ]
        )
Example #14
0
    def create(self, filename, base_image):
        """
        Create compressed oci system container tar archive

        :param string filename: archive file name
        :param string base_image: archive used as a base image
        """
        exclude_list = Defaults.get_exclude_list_for_root_data_sync()
        exclude_list.append('boot')
        exclude_list.append('dev')
        exclude_list.append('sys')
        exclude_list.append('proc')

        self.oci_dir = mkdtemp(prefix='kiwi_oci_dir.')
        self.oci_root_dir = mkdtemp(prefix='kiwi_oci_root_dir.')

        container_dir = os.sep.join(
            [self.oci_dir, 'umoci_layout']
        )
        container_name = ':'.join(
            [container_dir, self.container_tag]
        )

        if base_image:
            Path.create(container_dir)
            image_tar = ArchiveTar(base_image)
            image_tar.extract(container_dir)
            Command.run([
                'umoci', 'config', '--image',
                '{0}:base_layer'.format(container_dir),
                '--tag', self.container_tag
            ])
        else:
            Command.run(
                ['umoci', 'init', '--layout', container_dir]
            )
            Command.run(
                ['umoci', 'new', '--image', container_name]
            )

        Command.run(
            ['umoci', 'unpack', '--image', container_name, self.oci_root_dir]
        )
        oci_root = DataSync(
            ''.join([self.root_dir, os.sep]),
            os.sep.join([self.oci_root_dir, 'rootfs'])
        )
        oci_root.sync_data(
            options=['-a', '-H', '-X', '-A', '--delete'], exclude=exclude_list
        )
        Command.run(
            ['umoci', 'repack', '--image', container_name, self.oci_root_dir]
        )
        for tag in self.additional_tags:
            Command.run(
                ['umoci', 'config', '--image', container_name, '--tag', tag]
            )
        Command.run(
            [
                'umoci', 'config'
            ] +
            self.maintainer +
            self.user +
            self.workingdir +
            self.entry_command +
            self.entry_subcommand +
            self.expose_ports +
            self.volumes +
            self.environment +
            self.labels +
            [
                '--image', container_name,
                '--created', datetime.utcnow().strftime(
                    '%Y-%m-%dT%H:%M:%S+00:00'
                )
            ]
        )
        Command.run(
            ['umoci', 'gc', '--layout', container_dir]
        )

        return self.pack_image_to_file(filename)
Example #15
0
class TestArchiveTar(object):
    def setup(self):
        self.archive = ArchiveTar('foo.tar')

    @patch('kiwi.archive.tar.Command.run')
    def test_extract(self, mock_command):
        self.archive.extract('destination')
        mock_command.assert_called_once_with(
            ['tar', '-C', 'destination', '-x', '-v', '-f', 'foo.tar']
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        self.archive.create('source-dir')
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir',
                '--xattrs', '--xattrs-include=*',
                '-c', '-f', 'foo.tar', 'foo', 'bar'
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    def test_create_from_dir_with_excludes(self, mock_command):
        archive = ArchiveTar('foo.tar', False)
        archive.create('source-dir', ['foo', 'bar'])
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*',
                '-c', '-f', 'foo.tar', '.',
                '--exclude', './foo', '--exclude', './bar'
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_xz_compressed(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        self.archive.create_xz_compressed('source-dir')
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir',
                '--xattrs', '--xattrs-include=*',
                '-c', '-J', '-f', 'foo.tar.xz', 'foo', 'bar'
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_gnu_gzip_compressed(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        self.archive.create_gnu_gzip_compressed('source-dir')
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir',
                '--format=gnu', '-cSz', '-f', 'foo.tar.gz', 'foo', 'bar'
            ]
        )

    @patch('kiwi.archive.tar.Command.run')
    @patch('os.listdir')
    def test_create_exclude(self, mock_os_dir, mock_command):
        mock_os_dir.return_value = ['foo', 'bar']
        self.archive.create('source-dir', ['foo'])
        mock_command.assert_called_once_with(
            [
                'tar', '-C', 'source-dir', '--xattrs', '--xattrs-include=*',
                '-c', '-f', 'foo.tar', 'bar'
            ]
        )