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
This commit is contained in:
parent
2afbd77c12
commit
2ffbfb4b46
|
@ -83,56 +83,11 @@ KERNEL_RAMDISK_LABELS = {
|
|||
'rescue': RESCUE_PROPERTIES
|
||||
}
|
||||
|
||||
IMAGE_SUBDIR = 'redfish'
|
||||
|
||||
sushy = importutils.try_import('sushy')
|
||||
|
||||
|
||||
class RedfishVirtualMediaBoot(base.BootInterface):
|
||||
"""Virtual media boot interface over Redfish.
|
||||
|
||||
Virtual Media allows booting the system from the "virtual"
|
||||
CD/DVD drive containing the user image that BMC "inserts"
|
||||
into the drive.
|
||||
|
||||
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.
|
||||
|
||||
The baseline boot workflow looks like this:
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
IMAGE_SUBDIR = 'redfish'
|
||||
|
||||
capabilities = ['iscsi_volume_boot', 'ramdisk_boot']
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the Redfish virtual media boot interface.
|
||||
|
||||
: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'))
|
||||
|
||||
@staticmethod
|
||||
def _parse_driver_info(node):
|
||||
"""Gets the driver specific Node deployment info.
|
||||
|
||||
|
@ -175,7 +130,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
|
||||
return deploy_info
|
||||
|
||||
@staticmethod
|
||||
|
||||
def _parse_instance_info(node):
|
||||
"""Gets the instance specific Node deployment info.
|
||||
|
||||
|
@ -193,29 +148,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
# NOTE(etingof): this method is currently no-op, here for completeness
|
||||
return deploy_info
|
||||
|
||||
@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
|
||||
|
||||
@staticmethod
|
||||
def _append_filename_param(url, filename):
|
||||
"""Append 'filename=<file>' parameter to given URL.
|
||||
|
||||
|
@ -245,63 +178,120 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
|
||||
return urlparse.urlunparse(parsed_url)
|
||||
|
||||
@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 _get_floppy_image_name(node):
|
||||
"""Returns the floppy image name for a given node.
|
||||
|
||||
:param image_file: path to file to publish
|
||||
:param object_name: name of the published file
|
||||
:return: a URL to download published file
|
||||
:param node: the node for which image name is to be provided.
|
||||
"""
|
||||
return "image-%s" % node.uuid
|
||||
|
||||
if CONF.redfish.use_swift:
|
||||
container = CONF.redfish.swift_container
|
||||
timeout = CONF.redfish.swift_object_expiry_timeout
|
||||
|
||||
object_headers = {'X-Delete-After': str(timeout)}
|
||||
def _get_iso_image_name(node):
|
||||
"""Returns the boot iso image name for a given node.
|
||||
|
||||
swift_api = swift.SwiftAPI()
|
||||
:param node: the node for which image name is to be provided.
|
||||
"""
|
||||
return "boot-%s" % node.uuid
|
||||
|
||||
swift_api.create_object(container, object_name, image_file,
|
||||
object_headers=object_headers)
|
||||
|
||||
image_url = swift_api.get_temp_url(container, object_name, timeout)
|
||||
def _insert_vmedia(task, boot_url, boot_device):
|
||||
"""Insert bootable ISO image into virtual CD or DVD
|
||||
|
||||
else:
|
||||
public_dir = os.path.join(CONF.deploy.http_root, cls.IMAGE_SUBDIR)
|
||||
: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)
|
||||
|
||||
if not os.path.exists(public_dir):
|
||||
os.mkdir(public_dir, 0x755)
|
||||
for manager in system.managers:
|
||||
for v_media in manager.virtual_media.get_members():
|
||||
if boot_device not in v_media.media_types:
|
||||
continue
|
||||
|
||||
published_file = os.path.join(public_dir, object_name)
|
||||
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
|
||||
|
||||
try:
|
||||
os.link(image_file, published_file)
|
||||
continue
|
||||
|
||||
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})
|
||||
v_media.insert_media(boot_url, inserted=True,
|
||||
write_protected=True)
|
||||
|
||||
shutil.copyfile(image_file, published_file)
|
||||
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
|
||||
|
||||
image_url = os.path.join(
|
||||
CONF.deploy.http_url, cls.IMAGE_SUBDIR, object_name)
|
||||
raise exception.InvalidParameterValue(
|
||||
_('No suitable virtual media device found'))
|
||||
|
||||
image_url = cls._append_filename_param(
|
||||
image_url, os.path.basename(image_file))
|
||||
|
||||
return image_url
|
||||
def _eject_vmedia(task, boot_device=None):
|
||||
"""Eject virtual CDs and DVDs
|
||||
|
||||
@classmethod
|
||||
def _unpublish_image(cls, object_name):
|
||||
: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})
|
||||
|
||||
|
||||
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)
|
||||
|
||||
for manager in system.managers:
|
||||
for v_media in manager.virtual_media.get_members():
|
||||
if boot_device in v_media.media_types:
|
||||
return True
|
||||
|
||||
|
||||
def _cleanup_iso_image(task):
|
||||
"""Deletes the ISO if it was created for the instance.
|
||||
|
||||
:param task: A task from TaskManager.
|
||||
"""
|
||||
iso_object_name = _get_iso_image_name(task.node)
|
||||
|
||||
_unpublish_image(iso_object_name)
|
||||
|
||||
|
||||
def _unpublish_image(object_name):
|
||||
"""Withdraw the image previously made downloadable.
|
||||
|
||||
Depending on ironic settings, removes previously published file
|
||||
|
@ -329,30 +319,12 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
|
||||
else:
|
||||
published_file = os.path.join(
|
||||
CONF.deploy.http_root, cls.IMAGE_SUBDIR, object_name)
|
||||
CONF.deploy.http_root, IMAGE_SUBDIR, object_name)
|
||||
|
||||
ironic_utils.unlink_without_raise(published_file)
|
||||
|
||||
@staticmethod
|
||||
def _get_floppy_image_name(node):
|
||||
"""Returns the floppy image name for a given node.
|
||||
|
||||
:param node: the node for which image name is to be provided.
|
||||
"""
|
||||
return "image-%s" % node.uuid
|
||||
|
||||
@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)
|
||||
|
||||
cls._unpublish_image(floppy_object_name)
|
||||
|
||||
@classmethod
|
||||
def _prepare_floppy_image(cls, task, params=None):
|
||||
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
|
||||
|
@ -371,7 +343,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
: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_name = _get_floppy_image_name(task.node)
|
||||
|
||||
LOG.debug("Trying to create floppy image for node "
|
||||
"%(node)s", {'node': task.node.uuid})
|
||||
|
@ -382,7 +354,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
vfat_image_tmpfile = vfat_image_tmpfile_obj.name
|
||||
images.create_vfat_image(vfat_image_tmpfile, parameters=params)
|
||||
|
||||
image_url = cls._publish_image(vfat_image_tmpfile, object_name)
|
||||
image_url = _publish_image(vfat_image_tmpfile, object_name)
|
||||
|
||||
LOG.debug("Created floppy image %(name)s in Swift for node %(node)s, "
|
||||
"exposed as temporary URL "
|
||||
|
@ -392,26 +364,95 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
|
||||
return image_url
|
||||
|
||||
@staticmethod
|
||||
def _get_iso_image_name(node):
|
||||
"""Returns the boot iso image name for a given node.
|
||||
|
||||
:param node: the node for which image name is to be provided.
|
||||
def _publish_image(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.
|
||||
|
||||
:param image_file: path to file to publish
|
||||
:param object_name: name of the published file
|
||||
:return: a URL to download published file
|
||||
"""
|
||||
return "boot-%s" % node.uuid
|
||||
|
||||
@classmethod
|
||||
def _cleanup_iso_image(cls, task):
|
||||
"""Deletes the ISO if it was created for the instance.
|
||||
if CONF.redfish.use_swift:
|
||||
container = CONF.redfish.swift_container
|
||||
timeout = CONF.redfish.swift_object_expiry_timeout
|
||||
|
||||
object_headers = {'X-Delete-After': str(timeout)}
|
||||
|
||||
swift_api = swift.SwiftAPI()
|
||||
|
||||
swift_api.create_object(container, object_name, image_file,
|
||||
object_headers=object_headers)
|
||||
|
||||
image_url = swift_api.get_temp_url(container, object_name, timeout)
|
||||
|
||||
else:
|
||||
public_dir = os.path.join(CONF.deploy.http_root, IMAGE_SUBDIR)
|
||||
|
||||
if not os.path.exists(public_dir):
|
||||
os.mkdir(public_dir, 0x755)
|
||||
|
||||
published_file = os.path.join(public_dir, object_name)
|
||||
|
||||
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})
|
||||
|
||||
shutil.copyfile(image_file, published_file)
|
||||
|
||||
image_url = os.path.join(
|
||||
CONF.deploy.http_url, IMAGE_SUBDIR, object_name)
|
||||
|
||||
image_url = _append_filename_param(
|
||||
image_url, os.path.basename(image_file))
|
||||
|
||||
return image_url
|
||||
|
||||
|
||||
def _cleanup_floppy_image(task):
|
||||
"""Deletes the floppy image if it was created for the node.
|
||||
|
||||
:param task: an ironic node object.
|
||||
"""
|
||||
iso_object_name = cls._get_iso_image_name(task.node)
|
||||
floppy_object_name = _get_floppy_image_name(task.node)
|
||||
|
||||
cls._unpublish_image(iso_object_name)
|
||||
_unpublish_image(floppy_object_name)
|
||||
|
||||
@classmethod
|
||||
def _prepare_iso_image(cls, task, kernel_href, ramdisk_href,
|
||||
|
||||
def _parse_deploy_info(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(_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.
|
||||
|
@ -504,9 +545,9 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
kernel_params=kernel_params,
|
||||
boot_mode=boot_mode)
|
||||
|
||||
iso_object_name = cls._get_iso_image_name(task.node)
|
||||
iso_object_name = _get_iso_image_name(task.node)
|
||||
|
||||
image_url = cls._publish_image(
|
||||
image_url = _publish_image(
|
||||
boot_iso_tmp_file, iso_object_name)
|
||||
|
||||
LOG.debug("Created ISO %(name)s in object store for node %(node)s, "
|
||||
|
@ -517,8 +558,8 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
|
||||
return image_url
|
||||
|
||||
@classmethod
|
||||
def _prepare_deploy_iso(cls, task, params, mode):
|
||||
|
||||
def _prepare_deploy_iso(task, params, mode):
|
||||
"""Prepare deploy or rescue ISO image
|
||||
|
||||
Build bootable ISO out of
|
||||
|
@ -540,17 +581,17 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
"""
|
||||
node = task.node
|
||||
|
||||
d_info = cls._parse_driver_info(node)
|
||||
d_info = _parse_driver_info(node)
|
||||
|
||||
kernel_href = d_info.get('%s_kernel' % mode)
|
||||
ramdisk_href = d_info.get('%s_ramdisk' % mode)
|
||||
bootloader_href = d_info.get('bootloader')
|
||||
|
||||
return cls._prepare_iso_image(
|
||||
return _prepare_iso_image(
|
||||
task, kernel_href, ramdisk_href, bootloader_href, params=params)
|
||||
|
||||
@classmethod
|
||||
def _prepare_boot_iso(cls, task, root_uuid=None):
|
||||
|
||||
def _prepare_boot_iso(task, root_uuid=None):
|
||||
"""Prepare boot ISO image
|
||||
|
||||
Build bootable ISO out of `[instance_info]/kernel`,
|
||||
|
@ -571,7 +612,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
"""
|
||||
node = task.node
|
||||
|
||||
d_info = cls._parse_deploy_info(node)
|
||||
d_info = _parse_deploy_info(node)
|
||||
|
||||
kernel_href = node.instance_info.get('kernel')
|
||||
ramdisk_href = node.instance_info.get('ramdisk')
|
||||
|
@ -598,10 +639,55 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||
|
||||
bootloader_href = d_info.get('bootloader')
|
||||
|
||||
return cls._prepare_iso_image(
|
||||
return _prepare_iso_image(
|
||||
task, kernel_href, ramdisk_href, bootloader_href,
|
||||
root_uuid=root_uuid)
|
||||
|
||||
|
||||
class RedfishVirtualMediaBoot(base.BootInterface):
|
||||
"""Virtual media boot interface over Redfish.
|
||||
|
||||
Virtual Media allows booting the system from the "virtual"
|
||||
CD/DVD drive containing the user image that BMC "inserts"
|
||||
into the drive.
|
||||
|
||||
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.
|
||||
|
||||
The baseline boot workflow looks like this:
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
capabilities = ['iscsi_volume_boot', 'ramdisk_boot']
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the Redfish virtual media boot interface.
|
||||
|
||||
: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)
|
||||
_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)
|
||||
|
||||
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):
|
||||
|
|
|
@ -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,41 +174,33 @@ 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(
|
||||
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(
|
||||
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(
|
||||
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'
|
||||
|
||||
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)
|
||||
|
@ -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,10 +235,7 @@ 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)
|
||||
|
@ -266,10 +254,7 @@ 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)
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue