Skip to content

Commit 0dfa695

Browse files
committed
Check NVMe devices: handle NVMe-FC and NVMe-pci
TBD Jira-ref: RHEL-46807
1 parent 1db1e39 commit 0dfa695

File tree

3 files changed

+158
-0
lines changed

3 files changed

+158
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from leapp.actors import Actor
2+
from leapp.libraries.actor import checknvme
3+
from leapp.models import NVMEInfo
4+
from leapp.reporting import Report
5+
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
6+
7+
8+
class CheckLuks(Actor):
9+
"""
10+
Check if NVMe devices are used and possibly register additional actions.
11+
12+
To be able to boot correctly the storage with NVMe devices, the initramfs
13+
needs to contain nvmf dracut module with additional possibly required data.
14+
Register all required actions that should happen to handle correctly systems
15+
with NVMe devices.
16+
17+
Currently covered:
18+
* NVMe (PCIe)
19+
* NVMe-FC
20+
"""
21+
# FIXME(pstodulk): update the description once the actor is fully
22+
# implemented
23+
24+
name = 'check_nvme'
25+
consumes = (NVMEInfo,)
26+
produces = (Report, TargetUserSpaceUpgradeTasks, UpgradeInitramfsTasks)
27+
tags = (ChecksPhaseTag, IPUWorkflowTag)
28+
29+
def process(self):
30+
checknvme.process()
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
from leapp import reporting
2+
from leapp.libraries.stdlib import api
3+
from leapp.models import (
4+
CopyFile,
5+
DracutModule,
6+
NVMEInfo,
7+
TargetUserSpaceUpgradeTasks,
8+
UpgradeInitramfsTasks
9+
)
10+
from leapp.reporting import create_report
11+
12+
FMT_LIST_SEPARATOR = '\n - '
13+
BROKEN_TRANSPORT_TYPES = ['tcp', 'rdma']
14+
SAFE_TRANSPORT_TYPES = ['pcie', 'fc']
15+
RQ_RPMS_CONTAINER = [
16+
'iproute',
17+
'jq',
18+
'nvme-cli',
19+
'sed',
20+
]
21+
RQ_CONFIG_FILES = [
22+
'/etc/nvme/hostid',
23+
'/etc/nvme/hostnqn',
24+
]
25+
"""
26+
These config files seems to be required, but potentially they could be missing
27+
on the source system. Tracking them explicitely.
28+
"""
29+
30+
31+
def _format_list(data, sep=FMT_LIST_SEPARATOR, callback_sort=sorted, limit=0):
32+
# NOTE(pstodulk): Teaser O:-> https://issues.redhat.com/browse/RHEL-126447
33+
if callback_sort is None:
34+
callback_sort = lambda x: x
35+
res = ['{}{}'.format(sep, item) for item in callback_sort(data)]
36+
if limit:
37+
return ''.join(res[:limit])
38+
return ''.join(res)
39+
40+
41+
def _register_upgrade_tasks():
42+
"""
43+
Register tasks that should happen during IPU to handle NVMe devices
44+
successfully.
45+
"""
46+
api.produce(TargetUserSpaceUpgradeTasks(
47+
copy_files=[CopyFile(src='/etc/nvme/')],
48+
install_rpms=RQ_RPMS_CONTAINER)
49+
)
50+
51+
api.produce(UpgradeInitramfsTasks(
52+
# TODO(pstodulk): the module should take all files as it needs them.
53+
# Drop the comment when verified, uncomment the line below otherwise
54+
# include_files=RQ_CONFIG_FILES,
55+
include_dracut_modules=[DracutModule(name='nvmf')])
56+
)
57+
58+
59+
def report_missing_configs(nvmeinfo, nvmeof_devices):
60+
# TODO(pstodulk)
61+
pass
62+
63+
64+
def check_nvme(nvmeinfo):
65+
"""
66+
Check the system can be configured with discovered NVMe configuration.
67+
68+
In case the discovered configuration is considered
69+
70+
Return True if upgrade can continue, False otherwise.
71+
"""
72+
upgrade_can_continue = True
73+
unhandled_devices = []
74+
safe_devices = []
75+
nvmeof_devices = []
76+
for device in nvmeinfo.devices:
77+
if device.transport in BROKEN_TRANSPORT_TYPES:
78+
unhandled_devices.append(device)
79+
elif device.transport in SAFE_TRANSPORT_TYPES:
80+
safe_devices.append(device)
81+
else:
82+
# TODO(pstodulk): hm? loop, apple-..., etc. types
83+
if device.transport != 'pcie':
84+
nvmeof_devices.append(device)
85+
86+
87+
if unhandled_devices:
88+
# TODO(pstodulk): what we will do here? It's not clear whether to stop
89+
# the upgrade or not, as it could be about devices used for a data
90+
# storage - unrelated to the system partitions / filesystems.
91+
# maybe just report potential risk?
92+
93+
if nvmeof_devices and not (nvmeinfo.hostid and nvmeinfo.hostnqn):
94+
# NOTE(pstodulk): hostid and hostnqn are mandatory for NVMe-oF devices.
95+
# That means practically FC, RDMA, TCP. Let's inform user the upgrade
96+
# is blocked and they must cofigure the system properly to be able to
97+
# upgrade
98+
upgrade_can_continue = False
99+
report_missing_configs(nvmeinfo, nvmeof_devices)
100+
101+
return upgrade_can_continue
102+
103+
104+
def process():
105+
nvmeinfo = next(api.consume(NVMEInfo), None)
106+
if not nvmeinfo or not nvmeinfo.devices:
107+
# Nothing to do
108+
return
109+
110+
if check_nvme(nvmeinfo):
111+
_register_upgrade_tasks()
112+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
Unit tests for checknvme actor
3+
4+
Skip isort as it's kind of broken when mixing grid import and one line imports
5+
6+
isort:skip_file
7+
"""
8+
9+
# from leapp.models import (
10+
# )
11+
# from leapp.reporting import Report
12+
# from leapp.utils.report import is_inhibitor
13+
14+
def test_missing():
15+
# FIXME(pstodulk): add the missint tests. Created just an empty boilerplate
16+
pass

0 commit comments

Comments
 (0)