Avoid default installation of dracut kiwi modules

With this commit dracut modules won't be installed by default
in the initrd unless they are requested by the commandline calling
dracut or by a dracut configuration file.

Fixes bsc#1142899 bsc#1136444
Fixes #1103
This commit is contained in:
David Cassany 2019-08-23 11:28:36 +02:00
parent a553825023
commit 07ea23a4c4
No known key found for this signature in database
GPG Key ID: D91C0AAD9018D486
14 changed files with 256 additions and 149 deletions

View File

@ -11,6 +11,8 @@ root_uuid=$(
grep root= | cut -f2- -d=
)
[ -z "${root_uuid}" ] && exit 1
{
echo "[Unit]"
echo "Before=initrd-root-fs.target"

View File

@ -1,5 +1,10 @@
#!/bin/bash
# called by dracut
check() {
return 255
}
# called by dracut
depends() {
echo network rootfs-block dm kiwi-lib

View File

@ -1,5 +1,10 @@
#!/bin/bash
# called by dracut
check() {
return 255
}
# called by dracut
depends() {
echo rootfs-block dm

View File

@ -1,5 +1,10 @@
#!/bin/bash
# called by dracut
check() {
return 255
}
# called by dracut
depends() {
echo rootfs-block dm kiwi-lib

View File

@ -92,6 +92,48 @@ class BootImageBase:
"""
pass
def include_module(self, module, install_media=False):
"""
Include module to boot image
For kiwi boot no modules configuration is required. Thus in
such a case this method is a noop.
:param string module: module to include
:param bool install_media: include the module for install initrds
"""
pass
def omit_module(self, module, install_media=False):
"""
Omit module to boot image
For kiwi boot no modules configuration is required. Thus in
such a case this method is a noop.
:param string module: module to omit
:param bool install_media: omit the module for install initrds
"""
pass
def write_system_config_file(
self, config, config_file=None
):
"""
Writes relevant boot image configuration into configuration file
that will be part of the system image.
This is used to configure any further boot image rebuilds after
deployment. For instance, initrds recreated on kernel update.
For kiwi boot no specific configuration is required for initrds
recreation, thus this method is a noop in that case.
:param dict config: dictonary including configuration parameters
:param string config_file: configuration file to write
"""
pass
def dump(self, filename):
"""
Pickle dump this instance to a file. If the object dump

View File

@ -45,6 +45,10 @@ class BootImageDracut(BootImageBase):
self.dracut_options = []
self.included_files = []
self.included_files_install = []
self.modules = []
self.install_modules = []
self.omit_modules = []
self.omit_install_modules = []
def include_file(self, filename, install_media=False):
"""
@ -58,6 +62,58 @@ class BootImageDracut(BootImageBase):
self.included_files_install.append('--install')
self.included_files_install.append(filename)
def include_module(self, module, install_media=False):
"""
Include module to dracut boot image
:param string module: module to include
:param bool install_media: include the module for install initrds
"""
if install_media and module not in self.install_modules:
self.install_modules.append(module)
elif module not in self.modules:
self.modules.append(module)
def omit_module(self, module, install_media=False):
"""
Omit module to dracut boot image
:param string module: module to omit
:param bool install_media: omit the module for install initrds
"""
if install_media and module not in self.omit_install_modules:
self.omit_install_modules.append(module)
elif module not in self.omit_modules:
self.omit_modules.append(module)
def write_system_config_file(self, config, config_file=None):
"""
Writes modules configuration into a dracut configuration file.
:param dict config: a dictionary containing the modules to add and omit
:param string conf_file: configuration file to write
"""
dracut_config = []
if not config_file:
config_file = os.path.normpath(
self.boot_root_directory + Defaults.get_dracut_conf_name()
)
if config.get('modules'):
dracut_config.append(
'add_dracutmodules+=" {0} "\n'.format(
' '.join(config['modules'])
)
)
if config.get('omit_modules'):
dracut_config.append(
'omit_dracutmodules+=" {0} "\n'.format(
' '.join(config['omit_modules'])
)
)
if dracut_config:
with open(config_file, 'w') as config:
config.writelines(dracut_config)
def prepare(self):
"""
Prepare dracut caller environment
@ -95,9 +151,25 @@ class BootImageDracut(BootImageBase):
dracut_initrd_basename = self.initrd_base_name
if install_initrd:
included_files = self.included_files_install
modules_args = [
'--add', ' {0} '.format(' '.join(self.install_modules))
] if self.install_modules else []
omit_modules_args = [
'--omit', ' {0} '.format(
' '.join(self.omit_install_modules)
)
] if self.omit_install_modules else []
else:
included_files = self.included_files
modules_args = [
'--add', ' {0} '.format(' '.join(self.modules))
] if self.modules else []
omit_modules_args = [
'--omit', ' {0} '.format(' '.join(self.omit_modules))
] if self.omit_install_modules else []
dracut_initrd_basename += '.xz'
options = self.dracut_options + modules_args +\
omit_modules_args + included_files
dracut_call = Command.run(
[
'chroot', self.boot_root_directory,
@ -105,7 +177,7 @@ class BootImageDracut(BootImageBase):
'--no-hostonly',
'--no-hostonly-cmdline',
'--xz'
] + self.dracut_options + included_files + [
] + options + [
dracut_initrd_basename,
kernel_details.version
],

View File

@ -373,15 +373,19 @@ class DiskBuilder:
self._write_generic_fstab_to_system_image(device_map)
if self.initrd_system == 'dracut':
self._create_dracut_config()
if self.root_filesystem_is_multipath is False:
self.boot_image.omit_module('multipath')
if self.root_filesystem_is_overlay:
self.boot_image.include_module('kiwi-overlay')
self.boot_image.write_system_config_file(
config={'modules': ['kiwi-overlay']}
)
if self.build_type_name == 'oem':
self.boot_image.include_module('kiwi-repart')
# create initrd cpio archive
self.boot_image.create_initrd(self.mbrid)
# create dracut config omitting one time kiwi dracut modules
if self.initrd_system == 'dracut':
self._create_system_dracut_config()
# create second stage metadata to system image
self._copy_first_boot_files_to_system_image()
@ -769,55 +773,6 @@ class DiskBuilder:
return self.disk.get_device()
def _create_dracut_config(self):
dracut_config = [
'hostonly="no"',
'dracut_rescue_image="no"'
]
dracut_modules = []
dracut_modules_omit = ['kiwi-live', 'kiwi-dump']
if self.root_filesystem_is_multipath is False:
dracut_modules_omit.append('multipath')
if self.root_filesystem_is_overlay:
dracut_modules.append('kiwi-overlay')
else:
dracut_modules_omit.append('kiwi-overlay')
if self.build_type_name == 'oem':
dracut_modules.append('kiwi-lib')
dracut_modules.append('kiwi-repart')
self._write_dracut_config(
config=dracut_config,
modules=dracut_modules,
omit_modules=dracut_modules_omit
)
def _create_system_dracut_config(self):
dracut_modules = []
dracut_modules_omit = ['kiwi-live', 'kiwi-dump', 'kiwi-repart']
if self.root_filesystem_is_overlay:
dracut_modules.append('kiwi-overlay')
else:
dracut_modules_omit.append('kiwi-overlay')
self._write_dracut_config(
config=[], modules=dracut_modules, omit_modules=dracut_modules_omit
)
def _write_dracut_config(self, config, modules, omit_modules):
dracut_config_file = ''.join(
[self.root_dir, Defaults.get_dracut_conf_name()]
)
if modules:
config.append(
'add_dracutmodules+=" {0} "'.format(' '.join(modules))
)
if omit_modules:
config.append(
'omit_dracutmodules+=" {0} "'.format(' '.join(omit_modules))
)
with open(dracut_config_file, 'w') as dracut_config:
for entry in config:
dracut_config.write(entry + os.linesep)
def _write_partition_id_config_to_boot_image(self):
log.info('Creating config.partids in boot system')
filename = ''.join(

View File

@ -358,7 +358,13 @@ class InstallImageBuilder:
self.boot_image_task.boot_root_directory
)
if self.initrd_system == 'dracut':
self._create_dracut_install_config()
self.boot_image_task.include_module(
'kiwi-dump', install_media=True
)
if self.root_filesystem_is_multipath is False:
self.boot_image_task.omit_module(
'multipath', install_media=True
)
self._add_system_image_boot_options_to_boot_image()
self.boot_image_task.create_initrd(
self.mbrid, 'initrd_kiwi_install',
@ -392,7 +398,13 @@ class InstallImageBuilder:
self.boot_image_task.boot_root_directory
)
if self.initrd_system == 'dracut':
self._create_dracut_install_config()
self.boot_image_task.include_module(
'kiwi-dump', install_media=True
)
if self.root_filesystem_is_multipath is False:
self.boot_image_task.omit_module(
'multipath', install_media=True
)
self._add_system_image_boot_options_to_boot_image()
self.boot_image_task.create_initrd(
self.mbrid, 'initrd_kiwi_install',
@ -433,33 +445,8 @@ class InstallImageBuilder:
with open(initrd_trigger, 'w') as vmx_system:
vmx_system.write('IMAGE="%s"\n' % self.squashed_diskname)
def _create_dracut_install_config(self):
dracut_config = [
'hostonly="no"',
'dracut_rescue_image="no"'
]
dracut_modules = ['kiwi-lib', 'kiwi-dump']
dracut_modules_omit = ['kiwi-overlay', 'kiwi-live', 'kiwi-repart']
if self.root_filesystem_is_multipath is False:
dracut_modules_omit.append('multipath')
dracut_config.append(
'add_dracutmodules+=" {0} "'.format(' '.join(dracut_modules))
)
dracut_config.append(
'omit_dracutmodules+=" {0} "'.format(' '.join(dracut_modules_omit))
)
with open(self.dracut_config_file, 'w') as config:
for entry in dracut_config:
config.write(entry + os.linesep)
def _delete_dracut_install_config(self):
if os.path.exists(self.dracut_config_file):
os.remove(self.dracut_config_file)
def __del__(self):
log.info('Cleaning up %s instance', type(self).__name__)
if self.initrd_system == 'dracut':
self._delete_dracut_install_config()
if self.media_dir:
Path.wipe(self.media_dir)
if self.pxe_dir:

View File

@ -182,7 +182,19 @@ class LiveImageBuilder:
# create dracut initrd for live image
log.info('Creating live ISO boot image')
self._create_dracut_live_iso_config()
live_dracut_module = Defaults.get_live_dracut_module_from_flag(
self.live_type
)
self.boot_image.include_module('pollcdrom')
self.boot_image.include_module(live_dracut_module)
self.boot_image.omit_module('multipath')
self.boot_image.write_system_config_file(
config={
'modules': ['pollcdrom', live_dracut_module],
'omit_modules': ['multipath']
},
config_file=self.root_dir + '/etc/dracut.conf.d/02-livecd.conf'
)
self.boot_image.create_initrd(self.mbrid)
# setup kernel file(s) and initrd in ISO boot layout
@ -293,23 +305,6 @@ class LiveImageBuilder:
)
return self.result
def _create_dracut_live_iso_config(self):
live_config_file = self.root_dir + '/etc/dracut.conf.d/02-livecd.conf'
omit_modules = [
'kiwi-dump', 'kiwi-overlay', 'kiwi-repart', 'kiwi-lib', 'multipath'
]
live_config = [
'add_dracutmodules+=" {0} pollcdrom "'.format(
Defaults.get_live_dracut_module_from_flag(self.live_type)
),
'omit_dracutmodules+=" {0} "'.format(' '.join(omit_modules)),
'hostonly="no"',
'dracut_rescue_image="no"'
]
with open(live_config_file, 'w') as config:
for entry in live_config:
config.write(entry + os.linesep)
def _setup_live_iso_kernel_and_initrd(self):
"""
Copy kernel and initrd from the root tree into the iso boot structure

View File

@ -116,3 +116,8 @@ class TestBootImageBase:
@raises(NotImplementedError)
def test_get_boot_names(self):
self.boot_image.get_boot_names()
def test_noop_methods(self):
self.boot_image.include_module('module')
self.boot_image.omit_module('module')
self.boot_image.write_system_config_file({'config_key': 'value'})

View File

@ -57,6 +57,50 @@ class TestBootImageKiwi:
]
assert self.boot_image.included_files_install == []
def test_include_module(self):
self.boot_image.include_module('foobar')
assert self.boot_image.modules == ['foobar']
assert self.boot_image.install_modules == []
self.boot_image.include_module('module', install_media=True)
self.boot_image.include_module('foobar')
assert self.boot_image.modules == ['foobar']
assert self.boot_image.install_modules == ['module']
def test_omit_module(self):
self.boot_image.omit_module('foobar')
assert self.boot_image.omit_modules == ['foobar']
assert self.boot_image.omit_install_modules == []
self.boot_image.omit_module('module', install_media=True)
self.boot_image.omit_module('foobar')
assert self.boot_image.omit_modules == ['foobar']
assert self.boot_image.omit_install_modules == ['module']
def test_write_system_config_file(self):
with patch('builtins.open', create=True) as mock_write:
self.boot_image.write_system_config_file(
config={'modules': ['module'], 'omit_modules': ['foobar']},
config_file='/root/dir/my_dracut_conf.conf'
)
assert call().__enter__().writelines(
[
'add_dracutmodules+=" module "\n',
'omit_dracutmodules+=" foobar "\n'
]
) in mock_write.mock_calls
assert call(
'/root/dir/my_dracut_conf.conf', 'w'
) in mock_write.mock_calls
with patch('builtins.open', create=True) as mock_write:
self.boot_image.write_system_config_file(
config={'modules': ['module'], 'omit_modules': ['foobar']},
)
assert call(
'system-directory/etc/dracut.conf.d/02-kiwi.conf', 'w'
) in mock_write.mock_calls
def test_include_file_install(self):
self.boot_image.include_file('foo', install_media=True)
assert self.boot_image.included_files == [

View File

@ -462,8 +462,6 @@ class TestDiskBuilder:
assert mock_open.call_args_list == [
call('boot_dir/config.partids', 'w'),
call('root_dir/boot/mbrid', 'w'),
call('root_dir/etc/dracut.conf.d/02-kiwi.conf', 'w'),
call('root_dir/etc/dracut.conf.d/02-kiwi.conf', 'w'),
call('boot_dir/config.bootoptions', 'w'),
call('/dev/some-loop', 'wb')
]
@ -471,13 +469,6 @@ class TestDiskBuilder:
call('kiwi_BootPart="1"\n'),
call('kiwi_RootPart="1"\n'),
call('0x0f0f0f0f\n'),
call('hostonly="no"\n'),
call('dracut_rescue_image="no"\n'),
# before dracut is called, image dracut setup
call('add_dracutmodules+=" kiwi-lib kiwi-repart "\n'),
call('omit_dracutmodules+=" kiwi-live kiwi-dump multipath kiwi-overlay "\n'),
# after dracut was called, system dracut setup
call('omit_dracutmodules+=" kiwi-live kiwi-dump kiwi-repart kiwi-overlay "\n'),
call('boot_cmdline\n'),
call(bytes(b'\x0f\x0f\x0f\x0f'))
]
@ -495,6 +486,11 @@ class TestDiskBuilder:
call('/config.partids'),
call('/recovery.partition.size')
]
self.boot_image_task.include_module.assert_called_once_with(
'kiwi-repart'
)
self.boot_image_task.omit_module.assert_called_once_with('multipath')
assert self.boot_image_task.write_system_config_file.call_args_list == []
@patch('kiwi.builder.disk.FileSystem')
@patch('kiwi.builder.disk.FileSystemSquashFs')
@ -543,17 +539,16 @@ class TestDiskBuilder:
call('kiwi_BootPart="1"\n'),
call('kiwi_RootPart="1"\n'),
call('0x0f0f0f0f\n'),
call('hostonly="no"\n'),
call('dracut_rescue_image="no"\n'),
# before dracut is called, image dracut setup
call('add_dracutmodules+=" kiwi-overlay kiwi-lib kiwi-repart "\n'),
call('omit_dracutmodules+=" kiwi-live kiwi-dump multipath "\n'),
# after dracut was called, system dracut setup
call('add_dracutmodules+=" kiwi-overlay "\n'),
call('omit_dracutmodules+=" kiwi-live kiwi-dump kiwi-repart "\n'),
call('boot_cmdline\n'),
call(b'\x0f\x0f\x0f\x0f')
]
assert self.boot_image_task.include_module.call_args_list == [
call('kiwi-overlay'), call('kiwi-repart')
]
self.boot_image_task.omit_module.assert_called_once_with('multipath')
self.boot_image_task.write_system_config_file.assert_called_once_with(
config={'modules': ['kiwi-overlay']}
)
@patch('kiwi.builder.disk.FileSystem')
@patch_open

View File

@ -213,22 +213,21 @@ class TestInstallImageBuilder:
self.install_image.create_install_iso()
self.boot_image_task.include_module.assert_called_once_with(
'kiwi-dump', install_media=True
)
self.boot_image_task.omit_module.assert_called_once_with(
'multipath', install_media=True
)
self.boot_image_task.include_file.assert_called_once_with(
'/config.bootoptions', install_media=True
)
assert mock_open.call_args_list == [
call('temp_media_dir/config.isoclient', 'w'),
call('root_dir/etc/dracut.conf.d/02-kiwi.conf', 'w')
]
assert file_mock.write.call_args_list == [
call('IMAGE="result-image.raw"\n'),
call('hostonly="no"\n'),
call('dracut_rescue_image="no"\n'),
call('add_dracutmodules+=" kiwi-lib kiwi-dump "\n'),
call(
'omit_dracutmodules+=" kiwi-overlay kiwi-live kiwi-repart '
'multipath "\n'
)
call('IMAGE="result-image.raw"\n')
]
mock_BootLoaderConfig.reset_mock()
@ -392,7 +391,6 @@ class TestInstallImageBuilder:
]
assert mock_open.call_args_list == [
call('tmpdir/result-image.append', 'w'),
call('root_dir/etc/dracut.conf.d/02-kiwi.conf', 'w')
]
assert file_mock.write.call_args_list == [
call(
@ -401,26 +399,25 @@ class TestInstallImageBuilder:
'rd.kiwi.install.image=http://example.com/image.xz',
'custom_kernel_options\n'
])
),
call('hostonly="no"\n'),
call('dracut_rescue_image="no"\n'),
call('add_dracutmodules+=" kiwi-lib kiwi-dump "\n'),
call('omit_dracutmodules+=" kiwi-overlay kiwi-live kiwi-repart multipath "\n')
)
]
self.boot_image_task.include_module.assert_called_once_with(
'kiwi-dump', install_media=True
)
self.boot_image_task.omit_module.assert_called_once_with(
'multipath', install_media=True
)
@patch('kiwi.builder.install.Path.wipe')
@patch('os.path.exists')
@patch('os.remove')
def test_destructor(self, mock_remove, mock_exists, mock_wipe):
def test_destructor(self, mock_exists, mock_wipe):
mock_exists.return_value = True
self.install_image.initrd_system = 'dracut'
self.install_image.pxe_dir = 'pxe-dir'
self.install_image.media_dir = 'media-dir'
self.install_image.squashed_contents = 'squashed-dir'
self.install_image.__del__()
mock_remove.assert_called_once_with(
'root_dir/etc/dracut.conf.d/02-kiwi.conf'
)
assert mock_wipe.call_args_list == [
call('media-dir'), call('pxe-dir'), call('squashed-dir')
]

View File

@ -213,19 +213,17 @@ class TestLiveImageBuilder:
working_directory='root_dir'
)
assert call(
'root_dir/etc/dracut.conf.d/02-livecd.conf', 'w'
) in mock_open.call_args_list
assert self.file_mock.write.call_args_list == [
call('add_dracutmodules+=" kiwi-live pollcdrom "\n'),
call(
'omit_dracutmodules+=" '
'kiwi-dump kiwi-overlay kiwi-repart kiwi-lib multipath "\n'
),
call('hostonly="no"\n'),
call('dracut_rescue_image="no"\n')
assert self.boot_image_task.include_module.call_args_list == [
call('pollcdrom'), call('kiwi-live')
]
self.boot_image_task.omit_module.assert_called_once_with('multipath')
self.boot_image_task.write_system_config_file.assert_called_once_with(
config={
'modules': ['pollcdrom', 'kiwi-live'],
'omit_modules': ['multipath']
},
config_file='root_dir/etc/dracut.conf.d/02-livecd.conf'
)
kiwi.builder.live.BootLoaderConfig.assert_called_once_with(
'grub2', self.xml_state, root_dir='root_dir',