summaryrefslogtreecommitdiff
path: root/ironic/drivers/modules/image_utils.py
diff options
context:
space:
mode:
authorDmitry Tantsur <dtantsur@protonmail.com>2020-10-12 16:50:29 +0200
committerDmitry Tantsur <dtantsur@protonmail.com>2020-11-11 12:20:20 +0100
commitd48479b52da7ede21f26299db4bd0370bb71ec21 (patch)
treea4217fb837ae0a6f2b4ef3bcb00abe78b52c6ce4 /ironic/drivers/modules/image_utils.py
parent3fd513ee1c5d9846b7d44ccd7f591e42a4b88f97 (diff)
downloadironic-d48479b52da7ede21f26299db4bd0370bb71ec21.tar.gz
Simplify injecting network data into an ISO image
Currently we're building a VFAT image with the network data just to unpack it back on the next step. Just pass the file directly. This fixes a permission denied problem on Bifrost on Fedora (at least). As a nice side effect, the change reduces the amount of IO done for virtual media quite substantially. Change-Id: I5499fa42c1d82a1a29099fbbba6f45d440448b72
Diffstat (limited to 'ironic/drivers/modules/image_utils.py')
-rw-r--r--ironic/drivers/modules/image_utils.py96
1 files changed, 25 insertions, 71 deletions
diff --git a/ironic/drivers/modules/image_utils.py b/ironic/drivers/modules/image_utils.py
index dcdeff9d1..b50ffe867 100644
--- a/ironic/drivers/modules/image_utils.py
+++ b/ironic/drivers/modules/image_utils.py
@@ -22,7 +22,6 @@ from urllib import parse as urlparse
from ironic_lib import utils as ironic_utils
from oslo_log import log
-from oslo_serialization import base64
from ironic.common import exception
from ironic.common.i18n import _
@@ -288,28 +287,24 @@ def cleanup_floppy_image(task):
def _prepare_iso_image(task, kernel_href, ramdisk_href,
- bootloader_href=None, configdrive=None,
- root_uuid=None, params=None, base_iso=None):
+ bootloader_href=None, root_uuid=None, params=None,
+ base_iso=None, inject_files=None):
"""Prepare an ISO to boot the node.
Build bootable ISO out of `kernel_href` and `ramdisk_href` (and
`bootloader` if it's UEFI boot), then push built image up to Swift and
return a temporary URL.
- If `configdrive` is specified it will be eventually written onto
- the boot ISO image.
-
:param task: a TaskManager instance containing the node to act on.
: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 bootloader_href: URL or Glance UUID of the EFI bootloader
image to use when creating UEFI bootbable ISO
- :param configdrive: URL to or a compressed blob of a ISO9660 or
- FAT-formatted OpenStack config drive image. This image will be
- written onto the built ISO image. Optional.
:param root_uuid: optional uuid of the root partition.
:param params: a dictionary containing 'parameter name'->'value'
mapping to be passed to kernel command line.
+ :param inject_files: Mapping of local source file paths to their location
+ on the final ISO image.
:returns: bootable ISO HTTP URL.
:raises: MissingParameterValue, if any of the required parameters are
missing.
@@ -360,44 +355,21 @@ def _prepare_iso_image(task, kernel_href, ramdisk_href,
with tempfile.NamedTemporaryFile(
dir=CONF.tempdir, suffix='.iso') as boot_fileobj:
- with tempfile.NamedTemporaryFile(
- dir=CONF.tempdir, suffix='.img') as cfgdrv_fileobj:
-
- configdrive_href = configdrive
-
- # FIXME(TheJulia): This is treated as conditional with
- # a base_iso as the intent, eventually, is to support
- # injection into the supplied image.
-
- if configdrive and not base_iso:
- parsed_url = urlparse.urlparse(configdrive)
- if not parsed_url.scheme:
- cfgdrv_blob = base64.decode_as_bytes(configdrive)
-
- with open(cfgdrv_fileobj.name, 'wb') as f:
- f.write(cfgdrv_blob)
-
- configdrive_href = urlparse.urlunparse(
- ('file', '', cfgdrv_fileobj.name, '', '', ''))
-
- LOG.debug("Built configdrive out of configdrive blob "
- "for node %(node)s", {'node': task.node.uuid})
-
- boot_iso_tmp_file = boot_fileobj.name
- images.create_boot_iso(
- task.context, boot_iso_tmp_file,
- kernel_href, ramdisk_href,
- esp_image_href=bootloader_href,
- configdrive_href=configdrive_href,
- root_uuid=root_uuid,
- kernel_params=kernel_params,
- boot_mode=boot_mode,
- base_iso=base_iso)
+ boot_iso_tmp_file = boot_fileobj.name
+ images.create_boot_iso(
+ task.context, boot_iso_tmp_file,
+ kernel_href, ramdisk_href,
+ esp_image_href=bootloader_href,
+ root_uuid=root_uuid,
+ kernel_params=kernel_params,
+ boot_mode=boot_mode,
+ base_iso=base_iso,
+ inject_files=inject_files)
- iso_object_name = _get_iso_image_name(task.node)
+ iso_object_name = _get_iso_image_name(task.node)
- image_url = img_handler.publish_image(
- boot_iso_tmp_file, iso_object_name)
+ image_url = img_handler.publish_image(
+ boot_iso_tmp_file, iso_object_name)
LOG.debug("Created ISO %(name)s in object store for node %(node)s, "
"exposed as temporary URL "
@@ -426,8 +398,8 @@ def prepare_deploy_iso(task, params, mode, d_info):
and return temporary Swift URL to the image.
If network interface supplies network configuration (`network_data`),
- a new `configdrive` will be created with `network_data.json` inside,
- and eventually written down onto the boot ISO.
+ a `network_data.json` will be written into an appropriate location on
+ the final ISO.
:param task: a TaskManager instance containing the node to act on.
:param params: a dictionary containing 'parameter name'->'value'
@@ -457,35 +429,17 @@ def prepare_deploy_iso(task, params, mode, d_info):
_prepare_iso_image, task, kernel_href, ramdisk_href,
bootloader_href=bootloader_href, params=params)
+ inject_files = {}
network_data = task.driver.network.get_node_network_data(task)
if network_data:
LOG.debug('Injecting custom network data for node %s',
task.node.uuid)
- with tempfile.NamedTemporaryFile(dir=CONF.tempdir,
- suffix='.iso') as metadata_fileobj:
-
- with open(metadata_fileobj.name, 'w') as f:
- json.dump(network_data, f, indent=2)
-
- files_info = {
- metadata_fileobj.name: 'openstack/latest/network_data.json'
- }
-
- with tempfile.NamedTemporaryFile(
- dir=CONF.tempdir, suffix='.img') as cfgdrv_fileobj:
-
- images.create_vfat_image(cfgdrv_fileobj.name, files_info)
-
- configdrive_href = urlparse.urlunparse(
- ('file', '', cfgdrv_fileobj.name, '', '', ''))
-
- LOG.debug("Built configdrive %(name)s out of network data "
- "for node %(node)s", {'name': configdrive_href,
- 'node': task.node.uuid})
-
- return prepare_iso_image(configdrive=configdrive_href)
+ network_data = json.dumps(network_data, indent=2).encode('utf-8')
+ inject_files[network_data] = (
+ 'openstack/latest/network_data.json'
+ )
- return prepare_iso_image()
+ return prepare_iso_image(inject_files=inject_files)
def prepare_boot_iso(task, d_info, root_uuid=None):