def parse_schemes(self): self.image_scheme = objects.ImageScheme() self.partition_scheme = objects.PartitionScheme() for mount, image in six.iteritems(self.data['image_data']): filename = os.path.basename(urlsplit(image['uri']).path) # Loop does not allocate any loop device # during initialization. device = objects.Loop() self.image_scheme.add_image( uri='file://' + os.path.join(self.data['output'], filename), format=image['format'], container=image['container'], target_device=device) self.partition_scheme.add_fs( device=device, mount=mount, fs_type=image['format']) if mount == '/': metadata_filename = filename.split('.', 1)[0] + '.yaml' self.metadata_uri = 'file://' + os.path.join( self.data['output'], metadata_filename)
def __init__(self, data): super(NailgunBuildImage, self).__init__(data) self._image_scheme = objects.ImageScheme() self._partition_scheme = objects.PartitionScheme() self.parse_schemes() self._operating_system = self.parse_operating_system()
def parse_partition_scheme(self): partition_scheme = objects.PartitionScheme() for obj in ('lv', 'pv', 'fs', 'vg', 'md', 'parted'): attr = '{0}s'.format(obj) parse_method = getattr(self, 'parse_{0}_data'.format(obj)) raw = self.partition_data.get(attr, {}) setattr(partition_scheme, attr, parse_method(raw)) return partition_scheme
def parse_partition_scheme(self): LOG.debug('--- Preparing partition scheme ---') data = self.partition_data() ks_spaces_validator.validate(data) partition_scheme = objects.PartitionScheme() ceph_osds = self._num_ceph_osds() journals_left = ceph_osds ceph_journals = self._num_ceph_journals() LOG.debug('Looping over all disks in provision data') for disk in self.ks_disks: # skipping disk if there are no volumes with size >0 # to be allocated on it which are not boot partitions if all(( v["size"] <= 0 for v in disk["volumes"] if v["type"] != "boot" and v.get("mount") != "/boot" )): continue LOG.debug('Processing disk %s' % disk['name']) LOG.debug('Adding gpt table on disk %s' % disk['name']) parted = partition_scheme.add_parted( name=self._disk_dev(disk), label='gpt') if disk in self.boot_disks: # we install bootloader only on every suitable disk LOG.debug('Adding bootloader stage0 on disk %s' % disk['name']) parted.install_bootloader = True # legacy boot partition LOG.debug('Adding bios_grub partition on disk %s: size=24' % disk['name']) parted.add_partition(size=24, flags=['bios_grub']) # uefi partition (for future use) LOG.debug('Adding UEFI partition on disk %s: size=200' % disk['name']) parted.add_partition(size=200) LOG.debug('Looping over all volumes on disk %s' % disk['name']) for volume in disk['volumes']: LOG.debug('Processing volume: ' 'name=%s type=%s size=%s mount=%s vg=%s' % (volume.get('name'), volume.get('type'), volume.get('size'), volume.get('mount'), volume.get('vg'))) if volume['size'] <= 0: LOG.debug('Volume size is zero. Skipping.') continue if volume.get('name') == 'cephjournal': LOG.debug('Volume seems to be a CEPH journal volume. ' 'Special procedure is supposed to be applied.') # We need to allocate a journal partition for each ceph OSD # Determine the number of journal partitions we need on # each device ratio = int(math.ceil(float(ceph_osds) / ceph_journals)) # No more than 10GB will be allocated to a single journal # partition size = volume["size"] / ratio if size > 10240: size = 10240 # This will attempt to evenly spread partitions across # multiple devices e.g. 5 osds with 2 journal devices will # create 3 partitions on the first device and 2 on the # second if ratio < journals_left: end = ratio else: end = journals_left for i in range(0, end): journals_left -= 1 if volume['type'] == 'partition': LOG.debug('Adding CEPH journal partition on ' 'disk %s: size=%s' % (disk['name'], size)) prt = parted.add_partition(size=size) LOG.debug('Partition name: %s' % prt.name) if 'partition_guid' in volume: LOG.debug('Setting partition GUID: %s' % volume['partition_guid']) prt.set_guid(volume['partition_guid']) continue if volume['type'] in ('partition', 'pv', 'raid'): if volume.get('mount') != '/boot': LOG.debug('Adding partition on disk %s: size=%s' % (disk['name'], volume['size'])) prt = parted.add_partition( size=volume['size'], keep_data=volume.get('keep_data', False)) LOG.debug('Partition name: %s' % prt.name) elif volume.get('mount') == '/boot' \ and not self._boot_partition_done \ and disk in self.boot_disks: LOG.debug('Adding /boot partition on disk %s: ' 'size=%s', disk['name'], volume['size']) prt = parted.add_partition( size=volume['size'], keep_data=volume.get('keep_data', False)) LOG.debug('Partition name: %s', prt.name) self._boot_partition_done = True else: LOG.debug('No need to create partition on disk %s. ' 'Skipping.', disk['name']) continue if volume['type'] == 'partition': if 'partition_guid' in volume: LOG.debug('Setting partition GUID: %s' % volume['partition_guid']) prt.set_guid(volume['partition_guid']) if 'mount' in volume and volume['mount'] != 'none': LOG.debug('Adding file system on partition: ' 'mount=%s type=%s' % (volume['mount'], volume.get('file_system', 'xfs'))) partition_scheme.add_fs( device=prt.name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=volume.get('disk_label')) if volume['mount'] == '/boot' and not self._boot_done: self._boot_done = True if volume['type'] == 'pv': LOG.debug('Creating pv on partition: pv=%s vg=%s' % (prt.name, volume['vg'])) lvm_meta_size = volume.get('lvm_meta_size', 64) # The reason for that is to make sure that # there will be enough space for creating logical volumes. # Default lvm extension size is 4M. Nailgun volume # manager does not care of it and if physical volume size # is 4M * N + 3M and lvm metadata size is 4M * L then only # 4M * (N-L) + 3M of space will be available for # creating logical extensions. So only 4M * (N-L) of space # will be available for logical volumes, while nailgun # volume manager might reguire 4M * (N-L) + 3M # logical volume. Besides, parted aligns partitions # according to its own algorithm and actual partition might # be a bit smaller than integer number of mebibytes. if lvm_meta_size < 10: raise errors.WrongPartitionSchemeError( 'Error while creating physical volume: ' 'lvm metadata size is too small') metadatasize = int(math.floor((lvm_meta_size - 8) / 2)) metadatacopies = 2 partition_scheme.vg_attach_by_name( pvname=prt.name, vgname=volume['vg'], metadatasize=metadatasize, metadatacopies=metadatacopies) if volume['type'] == 'raid': if 'mount' in volume and \ volume['mount'] not in ('none', '/boot'): LOG.debug('Attaching partition to RAID ' 'by its mount point %s' % volume['mount']) metadata = 'default' if self.have_grub1_by_default: metadata = '0.90' LOG.debug('Going to use MD metadata version {0}. ' 'The version was guessed at the data has ' 'been given about the operating system.' .format(metadata)) partition_scheme.md_attach_by_mount( device=prt.name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=volume.get('disk_label'), metadata=metadata) if 'mount' in volume and volume['mount'] == '/boot' and \ not self._boot_done: LOG.debug('Adding file system on partition: ' 'mount=%s type=%s' % (volume['mount'], volume.get('file_system', 'ext2'))) partition_scheme.add_fs( device=prt.name, mount=volume['mount'], fs_type=volume.get('file_system', 'ext2'), fs_label=volume.get('disk_label')) self._boot_done = True # this partition will be used to put there configdrive image if (partition_scheme.configdrive_device() is None and 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) # 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') # 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']) LOG.debug('Looping over all logical volumes in vg %s' % vg['id']) for volume in vg['volumes']: LOG.debug('Processing lv %s' % volume['name']) if volume['size'] <= 0: LOG.debug('LogicalVolume size is zero. Skipping.') continue if volume['type'] == 'lv': LOG.debug('Adding lv to vg %s: name=%s, size=%s' % (vg['id'], volume['name'], volume['size'])) lv = partition_scheme.add_lv(name=volume['name'], vgname=vg['id'], size=volume['size']) if 'mount' in volume and volume['mount'] != 'none': LOG.debug('Adding file system on lv: ' 'mount=%s type=%s' % (volume['mount'], volume.get('file_system', 'xfs'))) partition_scheme.add_fs( device=lv.device_name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=volume.get('disk_label')) partition_scheme.elevate_keep_data() return partition_scheme
def test_do_build_image(self, mock_umount_target, mock_mount_target, mock_yaml_dump, mock_mkdtemp, mock_open, mock_shutil_move, mock_os, mock_utils, mock_fu, mock_bu): loops = [objects.Loop(), objects.Loop()] self.mgr.driver.image_scheme = objects.ImageScheme([ objects.Image('file:///fake/img.img.gz', loops[0], 'ext4', 'gzip'), objects.Image('file:///fake/img-boot.img.gz', loops[1], 'ext2', 'gzip') ]) self.mgr.driver.partition_scheme = objects.PartitionScheme() self.mgr.driver.partition_scheme.add_fs(device=loops[0], mount='/', fs_type='ext4') self.mgr.driver.partition_scheme.add_fs(device=loops[1], mount='/boot', fs_type='ext2') self.mgr.driver.metadata_uri = 'file:///fake/img.yaml' self.mgr.driver.operating_system = objects.Ubuntu( repos=[ objects.DEBRepo('ubuntu', 'http://fakeubuntu', 'trusty', 'fakesection', priority=900), objects.DEBRepo('ubuntu_zero', 'http://fakeubuntu_zero', 'trusty', 'fakesection', priority=None), objects.DEBRepo('mos', 'http://fakemos', 'mosX.Y', 'fakesection', priority=1000) ], packages=['fakepackage1', 'fakepackage2']) mock_os.path.exists.return_value = False mock_os.path.join.return_value = '/tmp/imgdir/proc' mock_os.path.basename.side_effect = ['img.img.gz', 'img-boot.img.gz'] mock_bu.create_sparse_tmp_file.side_effect = \ ['/tmp/img', '/tmp/img-boot'] mock_bu.get_free_loop_device.side_effect = ['/dev/loop0', '/dev/loop1'] mock_mkdtemp.return_value = '/tmp/imgdir' getsize_side = [20, 2, 10, 1] mock_os.path.getsize.side_effect = getsize_side md5_side = [ 'fakemd5_raw', 'fakemd5_gzip', 'fakemd5_raw_boot', 'fakemd5_gzip_boot' ] mock_utils.calculate_md5.side_effect = md5_side mock_bu.containerize.side_effect = ['/tmp/img.gz', '/tmp/img-boot.gz'] mock_bu.stop_chrooted_processes.side_effect = [ False, True, False, True ] self.mgr.do_build_image() self.assertEqual([ mock.call('/fake/img.img.gz'), mock.call('/fake/img-boot.img.gz') ], mock_os.path.exists.call_args_list) self.assertEqual([ mock.call(dir=CONF.image_build_dir, suffix=CONF.image_build_suffix) ] * 2, mock_bu.create_sparse_tmp_file.call_args_list) self.assertEqual([mock.call()] * 2, mock_bu.get_free_loop_device.call_args_list) self.assertEqual([ mock.call('/tmp/img', '/dev/loop0'), mock.call('/tmp/img-boot', '/dev/loop1') ], mock_bu.attach_file_to_loop.call_args_list) self.assertEqual([ mock.call( fs_type='ext4', fs_options='', fs_label='', dev='/dev/loop0'), mock.call( fs_type='ext2', fs_options='', fs_label='', dev='/dev/loop1') ], mock_fu.make_fs.call_args_list) mock_mkdtemp.assert_called_once_with(dir=CONF.image_build_dir, suffix=CONF.image_build_suffix) mock_mount_target.assert_called_once_with('/tmp/imgdir', treat_mtab=False, pseudo=False) self.assertEqual([mock.call('/tmp/imgdir')] * 2, mock_bu.suppress_services_start.call_args_list) mock_bu.run_debootstrap.assert_called_once_with( uri='http://fakeubuntu', suite='trusty', chroot='/tmp/imgdir') mock_bu.set_apt_get_env.assert_called_once_with() mock_bu.pre_apt_get.assert_called_once_with('/tmp/imgdir') self.assertEqual([ mock.call(name='ubuntu', uri='http://fakeubuntu', suite='trusty', section='fakesection', chroot='/tmp/imgdir'), mock.call(name='ubuntu_zero', uri='http://fakeubuntu_zero', suite='trusty', section='fakesection', chroot='/tmp/imgdir'), mock.call(name='mos', uri='http://fakemos', suite='mosX.Y', section='fakesection', chroot='/tmp/imgdir') ], mock_bu.add_apt_source.call_args_list) # we don't call add_apt_preference for ubuntu_zero # because it has priority == None self.assertEqual([ mock.call(name='ubuntu', priority=900, suite='trusty', section='fakesection', chroot='/tmp/imgdir', uri='http://fakeubuntu'), mock.call(name='mos', priority=1000, suite='mosX.Y', section='fakesection', chroot='/tmp/imgdir', uri='http://fakemos') ], mock_bu.add_apt_preference.call_args_list) mock_utils.makedirs_if_not_exists.assert_called_once_with( '/tmp/imgdir/proc') self.assertEqual([ mock.call('tune2fs', '-O', '^has_journal', '/dev/loop0'), mock.call('tune2fs', '-O', 'has_journal', '/dev/loop0') ], mock_utils.execute.call_args_list) mock_fu.mount_bind.assert_called_once_with('/tmp/imgdir', '/proc') mock_bu.run_apt_get.assert_called_once_with( '/tmp/imgdir', packages=['fakepackage1', 'fakepackage2']) mock_bu.do_post_inst.assert_called_once_with('/tmp/imgdir') signal_calls = mock_bu.stop_chrooted_processes.call_args_list self.assertEqual( 2 * [ mock.call('/tmp/imgdir', signal=signal.SIGTERM), mock.call('/tmp/imgdir', signal=signal.SIGKILL) ], signal_calls) self.assertEqual([mock.call('/tmp/imgdir/proc')] * 2, mock_fu.umount_fs.call_args_list) self.assertEqual( [mock.call('/tmp/imgdir', try_lazy_umount=False, pseudo=False)] * 2, mock_umount_target.call_args_list) self.assertEqual([mock.call('/dev/loop0'), mock.call('/dev/loop1')] * 2, mock_bu.deattach_loop.call_args_list) self.assertEqual([mock.call('/tmp/img'), mock.call('/tmp/img-boot')], mock_bu.shrink_sparse_file.call_args_list) self.assertEqual([ mock.call('/tmp/img'), mock.call('/fake/img.img.gz'), mock.call('/tmp/img-boot'), mock.call('/fake/img-boot.img.gz') ], mock_os.path.getsize.call_args_list) self.assertEqual([ mock.call('/tmp/img', 20), mock.call('/fake/img.img.gz', 2), mock.call('/tmp/img-boot', 10), mock.call('/fake/img-boot.img.gz', 1) ], mock_utils.calculate_md5.call_args_list) self.assertEqual([ mock.call('/tmp/img', 'gzip'), mock.call('/tmp/img-boot', 'gzip') ], mock_bu.containerize.call_args_list) mock_open.assert_called_once_with('/fake/img.yaml', 'w') self.assertEqual([ mock.call('/tmp/img.gz', '/fake/img.img.gz'), mock.call('/tmp/img-boot.gz', '/fake/img-boot.img.gz') ], mock_shutil_move.call_args_list) metadata = {} for repo in self.mgr.driver.operating_system.repos: metadata.setdefault('repos', []).append({ 'type': 'deb', 'name': repo.name, 'uri': repo.uri, 'suite': repo.suite, 'section': repo.section, 'priority': repo.priority, 'meta': repo.meta }) metadata['packages'] = self.mgr.driver.operating_system.packages metadata['images'] = [{ 'raw_md5': md5_side[0], 'raw_size': getsize_side[0], 'raw_name': None, 'container_name': os.path.basename(self.mgr.driver.image_scheme.images[0].uri.split( 'file://', 1)[1]), 'container_md5': md5_side[1], 'container_size': getsize_side[1], 'container': self.mgr.driver.image_scheme.images[0].container, 'format': self.mgr.driver.image_scheme.images[0].format }, { 'raw_md5': md5_side[2], 'raw_size': getsize_side[2], 'raw_name': None, 'container_name': os.path.basename(self.mgr.driver.image_scheme.images[1].uri.split( 'file://', 1)[1]), 'container_md5': md5_side[3], 'container_size': getsize_side[3], 'container': self.mgr.driver.image_scheme.images[1].container, 'format': self.mgr.driver.image_scheme.images[1].format }] mock_yaml_dump.assert_called_once_with(metadata, stream=mock_open())
def setUp(self): super(TestPartitionScheme, self).setUp() self.p_scheme = objects.PartitionScheme()
def partition_scheme(self): data = self.partition_data() ks_spaces_validator.validate(data) partition_scheme = objects.PartitionScheme() ceph_osds = self._num_ceph_osds() journals_left = ceph_osds ceph_journals = self._num_ceph_journals() for disk in self.ks_disks: parted = partition_scheme.add_parted( name=self._disk_dev(disk), label='gpt') # we install bootloader on every disk parted.install_bootloader = True # legacy boot partition parted.add_partition(size=24, flags=['bios_grub']) # uefi partition (for future use) parted.add_partition(size=200) for volume in disk['volumes']: if volume['size'] <= 0: continue if volume.get('name') == 'cephjournal': # We need to allocate a journal partition for each ceph OSD # Determine the number of journal partitions we need on # each device ratio = math.ceil(float(ceph_osds) / ceph_journals) # No more than 10GB will be allocated to a single journal # partition size = volume["size"] / ratio if size > 10240: size = 10240 # This will attempt to evenly spread partitions across # multiple devices e.g. 5 osds with 2 journal devices will # create 3 partitions on the first device and 2 on the # second if ratio < journals_left: end = ratio else: end = journals_left for i in range(0, end): journals_left -= 1 if volume['type'] == 'partition': prt = parted.add_partition(size=size) if 'partition_guid' in volume: prt.set_guid(volume['partition_guid']) continue if volume['type'] in ('partition', 'pv', 'raid'): prt = parted.add_partition(size=volume['size']) if volume['type'] == 'partition': if 'partition_guid' in volume: prt.set_guid(volume['partition_guid']) if 'mount' in volume and volume['mount'] != 'none': partition_scheme.add_fs( device=prt.name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=self._getlabel(volume.get('disk_label'))) if volume['type'] == 'pv': partition_scheme.vg_attach_by_name( pvname=prt.name, vgname=volume['vg']) if volume['type'] == 'raid': if 'mount' in volume and volume['mount'] != 'none': partition_scheme.md_attach_by_mount( device=prt.name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=self._getlabel(volume.get('disk_label'))) # this partition will be used to put there configdrive image if partition_scheme.configdrive_device() is None: parted.add_partition(size=20, configdrive=True) for vg in self.ks_vgs: for volume in vg['volumes']: if volume['size'] <= 0: continue if volume['type'] == 'lv': lv = partition_scheme.add_lv(name=volume['name'], vgname=vg['id'], size=volume['size']) if 'mount' in volume and volume['mount'] != 'none': partition_scheme.add_fs( device=lv.device_name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=self._getlabel(volume.get('disk_label'))) partition_scheme.append_kernel_params( self.data['ks_meta']['pm_data']['kernel_params']) return partition_scheme
def partition_scheme(self): LOG.debug('--- Preparing partition scheme ---') data = self.partition_data() ks_spaces_validator.validate(data) partition_scheme = objects.PartitionScheme() ceph_osds = self._num_ceph_osds() journals_left = ceph_osds ceph_journals = self._num_ceph_journals() LOG.debug('Looping over all disks in provision data') for disk in self.ks_disks: LOG.debug('Processing disk %s' % disk['name']) LOG.debug('Adding gpt table on disk %s' % disk['name']) parted = partition_scheme.add_parted(name=self._disk_dev(disk), label='gpt') # we install bootloader on every disk LOG.debug('Adding bootloader stage0 on disk %s' % disk['name']) parted.install_bootloader = True # legacy boot partition LOG.debug('Adding bios_grub partition on disk %s: size=24' % disk['name']) parted.add_partition(size=24, flags=['bios_grub']) # uefi partition (for future use) LOG.debug('Adding UEFI partition on disk %s: size=200' % disk['name']) parted.add_partition(size=200) LOG.debug('Looping over all volumes on disk %s' % disk['name']) for volume in disk['volumes']: LOG.debug('Processing volume: ' 'name=%s type=%s size=%s mount=%s vg=%s' % (volume.get('name'), volume.get('type'), volume.get('size'), volume.get('mount'), volume.get('vg'))) if volume['size'] <= 0: LOG.debug('Volume size is zero. Skipping.') continue if volume.get('name') == 'cephjournal': LOG.debug('Volume seems to be a CEPH journal volume. ' 'Special procedure is supposed to be applied.') # We need to allocate a journal partition for each ceph OSD # Determine the number of journal partitions we need on # each device ratio = math.ceil(float(ceph_osds) / ceph_journals) # No more than 10GB will be allocated to a single journal # partition size = volume["size"] / ratio if size > 10240: size = 10240 # This will attempt to evenly spread partitions across # multiple devices e.g. 5 osds with 2 journal devices will # create 3 partitions on the first device and 2 on the # second if ratio < journals_left: end = ratio else: end = journals_left for i in range(0, end): journals_left -= 1 if volume['type'] == 'partition': LOG.debug('Adding CEPH journal partition on ' 'disk %s: size=%s' % (disk['name'], size)) prt = parted.add_partition(size=size) LOG.debug('Partition name: %s' % prt.name) if 'partition_guid' in volume: LOG.debug('Setting partition GUID: %s' % volume['partition_guid']) prt.set_guid(volume['partition_guid']) continue if volume['type'] in ('partition', 'pv', 'raid'): LOG.debug('Adding partition on disk %s: size=%s' % (disk['name'], volume['size'])) prt = parted.add_partition(size=volume['size']) LOG.debug('Partition name: %s' % prt.name) if volume['type'] == 'partition': if 'partition_guid' in volume: LOG.debug('Setting partition GUID: %s' % volume['partition_guid']) prt.set_guid(volume['partition_guid']) if 'mount' in volume and volume['mount'] != 'none': LOG.debug('Adding file system on partition: ' 'mount=%s type=%s' % (volume['mount'], volume.get('file_system', 'xfs'))) partition_scheme.add_fs( device=prt.name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=self._getlabel(volume.get('disk_label'))) if volume['type'] == 'pv': LOG.debug('Creating pv on partition: pv=%s vg=%s' % (prt.name, volume['vg'])) lvm_meta_size = volume.get('lvm_meta_size', 64) # The reason for that is to make sure that # there will be enough space for creating logical volumes. # Default lvm extension size is 4M. Nailgun volume # manager does not care of it and if physical volume size # is 4M * N + 3M and lvm metadata size is 4M * L then only # 4M * (N-L) + 3M of space will be available for # creating logical extensions. So only 4M * (N-L) of space # will be available for logical volumes, while nailgun # volume manager might reguire 4M * (N-L) + 3M # logical volume. Besides, parted aligns partitions # according to its own algorithm and actual partition might # be a bit smaller than integer number of mebibytes. if lvm_meta_size < 10: raise errors.WrongPartitionSchemeError( 'Error while creating physical volume: ' 'lvm metadata size is too small') metadatasize = int(math.floor((lvm_meta_size - 8) / 2)) metadatacopies = 2 partition_scheme.vg_attach_by_name( pvname=prt.name, vgname=volume['vg'], metadatasize=metadatasize, metadatacopies=metadatacopies) if volume['type'] == 'raid': if 'mount' in volume and volume['mount'] != 'none': LOG.debug('Attaching partition to RAID ' 'by its mount point %s' % volume['mount']) partition_scheme.md_attach_by_mount( device=prt.name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=self._getlabel(volume.get('disk_label'))) # this partition will be used to put there configdrive image if partition_scheme.configdrive_device() is None: LOG.debug('Adding configdrive partition on disk %s: size=20' % disk['name']) parted.add_partition(size=20, configdrive=True) LOG.debug('Looping over all volume groups in provision data') for vg in self.ks_vgs: LOG.debug('Processing vg %s' % vg['id']) LOG.debug('Looping over all logical volumes in vg %s' % vg['id']) for volume in vg['volumes']: LOG.debug('Processing lv %s' % volume['name']) if volume['size'] <= 0: LOG.debug('Lv size is zero. Skipping.') continue if volume['type'] == 'lv': LOG.debug('Adding lv to vg %s: name=%s, size=%s' % (vg['id'], volume['name'], volume['size'])) lv = partition_scheme.add_lv(name=volume['name'], vgname=vg['id'], size=volume['size']) if 'mount' in volume and volume['mount'] != 'none': LOG.debug('Adding file system on lv: ' 'mount=%s type=%s' % (volume['mount'], volume.get('file_system', 'xfs'))) partition_scheme.add_fs( device=lv.device_name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=self._getlabel(volume.get('disk_label'))) LOG.debug('Appending kernel parameters: %s' % self.data['ks_meta']['pm_data']['kernel_params']) partition_scheme.append_kernel_params( self.data['ks_meta']['pm_data']['kernel_params']) return partition_scheme
def partition_scheme(self): data = self.partition_data() ks_spaces_validator.validate(data) partition_scheme = objects.PartitionScheme() for disk in self.ks_disks: parted = partition_scheme.add_parted(name=self._disk_dev(disk), label='gpt') # legacy boot partition parted.add_partition(size=24, flags=['bios_grub']) # uefi partition (for future use) parted.add_partition(size=200) for volume in disk['volumes']: if volume['size'] <= 0: continue if volume['type'] in ('partition', 'pv', 'raid'): prt = parted.add_partition(size=volume['size']) if volume['type'] == 'partition': if 'partition_guid' in volume: prt.set_guid(volume['partition_guid']) if 'mount' in volume and volume['mount'] != 'none': partition_scheme.add_fs( device=prt.name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=self._getlabel(volume.get('disk_label'))) if volume['type'] == 'pv': partition_scheme.vg_attach_by_name(pvname=prt.name, vgname=volume['vg']) if volume['type'] == 'raid': if 'mount' in volume and volume['mount'] != 'none': partition_scheme.md_attach_by_mount( device=prt.name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=self._getlabel(volume.get('disk_label'))) # this partition will be used to put there configdrive image if partition_scheme.configdrive_device() is None: parted.add_partition(size=20, configdrive=True) for vg in self.ks_vgs: for volume in vg['volumes']: if volume['size'] <= 0: continue if volume['type'] == 'lv': lv = partition_scheme.add_lv(name=volume['name'], vgname=vg['id'], size=volume['size']) if 'mount' in volume and volume['mount'] != 'none': partition_scheme.add_fs( device=lv.device_name, mount=volume['mount'], fs_type=volume.get('file_system', 'xfs'), fs_label=self._getlabel(volume.get('disk_label'))) return partition_scheme