Skip to content

Commit 5e67665

Browse files
authored
Merge pull request #2978 from OSInside/fix_bootloader_setup_with_custom_partitions
Fix bootloader setup with custom partitions
2 parents c7c7e9a + 963ecfd commit 5e67665

File tree

11 files changed

+123
-18
lines changed

11 files changed

+123
-18
lines changed

build-tests/x86/tumbleweed/test-image-partitions-and-volumes/appliance.kiwi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<bootsplash-theme>breeze</bootsplash-theme>
1818
<bootloader-theme>openSUSE</bootloader-theme>
1919
<type image="oem" bootpartition="false" filesystem="xfs" kernelcmdline="console=ttyS0" firmware="uefi" format="qcow2">
20-
<size unit="G">5</size>
20+
<size unit="G">10</size>
2121
<oemconfig>
2222
<oem-swap>true</oem-swap>
2323
<oem-swapsize>512</oem-swapsize>
@@ -26,6 +26,7 @@
2626
<bootloader name="grub2" console="serial" timeout="10"/>
2727
<partitions>
2828
<partition name="var" size="1G" mountpoint="/var" filesystem="ext3"/>
29+
<partition name="usr" size="5G" mountpoint="/usr" filesystem="btrfs"/>
2930
</partitions>
3031
<systemdisk>
3132
<volume name="home" freespace="all"/>

kiwi/bootloader/config/base.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def __init__(self, xml_state, root_dir, boot_dir=None, custom_args={}):
5353

5454
self.system_is_mounted = False
5555
self.volumes_mount = []
56+
self.partitions_mount = []
5657
self.root_mount = None
5758
self.boot_mount = None
5859
self.efi_mount = None
@@ -495,8 +496,8 @@ def get_gfxmode(self, target):
495496
return gfxmode
496497

