def create_boot_iso(context, output_filename, kernel_uuid, ramdisk_uuid, root_uuid=None, kernel_params=None): """Creates a bootable ISO image for a node. Given the glance UUID of kernel, ramdisk, root partition's UUID and kernel cmdline arguments, this method fetches the kernel, ramdisk from glance, and builds a bootable ISO image that can be used to boot up the baremetal node. :param context: context :param output_filename: the absolute path of the output ISO file :param kernel_uuid: glance uuid of the kernel to use :param ramdisk_uuid: glance uuid of the ramdisk to use :param root_uuid: uuid of the root filesystem (optional) :param kernel_params: a string containing whitespace separated values kernel cmdline arguments of the form K=V or K (optional). :raises: ImageCreationFailed, if creating boot ISO failed. """ with utils.tempdir() as tmpdir: kernel_path = os.path.join(tmpdir, kernel_uuid) ramdisk_path = os.path.join(tmpdir, ramdisk_uuid) fetch(context, kernel_uuid, kernel_path, CONF.force_raw_images) fetch(context, ramdisk_uuid, ramdisk_path, CONF.force_raw_images) params = [] if root_uuid: params.append('root=UUID=%s' % root_uuid) if kernel_params: params.append(kernel_params) create_isolinux_image(output_filename, kernel_path, ramdisk_path, params)
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 test_tempdir(self): dirname = None with utils.tempdir() as tempdir: self.assertTrue(os.path.isdir(tempdir)) dirname = tempdir self.assertFalse(os.path.exists(dirname))
def create_boot_iso(context, output_filename, kernel_uuid, ramdisk_uuid, root_uuid=None, kernel_params=None): """Creates a bootable ISO image for a node. Given the glance UUID of kernel, ramdisk, root partition's UUID and kernel cmdline arguments, this method fetches the kernel, ramdisk from glance, and builds a bootable ISO image that can be used to boot up the baremetal node. :param context: context :param output_filename: the absolute path of the output ISO file :param kernel_uuid: glance uuid of the kernel to use :param ramdisk_uuid: glance uuid of the ramdisk to use :param root_uuid: uuid of the root filesystem (optional) :param kernel_params: a string containing whitespace separated values kernel cmdline arguments of the form K=V or K (optional). :raises: ImageCreationFailed, if creating boot ISO failed. """ with utils.tempdir() as tmpdir: kernel_path = os.path.join(tmpdir, kernel_uuid) ramdisk_path = os.path.join(tmpdir, ramdisk_uuid) fetch(context, kernel_uuid, kernel_path) fetch(context, ramdisk_uuid, ramdisk_path) params = [] if root_uuid: params.append('root=UUID=%s' % root_uuid) if kernel_params: params.append(kernel_params) create_isolinux_image(output_filename, kernel_path, ramdisk_path, params)
def _collect_files(image_path): """Mount image and return a dictionary of paths found there. Mounts given image under a temporary directory, walk its contents and produce a dictionary of absolute->relative paths found on the image. :param image_path: ISO9660 or FAT-formatted image to mount. :raises: ImageCreationFailed, if image inspection failed. :returns: a dict mapping absolute paths to relative to the mount point. """ if not image_path: yield {} return with utils.tempdir() as mount_dir: try: utils.mount(image_path, mount_dir, '-o', 'loop') except processutils.ProcessExecutionError as e: LOG.exception("Mounting filesystem image %(image)s " "failed", {'image': image_path}) raise exception.ImageCreationFailed(image_type='iso', error=e) try: yield _read_dir(mount_dir) except EnvironmentError as e: LOG.exception("Examining image %(images)s failed: ", {'image': image_path}) _umount_without_raise(mount_dir) raise exception.ImageCreationFailed(image_type='iso', error=e) _umount_without_raise(mount_dir)
def create_isolinux_image_for_bios(output_file, kernel, ramdisk, kernel_params=None): """Creates an isolinux image on the specified file. Copies the provided kernel, ramdisk to a directory, generates the isolinux configuration file using the kernel parameters provided, and then generates a bootable ISO image. :param output_file: the path to the file where the iso image needs to be created. :param kernel: the kernel to use. :param ramdisk: the ramdisk to use. :param kernel_params: a list of strings(each element being a string like 'K=V' or 'K' or combination of them like 'K1=V1,K2,...') to be added as the kernel cmdline. :raises: ImageCreationFailed, if image creation failed while copying files or while running command to generate iso. """ ISOLINUX_BIN = "isolinux/isolinux.bin" ISOLINUX_CFG = "isolinux/isolinux.cfg" options = {"kernel": "/vmlinuz", "ramdisk": "/initrd"} with utils.tempdir() as tmpdir: files_info = {kernel: "vmlinuz", ramdisk: "initrd", CONF.isolinux_bin: ISOLINUX_BIN} try: _create_root_fs(tmpdir, files_info) except (OSError, IOError) as e: LOG.exception(_LE("Creating the filesystem root failed.")) raise exception.ImageCreationFailed(image_type="iso", error=e) cfg = _generate_cfg(kernel_params, CONF.isolinux_config_template, options) isolinux_cfg = os.path.join(tmpdir, ISOLINUX_CFG) utils.write_to_file(isolinux_cfg, cfg) try: utils.execute( "mkisofs", "-r", "-V", "VMEDIA_BOOT_ISO", "-cache-inodes", "-J", "-l", "-no-emul-boot", "-boot-load-size", "4", "-boot-info-table", "-b", ISOLINUX_BIN, "-o", output_file, tmpdir, ) except processutils.ProcessExecutionError as e: LOG.exception(_LE("Creating ISO image failed.")) raise exception.ImageCreationFailed(image_type="iso", 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_tempdir_mocked(self, mkdtemp_mock, rmtree_mock): self.config(tempdir='abc') mkdtemp_mock.return_value = 'temp-dir' kwargs = {'dir': 'b'} with utils.tempdir(**kwargs) as tempdir: self.assertEqual('temp-dir', tempdir) tempdir_created = tempdir mkdtemp_mock.assert_called_once_with(**kwargs) rmtree_mock.assert_called_once_with(tempdir_created)
def test_tempdir_mocked(self, mkdtemp_mock, rmtree_mock): self.config(tempdir="abc") mkdtemp_mock.return_value = "temp-dir" kwargs = {"dir": "b"} with utils.tempdir(**kwargs) as tempdir: self.assertEqual("temp-dir", tempdir) tempdir_created = tempdir mkdtemp_mock.assert_called_once_with(**kwargs) rmtree_mock.assert_called_once_with(tempdir_created)
def test_tempdir_mocked_error_on_rmtree(self, mkdtemp_mock, rmtree_mock, log_mock): self.config(tempdir="abc") mkdtemp_mock.return_value = "temp-dir" rmtree_mock.side_effect = OSError with utils.tempdir() as tempdir: self.assertEqual("temp-dir", tempdir) tempdir_created = tempdir rmtree_mock.assert_called_once_with(tempdir_created) self.assertTrue(log_mock.error.called)
def test_tempdir_mocked_error_on_rmtree(self, mkdtemp_mock, rmtree_mock, log_mock): self.config(tempdir='abc') mkdtemp_mock.return_value = 'temp-dir' rmtree_mock.side_effect = OSError with utils.tempdir() as tempdir: self.assertEqual('temp-dir', tempdir) tempdir_created = tempdir rmtree_mock.assert_called_once_with(tempdir_created) self.assertTrue(log_mock.error.called)
def create_isolinux_image_for_bios(output_file, kernel, ramdisk, kernel_params=None): """Creates an isolinux image on the specified file. Copies the provided kernel, ramdisk to a directory, generates the isolinux configuration file using the kernel parameters provided, and then generates a bootable ISO image. :param output_file: the path to the file where the iso image needs to be created. :param kernel: the kernel to use. :param ramdisk: the ramdisk to use. :param kernel_params: a list of strings(each element being a string like 'K=V' or 'K' or combination of them like 'K1=V1,K2,...') to be added as the kernel cmdline. :raises: ImageCreationFailed, if image creation failed while copying files or while running command to generate iso. """ ISOLINUX_BIN = 'isolinux/isolinux.bin' ISOLINUX_CFG = 'isolinux/isolinux.cfg' options = {'kernel': '/vmlinuz', 'ramdisk': '/initrd'} with utils.tempdir() as tmpdir: files_info = { kernel: 'vmlinuz', ramdisk: 'initrd', CONF.isolinux_bin: ISOLINUX_BIN, } try: _create_root_fs(tmpdir, files_info) except (OSError, IOError) as e: LOG.exception(_LE("Creating the filesystem root failed.")) raise exception.ImageCreationFailed(image_type='iso', error=e) cfg = _generate_cfg(kernel_params, CONF.isolinux_config_template, options) isolinux_cfg = os.path.join(tmpdir, ISOLINUX_CFG) utils.write_to_file(isolinux_cfg, cfg) try: utils.execute('mkisofs', '-r', '-V', "VMEDIA_BOOT_ISO", '-cache-inodes', '-J', '-l', '-no-emul-boot', '-boot-load-size', '4', '-boot-info-table', '-b', ISOLINUX_BIN, '-o', output_file, tmpdir) except processutils.ProcessExecutionError as e: LOG.exception(_LE("Creating ISO image failed.")) raise exception.ImageCreationFailed(image_type='iso', error=e)
def create_isolinux_image(output_file, kernel, ramdisk, kernel_params=None): """Creates an isolinux image on the specified file. Copies the provided kernel, ramdisk to a directory, generates the isolinux configuration file using the kernel parameters provided, and then generates a bootable ISO image. :param output_file: the path to the file where the iso image needs to be created. :param kernel: the kernel to use. :param ramdisk: the ramdisk to use. :param kernel_params: a list of strings(each element being a string like 'K=V' or 'K' or combination of them like 'K1=V1,K2,...') to be added as the kernel cmdline. :raises: ImageCreationFailed, if image creation failed while copying files or while running command to generate iso. """ ISOLINUX_BIN = 'isolinux/isolinux.bin' ISOLINUX_CFG = 'isolinux/isolinux.cfg' with utils.tempdir() as tmpdir: files_info = { kernel: 'vmlinuz', ramdisk: 'initrd', CONF.isolinux_bin: ISOLINUX_BIN, } try: _create_root_fs(tmpdir, files_info) except (OSError, IOError) as e: LOG.exception(_LE("Creating the filesystem root failed.")) raise exception.ImageCreationFailed(image_type='iso', error=e) cfg = _generate_isolinux_cfg(kernel_params) isolinux_cfg = os.path.join(tmpdir, ISOLINUX_CFG) utils.write_to_file(isolinux_cfg, cfg) try: utils.execute('mkisofs', '-r', '-V', "BOOT IMAGE", '-cache-inodes', '-J', '-l', '-no-emul-boot', '-boot-load-size', '4', '-boot-info-table', '-b', ISOLINUX_BIN, '-o', output_file, tmpdir) except processutils.ProcessExecutionError as e: LOG.exception(_LE("Creating ISO image failed.")) raise exception.ImageCreationFailed(image_type='iso', error=e)
def create_boot_iso(context, output_filename, kernel_href, ramdisk_href, deploy_iso_href, root_uuid=None, kernel_params=None, boot_mode=None): """Creates a bootable ISO image for a node. Given the hrefs for kernel, ramdisk, root partition's UUID and kernel cmdline arguments, this method fetches the kernel and ramdisk, and builds a bootable ISO image that can be used to boot up the baremetal node. :param context: context :param output_filename: the absolute path of the output ISO file :param kernel_href: URL or glance uuid of the kernel to use :param ramdisk_href: URL or glance uuid of the ramdisk to use :param deploy_iso_href: URL or glance uuid of the deploy iso used :param root_uuid: uuid of the root filesystem (optional) :param kernel_params: a string containing whitespace separated values kernel cmdline arguments of the form K=V or K (optional). :boot_mode: the boot mode in which the deploy is to happen. :raises: ImageCreationFailed, if creating boot ISO failed. """ with utils.tempdir() as tmpdir: kernel_path = os.path.join(tmpdir, kernel_href.split('/')[-1]) ramdisk_path = os.path.join(tmpdir, ramdisk_href.split('/')[-1]) fetch(context, kernel_href, kernel_path) fetch(context, ramdisk_href, ramdisk_path) params = [] if root_uuid: params.append('root=UUID=%s' % root_uuid) if kernel_params: params.append(kernel_params) if boot_mode == 'uefi': deploy_iso = os.path.join(tmpdir, deploy_iso_href.split('/')[-1]) fetch(context, deploy_iso_href, deploy_iso) create_isolinux_image_for_uefi(output_filename, deploy_iso, kernel_path, ramdisk_path, params) else: create_isolinux_image_for_bios(output_filename, kernel_path, ramdisk_path, params)
def create_isolinux_image_for_bios(output_file, kernel, ramdisk, kernel_params=None): """Creates an isolinux image on the specified file. Copies the provided kernel, ramdisk to a directory, generates the isolinux configuration file using the kernel parameters provided, and then generates a bootable ISO image. :param output_file: the path to the file where the iso image needs to be created. :param kernel: the kernel to use. :param ramdisk: the ramdisk to use. :param kernel_params: a list of strings(each element being a string like 'K=V' or 'K' or combination of them like 'K1=V1,K2,...') to be added as the kernel cmdline. :raises: ImageCreationFailed, if image creation failed while copying files or while running command to generate iso. """ ISOLINUX_BIN = 'isolinux/isolinux.bin' ISOLINUX_CFG = 'isolinux/isolinux.cfg' LDLINUX_SRC_DIRS = ['/usr/lib/syslinux/modules/bios', '/usr/share/syslinux'] LDLINUX_BIN = 'isolinux/ldlinux.c32' options = {'kernel': '/vmlinuz', 'ramdisk': '/initrd'} with utils.tempdir() as tmpdir: files_info = { kernel: 'vmlinuz', ramdisk: 'initrd', CONF.isolinux_bin: ISOLINUX_BIN, } # ldlinux.c32 is required for syslinux 5.0 or later. if CONF.ldlinux_c32: ldlinux_src = CONF.ldlinux_c32 else: for directory in LDLINUX_SRC_DIRS: ldlinux_src = os.path.join(directory, 'ldlinux.c32') if os.path.isfile(ldlinux_src): break else: ldlinux_src = None if ldlinux_src: files_info[ldlinux_src] = LDLINUX_BIN try: _create_root_fs(tmpdir, files_info) except (OSError, IOError) as e: LOG.exception("Creating the filesystem root failed.") raise exception.ImageCreationFailed(image_type='iso', error=e) cfg = _generate_cfg(kernel_params, CONF.isolinux_config_template, options) isolinux_cfg = os.path.join(tmpdir, ISOLINUX_CFG) utils.write_to_file(isolinux_cfg, cfg) try: utils.execute('mkisofs', '-r', '-V', "VMEDIA_BOOT_ISO", '-cache-inodes', '-J', '-l', '-no-emul-boot', '-boot-load-size', '4', '-boot-info-table', '-b', ISOLINUX_BIN, '-o', output_file, tmpdir) except processutils.ProcessExecutionError as e: LOG.exception("Creating ISO image failed.") raise exception.ImageCreationFailed(image_type='iso', error=e)
def create_isolinux_image_for_bios(output_file, kernel, ramdisk, kernel_params=None, inject_files=None): """Creates an isolinux image on the specified file. Copies the provided kernel, ramdisk to a directory, generates the isolinux configuration file using the kernel parameters provided, and then generates a bootable ISO image. :param output_file: the path to the file where the iso image needs to be created. :param kernel: the kernel to use. :param ramdisk: the ramdisk to use. :param kernel_params: a list of strings(each element being a string like 'K=V' or 'K' or combination of them like 'K1=V1,K2,...') to be added as the kernel cmdline. :param inject_files: Mapping of local source file paths to their location on the final ISO image. :raises: ImageCreationFailed, if image creation failed while copying files or while running command to generate iso. """ ISOLINUX_BIN = 'isolinux/isolinux.bin' ISOLINUX_CFG = 'isolinux/isolinux.cfg' LDLINUX_SRC_DIRS = [ '/usr/lib/syslinux/modules/bios', '/usr/share/syslinux' ] LDLINUX_BIN = 'isolinux/ldlinux.c32' options = {'kernel': '/vmlinuz', 'ramdisk': '/initrd'} with utils.tempdir() as tmpdir: files_info = { kernel: 'vmlinuz', ramdisk: 'initrd', CONF.isolinux_bin: ISOLINUX_BIN, } if inject_files: files_info.update(inject_files) # ldlinux.c32 is required for syslinux 5.0 or later. if CONF.ldlinux_c32: ldlinux_src = CONF.ldlinux_c32 else: for directory in LDLINUX_SRC_DIRS: ldlinux_src = os.path.join(directory, 'ldlinux.c32') if os.path.isfile(ldlinux_src): break else: ldlinux_src = None if ldlinux_src: files_info[ldlinux_src] = LDLINUX_BIN try: _create_root_fs(tmpdir, files_info) except EnvironmentError as e: LOG.exception("Creating the filesystem root failed.") raise exception.ImageCreationFailed(image_type='iso', error=e) cfg = _generate_cfg(kernel_params, CONF.isolinux_config_template, options) isolinux_cfg = os.path.join(tmpdir, ISOLINUX_CFG) utils.write_to_file(isolinux_cfg, cfg) try: utils.execute('mkisofs', '-r', '-V', _label(files_info), '-cache-inodes', '-J', '-l', '-no-emul-boot', '-boot-load-size', '4', '-boot-info-table', '-b', ISOLINUX_BIN, '-o', output_file, tmpdir) except processutils.ProcessExecutionError as e: LOG.exception("Creating ISO image failed.") raise exception.ImageCreationFailed(image_type='iso', error=e)
def create_boot_iso(context, output_filename, kernel_href, ramdisk_href, deploy_iso_href=None, esp_image_href=None, root_uuid=None, kernel_params=None, boot_mode=None): """Creates a bootable ISO image for a node. Given the hrefs for kernel, ramdisk, root partition's UUID and kernel cmdline arguments, this method fetches the kernel and ramdisk, and builds a bootable ISO image that can be used to boot up the baremetal node. :param context: context :param output_filename: the absolute path of the output ISO file :param kernel_href: URL or glance uuid of the kernel to use :param ramdisk_href: URL or glance uuid of the ramdisk to use :param deploy_iso_href: URL or glance UUID of the deploy ISO image to extract EFI system partition image. If not specified, the `esp_image_href` option must be present if UEFI-bootable ISO is desired. :param esp_image_href: URL or glance UUID of FAT12/16/32-formatted EFI system partition image containing the EFI boot loader (e.g. GRUB2) for each hardware architecture to boot. This image will be embedded into the ISO image. If not specified, the `deploy_iso_href` option is only required for building UEFI-bootable ISO. :param kernel_params: a string containing whitespace separated values kernel cmdline arguments of the form K=V or K (optional). :boot_mode: the boot mode in which the deploy is to happen. :raises: ImageCreationFailed, if creating boot ISO failed. """ with utils.tempdir() as tmpdir: kernel_path = os.path.join(tmpdir, kernel_href.split('/')[-1]) ramdisk_path = os.path.join(tmpdir, ramdisk_href.split('/')[-1]) fetch(context, kernel_href, kernel_path) fetch(context, ramdisk_href, ramdisk_path) params = [] if root_uuid: params.append('root=UUID=%s' % root_uuid) if kernel_params: params.append(kernel_params) if boot_mode == 'uefi': deploy_iso_path = esp_image_path = None if deploy_iso_href: deploy_iso_path = os.path.join( tmpdir, deploy_iso_href.split('/')[-1]) fetch(context, deploy_iso_href, deploy_iso_path) elif esp_image_href: esp_image_path = os.path.join( tmpdir, esp_image_href.split('/')[-1]) fetch(context, esp_image_href, esp_image_path) elif CONF.esp_image: esp_image_path = CONF.esp_image create_isolinux_image_for_uefi(output_filename, kernel_path, ramdisk_path, deploy_iso=deploy_iso_path, esp_image=esp_image_path, kernel_params=params) else: create_isolinux_image_for_bios(output_filename, kernel_path, ramdisk_path, params)
def create_isolinux_image_for_uefi(output_file, deploy_iso, kernel, ramdisk, kernel_params=None): """Creates an isolinux image on the specified file. Copies the provided kernel, ramdisk, efiboot.img to a directory, creates the path for grub config file, generates the isolinux configuration file using the kernel parameters provided, generates the grub configuration file using kernel parameters and then generates a bootable ISO image for uefi. :param output_file: the path to the file where the iso image needs to be created. :param deploy_iso: deploy iso used to initiate the deploy. :param kernel: the kernel to use. :param ramdisk: the ramdisk to use. :param kernel_params: a list of strings(each element being a string like 'K=V' or 'K' or combination of them like 'K1=V1,K2,...') to be added as the kernel cmdline. :raises: ImageCreationFailed, if image creation failed while copying files or while running command to generate iso. """ ISOLINUX_BIN = 'isolinux/isolinux.bin' ISOLINUX_CFG = 'isolinux/isolinux.cfg' isolinux_options = {'kernel': '/vmlinuz', 'ramdisk': '/initrd'} grub_options = {'linux': '/vmlinuz', 'initrd': '/initrd'} with utils.tempdir() as tmpdir: files_info = { kernel: 'vmlinuz', ramdisk: 'initrd', CONF.isolinux_bin: ISOLINUX_BIN, } # Open the deploy iso used to initiate deploy and copy the # efiboot.img i.e. boot loader to the current temporary # directory. with utils.tempdir() as mountdir: uefi_path_info, e_img_rel_path, grub_rel_path = ( _mount_deploy_iso(deploy_iso, mountdir)) # if either of these variables are not initialized then the # uefi efiboot.img cannot be created. files_info.update(uefi_path_info) try: _create_root_fs(tmpdir, files_info) except (OSError, IOError) as e: LOG.exception(_LE("Creating the filesystem root failed.")) raise exception.ImageCreationFailed(image_type='iso', error=e) finally: _umount_without_raise(mountdir) cfg = _generate_cfg(kernel_params, CONF.isolinux_config_template, isolinux_options) isolinux_cfg = os.path.join(tmpdir, ISOLINUX_CFG) utils.write_to_file(isolinux_cfg, cfg) # Generate and copy grub config file. grub_cfg = os.path.join(tmpdir, grub_rel_path) grub_conf = _generate_cfg(kernel_params, CONF.grub_config_template, grub_options) utils.write_to_file(grub_cfg, grub_conf) # Create the boot_iso. try: utils.execute('mkisofs', '-r', '-V', "VMEDIA_BOOT_ISO", '-cache-inodes', '-J', '-l', '-no-emul-boot', '-boot-load-size', '4', '-boot-info-table', '-b', ISOLINUX_BIN, '-eltorito-alt-boot', '-e', e_img_rel_path, '-no-emul-boot', '-o', output_file, tmpdir) except processutils.ProcessExecutionError as e: LOG.exception(_LE("Creating ISO image failed.")) raise exception.ImageCreationFailed(image_type='iso', error=e)
def create_boot_iso(context, output_filename, kernel_href, ramdisk_href, deploy_iso_href=None, esp_image_href=None, root_uuid=None, kernel_params=None, boot_mode=None, base_iso=None, inject_files=None): """Creates a bootable ISO image for a node. Given the hrefs for kernel, ramdisk, root partition's UUID and kernel cmdline arguments, this method fetches the kernel and ramdisk, and builds a bootable ISO image that can be used to boot up the baremetal node. :param context: context :param output_filename: the absolute path of the output ISO file :param kernel_href: URL or glance uuid of the kernel to use :param ramdisk_href: URL or glance uuid of the ramdisk to use :param deploy_iso_href: URL or glance UUID of the deploy ISO image to extract EFI system partition image. If not specified, the `esp_image_href` option must be present if UEFI-bootable ISO is desired. :param esp_image_href: URL or glance UUID of FAT12/16/32-formatted EFI system partition image containing the EFI boot loader (e.g. GRUB2) for each hardware architecture to boot. This image will be written onto the ISO image. If not specified, the `deploy_iso_href` option is only required for building UEFI-bootable ISO. :param kernel_params: a string containing whitespace separated values kernel cmdline arguments of the form K=V or K (optional). :boot_mode: the boot mode in which the deploy is to happen. :param base_iso: URL or glance UUID of a to be used as an override of what should be retrieved for to use, instead of building an ISO bootable ramdisk. :param inject_files: Mapping of local source file paths to their location on the final ISO image. :raises: ImageCreationFailed, if creating boot ISO failed. """ with utils.tempdir() as tmpdir: if base_iso: # NOTE(TheJulia): Eventually we want to use the creation method # to perform the massaging of the image, because oddly enough # we need to do all the same basic things, just a little # differently. fetch(context, base_iso, output_filename) # Temporary, return to the caller until we support the combined # operation. return else: kernel_path = os.path.join(tmpdir, kernel_href.split('/')[-1]) ramdisk_path = os.path.join(tmpdir, ramdisk_href.split('/')[-1]) fetch(context, kernel_href, kernel_path) fetch(context, ramdisk_href, ramdisk_path) params = [] if root_uuid: params.append('root=UUID=%s' % root_uuid) if kernel_params: params.append(kernel_params) if boot_mode == 'uefi': deploy_iso_path = esp_image_path = None if deploy_iso_href: deploy_iso_path = os.path.join(tmpdir, deploy_iso_href.split('/')[-1]) fetch(context, deploy_iso_href, deploy_iso_path) elif esp_image_href: esp_image_path = os.path.join(tmpdir, esp_image_href.split('/')[-1]) fetch(context, esp_image_href, esp_image_path) elif CONF.esp_image: esp_image_path = CONF.esp_image # TODO(TheJulia): we should opportunisticly try to make bios # bootable and UEFI. In other words, collapse a lot of this # path since they are not mutually exclusive. # UEFI boot mode, but Network iPXE -> ISO means bios bootable # contents are still required. create_esp_image_for_uefi(output_filename, kernel_path, ramdisk_path, deploy_iso=deploy_iso_path, esp_image=esp_image_path, kernel_params=params, inject_files=inject_files) else: create_isolinux_image_for_bios(output_filename, kernel_path, ramdisk_path, kernel_params=params, inject_files=inject_files)
def create_isolinux_image_for_uefi(output_file, kernel, ramdisk, deploy_iso=None, esp_image=None, kernel_params=None): """Creates an isolinux image on the specified file. Copies the provided kernel, ramdisk and EFI system partition image to a directory, generates the grub configuration file using kernel parameters and then generates a bootable ISO image for UEFI. :param output_file: the path to the file where the iso image needs to be created. :param kernel: the kernel to use. :param ramdisk: the ramdisk to use. :param deploy_iso: deploy ISO image to extract EFI system partition image from. If not specified, the `esp_image` option is required. :param esp_image: FAT12/16/32-formatted EFI system partition image containing the EFI boot loader (e.g. GRUB2) for each hardware architecture to boot. This image will be embedded into the ISO image. If not specified, the `deploy_iso` option is required. :param kernel_params: a list of strings(each element being a string like 'K=V' or 'K' or combination of them like 'K1=V1,K2,...') to be added as the kernel cmdline. :raises: ImageCreationFailed, if image creation failed while copying files or while running command to generate iso. """ EFIBOOT_LOCATION = 'boot/grub/efiboot.img' grub_options = {'linux': '/vmlinuz', 'initrd': '/initrd'} with utils.tempdir() as tmpdir: files_info = { kernel: 'vmlinuz', ramdisk: 'initrd', } with utils.tempdir() as mountdir: # Open the deploy iso used to initiate deploy and copy the # efiboot.img i.e. boot loader to the current temporary # directory. if deploy_iso and not esp_image: uefi_path_info, e_img_rel_path, grub_rel_path = ( _mount_deploy_iso(deploy_iso, mountdir)) grub_cfg = os.path.join(tmpdir, grub_rel_path) # Use ELF boot loader provided elif esp_image and not deploy_iso: e_img_rel_path = EFIBOOT_LOCATION grub_rel_path = CONF.grub_config_path.lstrip(' ' + os.sep) grub_cfg = os.path.join(tmpdir, grub_rel_path) uefi_path_info = { esp_image: e_img_rel_path, grub_cfg: grub_rel_path } else: msg = _('Neither deploy ISO nor ESP image configured or ' 'both of them configured') raise exception.ImageCreationFailed(image_type='iso', error=msg) files_info.update(uefi_path_info) try: _create_root_fs(tmpdir, files_info) except (OSError, IOError) as e: LOG.exception("Creating the filesystem root failed.") raise exception.ImageCreationFailed(image_type='iso', error=e) finally: if deploy_iso: _umount_without_raise(mountdir) # Generate and copy grub config file. grub_conf = _generate_cfg(kernel_params, CONF.grub_config_template, grub_options) utils.write_to_file(grub_cfg, grub_conf) # Create the boot_iso. try: utils.execute('mkisofs', '-r', '-V', "VMEDIA_BOOT_ISO", '-l', '-e', e_img_rel_path, '-no-emul-boot', '-o', output_file, tmpdir) except processutils.ProcessExecutionError as e: LOG.exception("Creating ISO image failed.") raise exception.ImageCreationFailed(image_type='iso', error=e)
def create_isolinux_image_for_uefi(output_file, kernel, ramdisk, deploy_iso=None, esp_image=None, kernel_params=None): """Creates an isolinux image on the specified file. Copies the provided kernel, ramdisk and EFI system partition image to a directory, generates the grub configuration file using kernel parameters and then generates a bootable ISO image for UEFI. :param output_file: the path to the file where the iso image needs to be created. :param kernel: the kernel to use. :param ramdisk: the ramdisk to use. :param deploy_iso: deploy ISO image to extract EFI system partition image from. If not specified, the `esp_image` option is required. :param esp_image: FAT12/16/32-formatted EFI system partition image containing the EFI boot loader (e.g. GRUB2) for each hardware architecture to boot. This image will be embedded into the ISO image. If not specified, the `deploy_iso` option is required. :param kernel_params: a list of strings(each element being a string like 'K=V' or 'K' or combination of them like 'K1=V1,K2,...') to be added as the kernel cmdline. :raises: ImageCreationFailed, if image creation failed while copying files or while running command to generate iso. """ EFIBOOT_LOCATION = 'boot/grub/efiboot.img' grub_options = {'linux': '/vmlinuz', 'initrd': '/initrd'} with utils.tempdir() as tmpdir: files_info = { kernel: 'vmlinuz', ramdisk: 'initrd', } with utils.tempdir() as mountdir: # Open the deploy iso used to initiate deploy and copy the # efiboot.img i.e. boot loader to the current temporary # directory. if deploy_iso and not esp_image: uefi_path_info, e_img_rel_path, grub_rel_path = ( _mount_deploy_iso(deploy_iso, mountdir)) grub_cfg = os.path.join(tmpdir, grub_rel_path) # Use ELF boot loader provided elif esp_image and not deploy_iso: e_img_rel_path = EFIBOOT_LOCATION grub_rel_path = CONF.grub_config_path.lstrip(' ' + os.sep) grub_cfg = os.path.join(tmpdir, grub_rel_path) uefi_path_info = { esp_image: e_img_rel_path } else: msg = _('Neither deploy ISO nor ESP image configured or ' 'both of them configured') raise exception.ImageCreationFailed( image_type='iso', error=msg) files_info.update(uefi_path_info) try: _create_root_fs(tmpdir, files_info) except (OSError, IOError) as e: LOG.exception("Creating the filesystem root failed.") raise exception.ImageCreationFailed(image_type='iso', error=e) finally: if deploy_iso: _umount_without_raise(mountdir) # Generate and copy grub config file. grub_conf = _generate_cfg(kernel_params, CONF.grub_config_template, grub_options) utils.write_to_file(grub_cfg, grub_conf) # Create the boot_iso. try: utils.execute('mkisofs', '-r', '-V', "VMEDIA_BOOT_ISO", '-l', '-e', e_img_rel_path, '-no-emul-boot', '-o', output_file, tmpdir) except processutils.ProcessExecutionError as e: LOG.exception("Creating ISO image failed.") raise exception.ImageCreationFailed(image_type='iso', error=e)
def create_boot_iso(context, output_filename, kernel_href, ramdisk_href, deploy_iso_href=None, esp_image_href=None, root_uuid=None, kernel_params=None, boot_mode=None): """Creates a bootable ISO image for a node. Given the hrefs for kernel, ramdisk, root partition's UUID and kernel cmdline arguments, this method fetches the kernel and ramdisk, and builds a bootable ISO image that can be used to boot up the baremetal node. :param context: context :param output_filename: the absolute path of the output ISO file :param kernel_href: URL or glance uuid of the kernel to use :param ramdisk_href: URL or glance uuid of the ramdisk to use :param deploy_iso_href: URL or glance UUID of the deploy ISO image to extract EFI system partition image. If not specified, the `esp_image_href` option must be present if UEFI-bootable ISO is desired. :param esp_image_href: URL or glance UUID of FAT12/16/32-formatted EFI system partition image containing the EFI boot loader (e.g. GRUB2) for each hardware architecture to boot. This image will be embedded into the ISO image. If not specified, the `deploy_iso_href` option is only required for building UEFI-bootable ISO. :param kernel_params: a string containing whitespace separated values kernel cmdline arguments of the form K=V or K (optional). :boot_mode: the boot mode in which the deploy is to happen. :raises: ImageCreationFailed, if creating boot ISO failed. """ with utils.tempdir() as tmpdir: kernel_path = os.path.join(tmpdir, kernel_href.split('/')[-1]) ramdisk_path = os.path.join(tmpdir, ramdisk_href.split('/')[-1]) fetch(context, kernel_href, kernel_path) fetch(context, ramdisk_href, ramdisk_path) params = [] if root_uuid: params.append('root=UUID=%s' % root_uuid) if kernel_params: params.append(kernel_params) if boot_mode == 'uefi': deploy_iso_path = esp_image_path = None if deploy_iso_href: deploy_iso_path = os.path.join(tmpdir, deploy_iso_href.split('/')[-1]) fetch(context, deploy_iso_href, deploy_iso_path) elif esp_image_href: esp_image_path = os.path.join(tmpdir, esp_image_href.split('/')[-1]) fetch(context, esp_image_href, esp_image_path) elif CONF.esp_image: esp_image_path = CONF.esp_image create_isolinux_image_for_uefi(output_filename, kernel_path, ramdisk_path, deploy_iso=deploy_iso_path, esp_image=esp_image_path, kernel_params=params) else: create_isolinux_image_for_bios(output_filename, kernel_path, ramdisk_path, params)
def create_isolinux_image_for_uefi(output_file, deploy_iso, kernel, ramdisk, kernel_params=None): """Creates an isolinux image on the specified file. Copies the provided kernel, ramdisk, efiboot.img to a directory, creates the path for grub config file, generates the isolinux configuration file using the kernel parameters provided, generates the grub configuration file using kernel parameters and then generates a bootable ISO image for uefi. :param output_file: the path to the file where the iso image needs to be created. :param deploy_iso: deploy iso used to initiate the deploy. :param kernel: the kernel to use. :param ramdisk: the ramdisk to use. :param kernel_params: a list of strings(each element being a string like 'K=V' or 'K' or combination of them like 'K1=V1,K2,...') to be added as the kernel cmdline. :raises: ImageCreationFailed, if image creation failed while copying files or while running command to generate iso. """ ISOLINUX_BIN = 'isolinux/isolinux.bin' ISOLINUX_CFG = 'isolinux/isolinux.cfg' isolinux_options = {'kernel': '/vmlinuz', 'ramdisk': '/initrd'} grub_options = {'linux': '/vmlinuz', 'initrd': '/initrd'} with utils.tempdir() as tmpdir: files_info = { kernel: 'vmlinuz', ramdisk: 'initrd', CONF.isolinux_bin: ISOLINUX_BIN, } # Open the deploy iso used to initiate deploy and copy the # efiboot.img i.e. boot loader to the current temporary # directory. with utils.tempdir() as mountdir: uefi_path_info, e_img_rel_path, grub_rel_path = (_mount_deploy_iso( deploy_iso, mountdir)) # if either of these variables are not initialized then the # uefi efiboot.img cannot be created. files_info.update(uefi_path_info) try: _create_root_fs(tmpdir, files_info) except (OSError, IOError) as e: LOG.exception("Creating the filesystem root failed.") raise exception.ImageCreationFailed(image_type='iso', error=e) finally: _umount_without_raise(mountdir) cfg = _generate_cfg(kernel_params, CONF.isolinux_config_template, isolinux_options) isolinux_cfg = os.path.join(tmpdir, ISOLINUX_CFG) utils.write_to_file(isolinux_cfg, cfg) # Generate and copy grub config file. grub_cfg = os.path.join(tmpdir, grub_rel_path) grub_conf = _generate_cfg(kernel_params, CONF.grub_config_template, grub_options) utils.write_to_file(grub_cfg, grub_conf) # Create the boot_iso. try: utils.execute('mkisofs', '-r', '-V', "VMEDIA_BOOT_ISO", '-cache-inodes', '-J', '-l', '-no-emul-boot', '-boot-load-size', '4', '-boot-info-table', '-b', ISOLINUX_BIN, '-eltorito-alt-boot', '-e', e_img_rel_path, '-no-emul-boot', '-o', output_file, tmpdir) except processutils.ProcessExecutionError as e: LOG.exception("Creating ISO image failed.") raise exception.ImageCreationFailed(image_type='iso', error=e)