Skip to content

Commit 660c20e

Browse files
author
mhecko
committed
refactor handling of kernel-related information
Refactor the handling of kernel-related information away from using distributed ad-hoc logic based only on kernel release in IPUConfiguration. Instead, introduce the KernelInfo message providing rich information about the booted kernel. These changes also affect the information about the target kernel which previously only included target kernel's nevra that was misleadingly marked as 'version'. The new target kernel info message also contains paths to frequently used files such as the kernel image path and initramfs location. All old functionality has been kept in place, but deprecated.
1 parent ad09a82 commit 660c20e

File tree

25 files changed

+801
-415
lines changed

25 files changed

+801
-415
lines changed

repos/system_upgrade/common/actors/forcedefaultboottotargetkernelversion/actor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from leapp.actors import Actor
22
from leapp.libraries.actor import forcedefaultboot
3-
from leapp.models import InstalledTargetKernelVersion
3+
from leapp.models import InstalledTargetKernelInfo
44
from leapp.tags import FinalizationPhaseTag, IPUWorkflowTag
55

66

@@ -14,7 +14,7 @@ class ForceDefaultBootToTargetKernelVersion(Actor):
1414
"""
1515

1616
name = 'force_default_boot_to_target_kernel_version'
17-
consumes = (InstalledTargetKernelVersion,)
17+
consumes = (InstalledTargetKernelInfo,)
1818
produces = ()
1919
tags = (FinalizationPhaseTag, IPUWorkflowTag)
2020

repos/system_upgrade/common/actors/forcedefaultboottotargetkernelversion/libraries/forcedefaultboot.py

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,33 @@
1-
import os
2-
from collections import namedtuple
3-
41
from leapp.libraries import stdlib
52
from leapp.libraries.common.config import architecture
63
from leapp.libraries.stdlib import api, config
7-
from leapp.models import InstalledTargetKernelVersion
8-
9-
KernelInfo = namedtuple('KernelInfo', ('kernel_path', 'initrd_path'))
10-
11-
12-
def get_kernel_info(message):
13-
kernel_name = 'vmlinuz-{}'.format(message.version)
14-
initrd_name = 'initramfs-{}.img'.format(message.version)
15-
kernel_path = os.path.join('/boot', kernel_name)
16-
initrd_path = os.path.join('/boot', initrd_name)
17-
18-
target_version_bootable = True
19-
if not os.path.exists(kernel_path):
20-
target_version_bootable = False
21-
api.current_logger().warning('Mandatory kernel %s does not exist', kernel_path)
22-
if not os.path.exists(initrd_path):
23-
target_version_bootable = False
24-
api.current_logger().warning('Mandatory initrd %s does not exist', initrd_path)
25-
26-
if target_version_bootable:
27-
return KernelInfo(kernel_path=kernel_path, initrd_path=initrd_path)
28-
29-
api.current_logger().warning('Skipping check due to missing mandatory files')
30-
return None
4+
from leapp.models import InstalledTargetKernelInfo
315

326

337
def update_default_kernel(kernel_info):
348
try:
35-
stdlib.run(['grubby', '--info', kernel_info.kernel_path])
9+
stdlib.run(['grubby', '--info', kernel_info.kernel_img_path])
3610
except stdlib.CalledProcessError:
3711
api.current_logger().error('Expected kernel %s to be installed at the boot loader but cannot be found.',
38-
kernel_info.kernel_path)
12+
kernel_info.kernel_img_path)
3913
except OSError:
4014
api.current_logger().error('Could not check for kernel existence in boot loader. Is grubby installed?')
4115
else:
4216
try:
43-
stdlib.run(['grubby', '--set-default', kernel_info.kernel_path])
17+
stdlib.run(['grubby', '--set-default', kernel_info.kernel_img_path])
4418
if architecture.matches_architecture(architecture.ARCH_S390X):
4519
# on s390x we need to call zipl explicitly because of issue in grubby,
4620
# otherwise the new boot entry will not be set as default
4721
# See https://bugzilla.redhat.com/show_bug.cgi?id=1764306
4822
stdlib.run(['/usr/sbin/zipl'])
4923
except (OSError, stdlib.CalledProcessError):
50-
api.current_logger().error('Failed to set default kernel to: %s', kernel_info.kernel_path, exc_info=True)
24+
api.current_logger().error('Failed to set default kernel to: %s',
25+
kernel_info.kernel_img_path, exc_info=True)
5126

5227

5328
def process():
54-
if (config.is_debug and not
55-
architecture.matches_architecture(architecture.ARCH_S390X)): # pylint: disable=using-constant-test
29+
is_system_s390x = architecture.matches_architecture(architecture.ARCH_S390X)
30+
if config.is_debug and not is_system_s390x: # pylint: disable=using-constant-test
5631
try:
5732
# the following command prints output of grubenv for debugging purposes and is repeated after setting
5833
# default kernel so we can be sure we have the right saved entry
@@ -65,12 +40,18 @@ def process():
6540
stdlib.run(['grub2-editenv', 'list'])
6641
except stdlib.CalledProcessError:
6742
api.current_logger().error('Failed to execute "grub2-editenv list" command')
68-
message = next(api.consume(InstalledTargetKernelVersion), None)
69-
if not message:
43+
44+
kernel_info = next(api.consume(InstalledTargetKernelInfo), None)
45+
if not kernel_info:
7046
api.current_logger().warning(('Skipped - Forcing checking and setting default boot entry to target kernel'
7147
' version due to missing message'))
7248
return
7349

50+
if not kernel_info.kernel_img_path: # Should be always set
51+
api.current_logger().warning(('Skipping forcing of default boot entry - target kernel info '
52+
'does not contain a kernel image path.'))
53+
return
54+
7455
try:
7556
current_default_kernel = stdlib.run(['grubby', '--default-kernel'])['stdout'].strip()
7657
except (OSError, stdlib.CalledProcessError):
@@ -84,17 +65,12 @@ def process():
8465
api.current_logger().warning('Failed to query grubby for default {}'.format(type_), exc_info=True)
8566
return
8667

87-
kernel_info = get_kernel_info(message)
88-
if not kernel_info:
89-
return
90-
91-
if current_default_kernel != kernel_info.kernel_path:
68+
if current_default_kernel != kernel_info.kernel_img_path:
9269
api.current_logger().warning(('Current default boot entry not target kernel version: Current default: %s.'
9370
'Forcing default kernel to %s'),
94-
current_default_kernel, kernel_info.kernel_path)
71+
current_default_kernel, kernel_info.kernel_img_path)
9572
update_default_kernel(kernel_info)
96-
if (config.is_debug and not
97-
architecture.matches_architecture(architecture.ARCH_S390X)): # pylint: disable=using-constant-test
73+
if config.is_debug and not is_system_s390x: # pylint: disable=using-constant-test
9874
try:
9975
stdlib.run(['grub2-editenv', 'list'])
10076
except stdlib.CalledProcessError:

repos/system_upgrade/common/actors/forcedefaultboottotargetkernelversion/tests/test_forcedefaultboot_forcedefaultboottotargetkernelversion.py

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from leapp.libraries.common.config import architecture
99
from leapp.libraries.common.testutils import CurrentActorMocked, logger_mocked
1010
from leapp.libraries.stdlib import api
11-
from leapp.models import InstalledTargetKernelVersion
11+
from leapp.models import InstalledTargetKernelInfo
1212

1313
Expected = namedtuple(
1414
'Expected', (
@@ -19,15 +19,15 @@
1919

2020
Case = namedtuple(
2121
'Case',
22-
('initrd_exists',
23-
'kernel_exists',
22+
('kernel_exists',
2423
'entry_default',
2524
'entry_exists',
2625
'message_available',
2726
'arch_s390x'
2827
)
2928
)
3029

30+
TARGET_KERNEL_NEVRA = 'kernel-core-1.2.3.4.el8.x86_64'
3131
TARGET_KERNEL_VERSION = '1.2.3.4.el8.x86_64'
3232
TARGET_KERNEL_TITLE = 'Red Hat Enterprise Linux ({}) 8.1 (Ootpa)'.format(TARGET_KERNEL_VERSION)
3333
TARGET_KERNEL_PATH = '/boot/vmlinuz-{}'.format(TARGET_KERNEL_VERSION)
@@ -37,48 +37,27 @@
3737
OLD_KERNEL_TITLE = 'Red Hat Enterprise Linux ({}) 7.6 (Maipo)'.format(OLD_KERNEL_VERSION)
3838
OLD_KERNEL_PATH = '/boot/vmlinuz-{}'.format(OLD_KERNEL_VERSION)
3939

40+
4041
CASES = (
41-
(Case(initrd_exists=True, kernel_exists=True, entry_default=True, entry_exists=True, message_available=True,
42-
arch_s390x=False),
43-
Expected(grubby_setdefault=False, zipl_called=False)),
44-
(Case(initrd_exists=False, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True,
45-
arch_s390x=False),
46-
Expected(grubby_setdefault=False, zipl_called=False)),
47-
(Case(initrd_exists=True, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True,
48-
arch_s390x=False),
42+
(Case(kernel_exists=True, entry_default=True, entry_exists=True, message_available=True, arch_s390x=False),
4943
Expected(grubby_setdefault=False, zipl_called=False)),
50-
(Case(initrd_exists=False, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True,
51-
arch_s390x=False),
44+
(Case(kernel_exists=False, entry_default=False, entry_exists=True, message_available=True, arch_s390x=False),
5245
Expected(grubby_setdefault=False, zipl_called=False)),
53-
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=False,
54-
arch_s390x=False),
46+
(Case(kernel_exists=True, entry_default=False, entry_exists=True, message_available=False, arch_s390x=False),
5547
Expected(grubby_setdefault=False, zipl_called=False)),
56-
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=False, message_available=False,
57-
arch_s390x=False),
48+
(Case(kernel_exists=True, entry_default=False, entry_exists=False, message_available=False, arch_s390x=False),
5849
Expected(grubby_setdefault=False, zipl_called=False)),
59-
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True,
60-
arch_s390x=False),
50+
(Case(kernel_exists=True, entry_default=False, entry_exists=True, message_available=True, arch_s390x=False),
6151
Expected(grubby_setdefault=True, zipl_called=False)),
62-
(Case(initrd_exists=True, kernel_exists=True, entry_default=True, entry_exists=True, message_available=True,
63-
arch_s390x=True),
64-
Expected(grubby_setdefault=False, zipl_called=False)),
65-
(Case(initrd_exists=False, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True,
66-
arch_s390x=True),
67-
Expected(grubby_setdefault=False, zipl_called=False)),
68-
(Case(initrd_exists=True, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True,
69-
arch_s390x=True),
52+
(Case(kernel_exists=True, entry_default=True, entry_exists=True, message_available=True, arch_s390x=True),
7053
Expected(grubby_setdefault=False, zipl_called=False)),
71-
(Case(initrd_exists=False, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True,
72-
arch_s390x=True),
54+
(Case(kernel_exists=False, entry_default=False, entry_exists=True, message_available=True, arch_s390x=True),
7355
Expected(grubby_setdefault=False, zipl_called=False)),
74-
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=False,
75-
arch_s390x=True),
56+
(Case(kernel_exists=True, entry_default=False, entry_exists=True, message_available=False, arch_s390x=True),
7657
Expected(grubby_setdefault=False, zipl_called=False)),
77-
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=False, message_available=False,
78-
arch_s390x=True),
58+
(Case(kernel_exists=True, entry_default=False, entry_exists=False, message_available=False, arch_s390x=True),
7959
Expected(grubby_setdefault=False, zipl_called=False)),
80-
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True,
81-
arch_s390x=True),
60+
(Case(kernel_exists=True, entry_default=False, entry_exists=True, message_available=True, arch_s390x=True),
8261
Expected(grubby_setdefault=True, zipl_called=True))
8362
)
8463

@@ -143,7 +122,12 @@ def grubby_set_default(self, cmd):
143122
def mocked_consume(case):
144123
def impl(*args):
145124
if case.message_available:
146-
return iter((InstalledTargetKernelVersion(version=TARGET_KERNEL_VERSION),))
125+
kernel_img_path = TARGET_KERNEL_PATH if case.kernel_exists else ''
126+
msg = InstalledTargetKernelInfo(pkg_nevra=TARGET_KERNEL_NEVRA,
127+
kernel_img_path=kernel_img_path,
128+
uname_r='',
129+
initramfs_path=TARGET_INITRD_PATH)
130+
return iter((msg,))
147131
return iter(())
148132
return impl
149133

repos/system_upgrade/common/actors/initramfs/targetinitramfsgenerator/actor.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
from leapp.actors import Actor
22
from leapp.libraries.actor import targetinitramfsgenerator
3-
from leapp.models import (
4-
InitrdIncludes, # deprecated
5-
InstalledTargetKernelVersion,
6-
TargetInitramfsTasks
7-
)
3+
from leapp.models import InitrdIncludes # deprecated
4+
from leapp.models import InstalledTargetKernelInfo, TargetInitramfsTasks
85
from leapp.tags import FinalizationPhaseTag, IPUWorkflowTag
96
from leapp.utils.deprecation import suppress_deprecation
107

@@ -16,7 +13,7 @@ class TargetInitramfsGenerator(Actor):
1613
"""
1714