497498
def _mount_system(
498-
self, root_device, boot_device, efi_device=None,
499-
volumes=None, root_volume_name=None
499+
self, device_map, root_device, boot_device, efi_device=None,
500+
volumes=None, root_volume_name=None, partitions=None
500501
):
501502
self.root_mount = MountManager(
502503
device=root_device
@@ -538,6 +539,19 @@ def _mount_system(
538539
options=[volumes[volume_path]['volume_options']]
539540
)
540541

542+
if partitions:
543+
for map_name in sorted(partitions.keys()):
544+
if map_name in device_map:
545+
partition_mount = MountManager(
546+
device=device_map[map_name].get_device(),
547+
mountpoint=os.path.join(
548+
self.root_mount.mountpoint,
549+
partitions[map_name].mountpoint.lstrip(os.sep)
550+
)
551+
)
552+
self.partitions_mount.append(partition_mount)
553+
partition_mount.mount()
554+
541555
if efi_device:
542556
self.efi_mount.mount()
543557

@@ -590,6 +604,8 @@ def _umount_system(self):
590604
self.boot_mount.umount()
591605
for volume_mount in reversed(self.volumes_mount):
592606
volume_mount.umount()
607+
for partition_mount in reversed(self.partitions_mount):
608+
partition_mount.umount()
593609
if self.device_mount:
594610
self.device_mount.umount()
595611
if self.proc_mount:

kiwi/bootloader/config/grub2.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,19 @@ def setup_disk_image_config(
270270
'system_volumes':
271271
volume_manager_instance.get_volumes(),
272272
'system_root_volume':
273-
volume_manager_instance.get_root_volume_name()
273+
volume_manager_instance.get_root_volume_name(),
274+
'system_partitions':
275+
xml_state.get_partitions()
274276
}
275277
"""
276278
self._mount_system(
279+
boot_options.get('device_map'),
277280
boot_options.get('root_device'),
278281
boot_options.get('boot_device'),
279282
boot_options.get('efi_device'),
280283
boot_options.get('system_volumes'),
281-
boot_options.get('system_root_volume')
284+
boot_options.get('system_root_volume'),
285+
boot_options.get('system_partitions')
282286
)
283287
config_file = os.sep.join(
284288
[

kiwi/bootloader/config/systemd_boot.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,13 @@ def setup_loader(self, target: str) -> None:
7575
)
7676
boot_options = self.custom_args['boot_options']
7777
self._mount_system(
78+
boot_options.get('device_map'),
7879
boot_options.get('root_device'),
7980
boot_options.get('boot_device'),
8081
boot_options.get('efi_device'),
81-
boot_options.get('system_volumes')
82+
boot_options.get('system_volumes'),
83+
boot_options.get('system_root_volume'),
84+
boot_options.get('system_partitions')
8285
)
8386
dracut_setup = self.xml_state.get_dracut_config('setup')
8487
self._run_bootctl(self.root_mount.mountpoint)

kiwi/bootloader/config/zipl.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,13 @@ def setup_loader(self, target: str) -> None:
6565
boot_path = self.get_boot_path()
6666
boot_options = self.custom_args['boot_options']
6767
self._mount_system(
68+
boot_options.get('device_map'),
6869
boot_options.get('root_device'),
6970
boot_options.get('boot_device'),
7071
boot_options.get('efi_device'),
7172
boot_options.get('system_volumes'),
72-
boot_options.get('system_root_volume')
73+
boot_options.get('system_root_volume'),
74+
boot_options.get('system_partitions')
7375
)
7476
root_dir = self.root_mount.mountpoint
7577
kernel_info = BootImageBase(

kiwi/bootloader/install/grub2.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,18 @@ def post_init(self, custom_args):
7171
self.root_mount = None
7272
self.sysfs_mount = None
7373
self.volumes = None
74+
self.partitions = None
7475
self.root_volume_name = None
7576
self.target_removable = None
77+
self.device_map = None
7678
if custom_args and 'target_removable' in custom_args:
7779
self.target_removable = custom_args['target_removable']
7880
if custom_args and 'system_volumes' in custom_args:
7981
self.volumes = custom_args['system_volumes']
82+
if custom_args and 'system_partitions' in custom_args:
83+
self.partitions = custom_args['system_partitions']
84+
if custom_args and 'device_map' in custom_args:
85+
self.device_map = custom_args['device_map']
8086
if custom_args and 'system_root_volume' in custom_args:
8187
self.root_volume_name = custom_args['system_root_volume']
8288
if custom_args and 'firmware' in custom_args:
@@ -358,6 +364,18 @@ def _mount_device_and_volumes(self, stack: ExitStack):
358364
volume_mount.mount(
359365
options=[self.volumes[volume_path]['volume_options']]
360366
)
367+
if self.partitions:
368+
for map_name in sorted(self.partitions.keys()):
369+
if map_name in self.device_map:
370+
partition_mount = MountManager(
371+
device=self.device_map[map_name].get_device(),
372+
mountpoint=os.path.join(
373+
self.root_mount.mountpoint,
374+
self.partitions[map_name].mountpoint.lstrip(os.sep)
375+
)
376+
)
377+
stack.push(partition_mount)
378+
partition_mount.mount()
361379
device_mount = MountManager(
362380
device='/dev',
363381
mountpoint=self.root_mount.mountpoint + '/dev'

kiwi/builder/disk.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,7 @@ def _install_bootloader(
19421942
boot_device = device_map['boot']
19431943

19441944
custom_install_arguments = {
1945+
'device_map': device_map,
19451946
'boot_image': boot_image,
19461947
'boot_device': boot_device.get_device(),
19471948
'root_device':
@@ -1976,6 +1977,11 @@ def _install_bootloader(
19761977
}
19771978
)
19781979

1980+
if system and self.custom_partitions:
1981+
custom_install_arguments.update(
1982+
{'system_partitions': self.custom_partitions}
1983+
)
1984+
19791985
# create bootloader config prior bootloader installation
19801986
try:
19811987
bootloader_config.setup_disk_image_config(

test/unit/bootloader/config/base_test.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from kiwi.xml_description import XMLDescription
1212
from kiwi.exceptions import KiwiBootLoaderTargetError
1313
from kiwi.bootloader.config.base import BootLoaderConfigBase
14+
from kiwi.storage.mapped_device import MappedDevice
15+
from kiwi.storage.disk import ptable_entry_type
1416

1517

1618
class BootLoaderConfigTestImpl(BootLoaderConfigBase):
@@ -360,7 +362,7 @@ def mount_managers_effect(**args):
360362

361363
mock_MountManager.side_effect = mount_managers_effect
362364
self.bootloader._mount_system(
363-
'rootdev', 'bootdev'
365+
{}, 'rootdev', 'bootdev'
364366
)
365367
assert mock_MountManager.call_args_list == [
366368
call(device='rootdev'),
@@ -392,10 +394,11 @@ def test_mount_system(
392394
efi_mount = MagicMock()
393395
efi_mount.device = 'efidev'
394396
volume_mount = MagicMock()
397+
partition_mount = MagicMock()
395398

396399
mount_managers = [
397400
proc_mount, sys_mount, dev_mount, tmp_mount, etc_kernel_mount,
398-
volume_mount, efi_mount, boot_mount, root_mount
401+
partition_mount, volume_mount, efi_mount, boot_mount, root_mount
399402
]
400403

401404
def mount_managers_effect(**args):
@@ -406,18 +409,38 @@ def mount_managers_effect(**args):
406409
with BootLoaderConfigTestImpl(self.state, 'root_dir') as bootloader:
407410
bootloader.root_filesystem_is_overlay = True
408411
bootloader._mount_system(
409-
'rootdev', 'bootdev', 'efidev', {
412+
{
413+
'var': MappedDevice('/dev/var-device', Mock())
414+
},
415+
'rootdev',
416+
'bootdev',
417+
'efidev',
418+
{
410419
'boot/grub2': {
411420
'volume_options': 'subvol=@/boot/grub2',
412421
'volume_device': 'device'
413422
}
414-
}, root_volume_name='root'
423+
},
424+
'root',
425+
{
426+
'var': ptable_entry_type(
427+
mbsize=100,
428+
clone=1,
429+
partition_name='p.lxvar',
430+
partition_type='t.linux',
431+
partition_id=None,
432+
mountpoint='/var',
433+
filesystem='ext3',
434+
label='var'
435+
)
436+
}
415437
)
416438
assert mock_MountManager.call_args_list == [
417439
call(device='rootdev'),
418440
call(device='bootdev', mountpoint='root_mount_point/boot'),
419441
call(device='efidev', mountpoint='root_mount_point/boot/efi'),
420442
call(device='device', mountpoint='root_mount_point/boot/grub2'),
443+
call(device='/dev/var-device', mountpoint='root_mount_point/var'),
421444
call(device='/tmp', mountpoint='root_mount_point/tmp'),
422445
call(device='efidev', mountpoint='root_mount_point/etc/kernel'),
423446
call(device='/dev', mountpoint='root_mount_point/dev'),
@@ -429,6 +452,7 @@ def mount_managers_effect(**args):
429452
)
430453
boot_mount.mount.assert_called_once_with()
431454
efi_mount.mount.assert_called_once_with()
455+
partition_mount.mount.assert_called_once_with()
432456
volume_mount.mount.assert_called_once_with(
433457
options=['subvol=@/boot/grub2']
434458
)

test/unit/bootloader/config/grub2_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,7 @@ def open_file(filename, mode=None):
12311231
}
12321232
)
12331233
mock_mount_system.assert_called_once_with(
1234-
'rootdev', 'bootdev', None, None, None
1234+
None, 'rootdev', 'bootdev', None, None, None, None
12351235
)
12361236
os.environ.update({'GRUB_DISABLE_OS_PROBER': 'true'})
12371237
assert mock_Command_run.call_args_list == [

test/unit/bootloader/install/grub2_test.py

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from pytest import raises
66
import unittest.mock as mock
77

8+
from kiwi.storage.mapped_device import MappedDevice
9+
from kiwi.storage.disk import ptable_entry_type
810
from kiwi.bootloader.install.grub2 import BootLoaderInstallGrub2
911
from kiwi.defaults import Defaults
1012

@@ -17,24 +19,43 @@
1719

1820

1921
class TestBootLoaderInstallGrub2:
20-
def setup(self):
22+
@patch('os.path.exists')
23+
def setup(self, mock_os_path_exists):
24+
mock_os_path_exists.return_value = True
2125
Defaults.set_platform_name('x86_64')
2226

2327
self.firmware = mock.Mock()
2428
self.firmware.efi_mode = mock.Mock(
2529
return_value=None
2630
)
27-
31+
self.device_map = {
32+
'var': MappedDevice('/dev/var-device', Mock())
33+
}
2834
self.custom_args = {
35+
'device_map': self.device_map,
2936
'boot_device': '/dev/mapper/loop0p2',
3037
'root_device': '/dev/mapper/loop0p1',
3138
'efi_device': '/dev/mapper/loop0p3',
3239
'prep_device': '/dev/mapper/loop0p2',
3340
'system_root_volume': 'root',
34-
'system_volumes': {'boot/grub2': {
35-
'volume_options': 'subvol=@/boot/grub2',
36-
'volume_device': 'device'
37-
}},
41+
'system_volumes': {
42+
'boot/grub2': {
43+
'volume_options': 'subvol=@/boot/grub2',
44+
'volume_device': 'device'
45+
}
46+
},
47+
'system_partitions': {
48+
'var': ptable_entry_type(
49+
mbsize=100,
50+
clone=1,
51+
partition_name='p.lxvar',
52+
partition_type='t.linux',
53+
partition_id=None,
54+
mountpoint='/var',
55+
filesystem='ext3',
56+
label='var'
57+
)
58+
},
3859
'firmware': self.firmware,
3960
'target_removable': None,
4061
'install_options': [],
@@ -49,6 +70,10 @@ def setup(self):
4970
self.volume_mount.device = self.custom_args['root_device']
5071
self.volume_mount.mountpoint = 'tmp_volume'
5172

73+
self.partition_mount = mock.Mock()
74+
self.partition_mount.device = self.custom_args['root_device']
75+
self.partition_mount.mountpoint = 'tmp_partition'
76+
5277
self.boot_mount = mock.Mock()
5378
self.boot_mount.device = self.custom_args['boot_device']
5479
self.boot_mount.mountpoint = 'tmp_boot'
@@ -74,6 +99,7 @@ def setup(self):
7499
self.sysfs_mount,
75100
self.proc_mount,
76101
self.device_mount,
102+
self.partition_mount,
77103
self.volume_mount,
78104
self.efi_mount,
79105
self.boot_mount,
@@ -357,6 +383,7 @@ def side_effect(device, mountpoint=None):
357383
self.root_mount.mount.assert_called_once_with(
358384
options=['subvol=root']
359385
)
386+
self.partition_mount.mount.assert_called_once_with()
360387
self.volume_mount.mount.assert_called_once_with(
361388
options=['subvol=@/boot/grub2']
362389
)
@@ -421,6 +448,7 @@ def side_effect(device, mountpoint=None):
421448
self.root_mount.mount.assert_called_once_with(
422449
options=['subvol=root']
423450
)
451+
self.partition_mount.mount.assert_called_once_with()
424452
self.volume_mount.mount.assert_called_once_with(
425453
options=['subvol=@/boot/grub2']
426454
)
@@ -446,6 +474,7 @@ def side_effect(device, mountpoint=None):
446474
self.root_mount.mount.assert_called_once_with(
447475
options=['subvol=root']
448476
)
477+
self.partition_mount.mount.assert_called_once_with()
449478
self.volume_mount.mount.assert_called_once_with(
450479
options=['subvol=@/boot/grub2']
451480
)

0 commit comments

Comments
 (0)