Merge "Add support for choosing the disk label"

This commit is contained in:
Jenkins 2016-03-01 17:28:01 +00:00 committed by Gerrit Code Review
commit 0d662256bd
2 changed files with 68 additions and 19 deletions

View File

@ -122,7 +122,8 @@ def get_disk_identifier(dev):
def make_partitions(dev, root_mb, swap_mb, ephemeral_mb,
configdrive_mb, node_uuid, commit=True,
boot_option="netboot", boot_mode="bios"):
boot_option="netboot", boot_mode="bios",
disk_label=None):
"""Partition the disk device.
Create partitions for root, swap, ephemeral and configdrive on a
@ -140,6 +141,9 @@ def make_partitions(dev, root_mb, swap_mb, ephemeral_mb,
:param boot_option: Can be "local" or "netboot". "netboot" by default.
:param boot_mode: Can be "bios" or "uefi". "bios" by default.
:param node_uuid: Node's uuid. Used for logging.
:param disk_label: The disk label to be used when creating the
partition table. Valid values are: "msdos", "gpt" or None; If None
Ironic will figure it out according to the boot_mode parameter.
:returns: A dictionary containing the partition type as Key and partition
path as Value for the partitions created by this method.
@ -150,16 +154,18 @@ def make_partitions(dev, root_mb, swap_mb, ephemeral_mb,
part_template = dev + '-part%d'
part_dict = {}
if disk_label is None:
disk_label = 'gpt' if boot_mode == 'uefi' else 'msdos'
dp = disk_partitioner.DiskPartitioner(dev, disk_label=disk_label)
# For uefi localboot, switch partition table to gpt and create the efi
# system partition as the first partition.
if boot_mode == "uefi" and boot_option == "local":
dp = disk_partitioner.DiskPartitioner(dev, disk_label="gpt")
part_num = dp.add_partition(CONF.disk_utils.efi_system_partition_size,
fs_type='fat32',
bootable=True)
part_dict['efi system partition'] = part_template % part_num
else:
dp = disk_partitioner.DiskPartitioner(dev)
if ephemeral_mb:
LOG.debug("Add ephemeral partition (%(size)d MB) to device: %(dev)s "
@ -394,7 +400,7 @@ def _get_configdrive(configdrive, node_uuid, tempdir=None):
def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format,
image_path, node_uuid, preserve_ephemeral=False,
configdrive=None, boot_option="netboot", boot_mode="bios",
tempdir=None):
tempdir=None, disk_label=None):
"""Create partitions and copy an image to the root partition.
:param dev: Path for the device to work on.
@ -414,6 +420,9 @@ def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format,
:param boot_option: Can be "local" or "netboot". "netboot" by default.
:param boot_mode: Can be "bios" or "uefi". "bios" by default.
:param tempdir: A temporary directory
:param disk_label: The disk label to be used when creating the
partition table. Valid values are: "msdos", "gpt" or None; If None
Ironic will figure it out according to the boot_mode parameter.
:returns: a dictionary containing the following keys:
'root uuid': UUID of root partition
'efi system partition uuid': UUID of the uefi system partition
@ -441,7 +450,8 @@ def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format,
configdrive_mb, node_uuid,
commit=commit,
boot_option=boot_option,
boot_mode=boot_mode)
boot_mode=boot_mode,
disk_label=disk_label)
LOG.info(_LI("Successfully completed the disk device"
" %(dev)s partitioning for node %(node)s"),
{'dev': dev, "node": node_uuid})

View File

