Place bootloader onto /boot partition-less disks
Sometimes, there's no separate /boot fs image. Therefore, a bootloader should have been installed onto disk where rootfs image lands. It seems that Nailgun driver didn't support such cases and then an expection regarding missing /boot partition was thrown. That was totally wrong approach. Nailgun driver should work fine without /boot partition if there's no /boot image. In addition, this change removes ugly hacks from Ironic driver. Apparently Ironic driver explicitly sets self._boot_done and self._boot_partition_done flags to True, hence enables to bypass that exception. Since now, Nailgun can handle such a case, so there're no any needs to keep that hack in Ironic driver. Change-Id: I2d97fec7810643865abf0414f2cb80da1c591398 Closes-Bug: #1529066
This commit is contained in:
parent
a05b6e49da
commit
95fe335f24
|
@ -147,6 +147,12 @@ class Nailgun(BaseDataDriver):
|
|||
disk for disk in disks
|
||||
if ('nvme' not in disk['name'] and self._is_boot_disk(disk))
|
||||
]
|
||||
# NOTE(agordeev) sometimes, there's no separate /boot fs image.
|
||||
# Therefore bootloader should be installed into
|
||||
# the disk where rootfs image lands. Ironic's case.
|
||||
if not suitable_disks and not self._have_boot_partition(disks):
|
||||
return [d for d in disks
|
||||
if self._is_root_disk(d) and 'nvme' not in d['name']]
|
||||
# FIXME(agordeev): if we have rootfs on fake raid, then /boot should
|
||||
# land on it too. We can't proceed with grub-install otherwise.
|
||||
md_boot_disks = [
|
||||
|
@ -156,11 +162,19 @@ class Nailgun(BaseDataDriver):
|
|||
else:
|
||||
return suitable_disks
|
||||
|
||||
def _have_boot_partition(self, disks):
|
||||
return any(self._is_boot_disk(d) for d in disks)
|
||||
|
||||
def _is_boot_disk(self, disk):
|
||||
return any(v["type"] in ('partition', 'raid') and
|
||||
v.get("mount") == "/boot"
|
||||
for v in disk["volumes"])
|
||||
|
||||
def _is_root_disk(self, disk):
|
||||
return any(v["type"] in ('partition', 'raid') and
|
||||
v.get("mount") == "/"
|
||||
for v in disk["volumes"])
|
||||
|
||||
def _is_os_volume(self, vol):
|
||||
return vol['size'] > 0 and vol['type'] == 'pv' and vol['vg'] == 'os'
|
||||
|
||||
|
@ -467,8 +481,9 @@ class Nailgun(BaseDataDriver):
|
|||
disk['name'])
|
||||
parted.add_partition(size=20, configdrive=True)
|
||||
|
||||
# checking if /boot is created
|
||||
if not self._boot_partition_done or not self._boot_done:
|
||||
# checking if /boot is expected to be created
|
||||
if self._have_boot_partition(self.ks_disks) and \
|
||||
(not self._boot_partition_done or not self._boot_done):
|
||||
raise errors.WrongPartitionSchemeError(
|
||||
'/boot partition has not been created for some reasons')
|
||||
|
||||
|
@ -648,14 +663,6 @@ class Ironic(Nailgun):
|
|||
def parse_configdrive_scheme(self):
|
||||
pass
|
||||
|
||||
def parse_partition_scheme(self):
|
||||
# FIXME(yuriyz): Using of internal attributes of base class is very
|
||||
# fragile. This code acts only as temporary solution. Ironic should
|
||||
# use own driver, based on simple driver.
|
||||
self._boot_partition_done = True
|
||||
self._boot_done = True
|
||||
return super(Ironic, self).parse_partition_scheme()
|
||||
|
||||
|
||||
class NailgunBuildImage(BaseDataDriver):
|
||||
|
||||
|
|
|
@ -634,6 +634,25 @@ FIRST_DISK_HUGE_KS_SPACES = [
|
|||
}
|
||||
]
|
||||
|
||||
ONLY_ROOTFS_IMAGE_SPACES = [
|
||||
{
|
||||
"name": "sda",
|
||||
"extra": [],
|
||||
"free_space": 11000,
|
||||
"volumes": [
|
||||
{
|
||||
"mount": "/",
|
||||
"type": "partition",
|
||||
"file_system": "ext4",
|
||||
"size": 10000
|
||||
}
|
||||
],
|
||||
"size": 11000,
|
||||
"type": "disk",
|
||||
"id": "sda",
|
||||
}
|
||||
]
|
||||
|
||||
FIRST_DISK_NVME_KS_SPACES = [
|
||||
{
|
||||
"name": "nvme0n1",
|
||||
|
@ -1433,8 +1452,13 @@ class TestNailgunMockedMeta(unittest2.TestCase):
|
|||
data = copy.deepcopy(PROVISION_SAMPLE_DATA)
|
||||
data['ks_meta']['pm_data']['ks_spaces'] = NO_BOOT_KS_SPACES
|
||||
mock_lbd.return_value = LIST_BLOCK_DEVICES_SAMPLE
|
||||
self.assertRaises(errors.WrongPartitionSchemeError,
|
||||
nailgun.Nailgun, data)
|
||||
drv = nailgun.Nailgun(data)
|
||||
self.assertEqual(
|
||||
drv.partition_scheme.fs_by_mount('/').device,
|
||||
'/dev/sda3')
|
||||
# there's no boot partition is scheme.
|
||||
# It is not expected to be created
|
||||
self.assertIsNone(drv.partition_scheme.fs_by_mount('/boot'))
|
||||
|
||||
def test_boot_partition_no_boot_nvme(self, mock_lbd, mock_image_meta):
|
||||
data = copy.deepcopy(PROVISION_SAMPLE_DATA)
|
||||
|
@ -1454,6 +1478,28 @@ class TestNailgunMockedMeta(unittest2.TestCase):
|
|||
drv.partition_scheme.fs_by_mount('/boot').device,
|
||||
'/dev/sda3')
|
||||
|
||||
def test_boot_partition_is_on_rootfs_nailgun(self, mock_lbd,
|
||||
mock_image_meta):
|
||||
data = copy.deepcopy(PROVISION_SAMPLE_DATA)
|
||||
data['ks_meta']['pm_data']['ks_spaces'] = ONLY_ROOTFS_IMAGE_SPACES
|
||||
mock_lbd.return_value = LIST_BLOCK_DEVICES_SAMPLE_NVME
|
||||
drv = nailgun.Nailgun(data)
|
||||
self.assertEqual(
|
||||
drv.partition_scheme.fs_by_mount('/').device,
|
||||
'/dev/sda3')
|
||||
self.assertIsNone(drv.partition_scheme.fs_by_mount('/boot'))
|
||||
|
||||
def test_boot_partition_is_on_rootfs_ironic(self, mock_lbd,
|
||||
mock_image_meta):
|
||||
data = copy.deepcopy(PROVISION_SAMPLE_DATA)
|
||||
data['ks_meta']['pm_data']['ks_spaces'] = ONLY_ROOTFS_IMAGE_SPACES
|
||||
mock_lbd.return_value = LIST_BLOCK_DEVICES_SAMPLE_NVME
|
||||
drv = nailgun.Ironic(data)
|
||||
self.assertEqual(
|
||||
drv.partition_scheme.fs_by_mount('/').device,
|
||||
'/dev/sda3')
|
||||
self.assertIsNone(drv.partition_scheme.fs_by_mount('/boot'))
|
||||
|
||||
def test_md_metadata_centos(self, mock_lbd, mock_image_meta):
|
||||
data = copy.deepcopy(PROVISION_SAMPLE_DATA)
|
||||
data['profile'] = 'base-centos-x86_64'
|
||||
|
|
Loading…
Reference in New Issue