def create_vfat_image(output_file, files_info=None, parameters=None, parameters_file='parameters.txt', fs_size_kib=100): """Creates the fat fs image on the desired file. This method copies the given files to a root directory (optional), writes the parameters specified to the parameters file within the root directory (optional), and then creates a vfat image of the root directory. :param output_file: The path to the file where the fat fs image needs to be created. :param files_info: A dict containing absolute path of file to be copied -> relative path within the vfat image. For example, { '/absolute/path/to/file' -> 'relative/path/within/root' ... } :param parameters: A dict containing key-value pairs of parameters. :param parameters_file: The filename for the parameters file. :param fs_size_kib: size of the vfat filesystem in KiB. :raises: ImageCreationFailed, if image creation failed while doing any of filesystem manipulation activities like creating dirs, mounting, creating filesystem, copying files, etc. """ try: utils.dd('/dev/zero', output_file, 'count=1', "bs=%dKiB" % fs_size_kib) except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type='vfat', error=e) with utils.tempdir() as tmpdir: try: # The label helps ramdisks to find the partition containing # the parameters (by using /dev/disk/by-label/ir-vfd-dev). # NOTE: FAT filesystem label can be up to 11 characters long. utils.mkfs('vfat', output_file, label="ir-vfd-dev") utils.mount(output_file, tmpdir, '-o', 'umask=0') except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type='vfat', error=e) try: if files_info: _create_root_fs(tmpdir, files_info) if parameters: parameters_file = os.path.join(tmpdir, parameters_file) params_list = ['%(key)s=%(val)s' % {'key': k, 'val': v} for k, v in parameters.items()] file_contents = '\n'.join(params_list) utils.write_to_file(parameters_file, file_contents) except Exception as e: LOG.exception(_LE("vfat image creation failed. Error: %s"), e) raise exception.ImageCreationFailed(image_type='vfat', error=e) finally: try: utils.umount(tmpdir) except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type='vfat', error=e)
def create_vfat_image(output_file, files_info=None, parameters=None, parameters_file="parameters.txt", fs_size_kib=100): """Creates the fat fs image on the desired file. This method copies the given files to a root directory (optional), writes the parameters specified to the parameters file within the root directory (optional), and then creates a vfat image of the root directory. :param output_file: The path to the file where the fat fs image needs to be created. :param files_info: A dict containing absolute path of file to be copied -> relative path within the vfat image. For example, { '/absolute/path/to/file' -> 'relative/path/within/root' ... } :param parameters: A dict containing key-value pairs of parameters. :param parameters_file: The filename for the parameters file. :param fs_size_kib: size of the vfat filesystem in KiB. :raises: ImageCreationFailed, if image creation failed while doing any of filesystem manipulation activities like creating dirs, mounting, creating filesystem, copying files, etc. """ try: utils.dd("/dev/zero", output_file, "count=1", "bs=%dKiB" % fs_size_kib) except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type="vfat", error=e) with utils.tempdir() as tmpdir: try: utils.mkfs("vfat", output_file) utils.mount(output_file, tmpdir, "-o", "umask=0") except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type="vfat", error=e) try: if files_info: _create_root_fs(tmpdir, files_info) if parameters: parameters_file = os.path.join(tmpdir, parameters_file) params_list = ["%(key)s=%(val)s" % {"key": k, "val": v} for k, v in parameters.items()] file_contents = "\n".join(params_list) utils.write_to_file(parameters_file, file_contents) except Exception as e: LOG.exception(_LE("vfat image creation failed. Error: %s"), e) raise exception.ImageCreationFailed(image_type="vfat", error=e) finally: try: utils.umount(tmpdir) except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type="vfat", error=e)
def test_mkfs_with_label(self): with mock.patch.object(utils, 'execute') as execute_mock: utils.mkfs('ext4', '/my/block/dev', 'ext4-vol') utils.mkfs('msdos', '/my/msdos/block/dev', 'msdos-vol') utils.mkfs('swap', '/my/swap/block/dev', 'swap-vol') expected = [ mock.call('mkfs', '-t', 'ext4', '-F', '-L', 'ext4-vol', '/my/block/dev', run_as_root=True), mock.call('mkfs', '-t', 'msdos', '-n', 'msdos-vol', '/my/msdos/block/dev', run_as_root=True), mock.call('mkswap', '-L', 'swap-vol', '/my/swap/block/dev', run_as_root=True) ] self.assertEqual(expected, execute_mock.call_args_list)
def test_mkfs_with_label(self, execute_mock): utils.mkfs('ext4', '/my/block/dev', 'ext4-vol') utils.mkfs('msdos', '/my/msdos/block/dev', 'msdos-vol') utils.mkfs('swap', '/my/swap/block/dev', 'swap-vol') expected = [ mock.call('mkfs', '-t', 'ext4', '-F', '-L', 'ext4-vol', '/my/block/dev', run_as_root=True, use_standard_locale=True), mock.call('mkfs', '-t', 'msdos', '-n', 'msdos-vol', '/my/msdos/block/dev', run_as_root=True, use_standard_locale=True), mock.call('mkswap', '-L', 'swap-vol', '/my/swap/block/dev', run_as_root=True, use_standard_locale=True) ] self.assertEqual(expected, execute_mock.call_args_list)
def test_mkfs_with_label(self, execute_mock, mock_env): lang_env_variable = {'LC_ALL': 'C'} mock_env.return_value = lang_env_variable utils.mkfs('ext4', '/my/block/dev', 'ext4-vol') utils.mkfs('msdos', '/my/msdos/block/dev', 'msdos-vol') utils.mkfs('swap', '/my/swap/block/dev', 'swap-vol') expected = [ mock.call('mkfs', '-t', 'ext4', '-F', '-L', 'ext4-vol', '/my/block/dev', run_as_root=True, env_variables=lang_env_variable), mock.call('mkfs', '-t', 'msdos', '-n', 'msdos-vol', '/my/msdos/block/dev', run_as_root=True, env_variables=lang_env_variable), mock.call('mkswap', '-L', 'swap-vol', '/my/swap/block/dev', run_as_root=True, env_variables=lang_env_variable) ] self.assertEqual(expected, execute_mock.call_args_list)
def test_mkfs(self): self.mox.StubOutWithMock(utils, 'execute') utils.execute('mkfs', '-t', 'ext4', '-F', '/my/block/dev') utils.execute('mkfs', '-t', 'msdos', '/my/msdos/block/dev') utils.execute('mkswap', '/my/swap/block/dev') self.mox.ReplayAll() utils.mkfs('ext4', '/my/block/dev') utils.mkfs('msdos', '/my/msdos/block/dev') utils.mkfs('swap', '/my/swap/block/dev')
def test_mkfs(self): with mock.patch.object(utils, 'execute') as execute_mock: utils.mkfs('ext4', '/my/block/dev') utils.mkfs('msdos', '/my/msdos/block/dev') utils.mkfs('swap', '/my/swap/block/dev') expected = [mock.call('mkfs', '-t', 'ext4', '-F', '/my/block/dev'), mock.call('mkfs', '-t', 'msdos', '/my/msdos/block/dev'), mock.call('mkswap', '/my/swap/block/dev')] self.assertEqual(execute_mock.call_args_list, expected)
def test_mkfs_with_label(self): with mock.patch.object(utils, 'execute') as execute_mock: utils.mkfs('ext4', '/my/block/dev', 'ext4-vol') utils.mkfs('msdos', '/my/msdos/block/dev', 'msdos-vol') utils.mkfs('swap', '/my/swap/block/dev', 'swap-vol') expected = [mock.call('mkfs', '-t', 'ext4', '-F', '-L', 'ext4-vol', '/my/block/dev', run_as_root=True), mock.call('mkfs', '-t', 'msdos', '-n', 'msdos-vol', '/my/msdos/block/dev', run_as_root=True), mock.call('mkswap', '-L', 'swap-vol', '/my/swap/block/dev', run_as_root=True)] self.assertEqual(expected, execute_mock.call_args_list)
def test_mkfs_with_label(self, execute_mock): utils.mkfs('ext4', '/my/block/dev', 'ext4-vol') utils.mkfs('msdos', '/my/msdos/block/dev', 'msdos-vol') utils.mkfs('swap', '/my/swap/block/dev', 'swap-vol') expected = [mock.call('mkfs', '-t', 'ext4', '-F', '-L', 'ext4-vol', '/my/block/dev', run_as_root=True, use_standard_locale=True), mock.call('mkfs', '-t', 'msdos', '-n', 'msdos-vol', '/my/msdos/block/dev', run_as_root=True, use_standard_locale=True), mock.call('mkswap', '-L', 'swap-vol', '/my/swap/block/dev', run_as_root=True, use_standard_locale=True)] self.assertEqual(expected, execute_mock.call_args_list)
def test_mkfs_with_label(self, execute_mock, mock_env): lang_env_variable = {'LC_ALL': 'C'} mock_env.return_value = lang_env_variable utils.mkfs('ext4', '/my/block/dev', 'ext4-vol') utils.mkfs('msdos', '/my/msdos/block/dev', 'msdos-vol') utils.mkfs('swap', '/my/swap/block/dev', 'swap-vol') expected = [mock.call('mkfs', '-t', 'ext4', '-F', '-L', 'ext4-vol', '/my/block/dev', run_as_root=True, env_variables=lang_env_variable), mock.call('mkfs', '-t', 'msdos', '-n', 'msdos-vol', '/my/msdos/block/dev', run_as_root=True, env_variables=lang_env_variable), mock.call('mkswap', '-L', 'swap-vol', '/my/swap/block/dev', run_as_root=True, env_variables=lang_env_variable)] self.assertEqual(expected, execute_mock.call_args_list)
def mkfs_ephemeral(dev, ephemeral_format, label="ephemeral0"): utils.mkfs(ephemeral_format, dev, label)
def mkswap(dev, label='swap1'): """Execute mkswap on a device.""" utils.mkfs('swap', dev, label)
def mkfs(fs, dev, label=None): """Execute mkfs on a device.""" utils.mkfs(fs, dev, label)
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"): """Create partitions and copy an image to the root partition. :param dev: Path for the device to work on. :param root_mb: Size of the root partition in megabytes. :param swap_mb: Size of the swap partition in megabytes. :param ephemeral_mb: Size of the ephemeral partition in megabytes. If 0, no ephemeral partition will be created. :param ephemeral_format: The type of file system to format the ephemeral partition. :param image_path: Path for the instance's disk image. :param node_uuid: node's uuid. Used for logging. :param preserve_ephemeral: If True, no filesystem is written to the ephemeral block device, preserving whatever content it had (if the partition table has not changed). :param configdrive: Optional. Base64 encoded Gzipped configdrive content or configdrive HTTP URL. :param boot_option: Can be "local" or "netboot". "netboot" by default. :param boot_mode: Can be "bios" or "uefi". "bios" by default. :returns: a dictionary containing the following keys: 'root uuid': UUID of root partition 'efi system partition uuid': UUID of the uefi system partition (if boot mode is uefi). NOTE: If key exists but value is None, it means partition doesn't exist. """ # the only way for preserve_ephemeral to be set to true is if we are # rebuilding an instance with --preserve_ephemeral. commit = not preserve_ephemeral # now if we are committing the changes to disk clean first. if commit: destroy_disk_metadata(dev, node_uuid) try: # If requested, get the configdrive file and determine the size # of the configdrive partition configdrive_mb = 0 configdrive_file = None if configdrive: configdrive_mb, configdrive_file = _get_configdrive(configdrive, node_uuid) part_dict = make_partitions(dev, root_mb, swap_mb, ephemeral_mb, configdrive_mb, node_uuid, commit=commit, boot_option=boot_option, boot_mode=boot_mode) LOG.info(_LI("Successfully completed the disk device" " %(dev)s partitioning for node %(node)s"), {'dev': dev, "node": node_uuid}) ephemeral_part = part_dict.get('ephemeral') swap_part = part_dict.get('swap') configdrive_part = part_dict.get('configdrive') root_part = part_dict.get('root') if not is_block_device(root_part): raise exception.InstanceDeployFailure( _("Root device '%s' not found") % root_part) for part in ('swap', 'ephemeral', 'configdrive', 'efi system partition'): part_device = part_dict.get(part) LOG.debug("Checking for %(part)s device (%(dev)s) on node " "%(node)s.", {'part': part, 'dev': part_device, 'node': node_uuid}) if part_device and not is_block_device(part_device): raise exception.InstanceDeployFailure( _("'%(partition)s' device '%(part_device)s' not found") % {'partition': part, 'part_device': part_device}) # If it's a uefi localboot, then we have created the efi system # partition. Create a fat filesystem on it. if boot_mode == "uefi" and boot_option == "local": efi_system_part = part_dict.get('efi system partition') utils.mkfs('vfat', efi_system_part, 'efi-part') if configdrive_part: # Copy the configdrive content to the configdrive partition dd(configdrive_file, configdrive_part) LOG.info(_LI("Configdrive for node %(node)s successfully copied " "onto partition %(partition)s"), {'node': node_uuid, 'partition': configdrive_part}) finally: # If the configdrive was requested make sure we delete the file # after copying the content to the partition if configdrive_file: utils.unlink_without_raise(configdrive_file) populate_image(image_path, root_part) LOG.info(_LI("Image for %(node)s successfully populated"), {'node': node_uuid}) if swap_part: utils.mkfs('swap', swap_part, 'swap1') LOG.info(_LI("Swap partition %(swap)s successfully formatted " "for node %(node)s"), {'swap': swap_part, 'node': node_uuid}) if ephemeral_part and not preserve_ephemeral: utils.mkfs(ephemeral_format, ephemeral_part, "ephemeral0") LOG.info(_LI("Ephemeral partition %(ephemeral)s successfully " "formatted for node %(node)s"), {'ephemeral': ephemeral_part, 'node': node_uuid}) uuids_to_return = { 'root uuid': root_part, 'efi system partition uuid': part_dict.get('efi system partition') } try: for part, part_dev in six.iteritems(uuids_to_return): if part_dev: uuids_to_return[part] = block_uuid(part_dev) except processutils.ProcessExecutionError: with excutils.save_and_reraise_exception(): LOG.error(_LE("Failed to detect %s"), part) return uuids_to_return
def mkswap(dev, label="swap1"): """Execute mkswap on a device.""" utils.mkfs("swap", dev, label)