@ -115,7 +115,8 @@ class WorkOnDiskTestCase(test_base.BaseTestCase):
self.configdrive_mb,
self.node_uuid, commit=True,
boot_option="netboot",
boot_mode="bios")
boot_mode="bios",
disk_label=None)
def test_no_swap_partition(self):
self.mock_ibd.side_effect = iter([True, False])
@ -132,7 +133,8 @@ class WorkOnDiskTestCase(test_base.BaseTestCase):
self.configdrive_mb,
self.node_uuid, commit=True,
boot_option="netboot",
boot_mode="bios")
boot_mode="bios",
disk_label=None)
def test_no_ephemeral_partition(self):
ephemeral_part = '/dev/fake-part1'
@ -158,7 +160,8 @@ class WorkOnDiskTestCase(test_base.BaseTestCase):
self.configdrive_mb,
self.node_uuid, commit=True,
boot_option="netboot",
boot_mode="bios")
boot_mode="bios",
disk_label=None)
@mock.patch.object(utils, 'unlink_without_raise')
@mock.patch.object(disk_utils, '_get_configdrive')
@ -190,9 +193,40 @@ class WorkOnDiskTestCase(test_base.BaseTestCase):
configdrive_mb, self.node_uuid,
commit=True,
boot_option="netboot",
boot_mode="bios")
boot_mode="bios",
disk_label=None)
mock_unlink.assert_called_once_with('fake-path')
@mock.patch.object(utils, 'mkfs', lambda *_: None)
@mock.patch.object(disk_utils, 'block_uuid', lambda p: 'uuid')
@mock.patch.object(disk_utils, 'populate_image', lambda *_: None)
def test_gpt_disk_label(self):
ephemeral_part = '/dev/fake-part1'
swap_part = '/dev/fake-part2'
root_part = '/dev/fake-part3'
ephemeral_mb = 256
ephemeral_format = 'exttest'
self.mock_mp.return_value = {'ephemeral': ephemeral_part,
'swap': swap_part,
'root': root_part}
self.mock_ibd.return_value = True
calls = [mock.call(root_part),
mock.call(swap_part),
mock.call(ephemeral_part)]
disk_utils.work_on_disk(self.dev, self.root_mb,
self.swap_mb, ephemeral_mb, ephemeral_format,
self.image_path, self.node_uuid,
disk_label='gpt')
self.assertEqual(self.mock_ibd.call_args_list, calls)
self.mock_mp.assert_called_once_with(self.dev, self.root_mb,
self.swap_mb, ephemeral_mb,
self.configdrive_mb,
self.node_uuid, commit=True,
boot_option="netboot",
boot_mode="bios",
disk_label='gpt')
@mock.patch.object(utils, 'execute')
class MakePartitionsTestCase(test_base.BaseTestCase):
@ -206,26 +240,27 @@ class MakePartitionsTestCase(test_base.BaseTestCase):
self.configdrive_mb = 0
self.node_uuid = "12345678-1234-1234-1234-1234567890abcxyz"
def _get_parted_cmd(self, dev):
def _get_parted_cmd(self, dev, label=None):
if label is None:
label = 'msdos'
return ['parted', '-a', 'optimal', '-s', dev,
'--', 'unit', 'MiB', 'mklabel', 'msdos']
'--', 'unit', 'MiB', 'mklabel', label]
def _get_parted_cmd_uefi(self, dev):
return ['parted', '-a', 'optimal', '-s',
dev, '--', 'unit', 'MiB', 'mklabel', 'gpt']
def _test_make_partitions(self, mock_exc, boot_option):
def _test_make_partitions(self, mock_exc, boot_option, disk_label=None):
mock_exc.return_value = (None, None)
disk_utils.make_partitions(self.dev, self.root_mb, self.swap_mb,
self.ephemeral_mb, self.configdrive_mb,
self.node_uuid, boot_option=boot_option)
self.node_uuid, boot_option=boot_option,
disk_label=disk_label)
expected_mkpart = ['mkpart', 'primary', 'linux-swap', '1', '513',
'mkpart', 'primary', '', '513', '1537']
if boot_option == "local":
expected_mkpart.extend(['set', '2', 'boot', 'on'])
self.dev = 'fake-dev'
parted_cmd = self._get_parted_cmd(self.dev) + expected_mkpart
parted_cmd = (self._get_parted_cmd(self.dev, disk_label) +
expected_mkpart)
parted_call = mock.call(*parted_cmd, use_standard_locale=True,
run_as_root=True, check_exit_code=[0])
fuser_cmd = ['fuser', 'fake-dev']
@ -239,6 +274,10 @@ class MakePartitionsTestCase(test_base.BaseTestCase):
def test_make_partitions_local_boot(self, mock_exc):
self._test_make_partitions(mock_exc, boot_option="local")
def test_make_partitions_disk_label_gpt(self, mock_exc):
self._test_make_partitions(mock_exc, boot_option="netboot",
disk_label="gpt")
def test_make_partitions_with_ephemeral(self, mock_exc):
self.ephemeral_mb = 2048
expected_mkpart = ['mkpart', 'primary', '', '1', '2049',