summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulia Kreger <juliaashleykreger@gmail.com>2022-08-04 10:10:00 -0700
committerJulia Kreger <juliaashleykreger@gmail.com>2022-08-04 10:42:01 -0700
commit7b47e09a385d388854a3c81bc13c333b36c18a36 (patch)
tree776b6eb3af263a37b4dcd1670dc01108898d8015
parent86638d1dfdfe770ac4317ae3546cc7816f7f5cf1 (diff)
downloadironic-7b47e09a385d388854a3c81bc13c333b36c18a36.tar.gz
Fix pxe image lookups
Image lookups in the PXE interface, for anaconda specific code, were previously hard coded to try and invoke use of glance if needed. Except, not everything is glance. Change-Id: I8791623be95e7e47739ee051753de97eb0e5e2a3
-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 c6dc9bffa..3ef606277 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
@@ -1465,6 +1466,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.