1815
name = 'target_initramfs_generator'
19-
consumes = (InitrdIncludes, InstalledTargetKernelVersion, TargetInitramfsTasks)
16+
consumes = (InitrdIncludes, InstalledTargetKernelInfo, TargetInitramfsTasks)
2017
produces = ()
2118
tags = (FinalizationPhaseTag, IPUWorkflowTag)
2219

repos/system_upgrade/common/actors/initramfs/targetinitramfsgenerator/libraries/targetinitramfsgenerator.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from leapp.exceptions import StopActorExecutionError
66
from leapp.libraries.stdlib import api, CalledProcessError, run
77
from leapp.models import InitrdIncludes # deprecated
8-
from leapp.models import InstalledTargetKernelVersion, TargetInitramfsTasks
8+
from leapp.models import InstalledTargetKernelInfo, TargetInitramfsTasks
99
from leapp.utils.deprecation import suppress_deprecation
1010

1111
DRACUT_DIR = '/usr/lib/dracut/modules.d/'
@@ -105,29 +105,29 @@ def process():
105105
'No additional files or modules required to add into the target initramfs.')
106106
return
107107

108-
target_kernel = next(api.consume(InstalledTargetKernelVersion), None)
109-
if not target_kernel:
108+
target_kernel_info = next(api.consume(InstalledTargetKernelInfo), None)
109+
if not target_kernel_info:
110110
raise StopActorExecutionError(
111111
'Cannot get version of the installed RHEL-8 kernel',
112112
details={'Problem': 'Did not receive a message with installed RHEL-8 kernel version'
113113
' (InstalledTargetKernelVersion)'})
114114

