149 lines
6.1 KiB
Python
149 lines
6.1 KiB
Python
# Copyright 2018 Red Hat, Inc.
|
|
# All Rights Reserved.
|
|
#
|
|
# 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.
|
|
|
|
from oslo_log import log as logging
|
|
|
|
from ironic.common import exception
|
|
from ironic.common.i18n import _
|
|
from ironic.conductor import utils as manager_utils
|
|
from ironic.conf import CONF
|
|
from ironic.drivers.modules import deploy_utils
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def _set_boot_mode_on_bm(task, ironic_boot_mode, fail_if_unsupported=False):
|
|
try:
|
|
manager_utils.node_set_boot_mode(task, ironic_boot_mode)
|
|
|
|
except exception.UnsupportedDriverExtension as ex:
|
|
if fail_if_unsupported:
|
|
msg = (_("Baremetal node %(uuid)s boot mode is not set "
|
|
"to boot mode %(boot_mode)s: %(error)s") %
|
|
{'uuid': task.node.uuid,
|
|
'boot_mode': ironic_boot_mode,
|
|
'error': ex})
|
|
LOG.error(msg)
|
|
raise exception.UnsupportedDriverExtension(msg)
|
|
|
|
msg_tmpl = _("Baremetal node %(uuid)s boot mode is not set "
|
|
"to boot mode %(boot_mode)s. Assuming "
|
|
"baremetal node is already in %(boot_mode)s or "
|
|
"driver set boot mode via some other "
|
|
"mechanism: %(error)s")
|
|
|
|
LOG.debug(msg_tmpl, {'uuid': task.node.uuid,
|
|
'boot_mode': ironic_boot_mode,
|
|
'error': ex})
|
|
|
|
except exception.InvalidParameterValue as ex:
|
|
msg = (_("Node %(uuid)s boot mode is not set. "
|
|
"Attempt to set %(ironic_boot_mode)s boot mode "
|
|
"on the baremetal node failed with error %(error)s") %
|
|
{'uuid': task.node.uuid,
|
|
'ironic_boot_mode': ironic_boot_mode,
|
|
'error': ex})
|
|
LOG.error(msg)
|
|
raise exception.InvalidParameterValue(msg)
|
|
|
|
else:
|
|
LOG.info("Baremetal node boot mode is set to boot "
|
|
"mode %(boot_mode)s",
|
|
{'uuid': task.node.uuid, 'boot_mode': ironic_boot_mode})
|
|
|
|
|
|
def sync_boot_mode(task):
|
|
"""Set node's boot mode from bare metal configuration
|
|
|
|
Attempt to read currently set boot mode off the bare metal machine.
|
|
Also read node's boot mode configuration:
|
|
|
|
* If BM driver does not implement getting boot mode, assume
|
|
BM boot mode is not set and apply the logic that follows
|
|
* If Ironic node boot mode is not set and BM node boot mode is
|
|
not set - set Ironic boot mode to `[deploy]/default_boot_mode`
|
|
* If Ironic node boot mode is not set and BM node boot mode
|
|
is set - set BM node boot mode on the Ironic node
|
|
* If Ironic node boot mode is set and BM node boot mode is
|
|
not set - set Ironic boot mode to BM boot mode
|
|
* If both Ironic and BM node boot modes are set but they
|
|
differ - try to set Ironic boot mode to BM boot mode and fail hard
|
|
if underlying hardware type does not support setting boot mode
|
|
|
|
In the end, the new boot mode may be set in
|
|
'driver_internal_info/deploy_boot_mode'.
|
|
|
|
:param task: a task object
|
|
"""
|
|
node = task.node
|
|
|
|
try:
|
|
bm_boot_mode = manager_utils.node_get_boot_mode(task)
|
|
|
|
except exception.UnsupportedDriverExtension as ex:
|
|
bm_boot_mode = None
|
|
|
|
LOG.debug("Cannot determine node %(uuid)s boot mode: %(error)s",
|
|
{'uuid': node.uuid, 'error': ex})
|
|
|
|
ironic_boot_mode = deploy_utils.get_boot_mode_for_deploy(node)
|
|
|
|
# NOTE(etingof): the outcome of the branching that follows is that
|
|
# the new boot mode may be set in 'driver_internal_info/deploy_boot_mode'
|
|
|
|
if not ironic_boot_mode and not bm_boot_mode:
|
|
driver_internal_info = node.driver_internal_info
|
|
default_boot_mode = CONF.deploy.default_boot_mode
|
|
driver_internal_info['deploy_boot_mode'] = default_boot_mode
|
|
node.driver_internal_info = driver_internal_info
|
|
node.save()
|
|
|
|
LOG.debug("Ironic node %(uuid)s boot mode will be set to default "
|
|
"boot mode %(boot_mode)s",
|
|
{'uuid': node.uuid, 'boot_mode': default_boot_mode})
|
|
|
|
_set_boot_mode_on_bm(task, default_boot_mode)
|
|
|
|
elif not ironic_boot_mode and bm_boot_mode:
|
|
driver_internal_info = node.driver_internal_info
|
|
driver_internal_info['deploy_boot_mode'] = bm_boot_mode
|
|
node.driver_internal_info = driver_internal_info
|
|
node.save()
|
|
|
|
LOG.debug("Ironic node %(uuid)s boot mode is set to boot mode "
|
|
"%(boot_mode)s reported by the driver",
|
|
{'uuid': node.uuid, 'boot_mode': bm_boot_mode})
|
|
|
|
elif ironic_boot_mode and not bm_boot_mode:
|
|
# NOTE(etingof): if only ironic boot mode is known, try to synchronize
|
|
# (e.g. ironic -> bm) and do not fail if setting boot mode is not
|
|
# supported by the underlying hardware type
|
|
_set_boot_mode_on_bm(task, ironic_boot_mode)
|
|
|
|
elif ironic_boot_mode != bm_boot_mode:
|
|
msg = (_("Boot mode %(node_boot_mode)s currently configured "
|
|
"on node %(uuid)s does not match the boot mode "
|
|
"%(ironic_boot_mode)s requested for provisioning."
|
|
"Attempting to set node boot mode to %(ironic_boot_mode)s.") %
|
|
{'uuid': node.uuid, 'node_boot_mode': bm_boot_mode,
|
|
'ironic_boot_mode': ironic_boot_mode})
|
|
LOG.info(msg)
|
|
|
|
# NOTE(etingof): if boot modes are known and different, try
|
|
# to synchronize them (e.g. ironic -> bm) and fail hard if
|
|
# underlying hardware type does not support setting boot mode as
|
|
# it seems to be a hopeless misconfiguration
|
|
_set_boot_mode_on_bm(task, ironic_boot_mode, fail_if_unsupported=True)
|