Create base pxe class
Create a base class to de-duplicate code across the pxe and ipxe interfaces. Only methods that do not have variation due to differences in iPXE behavior. Change-Id: I101f5ba7d44274d2b9d7d3a763198bc6fcc67e7a Task: 26738 Story: 1628069
This commit is contained in:
parent
9ccfc31c62
commit
5cb45a1756
@ -32,56 +32,22 @@ from ironic.drivers import base
|
||||
from ironic.drivers.modules import boot_mode_utils
|
||||
from ironic.drivers.modules import deploy_utils
|
||||
from ironic.drivers.modules import pxe
|
||||
from ironic.drivers.modules import pxe_base
|
||||
from ironic.drivers import utils as driver_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
METRICS = metrics_utils.get_metrics_logger(__name__)
|
||||
|
||||
# TODO(TheJulia): Lets rip these out ASAP and move them to a pxe_common.
|
||||
# One chunk moving at a time for sanity.
|
||||
REQUIRED_PROPERTIES = {
|
||||
'deploy_kernel': _("UUID (from Glance) of the deployment kernel. "
|
||||
"Required."),
|
||||
'deploy_ramdisk': _("UUID (from Glance) of the ramdisk that is "
|
||||
"mounted at boot time. Required."),
|
||||
}
|
||||
OPTIONAL_PROPERTIES = {
|
||||
'force_persistent_boot_device': _("True to enable persistent behavior "
|
||||
"when the boot device is set during "
|
||||
"deploy and cleaning operations. "
|
||||
"Defaults to False. Optional."),
|
||||
}
|
||||
RESCUE_PROPERTIES = {
|
||||
'rescue_kernel': _('UUID (from Glance) of the rescue kernel. This value '
|
||||
'is required for rescue mode.'),
|
||||
'rescue_ramdisk': _('UUID (from Glance) of the rescue ramdisk with agent '
|
||||
'that is used at node rescue time. This value is '
|
||||
'required for rescue mode.'),
|
||||
}
|
||||
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
|
||||
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
|
||||
COMMON_PROPERTIES.update(RESCUE_PROPERTIES)
|
||||
# TODO(TheJulia): Use these as the copy to move, no reason to touch pxe.py at
|
||||
# the same time as doing the initial split out as deduplication goes on.
|
||||
COMMON_PROPERTIES = pxe_base.COMMON_PROPERTIES
|
||||
|
||||
|
||||
class iPXEBoot(base.BootInterface):
|
||||
class iPXEBoot(pxe_base.PXEBaseMixin, base.BootInterface):
|
||||
|
||||
capabilities = ['iscsi_volume_boot', 'ramdisk_boot', 'ipxe_boot']
|
||||
|
||||
def __init__(self):
|
||||
pxe_utils.create_ipxe_boot_script()
|
||||
|
||||
def get_properties(self):
|
||||
"""Return the properties of the interface.
|
||||
|
||||
:returns: dictionary of <property name>:<property description> entries.
|
||||
"""
|
||||
# TODO(stendulker): COMMON_PROPERTIES should also include rescue
|
||||
# related properties (RESCUE_PROPERTIES). We can add them in Rocky,
|
||||
# when classic drivers get removed.
|
||||
return COMMON_PROPERTIES
|
||||
|
||||
@METRICS.timer('iPXEBoot.validate')
|
||||
def validate(self, task):
|
||||
"""Validate the PXE-specific info for booting deploy/instance images.
|
||||
@ -212,33 +178,6 @@ class iPXEBoot(base.BootInterface):
|
||||
if pxe_info:
|
||||
pxe_utils.cache_ramdisk_kernel(task, pxe_info)
|
||||
|
||||
@METRICS.timer('iPXEBoot.clean_up_ramdisk')
|
||||
def clean_up_ramdisk(self, task):
|
||||
"""Cleans up the boot of ironic ramdisk.
|
||||
|
||||
This method cleans up the PXE environment that was setup for booting
|
||||
the deploy or rescue ramdisk. It unlinks the deploy/rescue
|
||||
kernel/ramdisk in the node's directory in tftproot and removes it's PXE
|
||||
config.
|
||||
|
||||
:param task: a task from TaskManager.
|
||||
:param mode: Label indicating a deploy or rescue operation
|
||||
was carried out on the node. Supported values are 'deploy' and
|
||||
'rescue'. Defaults to 'deploy', indicating deploy operation was
|
||||
carried out.
|
||||
:returns: None
|
||||
"""
|
||||
node = task.node
|
||||
mode = deploy_utils.rescue_or_deploy_mode(node)
|
||||
try:
|
||||
images_info = pxe_utils.get_image_info(node, mode=mode)
|
||||
except exception.MissingParameterValue as e:
|
||||
LOG.warning('Could not get %(mode)s image info '
|
||||
'to clean up images for node %(node)s: %(err)s',
|
||||
{'mode': mode, 'node': node.uuid, 'err': e})
|
||||
else:
|
||||
pxe_utils.clean_up_pxe_env(task, images_info)
|
||||
|
||||
@METRICS.timer('iPXEBoot.prepare_instance')
|
||||
def prepare_instance(self, task):
|
||||
"""Prepares the boot of instance.
|
||||
@ -346,13 +285,3 @@ class iPXEBoot(base.BootInterface):
|
||||
{'node': node.uuid, 'err': e})
|
||||
else:
|
||||
pxe_utils.clean_up_pxe_env(task, images_info)
|
||||
|
||||
@METRICS.timer('iPXEBoot.validate_rescue')
|
||||
def validate_rescue(self, task):
|
||||
"""Validate that the node has required properties for rescue.
|
||||
|
||||
:param task: a TaskManager instance with the node being checked
|
||||
:raises: MissingParameterValue if node is missing one or more required
|
||||
parameters
|
||||
"""
|
||||
pxe_utils.parse_driver_info(task.node, mode='rescue')
|
||||
|
@ -33,32 +33,13 @@ from ironic.drivers import base
|
||||
from ironic.drivers.modules import agent
|
||||
from ironic.drivers.modules import boot_mode_utils
|
||||
from ironic.drivers.modules import deploy_utils
|
||||
from ironic.drivers.modules import pxe_base
|
||||
from ironic.drivers import utils as driver_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
METRICS = metrics_utils.get_metrics_logger(__name__)
|
||||
|
||||
REQUIRED_PROPERTIES = {
|
||||
'deploy_kernel': _("UUID (from Glance) of the deployment kernel. "
|
||||
"Required."),
|
||||
'deploy_ramdisk': _("UUID (from Glance) of the ramdisk that is "
|
||||
"mounted at boot time. Required."),
|
||||
}
|
||||
OPTIONAL_PROPERTIES = {
|
||||
'force_persistent_boot_device': _("True to enable persistent behavior "
|
||||
"when the boot device is set during "
|
||||
"deploy and cleaning operations. "
|
||||
"Defaults to False. Optional."),
|
||||
}
|
||||
RESCUE_PROPERTIES = {
|
||||
'rescue_kernel': _('UUID (from Glance) of the rescue kernel. This value '
|
||||
'is required for rescue mode.'),
|
||||
'rescue_ramdisk': _('UUID (from Glance) of the rescue ramdisk with agent '
|
||||
'that is used at node rescue time. This value is '
|
||||
'required for rescue mode.'),
|
||||
}
|
||||
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
|
||||
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
|
||||
COMMON_PROPERTIES = pxe_base.COMMON_PROPERTIES
|
||||
|
||||
# NOTE(TheJulia): This was previously a public method to the code being
|
||||
# moved. This mapping should be removed in the T* cycle.
|
||||
@ -67,8 +48,11 @@ TFTPImageCache = pxe_utils.TFTPImageCache
|
||||
# NOTE(TheJulia): End section of mappings for migrated common pxe code.
|
||||
|
||||
|
||||
class PXEBoot(base.BootInterface):
|
||||
class PXEBoot(pxe_base.PXEBaseMixin, base.BootInterface):
|
||||
|
||||
# TODO(TheJulia): iscsi_volume_boot should be removed from
|
||||
# the list below once ipxe support is removed from the PXE
|
||||
# interface.
|
||||
capabilities = ['iscsi_volume_boot', 'ramdisk_boot', 'ipxe_boot',
|
||||
'pxe_boot']
|
||||
|
||||
@ -78,16 +62,6 @@ class PXEBoot(base.BootInterface):
|
||||
if CONF.pxe.ipxe_enabled:
|
||||
pxe_utils.create_ipxe_boot_script()
|
||||
|
||||
def get_properties(self):
|
||||
"""Return the properties of the interface.
|
||||
|
||||
:returns: dictionary of <property name>:<property description> entries.
|
||||
"""
|
||||
# TODO(stendulker): COMMON_PROPERTIES should also include rescue
|
||||
# related properties (RESCUE_PROPERTIES). We can add them in Rocky,
|
||||
# when classic drivers get removed.
|
||||
return COMMON_PROPERTIES
|
||||
|
||||
@METRICS.timer('PXEBoot.validate')
|
||||
def validate(self, task):
|
||||
"""Validate the PXE-specific info for booting deploy/instance images.
|
||||
@ -211,33 +185,6 @@ class PXEBoot(base.BootInterface):
|
||||
if pxe_info:
|
||||
pxe_utils.cache_ramdisk_kernel(task, pxe_info)
|
||||
|
||||
@METRICS.timer('PXEBoot.clean_up_ramdisk')
|
||||
def clean_up_ramdisk(self, task):
|
||||
"""Cleans up the boot of ironic ramdisk.
|
||||
|
||||
This method cleans up the PXE environment that was setup for booting
|
||||
the deploy or rescue ramdisk. It unlinks the deploy/rescue
|
||||
kernel/ramdisk in the node's directory in tftproot and removes it's PXE
|
||||
config.
|
||||
|
||||
:param task: a task from TaskManager.
|
||||
:param mode: Label indicating a deploy or rescue operation
|
||||
was carried out on the node. Supported values are 'deploy' and
|
||||
'rescue'. Defaults to 'deploy', indicating deploy operation was
|
||||
carried out.
|
||||
:returns: None
|
||||
"""
|
||||
node = task.node
|
||||
mode = deploy_utils.rescue_or_deploy_mode(node)
|
||||
try:
|
||||
images_info = pxe_utils.get_image_info(node, mode=mode)
|
||||
except exception.MissingParameterValue as e:
|
||||
LOG.warning('Could not get %(mode)s image info '
|
||||
'to clean up images for node %(node)s: %(err)s',
|
||||
{'mode': mode, 'node': node.uuid, 'err': e})
|
||||
else:
|
||||
pxe_utils.clean_up_pxe_env(task, images_info)
|
||||
|
||||
@METRICS.timer('PXEBoot.prepare_instance')
|
||||
def prepare_instance(self, task):
|
||||
"""Prepares the boot of instance.
|
||||
@ -343,16 +290,6 @@ class PXEBoot(base.BootInterface):
|
||||
else:
|
||||
pxe_utils.clean_up_pxe_env(task, images_info)
|
||||
|
||||
@METRICS.timer('PXEBoot.validate_rescue')
|
||||
def validate_rescue(self, task):
|
||||
"""Validate that the node has required properties for rescue.
|
||||
|
||||
:param task: a TaskManager instance with the node being checked
|
||||
:raises: MissingParameterValue if node is missing one or more required
|
||||
parameters
|
||||
"""
|
||||
pxe_utils.parse_driver_info(task.node, mode='rescue')
|
||||
|
||||
|
||||
class PXERamdiskDeploy(agent.AgentDeploy):
|
||||
|
||||
|
95
ironic/drivers/modules/pxe_base.py
Normal file
95
ironic/drivers/modules/pxe_base.py
Normal file
@ -0,0 +1,95 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""
|
||||
Base PXE Interface Methods
|
||||
"""
|
||||
|
||||
from ironic_lib import metrics_utils
|
||||
from oslo_log import log as logging
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.common.i18n import _
|
||||
from ironic.common import pxe_utils as pxe_utils
|
||||
from ironic.drivers.modules import deploy_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
METRICS = metrics_utils.get_metrics_logger(__name__)
|
||||
|
||||
REQUIRED_PROPERTIES = {
|
||||
'deploy_kernel': _("UUID (from Glance) of the deployment kernel. "
|
||||
"Required."),
|
||||
'deploy_ramdisk': _("UUID (from Glance) of the ramdisk that is "
|
||||
"mounted at boot time. Required."),
|
||||
}
|
||||
OPTIONAL_PROPERTIES = {
|
||||
'force_persistent_boot_device': _("True to enable persistent behavior "
|
||||
"when the boot device is set during "
|
||||
"deploy and cleaning operations. "
|
||||
"Defaults to False. Optional."),
|
||||
}
|
||||
RESCUE_PROPERTIES = {
|
||||
'rescue_kernel': _('UUID (from Glance) of the rescue kernel. This value '
|
||||
'is required for rescue mode.'),
|
||||
'rescue_ramdisk': _('UUID (from Glance) of the rescue ramdisk with agent '
|
||||
'that is used at node rescue time. This value is '
|
||||
'required for rescue mode.'),
|
||||
}
|
||||
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
|
||||
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
|
||||
COMMON_PROPERTIES.update(RESCUE_PROPERTIES)
|
||||
|
||||
|
||||
class PXEBaseMixin(object):
|
||||
|
||||
def get_properties(self):
|
||||
"""Return the properties of the interface.
|
||||
|
||||
:returns: dictionary of <property name>:<property description> entries.
|
||||
"""
|
||||
return COMMON_PROPERTIES
|
||||
|
||||
@METRICS.timer('PXEBaseMixin.clean_up_ramdisk')
|
||||
def clean_up_ramdisk(self, task):
|
||||
"""Cleans up the boot of ironic ramdisk.
|
||||
|
||||
This method cleans up the PXE environment that was setup for booting
|
||||
the deploy or rescue ramdisk. It unlinks the deploy/rescue
|
||||
kernel/ramdisk in the node's directory in tftproot and removes it's PXE
|
||||
config.
|
||||
|
||||
:param task: a task from TaskManager.
|
||||
:param mode: Label indicating a deploy or rescue operation
|
||||
was carried out on the node. Supported values are 'deploy' and
|
||||
'rescue'. Defaults to 'deploy', indicating deploy operation was
|
||||
carried out.
|
||||
:returns: None
|
||||
"""
|
||||
node = task.node
|
||||
mode = deploy_utils.rescue_or_deploy_mode(node)
|
||||
try:
|
||||
images_info = pxe_utils.get_image_info(node, mode=mode)
|
||||
except exception.MissingParameterValue as e:
|
||||
LOG.warning('Could not get %(mode)s image info '
|
||||
'to clean up images for node %(node)s: %(err)s',
|
||||
{'mode': mode, 'node': node.uuid, 'err': e})
|
||||
else:
|
||||
pxe_utils.clean_up_pxe_env(task, images_info)
|
||||
|
||||
@METRICS.timer('PXEBaseMixin.validate_rescue')
|
||||
def validate_rescue(self, task):
|
||||
"""Validate that the node has required properties for rescue.
|
||||
|
||||
:param task: a TaskManager instance with the node being checked
|
||||
:raises: MissingParameterValue if node is missing one or more required
|
||||
parameters
|
||||
"""
|
||||
pxe_utils.parse_driver_info(task.node, mode='rescue')
|
@ -6816,7 +6816,8 @@ class ManagerTestProperties(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
|
||||
'ipmi_target_address', 'ipmi_local_address',
|
||||
'deploy_kernel', 'deploy_ramdisk',
|
||||
'force_persistent_boot_device', 'ipmi_protocol_version',
|
||||
'ipmi_force_boot_device', 'deploy_forces_oob_reboot']
|
||||
'ipmi_force_boot_device', 'deploy_forces_oob_reboot',
|
||||
'rescue_kernel', 'rescue_ramdisk']
|
||||
self._check_driver_properties("ipmi", expected)
|
||||
|
||||
def test_driver_properties_snmp(self):
|
||||
@ -6824,6 +6825,7 @@ class ManagerTestProperties(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
|
||||
enabled_power_interfaces=['snmp'])
|
||||
expected = ['deploy_kernel', 'deploy_ramdisk',
|
||||
'force_persistent_boot_device',
|
||||
'rescue_kernel', 'rescue_ramdisk',
|
||||
'snmp_driver', 'snmp_address', 'snmp_port', 'snmp_version',
|
||||
'snmp_community',
|
||||
'snmp_community_read', 'snmp_community_write',
|
||||
@ -6873,7 +6875,8 @@ class ManagerTestHardwareTypeProperties(mgr_utils.ServiceSetUpMixin,
|
||||
|
||||
def test_hardware_type_properties_manual_management(self):
|
||||
expected = ['deploy_kernel', 'deploy_ramdisk',
|
||||
'force_persistent_boot_device', 'deploy_forces_oob_reboot']
|
||||
'force_persistent_boot_device', 'deploy_forces_oob_reboot',
|
||||
'rescue_kernel', 'rescue_ramdisk']
|
||||
self._check_hardware_type_properties('manual-management', expected)
|
||||
|
||||
|
||||
|
@ -67,7 +67,7 @@ class ManualManagementHardwareTestCase(db_base.DbTestCase):
|
||||
# These properties are from vendor (agent) and boot (pxe) interfaces
|
||||
expected_prop_keys = [
|
||||
'deploy_forces_oob_reboot', 'deploy_kernel', 'deploy_ramdisk',
|
||||
'force_persistent_boot_device']
|
||||
'force_persistent_boot_device', 'rescue_kernel', 'rescue_ramdisk']
|
||||
hardware_type = driver_factory.get_hardware_type("manual-management")
|
||||
properties = hardware_type.get_properties()
|
||||
self.assertEqual(sorted(expected_prop_keys), sorted(properties))
|
||||
|
Loading…
Reference in New Issue
Block a user