From 8cb6057450182d2d24cafcb27c2518094441fd3f Mon Sep 17 00:00:00 2001 From: Dmitry Tantsur Date: Tue, 6 Jul 2021 17:40:50 +0200 Subject: [PATCH] Support "swift" for ramdisk_image_download_source The ilo-virtual-media boot interface supports exposing Glance images via a temporary URL. This change brings this support to Redfish and others. Change-Id: Ie72bb5e62c29efa5eea1710e74f505329d28d726 --- ironic/conf/deploy.py | 5 +++- ironic/drivers/modules/image_utils.py | 19 ++++++++++----- .../unit/drivers/modules/test_image_utils.py | 24 +++++++++++++++++++ .../deploy-iso-swift-355ad6eba6c511b4.yaml | 7 ++++++ 4 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/deploy-iso-swift-355ad6eba6c511b4.yaml diff --git a/ironic/conf/deploy.py b/ironic/conf/deploy.py index 1e63c9a868..7163db9e2c 100644 --- a/ironic/conf/deploy.py +++ b/ironic/conf/deploy.py @@ -201,7 +201,10 @@ opts = [ ('local', _('This is the default behavior. ' 'The image is downloaded, prepared and ' 'cached locally, to be served from ' - 'the conductor.'))], + 'the conductor.')), + ('swift', _('Same as "http", but if the image ' + 'is a Glance UUID, it is exposed via a ' + 'Swift temporary URL.'))], default='local', mutable=True, help=_('Specifies whether a boot iso image should be served ' diff --git a/ironic/drivers/modules/image_utils.py b/ironic/drivers/modules/image_utils.py index 1d06f057cf..a0092ce22f 100644 --- a/ironic/drivers/modules/image_utils.py +++ b/ironic/drivers/modules/image_utils.py @@ -26,6 +26,7 @@ from ironic_lib import utils as ironic_utils from oslo_log import log from ironic.common import exception +from ironic.common.glance_service import service_utils from ironic.common.i18n import _ from ironic.common import images from ironic.common import swift @@ -435,12 +436,18 @@ def _prepare_iso_image(task, kernel_href, ramdisk_href, # NOTE(rpittau): if base_iso is defined as http address, we just access # it directly. - if base_iso and download_source == 'http': - if base_iso.startswith(('http://', 'https://')): - return base_iso - LOG.debug("ramdisk_image_download_source set to http but " - "boot_iso is not an HTTP URL: %(boot_iso)s", - {"boot_iso": base_iso}) + if base_iso: + if (download_source == 'swift' + and service_utils.is_glance_image(base_iso)): + base_iso = ( + images.get_temp_url_for_glance_image(task.context, base_iso)) + + if download_source != 'local': + if base_iso.startswith(('http://', 'https://')): + return base_iso + LOG.debug("ramdisk_image_download_source set to http but " + "boot_iso is not an HTTP URL: %(boot_iso)s", + {"boot_iso": base_iso}) img_handler = ImageHandler(task.node.driver) diff --git a/ironic/tests/unit/drivers/modules/test_image_utils.py b/ironic/tests/unit/drivers/modules/test_image_utils.py index 21575aab2e..f06b4eb7c0 100644 --- a/ironic/tests/unit/drivers/modules/test_image_utils.py +++ b/ironic/tests/unit/drivers/modules/test_image_utils.py @@ -19,6 +19,7 @@ import tempfile from unittest import mock from oslo_utils import importutils +from oslo_utils import uuidutils from ironic.common import images from ironic.common import utils @@ -642,6 +643,29 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase): kernel_params='nofb nomodeset vga=normal', boot_mode='bios', base_iso='/path/to/baseiso', inject_files=None) + @mock.patch.object(images, 'get_temp_url_for_glance_image', + autospec=True) + def test__prepare_iso_image_bootable_iso_from_swift(self, mock_temp_url): + with task_manager.acquire(self.context, self.node.uuid, + shared=True) as task: + base_image_url = uuidutils.generate_uuid() + self.config(ramdisk_image_download_source='swift', group='deploy') + url = image_utils._prepare_iso_image( + task, None, None, bootloader_href=None, root_uuid=None, + base_iso=base_image_url) + self.assertEqual(mock_temp_url.return_value, url) + mock_temp_url.assert_called_once_with(task.context, base_image_url) + + def test__prepare_iso_image_bootable_iso_swift_noop(self): + with task_manager.acquire(self.context, self.node.uuid, + shared=True) as task: + base_image_url = 'http://bearmetal.net/boot.iso' + self.config(ramdisk_image_download_source='swift', group='deploy') + url = image_utils._prepare_iso_image( + task, None, None, bootloader_href=None, root_uuid=None, + base_iso=base_image_url) + self.assertEqual(url, base_image_url) + def test__find_param(self): param_dict = { 'deploy_kernel': 'kernel', diff --git a/releasenotes/notes/deploy-iso-swift-355ad6eba6c511b4.yaml b/releasenotes/notes/deploy-iso-swift-355ad6eba6c511b4.yaml new file mode 100644 index 0000000000..737e6685da --- /dev/null +++ b/releasenotes/notes/deploy-iso-swift-355ad6eba6c511b4.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + The configuration option ``[deploy]ramdisk_image_download_source`` now + supports a new value ``swift``. If ``boot_iso`` or ``deploy_iso`` is a + Glance image, it will expose it via a Swift temporary URL. For other types + of images the new value works the same way as the existing ``http``.