summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2022-08-08 20:32:13 +0000
committerGerrit Code Review <review@openstack.org>2022-08-08 20:32:13 +0000
commitb746d330539eb7d35cbc2711eaa2ffb1dced7f48 (patch)
tree5ab0084e480e176ad1c6cf1c821dfbc8be03f057
parentb34d79e3f440c408520f24a2263dc587ac205ee2 (diff)
parent7b47e09a385d388854a3c81bc13c333b36c18a36 (diff)
downloadironic-b746d330539eb7d35cbc2711eaa2ffb1dced7f48.tar.gz
Merge "Fix pxe image lookups"
-rw-r--r--ironic/common/pxe_utils.py17
-rw-r--r--ironic/tests/unit/common/test_pxe_utils.py60
-rw-r--r--releasenotes/notes/fix-pxe-glance-lookup-anaconda-86fe616c6286ec08.yaml6
3 files changed, 77 insertions, 6 deletions
diff --git a/ironic/common/pxe_utils.py b/ironic/common/pxe_utils.py
index 88c55d6d7..40ad98217 100644
--- a/ironic/common/pxe_utils.py
+++ b/ironic/common/pxe_utils.py
@@ -681,8 +681,10 @@ def get_instance_image_info(task, ipxe_enabled=False):
def _get_image_properties():
nonlocal image_properties
if not image_properties:
- glance_service = service.GlanceImageService(context=ctx)
- image_properties = glance_service.show(
+ i_service = service.get_image_service(
+ d_info['image_source'],
+ context=ctx)
+ image_properties = i_service.show(
d_info['image_source'])['properties']
labels = ('kernel', 'ramdisk')
@@ -691,10 +693,13 @@ def get_instance_image_info(task, ipxe_enabled=False):
# we won't use any of them. We'll use the values specified
# with the image, which we assume have been set.
_get_image_properties()
- for label in labels:
- i_info[label] = str(image_properties[label + '_id'])
- node.instance_info = i_info
- node.save()
+ if image_properties:
+ # This is intended for Glance usage, but all image properties
+ # should be routed through the image service request routing.
+ for label in labels:
+ i_info[label] = str(image_properties[label + '_id'])
+ node.instance_info = i_info
+ node.save()
anaconda_labels = ()
if deploy_utils.get_boot_option(node) == 'kickstart':
diff --git a/ironic/tests/unit/common/test_pxe_utils.py b/ironic/tests/unit/common/test_pxe_utils.py
index 251b7e6f8..037ad7449 100644
--- a/ironic/tests/unit/common/test_pxe_utils.py
+++ b/ironic/tests/unit/common/test_pxe_utils.py
@@ -27,6 +27,7 @@ from oslo_utils import uuidutils
from ironic.common import exception
from ironic.common.glance_service import image_service
+from ironic.common import image_service as base_image_service
from ironic.common import pxe_utils
from ironic.common import states
from ironic.common import utils
@@ -1446,6 +1447,65 @@ class PXEInterfacesTestCase(db_base.DbTestCase):
@mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option',
return_value='kickstart', autospec=True)
+ @mock.patch.object(base_image_service.HttpImageService, 'show',
+ autospec=True)
+ def test_get_instance_image_info_with_kickstart_url_http(
+ self, image_show_mock, boot_opt_mock):
+ properties = {'properties': {}}
+ expected_info = {'ramdisk':
+ ('http://fake.url/ramdisk',
+ os.path.join(CONF.pxe.tftp_root,
+ self.node.uuid,
+ 'ramdisk')),
+ 'kernel':
+ ('http://fake.url/kernel',
+ os.path.join(CONF.pxe.tftp_root,
+ self.node.uuid,
+ 'kernel')),
+ 'ks_template':
+ (CONF.anaconda.default_ks_template,
+ os.path.join(CONF.deploy.http_root,
+ self.node.uuid,
+ 'ks.cfg.template')),
+ 'ks_cfg':
+ ('',
+ os.path.join(CONF.deploy.http_root,
+ self.node.uuid,
+ 'ks.cfg'))}
+ image_show_mock.return_value = properties
+ self.context.auth_token = 'fake'
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ dii = task.node.driver_internal_info
+ dii['is_source_a_path'] = True
+ task.node.driver_internal_info = dii
+ i_info = task.node.instance_info
+ i_info['image_source'] = 'http://fake.url/path'
+ i_info['kernel'] = 'http://fake.url/kernel'
+ i_info['ramdisk'] = 'http://fake.url/ramdisk'
+ task.node.instance_info = i_info
+ task.node.save()
+ image_info = pxe_utils.get_instance_image_info(
+ task, ipxe_enabled=False)
+ self.assertEqual(expected_info, image_info)
+ # In the absense of kickstart template in both instance_info and
+ # image default kickstart template is used
+ self.assertEqual(CONF.anaconda.default_ks_template,
+ image_info['ks_template'][0])
+ calls = [mock.call(task.node), mock.call(task.node)]
+ boot_opt_mock.assert_has_calls(calls)
+ # Instance info gets presedence over kickstart template on the
+ # image
+ properties['properties'] = {'ks_template': 'glance://template_id'}
+ task.node.instance_info['ks_template'] = 'https://server/fake.tmpl'
+ image_show_mock.return_value = properties
+ image_info = pxe_utils.get_instance_image_info(
+ task, ipxe_enabled=False)
+ self.assertEqual('https://server/fake.tmpl',
+ image_info['ks_template'][0])
+
+ @mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option',
+ return_value='kickstart', autospec=True)
@mock.patch.object(image_service.GlanceImageService, 'show', autospec=True)
def test_get_instance_image_info_kickstart_stage2_missing(
self, image_show_mock, boot_opt_mock):
diff --git a/releasenotes/notes/fix-pxe-glance-lookup-anaconda-86fe616c6286ec08.yaml b/releasenotes/notes/fix-pxe-glance-lookup-anaconda-86fe616c6286ec08.yaml
new file mode 100644
index 000000000..bf6b8ea85
--- /dev/null
+++ b/releasenotes/notes/fix-pxe-glance-lookup-anaconda-86fe616c6286ec08.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ Fixes an issue in the ``anaconda`` deployment interface where PXE argument
+ processing and preparation was erroniously directly connecting to Glance,
+ potentially leading to an exception in the standalone use case.