115115
_copy_modules(modules['dracut'], DRACUT_DIR, 'dracut')
116-
_copy_modules(modules['kernel'], _get_target_kernel_modules_dir(target_kernel.version), 'kernel')
116+
_copy_modules(modules['kernel'], _get_target_kernel_modules_dir(target_kernel_info.uname_r), 'kernel')
117117

118118
# Discover any new modules and regenerate modules.dep
119119
should_regenerate = any(module.module_path is not None for module in modules['kernel'])
120120
if should_regenerate:
121121
try:
122-
run(['depmod', target_kernel.version, '-a'])
122+
run(['depmod', target_kernel_info.uname_r, '-a'])
123123
except CalledProcessError as e:
124124
raise StopActorExecutionError('Failed to generate modules.dep and map files.', details={'details': str(e)})
125125

126126
try:
127127
# multiple files|modules need to be quoted, see --install | --add in dracut(8)
128128
dracut_module_names = list({module.name for module in modules['dracut']})
129129
kernel_module_names = list({module.name for module in modules['kernel']})
130-
cmd = ['dracut', '-f', '--kver', target_kernel.version]
130+
cmd = ['dracut', '-f', '--kver', target_kernel_info.uname_r]
131131
if files:
132132
cmd += ['--install', '{}'.format(' '.join(files))]
133133
if modules['dracut']:

