From a07e21c252053482bf79e245abdbec9eec231d97 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 11 Feb 2016 17:35:51 +0300 Subject: [PATCH] Always add configdrive partition to OS disk configdrive partition was put onto the first disk from the list of all available disks. When dealing with large number of nodes, sometimes disk names many vary from one node to another, so it's hard to predict onto which disk configdrive partition will land. Since now, configdive partition is always tied to OS disk. Change-Id: I6550b7c541050083991b4874f7230fc1606487df Related-Bug: #1544818 --- fuel_agent/drivers/nailgun.py | 14 ++++++- fuel_agent/tests/test_nailgun.py | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/fuel_agent/drivers/nailgun.py b/fuel_agent/drivers/nailgun.py index 7b7dc174..1ae99850 100644 --- a/fuel_agent/drivers/nailgun.py +++ b/fuel_agent/drivers/nailgun.py @@ -124,6 +124,10 @@ class Nailgun(BaseDataDriver): def partition_data(self): return self.data['ks_meta']['pm_data']['ks_spaces'] + def _needs_configdrive(self): + return (CONF.prepare_configdrive or + os.path.isfile(CONF.config_drive_path)) + @property def ks_disks(self): return filter( @@ -494,8 +498,8 @@ class Nailgun(BaseDataDriver): # this partition will be used to put there configdrive image if (partition_scheme.configdrive_device() is None and - CONF.prepare_configdrive or - os.path.isfile(CONF.config_drive_path)): + self._needs_configdrive() and + (self._is_root_disk(disk) or self._is_os_disk(disk))): LOG.debug('Adding configdrive partition on disk %s: size=20' % disk['name']) parted.add_partition(size=20, configdrive=True) @@ -506,6 +510,12 @@ class Nailgun(BaseDataDriver): raise errors.WrongPartitionSchemeError( '/boot partition has not been created for some reasons') + # checking if configdrive partition is created + if (not partition_scheme.configdrive_device() and + self._needs_configdrive()): + raise errors.WrongPartitionSchemeError( + 'configdrive partition has not been created for some reasons') + LOG.debug('Looping over all volume groups in provision data') for vg in self.ks_vgs: LOG.debug('Processing vg %s' % vg['id']) diff --git a/fuel_agent/tests/test_nailgun.py b/fuel_agent/tests/test_nailgun.py index 1d53a040..6f90e0e5 100644 --- a/fuel_agent/tests/test_nailgun.py +++ b/fuel_agent/tests/test_nailgun.py @@ -542,6 +542,52 @@ SINGLE_DISK_KS_SPACES = [ } ] +SECOND_DISK_OS_KS_SPACES = [ + { + "name": "sda", + "extra": ["sda"], + "free_space": 1024, + "volumes": [ + { + "type": "boot", + "size": 300 + }, + ], + "type": "disk", + "id": "sda", + "size": 102400 + }, + { + "name": "sdb", + "extra": ["sdb"], + "free_space": 1024, + "volumes": [ + { + "type": "boot", + "size": 300 + }, + { + "mount": "/boot", + "size": 200, + "type": "partition", + "file_system": "ext2", + "name": "Boot" + }, + { + "mount": "/", + "size": 200, + "type": "partition", + "file_system": "ext4", + "name": "Root", + "keep_data": True + }, + ], + "type": "disk", + "id": "sdb", + "size": 102400 + } +] + NO_BOOT_KS_SPACES = [ { "name": "sda", @@ -1431,6 +1477,25 @@ class TestNailgunMockedMeta(unittest2.TestCase): if fs.mount != '/': self.assertFalse(fs.keep_data) + def test_configdrive_partition_on_os_disk(self, mock_lbd, + mock_image_meta): + data = copy.deepcopy(PROVISION_SAMPLE_DATA) + data['ks_meta']['pm_data']['ks_spaces'] = SECOND_DISK_OS_KS_SPACES + mock_lbd.return_value = LIST_BLOCK_DEVICES_SAMPLE + drv = nailgun.Nailgun(data) + root_device = drv.partition_scheme.root_device()[:-1] + self.assertIn(root_device, drv.partition_scheme.configdrive_device()) + self.assertEqual('/dev/sdb', root_device) + + @mock.patch.object(nailgun.Nailgun, '_needs_configdrive', + return_value=False) + def test_configdrive_partition_not_needed(self, mock_cdrive, mock_lbd, + mock_image_meta): + data = copy.deepcopy(PROVISION_SAMPLE_DATA) + mock_lbd.return_value = LIST_BLOCK_DEVICES_SAMPLE + drv = nailgun.Nailgun(data) + self.assertIsNone(drv.partition_scheme.configdrive_device()) + def test_boot_partition_ok_many_normal_disks(self, mock_lbd, mock_image_meta): data = copy.deepcopy(PROVISION_SAMPLE_DATA)