summaryrefslogtreecommitdiff
path: root/ironic_python_agent
diff options
context:
space:
mode:
authorDmitry Tantsur <dtantsur@protonmail.com>2020-03-30 17:22:28 +0200
committerDmitry Tantsur <dtantsur@protonmail.com>2020-06-02 15:23:54 +0200
commit9d4cf5532ff3cc4725c247aa0e0aca2caa30e640 (patch)
treebf81d338378072f44f7fb99edea00828322efdb6 /ironic_python_agent
parent6c1545b75b157584f04901cdbfa4897fd15042bb (diff)
downloadironic-python-agent-9d4cf5532ff3cc4725c247aa0e0aca2caa30e640.tar.gz
Add a deploy step for writing an image
The new step just invokes the appropriate method of the standby extension. Change-Id: Ic74f83ab2b7e58f8e4b46e0abfab79e221afeb3e Story: 2006963
Diffstat (limited to 'ironic_python_agent')
-rw-r--r--ironic_python_agent/agent.py8
-rw-r--r--ironic_python_agent/extensions/base.py23
-rw-r--r--ironic_python_agent/hardware.py29
-rw-r--r--ironic_python_agent/tests/unit/base.py3
4 files changed, 56 insertions, 7 deletions
diff --git a/ironic_python_agent/agent.py b/ironic_python_agent/agent.py
index 5eb1e28d..b2e2e38e 100644
--- a/ironic_python_agent/agent.py
+++ b/ironic_python_agent/agent.py
@@ -29,7 +29,6 @@ from oslo_concurrency import processutils
from oslo_config import cfg
from oslo_log import log
import pkg_resources
-from stevedore import extension
from ironic_python_agent.api import app
from ironic_python_agent import config
@@ -171,12 +170,7 @@ class IronicPythonAgent(base.ExecuteCommandMixin):
if bool(cfg.CONF.keyfile) != bool(cfg.CONF.certfile):
LOG.warning("Only one of 'keyfile' and 'certfile' options is "
"defined in config file. Its value will be ignored.")
- self.ext_mgr = extension.ExtensionManager(
- namespace='ironic_python_agent.extensions',
- invoke_on_load=True,
- propagate_map_exceptions=True,
- invoke_kwds={'agent': self},
- )
+ self.ext_mgr = base.init_ext_manager(self)
self.api_url = api_url
if not self.api_url or self.api_url == 'mdns':
try:
diff --git a/ironic_python_agent/extensions/base.py b/ironic_python_agent/extensions/base.py
index a4314098..d2ea4337 100644
--- a/ironic_python_agent/extensions/base.py
+++ b/ironic_python_agent/extensions/base.py
@@ -19,6 +19,7 @@ import threading
from oslo_log import log
from oslo_utils import uuidutils
+from stevedore import extension
from ironic_python_agent import encoding
from ironic_python_agent import errors
@@ -331,3 +332,25 @@ def sync_command(command_name, validator=None):
return wrapper
return sync_decorator
+
+
+_EXT_MANAGER = None
+
+
+def init_ext_manager(agent):
+ global _EXT_MANAGER
+ _EXT_MANAGER = extension.ExtensionManager(
+ namespace='ironic_python_agent.extensions',
+ invoke_on_load=True,
+ propagate_map_exceptions=True,
+ invoke_kwds={'agent': agent},
+ )
+ return _EXT_MANAGER
+
+
+def get_extension(name):
+ if _EXT_MANAGER is None:
+ raise errors.ExtensionError('Extension manager is not initialized')
+ ext = _EXT_MANAGER[name].obj
+ ext.ext_mgr = _EXT_MANAGER
+ return ext
diff --git a/ironic_python_agent/hardware.py b/ironic_python_agent/hardware.py
index ea54300a..cdb268de 100644
--- a/ironic_python_agent/hardware.py
+++ b/ironic_python_agent/hardware.py
@@ -37,6 +37,7 @@ import yaml
from ironic_python_agent import encoding
from ironic_python_agent import errors
+from ironic_python_agent.extensions import base as ext_base
from ironic_python_agent import netutils
from ironic_python_agent import raid_utils
from ironic_python_agent import utils
@@ -1566,6 +1567,15 @@ class GenericHardwareManager(HardwareManager):
'reboot_requested': False,
'argsinfo': RAID_APPLY_CONFIGURATION_ARGSINFO,
},
+ {
+ 'step': 'write_image',
+ # NOTE(dtantsur): this step has to be proxied via an
+ # out-of-band step with the same name, hence the priority here
+ # doesn't really matter.
+ 'priority': 0,
+ 'interface': 'deploy',
+ 'reboot_requested': False,
+ },
]
def apply_configuration(self, node, ports, raid_config,
@@ -1993,6 +2003,25 @@ class GenericHardwareManager(HardwareManager):
'errors': '; '.join(raid_errors)}
raise errors.SoftwareRAIDError(error)
+ def write_image(self, node, ports, image_info, configdrive=None):
+ """A deploy step to write an image.
+
+ Downloads and writes an image to disk if necessary. Also writes a
+ configdrive to disk if the configdrive parameter is specified.
+
+ :param node: A dictionary of the node object
+ :param ports: A list of dictionaries containing information
+ of ports for the node
+ :param image_info: Image information dictionary.
+ :param configdrive: A string containing the location of the config
+ drive as a URL OR the contents (as gzip/base64)
+ of the configdrive. Optional, defaults to None.
+ """
+ ext = ext_base.get_extension('standby')
+ cmd = ext.prepare_image(image_info=image_info, configdrive=configdrive)
+ # The result is asynchronous, wait here.
+ cmd.join()
+
def _compare_extensions(ext1, ext2):
mgr1 = ext1.obj
diff --git a/ironic_python_agent/tests/unit/base.py b/ironic_python_agent/tests/unit/base.py
index 033c39cb..94196985 100644
--- a/ironic_python_agent/tests/unit/base.py
+++ b/ironic_python_agent/tests/unit/base.py
@@ -23,6 +23,7 @@ from oslo_config import cfg
from oslo_config import fixture as config_fixture
from oslotest import base as test_base
+from ironic_python_agent.extensions import base as ext_base
from ironic_python_agent import utils
CONF = cfg.CONF
@@ -58,6 +59,8 @@ class IronicAgentTest(test_base.BaseTestCase):
self.patch(subprocess, 'check_output', do_not_call)
self.patch(utils, 'execute', do_not_call)
+ ext_base._EXT_MANAGER = None
+
def _set_config(self):
self.cfg_fixture = self.useFixture(config_fixture.Config(CONF))