summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIury Gregory Melo Ferreira <imelofer@redhat.com>2020-04-30 16:54:16 +0200
committerJulia Kreger <juliaashleykreger@gmail.com>2021-07-22 08:35:02 -0700
commitf6a77cc14996c05329fbfb25d6b995ac0009f9b5 (patch)
tree6d221056f175c6590f83b43d2b2e7c18a4aa26a1
parent0c17549c2c81fcb2e3ce256d93f80befe36c2d0d (diff)
downloadironic-f6a77cc14996c05329fbfb25d6b995ac0009f9b5.tar.gz
Refactor RedfishVirtualMediaBoot
- Move staticmethods and classmethods to functions, since in py36 we have a bug when ussing unittest.mock [1] The only classmethod we are keeping is `_set_boot_device` since it's used by `DracRedfishVirtualMediaBoot` [1] https://bugs.python.org/issue23078 Change-Id: I6e51bb956890a01535c62f8a378756e65d438ac3 (cherry picked from commit 2ffbfb4b4627f05954ce453436982fca1448af9a)
-rw-r--r--ironic/drivers/modules/redfish/boot.py1033
-rw-r--r--ironic/tests/unit/drivers/modules/redfish/test_boot.py248
2 files changed, 609 insertions, 672 deletions
diff --git a/ironic/drivers/modules/redfish/boot.py b/ironic/drivers/modules/redfish/boot.py
index f842a04fd..43a2e9b50 100644
--- a/ironic/drivers/modules/redfish/boot.py
+++ b/ironic/drivers/modules/redfish/boot.py
@@ -83,524 +83,610 @@ KERNEL_RAMDISK_LABELS = {
'rescue': RESCUE_PROPERTIES
}
+IMAGE_SUBDIR = 'redfish'
+
sushy = importutils.try_import('sushy')
-class RedfishVirtualMediaBoot(base.BootInterface):
- """Virtual media boot interface over Redfish.
+def _parse_driver_info(node):
+ """Gets the driver specific Node deployment info.
- Virtual Media allows booting the system from the "virtual"
- CD/DVD drive containing the user image that BMC "inserts"
- into the drive.
+ This method validates whether the 'driver_info' property of the
+ supplied node contains the required or optional information properly
+ for this driver to deploy images to the node.
- The CD/DVD images must be in ISO format and (depending on
- BMC implementation) could be pulled over HTTP, served as
- iSCSI targets or NFS volumes.
+ :param node: a target node of the deployment
+ :returns: the driver_info values of the node.
+ :raises: MissingParameterValue, if any of the required parameters are
+ missing.
+ :raises: InvalidParameterValue, if any of the parameters have invalid
+ value.
+ """
+ d_info = node.driver_info
- The baseline boot workflow looks like this:
+ mode = deploy_utils.rescue_or_deploy_mode(node)
+ params_to_check = KERNEL_RAMDISK_LABELS[mode]
- 1. Pull kernel, ramdisk and ESP (FAT partition image with EFI boot
- loader) images (ESP is only needed for UEFI boot)
- 2. Create bootable ISO out of images (#1), push it to Glance and
- pass to the BMC as Swift temporary URL
- 3. Optionally create floppy image with desired system configuration data,
- push it to Glance and pass to the BMC as Swift temporary URL
- 4. Insert CD/DVD and (optionally) floppy images and set proper boot mode
+ deploy_info = {option: d_info.get(option)
+ for option in params_to_check}
- For building deploy or rescue ISO, redfish boot interface uses
- `deploy_kernel`/`deploy_ramdisk` or `rescue_kernel`/`rescue_ramdisk`
- properties from `[instance_info]` or `[driver_info]`.
+ if not any(deploy_info.values()):
+ # NOTE(dtantsur): avoid situation when e.g. deploy_kernel comes
+ # from driver_info but deploy_ramdisk comes from configuration,
+ # since it's a sign of a potential operator's mistake.
+ deploy_info = {k: getattr(CONF.conductor, k)
+ for k in params_to_check}
- For building boot (user) ISO, redfish boot interface seeks `kernel_id`
- and `ramdisk_id` properties in the Glance image metadata found in
- `[instance_info]image_source` node property.
- """
+ error_msg = _("Error validating Redfish virtual media. Some "
+ "parameters were missing in node's driver_info")
- IMAGE_SUBDIR = 'redfish'
+ deploy_utils.check_for_missing_params(deploy_info, error_msg)
- capabilities = ['iscsi_volume_boot', 'ramdisk_boot']
+ deploy_info.update(
+ {option: d_info.get(option, getattr(CONF.conductor, option, None))
+ for option in OPTIONAL_PROPERTIES})
- def __init__(self):
- """Initialize the Redfish virtual media boot interface.
+ deploy_info.update(redfish_utils.parse_driver_info(node))
- :raises: DriverLoadError if the driver can't be loaded due to
- missing dependencies
- """
- super(RedfishVirtualMediaBoot, self).__init__()
- if not sushy:
- raise exception.DriverLoadError(
- driver='redfish',
- reason=_('Unable to import the sushy library'))
+ return deploy_info
- @staticmethod
- def _parse_driver_info(node):
- """Gets the driver specific Node deployment info.
- This method validates whether the 'driver_info' property of the
- supplied node contains the required or optional information properly
- for this driver to deploy images to the node.
-
- :param node: a target node of the deployment
- :returns: the driver_info values of the node.
- :raises: MissingParameterValue, if any of the required parameters are
- missing.
- :raises: InvalidParameterValue, if any of the parameters have invalid
- value.
- """
- d_info = node.driver_info
+def _parse_instance_info(node):
+ """Gets the instance specific Node deployment info.
- mode = deploy_utils.rescue_or_deploy_mode(node)
- params_to_check = KERNEL_RAMDISK_LABELS[mode]
+ This method validates whether the 'instance_info' property of the
+ supplied node contains the required or optional information properly
+ for this driver to deploy images to the node.
- deploy_info = {option: d_info.get(option)
- for option in params_to_check}
+ :param node: a target node of the deployment
+ :returns: the instance_info values of the node.
+ :raises: InvalidParameterValue, if any of the parameters have invalid
+ value.
+ """
+ deploy_info = node.instance_info.copy()
- if not any(deploy_info.values()):
- # NOTE(dtantsur): avoid situation when e.g. deploy_kernel comes
- # from driver_info but deploy_ramdisk comes from configuration,
- # since it's a sign of a potential operator's mistake.
- deploy_info = {k: getattr(CONF.conductor, k)
- for k in params_to_check}
+ # NOTE(etingof): this method is currently no-op, here for completeness
+ return deploy_info
- error_msg = _("Error validating Redfish virtual media. Some "
- "parameters were missing in node's driver_info")
- deploy_utils.check_for_missing_params(deploy_info, error_msg)
+def _append_filename_param(url, filename):
+ """Append 'filename=<file>' parameter to given URL.
- deploy_info.update(
- {option: d_info.get(option, getattr(CONF.conductor, option, None))
- for option in OPTIONAL_PROPERTIES})
+ Some BMCs seem to validate boot image URL requiring the URL to end
+ with something resembling ISO image file name.
- deploy_info.update(redfish_utils.parse_driver_info(node))
+ This function tries to add, hopefully, meaningless 'filename'
+ parameter to URL's query string in hope to make the entire boot image
+ URL looking more convincing to the BMC.
- return deploy_info
+ However, `url` with fragments might not get cured by this hack.
- @staticmethod
- def _parse_instance_info(node):
- """Gets the instance specific Node deployment info.
+ :param url: a URL to work on
+ :param filename: name of the file to append to the URL
+ :returns: original URL with 'filename' parameter appended
+ """
+ parsed_url = urlparse.urlparse(url)
+ parsed_qs = urlparse.parse_qsl(parsed_url.query)
- This method validates whether the 'instance_info' property of the
- supplied node contains the required or optional information properly
- for this driver to deploy images to the node.
+ has_filename = [x for x in parsed_qs if x[0].lower() == 'filename']
+ if has_filename:
+ return url
- :param node: a target node of the deployment
- :returns: the instance_info values of the node.
- :raises: InvalidParameterValue, if any of the parameters have invalid
- value.
- """
- deploy_info = node.instance_info.copy()
+ parsed_qs.append(('filename', filename))
+ parsed_url = list(parsed_url)
+ parsed_url[4] = urlparse.urlencode(parsed_qs)
- # NOTE(etingof): this method is currently no-op, here for completeness
- return deploy_info
+ return urlparse.urlunparse(parsed_url)
- @classmethod
- def _parse_deploy_info(cls, node):
- """Gets the instance and driver specific Node deployment info.
-
- This method validates whether the 'instance_info' and 'driver_info'
- property of the supplied node contains the required information for
- this driver to deploy images to the node.
-
- :param node: a target node of the deployment
- :returns: a dict with the instance_info and driver_info values.
- :raises: MissingParameterValue, if any of the required parameters are
- missing.
- :raises: InvalidParameterValue, if any of the parameters have invalid
- value.
- """
- deploy_info = {}
- deploy_info.update(deploy_utils.get_image_instance_info(node))
- deploy_info.update(cls._parse_driver_info(node))
- deploy_info.update(cls._parse_instance_info(node))
- return deploy_info
+def _get_floppy_image_name(node):
+ """Returns the floppy image name for a given node.
- @staticmethod
- def _append_filename_param(url, filename):
- """Append 'filename=<file>' parameter to given URL.
+ :param node: the node for which image name is to be provided.
+ """
+ return "image-%s" % node.uuid
- Some BMCs seem to validate boot image URL requiring the URL to end
- with something resembling ISO image file name.
- This function tries to add, hopefully, meaningless 'filename'
- parameter to URL's query string in hope to make the entire boot image
- URL looking more convincing to the BMC.
+def _get_iso_image_name(node):
+ """Returns the boot iso image name for a given node.
- However, `url` with fragments might not get cured by this hack.
+ :param node: the node for which image name is to be provided.
+ """
+ return "boot-%s" % node.uuid
- :param url: a URL to work on
- :param filename: name of the file to append to the URL
- :returns: original URL with 'filename' parameter appended
- """
- parsed_url = urlparse.urlparse(url)
- parsed_qs = urlparse.parse_qsl(parsed_url.query)
- has_filename = [x for x in parsed_qs if x[0].lower() == 'filename']
- if has_filename:
- return url
+def _insert_vmedia(task, boot_url, boot_device):
+ """Insert bootable ISO image into virtual CD or DVD
- parsed_qs.append(('filename', filename))
- parsed_url = list(parsed_url)
- parsed_url[4] = urlparse.urlencode(parsed_qs)
+ :param task: A task from TaskManager.
+ :param boot_url: URL to a bootable ISO image
+ :param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
+ `VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY`
+ :raises: InvalidParameterValue, if no suitable virtual CD or DVD is
+ found on the node.
+ """
+ system = redfish_utils.get_system(task.node)
+
+ for manager in system.managers:
+ for v_media in manager.virtual_media.get_members():
+ if boot_device not in v_media.media_types:
+ continue
+
+ if v_media.inserted:
+ if v_media.image == boot_url:
+ LOG.debug("Boot media %(boot_url)s is already "
+ "inserted into %(boot_device)s for node "
+ "%(node)s", {'node': task.node.uuid,
+ 'boot_url': boot_url,
+ 'boot_device': boot_device})
+ return
+
+ continue
+
+ v_media.insert_media(boot_url, inserted=True,
+ write_protected=True)
+
+ LOG.info("Inserted boot media %(boot_url)s into "
+ "%(boot_device)s for node "
+ "%(node)s", {'node': task.node.uuid,
+ 'boot_url': boot_url,
+ 'boot_device': boot_device})
+ return
- return urlparse.urlunparse(parsed_url)
+ raise exception.InvalidParameterValue(
+ _('No suitable virtual media device found'))
- @classmethod
- def _publish_image(cls, image_file, object_name):
- """Make image file downloadable.
- Depending on ironic settings, pushes given file into Swift or copies
- it over to local HTTP server's document root and returns publicly
- accessible URL leading to the given file.
+def _eject_vmedia(task, boot_device=None):
+ """Eject virtual CDs and DVDs
- :param image_file: path to file to publish
- :param object_name: name of the published file
- :return: a URL to download published file
- """
+ :param task: A task from TaskManager.
+ :param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
+ `VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY` or `None` to
+ eject everything (default).
+ :raises: InvalidParameterValue, if no suitable virtual CD or DVD is
+ found on the node.
+ """
+ system = redfish_utils.get_system(task.node)
- if CONF.redfish.use_swift:
- container = CONF.redfish.swift_container
- timeout = CONF.redfish.swift_object_expiry_timeout
+ for manager in system.managers:
+ for v_media in manager.virtual_media.get_members():
+ if boot_device and boot_device not in v_media.media_types:
+ continue
- object_headers = {'X-Delete-After': str(timeout)}
+ inserted = v_media.inserted
- swift_api = swift.SwiftAPI()
+ if inserted:
+ v_media.eject_media()
- swift_api.create_object(container, object_name, image_file,
- object_headers=object_headers)
+ LOG.info("Boot media is%(already)s ejected from "
+ "%(boot_device)s for node %(node)s"
+ "", {'node': task.node.uuid,
+ 'already': '' if inserted else ' already',
+ 'boot_device': v_media.name})
- image_url = swift_api.get_temp_url(container, object_name, timeout)
- else:
- public_dir = os.path.join(CONF.deploy.http_root, cls.IMAGE_SUBDIR)
+def _has_vmedia_device(task, boot_device):
+ """Indicate if device exists at any of the managers
- if not os.path.exists(public_dir):
- os.mkdir(public_dir, 0x755)
+ :param task: A task from TaskManager.
+ :param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
+ `VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY`.
+ """
+ system = redfish_utils.get_system(task.node)
- published_file = os.path.join(public_dir, object_name)
+ for manager in system.managers:
+ for v_media in manager.virtual_media.get_members():
+ if boot_device in v_media.media_types:
+ return True
- try:
- os.link(image_file, published_file)
- except OSError as exc:
- LOG.debug(
- "Could not hardlink image file %(image)s to public "
- "location %(public)s (will copy it over): "
- "%(error)s", {'image': image_file,
- 'public': published_file,
- 'error': exc})
+def _cleanup_iso_image(task):
+ """Deletes the ISO if it was created for the instance.
- shutil.copyfile(image_file, published_file)
+ :param task: A task from TaskManager.
+ """
+ iso_object_name = _get_iso_image_name(task.node)
- image_url = os.path.join(
- CONF.deploy.http_url, cls.IMAGE_SUBDIR, object_name)
+ _unpublish_image(iso_object_name)
- image_url = cls._append_filename_param(
- image_url, os.path.basename(image_file))
- return image_url
+def _unpublish_image(object_name):
+ """Withdraw the image previously made downloadable.
- @classmethod
- def _unpublish_image(cls, object_name):
- """Withdraw the image previously made downloadable.
+ Depending on ironic settings, removes previously published file
+ from where it has been published - Swift or local HTTP server's
+ document root.
- Depending on ironic settings, removes previously published file
- from where it has been published - Swift or local HTTP server's
- document root.
+ :param object_name: name of the published file (optional)
+ """
+ if CONF.redfish.use_swift:
+ container = CONF.redfish.swift_container
- :param object_name: name of the published file (optional)
- """
- if CONF.redfish.use_swift:
- container = CONF.redfish.swift_container
+ swift_api = swift.SwiftAPI()
- swift_api = swift.SwiftAPI()
+ LOG.debug("Cleaning up image %(name)s from Swift container "
+ "%(container)s", {'name': object_name,
+ 'container': container})
- LOG.debug("Cleaning up image %(name)s from Swift container "
- "%(container)s", {'name': object_name,
- 'container': container})
+ try:
+ swift_api.delete_object(container, object_name)
+
+ except exception.SwiftOperationError as exc:
+ LOG.warning("Failed to clean up image %(image)s. Error: "
+ "%(error)s.", {'image': object_name,
+ 'error': exc})
+
+ else:
+ published_file = os.path.join(
+ CONF.deploy.http_root, IMAGE_SUBDIR, object_name)
+
+ ironic_utils.unlink_without_raise(published_file)
+
+
+def _prepare_floppy_image(task, params=None):
+ """Prepares the floppy image for passing the parameters.
+
+ This method prepares a temporary VFAT filesystem image and adds
+ a file into the image which contains parameters to be passed to
+ the ramdisk. Then this method uploads built image to Swift
+ '[redfish]swift_container', setting it to auto expire after
+ '[redfish]swift_object_expiry_timeout' seconds. Finally, a
+ temporary Swift URL is returned addressing Swift object just
+ created.
+
+ :param task: a TaskManager instance containing the node to act on.
+ :param params: a dictionary containing 'parameter name'->'value'
+ mapping to be passed to deploy or rescue image via floppy image.
+ :raises: ImageCreationFailed, if it failed while creating the floppy
+ image.
+ :raises: SwiftOperationError, if any operation with Swift fails.
+ :returns: image URL for the floppy image.
+ """
+ object_name = _get_floppy_image_name(task.node)
- try:
- swift_api.delete_object(container, object_name)
+ LOG.debug("Trying to create floppy image for node "
+ "%(node)s", {'node': task.node.uuid})
- except exception.SwiftOperationError as exc:
- LOG.warning("Failed to clean up image %(image)s. Error: "
- "%(error)s.", {'image': object_name,
- 'error': exc})
+ with tempfile.NamedTemporaryFile(
+ dir=CONF.tempdir, suffix='.img') as vfat_image_tmpfile_obj:
- else:
- published_file = os.path.join(
- CONF.deploy.http_root, cls.IMAGE_SUBDIR, object_name)
+ vfat_image_tmpfile = vfat_image_tmpfile_obj.name
+ images.create_vfat_image(vfat_image_tmpfile, parameters=params)
- ironic_utils.unlink_without_raise(published_file)
+ image_url = _publish_image(vfat_image_tmpfile, object_name)
- @staticmethod
- def _get_floppy_image_name(node):
- """Returns the floppy image name for a given node.
+ LOG.debug("Created floppy image %(name)s in Swift for node %(node)s, "
+ "exposed as temporary URL "
+ "%(url)s", {'node': task.node.uuid,
+ 'name': object_name,
+ 'url': image_url})
- :param node: the node for which image name is to be provided.
- """
- return "image-%s" % node.uuid
+ return image_url
- @classmethod
- def _cleanup_floppy_image(cls, task):
- """Deletes the floppy image if it was created for the node.
- :param task: an ironic node object.
- """
- floppy_object_name = cls._get_floppy_image_name(task.node)
+def _publish_image(image_file, object_name):
+ """Make image file downloadable.
- cls._unpublish_image(floppy_object_name)
+ Depending on ironic settings, pushes given file into Swift or copies
+ it over to local HTTP server's document root and returns publicly
+ accessible URL leading to the given file.
- @classmethod
- def _prepare_floppy_image(cls, task, params=None):
- """Prepares the floppy image for passing the parameters.
+ :param image_file: path to file to publish
+ :param object_name: name of the published file
+ :return: a URL to download published file
+ """
- This method prepares a temporary VFAT filesystem image and adds
- a file into the image which contains parameters to be passed to
- the ramdisk. Then this method uploads built image to Swift
- '[redfish]swift_container', setting it to auto expire after
- '[redfish]swift_object_expiry_timeout' seconds. Finally, a
- temporary Swift URL is returned addressing Swift object just
- created.
+ if CONF.redfish.use_swift:
+ container = CONF.redfish.swift_container
+ timeout = CONF.redfish.swift_object_expiry_timeout
- :param task: a TaskManager instance containing the node to act on.
- :param params: a dictionary containing 'parameter name'->'value'
- mapping to be passed to deploy or rescue image via floppy image.
- :raises: ImageCreationFailed, if it failed while creating the floppy
- image.
- :raises: SwiftOperationError, if any operation with Swift fails.
- :returns: image URL for the floppy image.
- """
- object_name = cls._get_floppy_image_name(task.node)
+ object_headers = {'X-Delete-After': str(timeout)}
- LOG.debug("Trying to create floppy image for node "
- "%(node)s", {'node': task.node.uuid})
+ swift_api = swift.SwiftAPI()
- with tempfile.NamedTemporaryFile(
- dir=CONF.tempdir, suffix='.img') as vfat_image_tmpfile_obj:
+ swift_api.create_object(container, object_name, image_file,
+ object_headers=object_headers)
- vfat_image_tmpfile = vfat_image_tmpfile_obj.name
- images.create_vfat_image(vfat_image_tmpfile, parameters=params)
+ image_url = swift_api.get_temp_url(container, object_name, timeout)
- image_url = cls._publish_image(vfat_image_tmpfile, object_name)
+ else:
+ public_dir = os.path.join(CONF.deploy.http_root, IMAGE_SUBDIR)
- LOG.debug("Created floppy image %(name)s in Swift for node %(node)s, "
- "exposed as temporary URL "
- "%(url)s", {'node': task.node.uuid,
- 'name': object_name,
- 'url': image_url})
+ if not os.path.exists(public_dir):
+ os.mkdir(public_dir, 0x755)
- return image_url
+ published_file = os.path.join(public_dir, object_name)
- @staticmethod
- def _get_iso_image_name(node):
- """Returns the boot iso image name for a given node.
+ try:
+ os.link(image_file, published_file)
- :param node: the node for which image name is to be provided.
- """
- return "boot-%s" % node.uuid
+ except OSError as exc:
+ LOG.debug(
+ "Could not hardlink image file %(image)s to public "
+ "location %(public)s (will copy it over): "
+ "%(error)s", {'image': image_file,
+ 'public': published_file,
+ 'error': exc})
- @classmethod
- def _cleanup_iso_image(cls, task):
- """Deletes the ISO if it was created for the instance.
+ shutil.copyfile(image_file, published_file)
- :param task: an ironic node object.
- """
- iso_object_name = cls._get_iso_image_name(task.node)
+ image_url = os.path.join(
+ CONF.deploy.http_url, IMAGE_SUBDIR, object_name)
- cls._unpublish_image(iso_object_name)
+ image_url = _append_filename_param(
+ image_url, os.path.basename(image_file))
- @classmethod
- def _prepare_iso_image(cls, task, kernel_href, ramdisk_href,
- bootloader_href=None, configdrive=None,
- root_uuid=None, params=None):
- """Prepare an ISO to boot the node.
+ return image_url
- 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.
- :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.
- :returns: bootable ISO HTTP URL.
- :raises: MissingParameterValue, if any of the required parameters are
- missing.
- :raises: InvalidParameterValue, if any of the parameters have invalid
- value.
- :raises: ImageCreationFailed, if creating ISO image failed.
- """
- if not kernel_href or not ramdisk_href:
- raise exception.InvalidParameterValue(_(
- "Unable to find kernel or ramdisk for "
- "building ISO for %(node)s") %
- {'node': task.node.uuid})
+def _cleanup_floppy_image(task):
+ """Deletes the floppy image if it was created for the node.
- i_info = task.node.instance_info
+ :param task: an ironic node object.
+ """
+ floppy_object_name = _get_floppy_image_name(task.node)
- if deploy_utils.get_boot_option(task.node) == "ramdisk":
- kernel_params = "root=/dev/ram0 text "
- kernel_params += i_info.get("ramdisk_kernel_arguments", "")
+ _unpublish_image(floppy_object_name)
- else:
- kernel_params = i_info.get(
- 'kernel_append_params', CONF.redfish.kernel_append_params)
-
- if params:
- kernel_params = ' '.join(
- (kernel_params, ' '.join(
- '%s=%s' % kv for kv in params.items())))
-
- boot_mode = boot_mode_utils.get_boot_mode_for_deploy(task.node)
-
- LOG.debug("Trying to create %(boot_mode)s ISO image for node %(node)s "
- "with kernel %(kernel_href)s, ramdisk %(ramdisk_href)s, "
- "bootloader %(bootloader_href)s and kernel params %(params)s"
- "", {'node': task.node.uuid,
- 'boot_mode': boot_mode,
- 'kernel_href': kernel_href,
- 'ramdisk_href': ramdisk_href,
- 'bootloader_href': bootloader_href,
- 'params': kernel_params})
- with tempfile.NamedTemporaryFile(
- dir=CONF.tempdir, suffix='.iso') as boot_fileobj:
+def _parse_deploy_info(node):
+ """Gets the instance and driver specific Node deployment info.
- with tempfile.NamedTemporaryFile(
- dir=CONF.tempdir, suffix='.img') as cfgdrv_fileobj:
+ This method validates whether the 'instance_info' and 'driver_info'
+ property of the supplied node contains the required information for
+ this driver to deploy images to the node.
- configdrive_href = configdrive
+ :param node: a target node of the deployment
+ :returns: a dict with the instance_info and driver_info values.
+ :raises: MissingParameterValue, if any of the required parameters are
+ missing.
+ :raises: InvalidParameterValue, if any of the parameters have invalid
+ value.
+ """
+ deploy_info = {}
+ deploy_info.update(deploy_utils.get_image_instance_info(node))
+ deploy_info.update(_parse_driver_info(node))
+ deploy_info.update(_parse_instance_info(node))
+
+ return deploy_info
+
+
+def _prepare_iso_image(task, kernel_href, ramdisk_href,
+ bootloader_href=None, configdrive=None,
+ root_uuid=None, params=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.
+
+ :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.
+ :returns: bootable ISO HTTP URL.
+ :raises: MissingParameterValue, if any of the required parameters are
+ missing.
+ :raises: InvalidParameterValue, if any of the parameters have invalid
+ value.
+ :raises: ImageCreationFailed, if creating ISO image failed.
+ """
+ if not kernel_href or not ramdisk_href:
+ raise exception.InvalidParameterValue(_(
+ "Unable to find kernel or ramdisk for "
+ "building ISO for %(node)s") %
+ {'node': task.node.uuid})
+
+ i_info = task.node.instance_info
+
+ if deploy_utils.get_boot_option(task.node) == "ramdisk":
+ kernel_params = "root=/dev/ram0 text "
+ kernel_params += i_info.get("ramdisk_kernel_arguments", "")
+
+ else:
+ kernel_params = i_info.get(
+ 'kernel_append_params', CONF.redfish.kernel_append_params)
+
+ if params:
+ kernel_params = ' '.join(
+ (kernel_params, ' '.join(
+ '%s=%s' % kv for kv in params.items())))
+
+ boot_mode = boot_mode_utils.get_boot_mode_for_deploy(task.node)
+
+ LOG.debug("Trying to create %(boot_mode)s ISO image for node %(node)s "
+ "with kernel %(kernel_href)s, ramdisk %(ramdisk_href)s, "
+ "bootloader %(bootloader_href)s and kernel params %(params)s"
+ "", {'node': task.node.uuid,
+ 'boot_mode': boot_mode,
+ 'kernel_href': kernel_href,
+ 'ramdisk_href': ramdisk_href,
+ 'bootloader_href': bootloader_href,
+ 'params': kernel_params})
+
+ with tempfile.NamedTemporaryFile(
+ dir=CONF.tempdir, suffix='.iso') as boot_fileobj:
- if configdrive:
- parsed_url = urlparse.urlparse(configdrive)
- if not parsed_url.scheme:
- cfgdrv_blob = base64.decode_as_bytes(configdrive)
+ with tempfile.NamedTemporaryFile(
+ dir=CONF.tempdir, suffix='.img') as cfgdrv_fileobj:
+
+ configdrive_href = configdrive
+
+ if configdrive:
+ 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.info("Burning configdrive %(url)s to boot ISO image "
+ "for node %(node)s", {'url': configdrive_href,
+ '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)
+
+ iso_object_name = _get_iso_image_name(task.node)
+
+ image_url = _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 "
+ "%(url)s", {'node': task.node.uuid,
+ 'name': iso_object_name,
+ 'url': image_url})
+
+ return image_url
+
+
+def _prepare_deploy_iso(task, params, mode):
+ """Prepare deploy or rescue ISO image
+
+ Build bootable ISO out of
+ `[driver_info]/deploy_kernel`/`[driver_info]/deploy_ramdisk` or
+ `[driver_info]/rescue_kernel`/`[driver_info]/rescue_ramdisk`
+ and `[driver_info]/bootloader`, then push built image up to Glance
+ and return temporary Swift URL to the image.
+
+ :param task: a TaskManager instance containing the node to act on.
+ :param params: a dictionary containing 'parameter name'->'value'
+ mapping to be passed to kernel command line.
+ :param mode: either 'deploy' or 'rescue'.
+ :returns: bootable ISO HTTP URL.
+ :raises: MissingParameterValue, if any of the required parameters are
+ missing.
+ :raises: InvalidParameterValue, if any of the parameters have invalid
+ value.
+ :raises: ImageCreationFailed, if creating ISO image failed.
+ """
+ node = task.node
- with open(cfgdrv_fileobj.name, 'wb') as f:
- f.write(cfgdrv_blob)
+ d_info = _parse_driver_info(node)
- configdrive_href = urlparse.urlunparse(
- ('file', '', cfgdrv_fileobj.name, '', '', ''))
+ kernel_href = d_info.get('%s_kernel' % mode)
+ ramdisk_href = d_info.get('%s_ramdisk' % mode)
+ bootloader_href = d_info.get('bootloader')
- LOG.info("Burning configdrive %(url)s to boot ISO image "
- "for node %(node)s", {'url': configdrive_href,
- 'node': task.node.uuid})
+ return _prepare_iso_image(
+ task, kernel_href, ramdisk_href, bootloader_href, params=params)
- 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)
- iso_object_name = cls._get_iso_image_name(task.node)
+def _prepare_boot_iso(task, root_uuid=None):
+ """Prepare boot ISO image
- image_url = cls._publish_image(
- boot_iso_tmp_file, iso_object_name)
+ Build bootable ISO out of `[instance_info]/kernel`,
+ `[instance_info]/ramdisk` and `[driver_info]/bootloader` if present.
+ Otherwise, read `kernel_id` and `ramdisk_id` from
+ `[instance_info]/image_source` Glance image metadata.
- LOG.debug("Created ISO %(name)s in object store for node %(node)s, "
- "exposed as temporary URL "
- "%(url)s", {'node': task.node.uuid,
- 'name': iso_object_name,
- 'url': image_url})
+ Push produced ISO image up to Glance and return temporary Swift
+ URL to the image.
- return image_url
+ :param task: a TaskManager instance containing the node to act on.
+ :returns: bootable ISO HTTP URL.
+ :raises: MissingParameterValue, if any of the required parameters are
+ missing.
+ :raises: InvalidParameterValue, if any of the parameters have invalid
+ value.
+ :raises: ImageCreationFailed, if creating ISO image failed.
+ """
+ node = task.node
- @classmethod
- def _prepare_deploy_iso(cls, task, params, mode):
- """Prepare deploy or rescue ISO image
+ d_info = _parse_deploy_info(node)
- Build bootable ISO out of
- `[driver_info]/deploy_kernel`/`[driver_info]/deploy_ramdisk` or
- `[driver_info]/rescue_kernel`/`[driver_info]/rescue_ramdisk`
- and `[driver_info]/bootloader`, then push built image up to Glance
- and return temporary Swift URL to the image.
+ kernel_href = node.instance_info.get('kernel')
+ ramdisk_href = node.instance_info.get('ramdisk')
- :param task: a TaskManager instance containing the node to act on.
- :param params: a dictionary containing 'parameter name'->'value'
- mapping to be passed to kernel command line.
- :param mode: either 'deploy' or 'rescue'.
- :returns: bootable ISO HTTP URL.
- :raises: MissingParameterValue, if any of the required parameters are
- missing.
- :raises: InvalidParameterValue, if any of the parameters have invalid
- value.
- :raises: ImageCreationFailed, if creating ISO image failed.
- """
- node = task.node
+ if not kernel_href or not ramdisk_href:
- d_info = cls._parse_driver_info(node)
+ image_href = d_info['image_source']
- kernel_href = d_info.get('%s_kernel' % mode)
- ramdisk_href = d_info.get('%s_ramdisk' % mode)
- bootloader_href = d_info.get('bootloader')
+ image_properties = (
+ images.get_image_properties(
+ task.context, image_href, ['kernel_id', 'ramdisk_id']))
- return cls._prepare_iso_image(
- task, kernel_href, ramdisk_href, bootloader_href, params=params)
+ if not kernel_href:
+ kernel_href = image_properties.get('kernel_id')
- @classmethod
- def _prepare_boot_iso(cls, task, root_uuid=None):
- """Prepare boot ISO image
+ if not ramdisk_href:
+ ramdisk_href = image_properties.get('ramdisk_id')
- Build bootable ISO out of `[instance_info]/kernel`,
- `[instance_info]/ramdisk` and `[driver_info]/bootloader` if present.
- Otherwise, read `kernel_id` and `ramdisk_id` from
- `[instance_info]/image_source` Glance image metadata.
+ if not kernel_href or not ramdisk_href:
+ raise exception.InvalidParameterValue(_(
+ "Unable to find kernel or ramdisk for "
+ "to generate boot ISO for %(node)s") %
+ {'node': task.node.uuid})
- Push produced ISO image up to Glance and return temporary Swift
- URL to the image.
+ bootloader_href = d_info.get('bootloader')
- :param task: a TaskManager instance containing the node to act on.
- :returns: bootable ISO HTTP URL.
- :raises: MissingParameterValue, if any of the required parameters are
- missing.
- :raises: InvalidParameterValue, if any of the parameters have invalid
- value.
- :raises: ImageCreationFailed, if creating ISO image failed.
- """
- node = task.node
+ return _prepare_iso_image(
+ task, kernel_href, ramdisk_href, bootloader_href,
+ root_uuid=root_uuid)
- d_info = cls._parse_deploy_info(node)
- kernel_href = node.instance_info.get('kernel')
- ramdisk_href = node.instance_info.get('ramdisk')
+class RedfishVirtualMediaBoot(base.BootInterface):
+ """Virtual media boot interface over Redfish.
- if not kernel_href or not ramdisk_href:
+ Virtual Media allows booting the system from the "virtual"
+ CD/DVD drive containing the user image that BMC "inserts"
+ into the drive.
- image_href = d_info['image_source']
+ The CD/DVD images must be in ISO format and (depending on
+ BMC implementation) could be pulled over HTTP, served as
+ iSCSI targets or NFS volumes.
- image_properties = (
- images.get_image_properties(
- task.context, image_href, ['kernel_id', 'ramdisk_id']))
+ The baseline boot workflow looks like this:
- if not kernel_href:
- kernel_href = image_properties.get('kernel_id')
+ 1. Pull kernel, ramdisk and ESP (FAT partition image with EFI boot
+ loader) images (ESP is only needed for UEFI boot)
+ 2. Create bootable ISO out of images (#1), push it to Glance and
+ pass to the BMC as Swift temporary URL
+ 3. Optionally create floppy image with desired system configuration data,
+ push it to Glance and pass to the BMC as Swift temporary URL
+ 4. Insert CD/DVD and (optionally) floppy images and set proper boot mode
- if not ramdisk_href:
- ramdisk_href = image_properties.get('ramdisk_id')
+ For building deploy or rescue ISO, redfish boot interface uses
+ `deploy_kernel`/`deploy_ramdisk` or `rescue_kernel`/`rescue_ramdisk`
+ properties from `[instance_info]` or `[driver_info]`.
+
+ For building boot (user) ISO, redfish boot interface seeks `kernel_id`
+ and `ramdisk_id` properties in the Glance image metadata found in
+ `[instance_info]image_source` node property.
+ """
- if not kernel_href or not ramdisk_href:
- raise exception.InvalidParameterValue(_(
- "Unable to find kernel or ramdisk for "
- "to generate boot ISO for %(node)s") %
- {'node': task.node.uuid})
+ capabilities = ['iscsi_volume_boot', 'ramdisk_boot']
- bootloader_href = d_info.get('bootloader')
+ def __init__(self):
+ """Initialize the Redfish virtual media boot interface.
- return cls._prepare_iso_image(
- task, kernel_href, ramdisk_href, bootloader_href,
- root_uuid=root_uuid)
+ :raises: DriverLoadError if the driver can't be loaded due to
+ missing dependencies
+ """
+ super(RedfishVirtualMediaBoot, self).__init__()
+ if not sushy:
+ raise exception.DriverLoadError(
+ driver='redfish',
+ reason=_('Unable to import the sushy library'))
def get_properties(self):
"""Return the properties of the interface.
@@ -609,8 +695,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
"""
return REQUIRED_PROPERTIES
- @classmethod
- def _validate_driver_info(cls, task):
+ def _validate_driver_info(self, task):
"""Validate the prerequisites for virtual media based boot.
This method validates whether the 'driver_info' property of the
@@ -623,10 +708,9 @@ class RedfishVirtualMediaBoot(base.BootInterface):
"""
node = task.node
- cls._parse_driver_info(node)
+ _parse_driver_info(node)
- @classmethod
- def _validate_instance_info(cls, task):
+ def _validate_instance_info(self, task):
"""Validate instance image information for the task's node.
This method validates whether the 'instance_info' property of the
@@ -639,7 +723,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
"""
node = task.node
- d_info = cls._parse_deploy_info(node)
+ d_info = _parse_deploy_info(node)
if node.driver_internal_info.get('is_whole_disk_image'):
props = []
@@ -720,7 +804,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
manager_utils.node_power_action(task, states.POWER_OFF)
- d_info = self._parse_driver_info(node)
+ d_info = _parse_driver_info(node)
config_via_floppy = d_info.get('config_via_floppy')
@@ -731,16 +815,16 @@ class RedfishVirtualMediaBoot(base.BootInterface):
if config_via_floppy:
- if self._has_vmedia_device(task, sushy.VIRTUAL_MEDIA_FLOPPY):
+ if _has_vmedia_device(task, sushy.VIRTUAL_MEDIA_FLOPPY):
# NOTE (etingof): IPA will read the diskette only if
# we tell it to
ramdisk_params['boot_method'] = 'vmedia'
- floppy_ref = self._prepare_floppy_image(
+ floppy_ref = _prepare_floppy_image(
task, params=ramdisk_params)
- self._eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
- self._insert_vmedia(
+ _eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
+ _insert_vmedia(
task, floppy_ref, sushy.VIRTUAL_MEDIA_FLOPPY)
LOG.debug('Inserted virtual floppy with configuration for '
@@ -753,10 +837,10 @@ class RedfishVirtualMediaBoot(base.BootInterface):
mode = deploy_utils.rescue_or_deploy_mode(node)
- iso_ref = self._prepare_deploy_iso(task, ramdisk_params, mode)
+ iso_ref = _prepare_deploy_iso(task, ramdisk_params, mode)
- self._eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
- self._insert_vmedia(task, iso_ref, sushy.VIRTUAL_MEDIA_CD)
+ _eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
+ _insert_vmedia(task, iso_ref, sushy.VIRTUAL_MEDIA_CD)
boot_mode_utils.sync_boot_mode(task)
@@ -775,22 +859,21 @@ class RedfishVirtualMediaBoot(base.BootInterface):
:param task: A task from TaskManager.
:returns: None
"""
- node = task.node
-
- d_info = self._parse_driver_info(node)
+ d_info = _parse_driver_info(task.node)
config_via_floppy = d_info.get('config_via_floppy')
LOG.debug("Cleaning up deploy boot for "
"%(node)s", {'node': task.node.uuid})
- self._eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
- self._cleanup_iso_image(task)
+ _eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
+ _cleanup_iso_image(task)
if (config_via_floppy
- and self._has_vmedia_device(task, sushy.VIRTUAL_MEDIA_FLOPPY)):
- self._eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
- self._cleanup_floppy_image(task)
+ and _has_vmedia_device(task, sushy.VIRTUAL_MEDIA_FLOPPY)):
+ _eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
+
+ _cleanup_floppy_image(task)
def prepare_instance(self, task):
"""Prepares the boot of instance over virtual media.
@@ -815,12 +898,10 @@ class RedfishVirtualMediaBoot(base.BootInterface):
node = task.node
boot_option = deploy_utils.get_boot_option(node)
-
self.clean_up_instance(task)
iwdi = node.driver_internal_info.get('is_whole_disk_image')
if boot_option == "local" or iwdi:
- self._set_boot_device(
- task, boot_devices.DISK, persistent=True)
+ self._set_boot_device(task, boot_devices.DISK, persistent=True)
LOG.debug("Node %(node)s is set to permanently boot from local "
"%(device)s", {'node': task.node.uuid,
@@ -831,28 +912,24 @@ class RedfishVirtualMediaBoot(base.BootInterface):
if boot_option != 'ramdisk':
root_uuid = node.driver_internal_info.get('root_uuid_or_disk_id')
-
if not root_uuid and task.driver.storage.should_write_image(task):
LOG.warning(
"The UUID of the root partition could not be found for "
"node %s. Booting instance from disk anyway.", node.uuid)
- self._set_boot_device(
- task, boot_devices.DISK, persistent=True)
+ self._set_boot_device(task, boot_devices.DISK, persistent=True)
return
params.update(root_uuid=root_uuid)
- iso_ref = self._prepare_boot_iso(task, **params)
-
- self._eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
- self._insert_vmedia(task, iso_ref, sushy.VIRTUAL_MEDIA_CD)
+ iso_ref = _prepare_boot_iso(task, **params)
+ _eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
+ _insert_vmedia(task, iso_ref, sushy.VIRTUAL_MEDIA_CD)
boot_mode_utils.sync_boot_mode(task)
- self._set_boot_device(
- task, boot_devices.CDROM, persistent=True)
+ self._set_boot_device(task, boot_devices.CDROM, persistent=True)
LOG.debug("Node %(node)s is set to permanently boot from "
"%(device)s", {'node': task.node.uuid,
@@ -870,99 +947,13 @@ class RedfishVirtualMediaBoot(base.BootInterface):
LOG.debug("Cleaning up instance boot for "
"%(node)s", {'node': task.node.uuid})
- self._eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
+ _eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
d_info = task.node.driver_info
config_via_floppy = d_info.get('config_via_floppy')
if config_via_floppy:
- self._eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
-
- self._cleanup_iso_image(task)
-
- @staticmethod
- def _insert_vmedia(task, boot_url, boot_device):
- """Insert bootable ISO image into virtual CD or DVD
-
- :param task: A task from TaskManager.
- :param boot_url: URL to a bootable ISO image
- :param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
- `VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY`
- :raises: InvalidParameterValue, if no suitable virtual CD or DVD is
- found on the node.
- """
- system = redfish_utils.get_system(task.node)
-
- for manager in system.managers:
- for v_media in manager.virtual_media.get_members():
- if boot_device not in v_media.media_types:
- continue
-
- if v_media.inserted:
- if v_media.image == boot_url:
- LOG.debug("Boot media %(boot_url)s is already "
- "inserted into %(boot_device)s for node "
- "%(node)s", {'node': task.node.uuid,
- 'boot_url': boot_url,
- 'boot_device': boot_device})
- return
-
- continue
-
- v_media.insert_media(boot_url, inserted=True,
- write_protected=True)
-
- LOG.info("Inserted boot media %(boot_url)s into "
- "%(boot_device)s for node "
- "%(node)s", {'node': task.node.uuid,
- 'boot_url': boot_url,
- 'boot_device': boot_device})
- return
-
- raise exception.InvalidParameterValue(
- _('No suitable virtual media device found'))
-
- @staticmethod
- def _eject_vmedia(task, boot_device=None):
- """Eject virtual CDs and DVDs
-
- :param task: A task from TaskManager.
- :param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
- `VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY` or `None` to
- eject everything (default).
- :raises: InvalidParameterValue, if no suitable virtual CD or DVD is
- found on the node.
- """
- system = redfish_utils.get_system(task.node)
-
- for manager in system.managers:
- for v_media in manager.virtual_media.get_members():
- if boot_device and boot_device not in v_media.media_types:
- continue
-
- inserted = v_media.inserted
-
- if inserted:
- v_media.eject_media()
-
- LOG.info("Boot media is%(already)s ejected from "
- "%(boot_device)s for node %(node)s"
- "", {'node': task.node.uuid,
- 'already': '' if inserted else ' already',
- 'boot_device': v_media.name})
-
- @staticmethod
- def _has_vmedia_device(task, boot_device):
- """Indicate if device exists at any of the managers
-
- :param task: A task from TaskManager.
- :param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
- `VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY`.
- """
- system = redfish_utils.get_system(task.node)
+ _eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
- for manager in system.managers:
- for v_media in manager.virtual_media.get_members():
- if boot_device in v_media.media_types:
- return True
+ _cleanup_iso_image(task)
@classmethod
def _set_boot_device(cls, task, device, persistent=False):
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_boot.py b/ironic/tests/unit/drivers/modules/redfish/test_boot.py
index c1d86486a..5558996ca 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_boot.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_boot.py
@@ -67,7 +67,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
'bootloader': 'bootloader'}
)
- actual_driver_info = task.driver.boot._parse_driver_info(task.node)
+ actual_driver_info = redfish_boot._parse_driver_info(task.node)
self.assertIn('kernel', actual_driver_info['deploy_kernel'])
self.assertIn('ramdisk', actual_driver_info['deploy_ramdisk'])
@@ -83,7 +83,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
'bootloader': 'bootloader'}
)
- actual_driver_info = task.driver.boot._parse_driver_info(task.node)
+ actual_driver_info = redfish_boot._parse_driver_info(task.node)
self.assertIn('kernel', actual_driver_info['rescue_kernel'])
self.assertIn('ramdisk', actual_driver_info['rescue_ramdisk'])
@@ -93,7 +93,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
self.assertRaises(exception.MissingParameterValue,
- task.driver.boot._parse_driver_info,
+ redfish_boot._parse_driver_info,
task.node)
def _test_parse_driver_info_from_conf(self, mode='deploy'):
@@ -109,7 +109,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
self.config(group='conductor', **expected)
- image_info = task.driver.boot._parse_driver_info(task.node)
+ image_info = redfish_boot._parse_driver_info(task.node)
for key, value in expected.items():
self.assertEqual(value, image_info[key])
@@ -139,7 +139,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
task.node.driver_info.update(ramdisk_config)
self.assertRaises(exception.MissingParameterValue,
- task.driver.boot._parse_driver_info, task.node)
+ redfish_boot._parse_driver_info, task.node)
def test_parse_driver_info_mixed_source_deploy(self):
self._test_parse_driver_info_mixed_source()
@@ -161,8 +161,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
'kernel': 'http://kernel/img',
'ramdisk': 'http://ramdisk/img'})
- actual_instance_info = task.driver.boot._parse_deploy_info(
- task.node)
+ actual_instance_info = redfish_boot._parse_deploy_info(task.node)
self.assertEqual(
'http://boot/iso', actual_instance_info['image_source'])
@@ -175,52 +174,44 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
self.assertRaises(exception.MissingParameterValue,
- task.driver.boot._parse_deploy_info,
+ redfish_boot._parse_deploy_info,
task.node)
def test__append_filename_param_without_qs(self):
- with task_manager.acquire(self.context, self.node.uuid,
- shared=True) as task:
- res = task.driver.boot._append_filename_param(
- 'http://a.b/c', 'b.img')
- expected = 'http://a.b/c?filename=b.img'
- self.assertEqual(expected, res)
+ res = redfish_boot._append_filename_param(
+ 'http://a.b/c', 'b.img')
+ expected = 'http://a.b/c?filename=b.img'
+ self.assertEqual(expected, res)
def test__append_filename_param_with_qs(self):
- with task_manager.acquire(self.context, self.node.uuid,
- shared=True) as task:
- res = task.driver.boot._append_filename_param(
- 'http://a.b/c?d=e&f=g', 'b.img')
- expected = 'http://a.b/c?d=e&f=g&filename=b.img'
- self.assertEqual(expected, res)
+ res = redfish_boot._append_filename_param(
+ 'http://a.b/c?d=e&f=g', 'b.img')
+ expected = 'http://a.b/c?d=e&f=g&filename=b.img'
+ self.assertEqual(expected, res)
def test__append_filename_param_with_filename(self):
- with task_manager.acquire(self.context, self.node.uuid,
- shared=True) as task:
- res = task.driver.boot._append_filename_param(
- 'http://a.b/c?filename=bootme.img', 'b.img')
- expected = 'http://a.b/c?filename=bootme.img'
- self.assertEqual(expected, res)
+ res = redfish_boot._append_filename_param(
+ 'http://a.b/c?filename=bootme.img', 'b.img')
+ expected = 'http://a.b/c?filename=bootme.img'
+ self.assertEqual(expected, res)
@mock.patch.object(redfish_boot, 'swift', autospec=True)
def test__publish_image_swift(self, mock_swift):
- with task_manager.acquire(self.context, self.node.uuid,
- shared=True) as task:
- mock_swift_api = mock_swift.SwiftAPI.return_value
- mock_swift_api.get_temp_url.return_value = 'https://a.b/c.f?e=f'
+ mock_swift_api = mock_swift.SwiftAPI.return_value
+ mock_swift_api.get_temp_url.return_value = 'https://a.b/c.f?e=f'
- url = task.driver.boot._publish_image('file.iso', 'boot.iso')
+ url = redfish_boot._publish_image('file.iso', 'boot.iso')
- self.assertEqual(
- 'https://a.b/c.f?e=f&filename=file.iso', url)
+ self.assertEqual(
+ 'https://a.b/c.f?e=f&filename=file.iso', url)
- mock_swift.SwiftAPI.assert_called_once_with()
+ mock_swift.SwiftAPI.assert_called_once_with()
- mock_swift_api.create_object.assert_called_once_with(
- mock.ANY, mock.ANY, mock.ANY, mock.ANY)
+ mock_swift_api.create_object.assert_called_once_with(
+ mock.ANY, mock.ANY, mock.ANY, mock.ANY)
- mock_swift_api.get_temp_url.assert_called_once_with(
- mock.ANY, mock.ANY, mock.ANY)
+ mock_swift_api.get_temp_url.assert_called_once_with(
+ mock.ANY, mock.ANY, mock.ANY)
@mock.patch.object(redfish_boot, 'swift', autospec=True)
def test__unpublish_image_swift(self, mock_swift):
@@ -228,7 +219,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
shared=True) as task:
object_name = 'image-%s' % task.node.uuid
- task.driver.boot._unpublish_image(object_name)
+ redfish_boot._unpublish_image(object_name)
mock_swift.SwiftAPI.assert_called_once_with()
mock_swift_api = mock_swift.SwiftAPI.return_value
@@ -244,17 +235,14 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
self.config(use_swift=False, group='redfish')
self.config(http_url='http://localhost', group='deploy')
- with task_manager.acquire(self.context, self.node.uuid,
- shared=True) as task:
-
- url = task.driver.boot._publish_image('file.iso', 'boot.iso')
+ url = redfish_boot._publish_image('file.iso', 'boot.iso')
- self.assertEqual(
- 'http://localhost/redfish/boot.iso?filename=file.iso', url)
+ self.assertEqual(
+ 'http://localhost/redfish/boot.iso?filename=file.iso', url)
- mock_mkdir.assert_called_once_with('/httpboot/redfish', 0x755)
- mock_link.assert_called_once_with(
- 'file.iso', '/httpboot/redfish/boot.iso')
+ mock_mkdir.assert_called_once_with('/httpboot/redfish', 0x755)
+ mock_link.assert_called_once_with(
+ 'file.iso', '/httpboot/redfish/boot.iso')
@mock.patch.object(redfish_boot, 'shutil', autospec=True)
@mock.patch.object(os, 'link', autospec=True)
@@ -266,18 +254,15 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock_link.side_effect = OSError()
- with task_manager.acquire(self.context, self.node.uuid,
- shared=True) as task:
-
- url = task.driver.boot._publish_image('file.iso', 'boot.iso')
+ url = redfish_boot._publish_image('file.iso', 'boot.iso')
- self.assertEqual(
- 'http://localhost/redfish/boot.iso?filename=file.iso', url)
+ self.assertEqual(
+ 'http://localhost/redfish/boot.iso?filename=file.iso', url)
- mock_mkdir.assert_called_once_with('/httpboot/redfish', 0x755)
+ mock_mkdir.assert_called_once_with('/httpboot/redfish', 0x755)
- mock_shutil.copyfile.assert_called_once_with(
- 'file.iso', '/httpboot/redfish/boot.iso')
+ mock_shutil.copyfile.assert_called_once_with(
+ 'file.iso', '/httpboot/redfish/boot.iso')
@mock.patch.object(redfish_boot, 'ironic_utils', autospec=True)
def test__unpublish_image_local(self, mock_ironic_utils):
@@ -289,24 +274,22 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
expected_file = '/httpboot/redfish/' + object_name
- task.driver.boot._unpublish_image(object_name)
+ redfish_boot._unpublish_image(object_name)
mock_ironic_utils.unlink_without_raise.assert_called_once_with(
expected_file)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_unpublish_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_unpublish_image', autospec=True)
def test__cleanup_floppy_image(self, mock_unpublish):
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
- task.driver.boot._cleanup_floppy_image(task)
+ redfish_boot._cleanup_floppy_image(task)
object_name = 'image-%s' % task.node.uuid
mock_unpublish.assert_called_once_with(object_name)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_publish_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_publish_image', autospec=True)
@mock.patch.object(images, 'create_vfat_image', autospec=True)
def test__prepare_floppy_image(
self, mock_create_vfat_image, mock__publish_image):
@@ -316,7 +299,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock__publish_image.return_value = expected_url
- url = task.driver.boot._prepare_floppy_image(task)
+ url = redfish_boot._prepare_floppy_image(task)
object_name = 'image-%s' % task.node.uuid
@@ -328,19 +311,17 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
self.assertEqual(expected_url, url)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_unpublish_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_unpublish_image', autospec=True)
def test__cleanup_iso_image(self, mock_unpublish):
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
- task.driver.boot._cleanup_iso_image(task)
+ redfish_boot._cleanup_iso_image(task)
object_name = 'boot-%s' % task.node.uuid
mock_unpublish.assert_called_once_with(object_name)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_publish_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_publish_image', autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_uefi(
self, mock_create_boot_iso, mock__publish_image):
@@ -352,7 +333,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock__publish_image.return_value = expected_url
- url = task.driver.boot._prepare_iso_image(
+ url = redfish_boot._prepare_iso_image(
task, 'http://kernel/img', 'http://ramdisk/img',
'http://bootloader/img', root_uuid=task.node.uuid)
@@ -370,8 +351,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
self.assertEqual(expected_url, url)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_publish_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_publish_image', autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_bios(
self, mock_create_boot_iso, mock__publish_image):
@@ -382,7 +362,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock__publish_image.return_value = expected_url
- url = task.driver.boot._prepare_iso_image(
+ url = redfish_boot._prepare_iso_image(
task, 'http://kernel/img', 'http://ramdisk/img',
bootloader_href=None, root_uuid=task.node.uuid)
@@ -400,8 +380,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
self.assertEqual(expected_url, url)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_publish_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_publish_image', autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_kernel_params(
self, mock_create_boot_iso, mock__publish_image):
@@ -411,7 +390,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
task.node.instance_info.update(kernel_append_params=kernel_params)
- task.driver.boot._prepare_iso_image(
+ redfish_boot._prepare_iso_image(
task, 'http://kernel/img', 'http://ramdisk/img',
bootloader_href=None, root_uuid=task.node.uuid)
@@ -422,8 +401,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
kernel_params=kernel_params,
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123')
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_prepare_iso_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_prepare_iso_image', autospec=True)
def test__prepare_deploy_iso(self, mock__prepare_iso_image):
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
@@ -436,13 +414,12 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
task.node.instance_info.update(deploy_boot_mode='uefi')
- task.driver.boot._prepare_deploy_iso(task, {}, 'deploy')
+ redfish_boot._prepare_deploy_iso(task, {}, 'deploy')
mock__prepare_iso_image.assert_called_once_with(
mock.ANY, 'kernel', 'ramdisk', 'bootloader', params={})
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_prepare_iso_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_prepare_iso_image', autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_boot_iso(self, mock_create_boot_iso,
mock__prepare_iso_image):
@@ -459,7 +436,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
'kernel': 'http://kernel/img',
'ramdisk': 'http://ramdisk/img'})
- task.driver.boot._prepare_boot_iso(
+ redfish_boot._prepare_boot_iso(
task, root_uuid=task.node.uuid)
mock__prepare_iso_image.assert_called_once_with(
@@ -557,14 +534,10 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
@mock.patch.object(redfish_boot.manager_utils, 'node_set_boot_device',
autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_prepare_deploy_iso', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_eject_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_insert_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_parse_driver_info', autospec=True)
+ @mock.patch.object(redfish_boot, '_prepare_deploy_iso', autospec=True)
+ @mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
@mock.patch.object(redfish_boot.manager_utils, 'node_power_action',
autospec=True)
@mock.patch.object(redfish_boot, 'boot_mode_utils', autospec=True)
@@ -607,14 +580,10 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
@mock.patch.object(redfish_boot.manager_utils, 'node_set_boot_device',
autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_prepare_deploy_iso', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_eject_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_insert_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_parse_driver_info', autospec=True)
+ @mock.patch.object(redfish_boot, '_prepare_deploy_iso', autospec=True)
+ @mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
@mock.patch.object(redfish_boot.manager_utils, 'node_power_action',
autospec=True)
@mock.patch.object(redfish_boot, 'boot_mode_utils', autospec=True)
@@ -656,18 +625,12 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
@mock.patch.object(redfish_boot.manager_utils, 'node_set_boot_device',
autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_prepare_floppy_image', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_prepare_deploy_iso', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_has_vmedia_device', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_eject_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_insert_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_parse_driver_info', autospec=True)
+ @mock.patch.object(redfish_boot, '_prepare_floppy_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_prepare_deploy_iso', autospec=True)
+ @mock.patch.object(redfish_boot, '_has_vmedia_device', autospec=True)
+ @mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
@mock.patch.object(redfish_boot.manager_utils, 'node_power_action',
autospec=True)
@mock.patch.object(redfish_boot, 'boot_mode_utils', autospec=True)
@@ -728,16 +691,11 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock_boot_mode_utils.sync_boot_mode.assert_called_once_with(task)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_has_vmedia_device', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_eject_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_cleanup_iso_image', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_cleanup_floppy_image', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_parse_driver_info', autospec=True)
+ @mock.patch.object(redfish_boot, '_has_vmedia_device', autospec=True)
+ @mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_cleanup_iso_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_cleanup_floppy_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
def test_clean_up_ramdisk(
self, mock__parse_driver_info, mock__cleanup_floppy_image,
mock__cleanup_iso_image, mock__eject_vmedia,
@@ -768,14 +726,10 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
@mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
'clean_up_instance', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_prepare_boot_iso', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_eject_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_insert_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_parse_driver_info', autospec=True)
+ @mock.patch.object(redfish_boot, '_prepare_boot_iso', autospec=True)
+ @mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
@mock.patch.object(redfish_boot, 'manager_utils', autospec=True)
@mock.patch.object(redfish_boot, 'deploy_utils', autospec=True)
@mock.patch.object(redfish_boot, 'boot_mode_utils', autospec=True)
@@ -817,14 +771,10 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
@mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
'clean_up_instance', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_prepare_boot_iso', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_eject_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_insert_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_parse_driver_info', autospec=True)
+ @mock.patch.object(redfish_boot, '_prepare_boot_iso', autospec=True)
+ @mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
@mock.patch.object(redfish_boot, 'manager_utils', autospec=True)
@mock.patch.object(redfish_boot, 'deploy_utils', autospec=True)
@mock.patch.object(redfish_boot, 'boot_mode_utils', autospec=True)
@@ -858,10 +808,8 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock_boot_mode_utils.sync_boot_mode.assert_called_once_with(task)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_eject_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_cleanup_iso_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_cleanup_iso_image', autospec=True)
@mock.patch.object(redfish_boot, 'manager_utils', autospec=True)
def _test_prepare_instance_local_boot(
self, mock_manager_utils,
@@ -893,10 +841,8 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
self.node.save()
self._test_prepare_instance_local_boot()
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_eject_vmedia', autospec=True)
- @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
- '_cleanup_iso_image', autospec=True)
+ @mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
+ @mock.patch.object(redfish_boot, '_cleanup_iso_image', autospec=True)
def _test_clean_up_instance(self, mock__cleanup_iso_image,
mock__eject_vmedia):
@@ -942,7 +888,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock_redfish_utils.get_system.return_value.managers = [
mock_manager]
- task.driver.boot._insert_vmedia(
+ redfish_boot._insert_vmedia(
task, 'img-url', sushy.VIRTUAL_MEDIA_CD)
mock_vmedia_cd.insert_media.assert_called_once_with(
@@ -967,7 +913,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock_redfish_utils.get_system.return_value.managers = [
mock_manager]
- task.driver.boot._insert_vmedia(
+ redfish_boot._insert_vmedia(
task, 'img-url', sushy.VIRTUAL_MEDIA_CD)
self.assertFalse(mock_vmedia_cd.insert_media.call_count)
@@ -990,7 +936,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
self.assertRaises(
exception.InvalidParameterValue,
- task.driver.boot._insert_vmedia,
+ redfish_boot._insert_vmedia,
task, 'img-url', sushy.VIRTUAL_MEDIA_CD)
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
@@ -1013,7 +959,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock_redfish_utils.get_system.return_value.managers = [
mock_manager]
- task.driver.boot._eject_vmedia(task)
+ redfish_boot._eject_vmedia(task)
mock_vmedia_cd.eject_media.assert_called_once_with()
mock_vmedia_floppy.eject_media.assert_called_once_with()
@@ -1038,7 +984,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock_redfish_utils.get_system.return_value.managers = [
mock_manager]
- task.driver.boot._eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
+ redfish_boot._eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
mock_vmedia_cd.eject_media.assert_called_once_with()
self.assertFalse(mock_vmedia_floppy.eject_media.call_count)
@@ -1063,7 +1009,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock_redfish_utils.get_system.return_value.managers = [
mock_manager]
- task.driver.boot._eject_vmedia(task)
+ redfish_boot._eject_vmedia(task)
self.assertFalse(mock_vmedia_cd.eject_media.call_count)
self.assertFalse(mock_vmedia_floppy.eject_media.call_count)
@@ -1085,6 +1031,6 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
mock_redfish_utils.get_system.return_value.managers = [
mock_manager]
- task.driver.boot._eject_vmedia(task)
+ redfish_boot._eject_vmedia(task)
self.assertFalse(mock_vmedia_cd.eject_media.call_count)