repos/system_upgrade/common/actors/initramfs/targetinitramfsgenerator/tests/test_targetinitramfsgenerator.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from leapp.models import ( # isort:skip
1010
InitrdIncludes, # deprecated
11-
DracutModule, KernelModule, InstalledTargetKernelVersion, TargetInitramfsTasks)
11+
DracutModule, KernelModule, InstalledTargetKernelInfo, TargetInitramfsTasks)
1212

1313
FILES = ['/file1', '/file2', '/dir/subdir/subsubdir/file3', '/file4', '/file5']
1414
MODULES = [
@@ -110,12 +110,20 @@ def test_no_kernel_version(monkeypatch, msgs):
110110
assert not run_mocked.called
111111

112112

113+
def mk_kernel_info(kernel_ver):
114+
kernel_info = InstalledTargetKernelInfo(pkg_nevra='nevra',
115+
kernel_img_path='vmlinuz',
116+
uname_r=kernel_ver,
117+
initramfs_path='initramfs')
118+
return kernel_info
119+
120+
113121
@pytest.mark.parametrize('msgs', TEST_CASES)
114122
def test_dracut_fail(monkeypatch, msgs):
115123
run_mocked = RunMocked(raise_err=True)
116124
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs))
117125
monkeypatch.setattr(api, 'current_actor',
118-
CurrentActorMocked(msgs=msgs + [InstalledTargetKernelVersion(version=KERNEL_VERSION)]))
126+
CurrentActorMocked(msgs=msgs + [mk_kernel_info(KERNEL_VERSION)]))
119127
monkeypatch.setattr(targetinitramfsgenerator, 'run', run_mocked)
120128
# FIXME
121129
monkeypatch.setattr(targetinitramfsgenerator, '_copy_modules', lambda *_: None)
@@ -185,7 +193,7 @@ def test_dracut_fail(monkeypatch, msgs):
185193
([gen_TIT([], MODULES, FILES[0:3]), gen_InitrdIncludes(FILES[3:])], FILES, [], MODULES),
186194
])
187195
def test_flawless(monkeypatch, msgs, files, dracut_modules, kernel_modules):
188-
_msgs = msgs + [InstalledTargetKernelVersion(version=KERNEL_VERSION)]
196+
_msgs = msgs + [mk_kernel_info(KERNEL_VERSION)]
189197
run_mocked = RunMocked()
190198
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=_msgs))
191199
monkeypatch.setattr(targetinitramfsgenerator, 'run', run_mocked)

repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def produce_ipu_config(actor):
6868
flavour = os.environ.get('LEAPP_UPGRADE_PATH_FLAVOUR')
6969
target_version = os.environ.get('LEAPP_UPGRADE_PATH_TARGET_RELEASE')
7070
os_release = get_os_release('/etc/os-release')
71+
7172
actor.produce(IPUConfig(
7273
leapp_env_vars=get_env_vars(),
7374
os_release=os_release,

repos/system_upgrade/common/actors/kernel/checkinstalledkernels/actor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from leapp.actors import Actor
22
from leapp.libraries.actor import checkinstalledkernels
3-
from leapp.models import InstalledRedHatSignedRPM
3+
from leapp.models import InstalledRedHatSignedRPM, KernelInfo
44
from leapp.reporting import Report
55
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
66

@@ -30,7 +30,7 @@ class CheckInstalledKernels(Actor):
3030
"""
3131

3232
name = 'check_installed_kernels'
33-
consumes = (InstalledRedHatSignedRPM,)
33+
consumes = (InstalledRedHatSignedRPM, KernelInfo)
3434
produces = (Report,)
3535
tags = (IPUWorkflowTag, ChecksPhaseTag)
3636

0 commit comments

Comments
 (0)