"Fossies" - the Fresh Open Source Software Archive

Member "ironic-16.0.3/ironic/drivers/modules/ilo/raid.py" (18 Jan 2021, 12296 Bytes) of package /linux/misc/openstack/ironic-16.0.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "raid.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 16.0.2_vs_16.0.3.

    1 # Copyright 2018 Hewlett Packard Enterprise Development LP
    2 #
    3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
    4 # not use this file except in compliance with the License. You may obtain
    5 # a copy of the License at
    6 #
    7 #      http://www.apache.org/licenses/LICENSE-2.0
    8 #
    9 # Unless required by applicable law or agreed to in writing, software
   10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   12 # License for the specific language governing permissions and limitations
   13 # under the License.
   14 
   15 """
   16 iLO5 RAID specific methods
   17 """
   18 
   19 from ironic_lib import metrics_utils
   20 from oslo_log import log as logging
   21 from oslo_utils import importutils
   22 
   23 from ironic.common import exception
   24 from ironic.common.i18n import _
   25 from ironic.common import raid
   26 from ironic.common import states
   27 from ironic.conductor import utils as manager_utils
   28 from ironic import conf
   29 from ironic.drivers import base
   30 from ironic.drivers.modules import deploy_utils
   31 from ironic.drivers.modules.ilo import common as ilo_common
   32 
   33 
   34 LOG = logging.getLogger(__name__)
   35 CONF = conf.CONF
   36 METRICS = metrics_utils.get_metrics_logger(__name__)
   37 
   38 ilo_error = importutils.try_import('proliantutils.exception')
   39 
   40 
   41 class Ilo5RAID(base.RAIDInterface):
   42     """Implementation of OOB RAIDInterface for iLO5."""
   43 
   44     _RAID_APPLY_CONFIGURATION_ARGSINFO = {
   45         "raid_config": {
   46             "description": "The RAID configuration to apply.",
   47             "required": True,
   48         },
   49         "create_root_volume": {
   50             "description": (
   51                 "Setting this to 'False' indicates not to create root "
   52                 "volume that is specified in 'raid_config'. Default "
   53                 "value is 'True'."
   54             ),
   55             "required": False,
   56         },
   57         "create_nonroot_volumes": {
   58             "description": (
   59                 "Setting this to 'False' indicates not to create "
   60                 "non-root volumes (all except the root volume) in "
   61                 "'raid_config'. Default value is 'True'."
   62             ),
   63             "required": False,
   64         }
   65     }
   66 
   67     def get_properties(self):
   68         """Return the properties of the interface."""
   69         return ilo_common.REQUIRED_PROPERTIES
   70 
   71     def _set_step_failed(self, task, msg, exc):
   72         log_msg = ("RAID configuration job failed for node %(node)s. "
   73                    "Message: '%(message)s'." %
   74                    {'node': task.node.uuid, 'message': msg})
   75         if task.node.provision_state == states.DEPLOYING:
   76             manager_utils.deploying_error_handler(task, log_msg, errmsg=msg)
   77         else:
   78             manager_utils.cleaning_error_handler(task, log_msg, errmsg=msg)
   79 
   80     def _set_driver_internal_true_value(self, task, *keys):
   81         driver_internal_info = task.node.driver_internal_info
   82         for key in keys:
   83             driver_internal_info[key] = True
   84         task.node.driver_internal_info = driver_internal_info
   85         task.node.save()
   86 
   87     def _set_driver_internal_false_value(self, task, *keys):
   88         driver_internal_info = task.node.driver_internal_info
   89         for key in keys:
   90             driver_internal_info[key] = False
   91         task.node.driver_internal_info = driver_internal_info
   92         task.node.save()
   93 
   94     def _pop_driver_internal_values(self, task, *keys):
   95         driver_internal_info = task.node.driver_internal_info
   96         for key in keys:
   97             driver_internal_info.pop(key, None)
   98         task.node.driver_internal_info = driver_internal_info
   99         task.node.save()
  100 
  101     def _prepare_for_read_raid(self, task, raid_step):
  102         deploy_opts = deploy_utils.build_agent_options(task.node)
  103         task.driver.boot.prepare_ramdisk(task, deploy_opts)
  104         manager_utils.node_power_action(task, states.REBOOT)
  105         if raid_step == 'create_raid':
  106             self._set_driver_internal_true_value(
  107                 task, 'ilo_raid_create_in_progress')
  108         else:
  109             self._set_driver_internal_true_value(
  110                 task, 'ilo_raid_delete_in_progress')
  111         deploy_utils.set_async_step_flags(task.node, reboot=True,
  112                                           skip_current_step=False)
  113 
  114     @base.deploy_step(priority=0,
  115                       argsinfo=_RAID_APPLY_CONFIGURATION_ARGSINFO)
  116     def apply_configuration(self, task, raid_config, create_root_volume=True,
  117                             create_nonroot_volumes=False):
  118         return super(Ilo5RAID, self).apply_configuration(
  119             task, raid_config, create_root_volume=create_root_volume,
  120             create_nonroot_volumes=create_nonroot_volumes)
  121 
  122     @METRICS.timer('Ilo5RAID.create_configuration')
  123     @base.clean_step(priority=0, abortable=False, argsinfo={
  124         'create_root_volume': {
  125             'description': (
  126                 'This specifies whether to create the root volume. '
  127                 'Defaults to `True`.'
  128             ),
  129             'required': False
  130         },
  131         'create_nonroot_volumes': {
  132             'description': (
  133                 'This specifies whether to create the non-root volumes. '
  134                 'Defaults to `True`.'
  135             ),
  136             'required': False
  137         }
  138     })
  139     def create_configuration(self, task, create_root_volume=True,
  140                              create_nonroot_volumes=True):
  141         """Create a RAID configuration on a bare metal using agent ramdisk.
  142 
  143         This method creates a RAID configuration on the given node.
  144 
  145         :param task: a TaskManager instance.
  146         :param create_root_volume: If True, a root volume is created
  147             during RAID configuration. Otherwise, no root volume is
  148             created. Default is True.
  149         :param create_nonroot_volumes: If True, non-root volumes are
  150             created. If False, no non-root volumes are created. Default
  151             is True.
  152         :raises: MissingParameterValue, if node.target_raid_config is missing
  153             or was found to be empty after skipping root volume and/or non-root
  154             volumes.
  155         :raises: NodeCleaningFailure, on failure to execute clean step.
  156         :raises: InstanceDeployFailure, on failure to execute deploy step.
  157         """
  158         node = task.node
  159         target_raid_config = raid.filter_target_raid_config(
  160             node, create_root_volume=create_root_volume,
  161             create_nonroot_volumes=create_nonroot_volumes)
  162         driver_internal_info = node.driver_internal_info
  163         driver_internal_info['target_raid_config'] = target_raid_config
  164         node.driver_internal_info = driver_internal_info
  165         node.save()
  166         LOG.debug("Calling OOB RAID create_configuration for node %(node)s "
  167                   "with the following target RAID configuration: %(target)s",
  168                   {'node': node.uuid, 'target': target_raid_config})
  169         ilo_object = ilo_common.get_ilo_object(node)
  170 
  171         try:
  172             # Raid configuration in progress, checking status
  173             if not driver_internal_info.get('ilo_raid_create_in_progress'):
  174                 ilo_object.create_raid_configuration(target_raid_config)
  175                 self._prepare_for_read_raid(task, 'create_raid')
  176                 return deploy_utils.get_async_step_return_state(node)
  177             else:
  178                 # Raid configuration is done, updating raid_config
  179                 raid_conf = (
  180                     ilo_object.read_raid_configuration(
  181                         raid_config=target_raid_config))
  182                 fields = ['ilo_raid_create_in_progress']
  183                 if node.clean_step:
  184                     fields.append('skip_current_clean_step')
  185                 else:
  186                     fields.append('skip_current_deploy_step')
  187                 self._pop_driver_internal_values(task, *fields)
  188                 if len(raid_conf['logical_disks']):
  189                     raid.update_raid_info(node, raid_conf)
  190                     LOG.debug("Node %(uuid)s raid create clean step is done.",
  191                               {'uuid': node.uuid})
  192                 else:
  193                     # Raid configuration failed
  194                     msg = (_("Step create_configuration failed "
  195                              "on node %(node)s with error: "
  196                              "Unable to create raid")
  197                            % {'node': node.uuid})
  198                     if node.clean_step:
  199                         raise exception.NodeCleaningFailure(msg)
  200                     else:
  201                         raise exception.InstanceDeployFailure(reason=msg)
  202         except ilo_error.IloError as ilo_exception:
  203             operation = (_("Failed to create raid configuration on node %s")
  204                          % node.uuid)
  205             fields = ['ilo_raid_create_in_progress']
  206             if node.clean_step:
  207                 fields.append('skip_current_clean_step')
  208             else:
  209                 fields.append('skip_current_deploy_step')
  210             self._pop_driver_internal_values(task, *fields)
  211             self._set_step_failed(task, operation, ilo_exception)
  212 
  213     @METRICS.timer('Ilo5RAID.delete_configuration')
  214     @base.clean_step(priority=0, abortable=False)
  215     @base.deploy_step(priority=0)
  216     def delete_configuration(self, task):
  217         """Delete the RAID configuration.
  218 
  219         :param task: a TaskManager instance  containing the node to act on.
  220         :raises: NodeCleaningFailure, on failure to execute clean step.
  221         :raises: InstanceDeployFailure, on failure to execute deploy step.
  222         """
  223         node = task.node
  224         LOG.debug("OOB RAID delete_configuration invoked for node %s.",
  225                   node.uuid)
  226         driver_internal_info = node.driver_internal_info
  227         ilo_object = ilo_common.get_ilo_object(node)
  228 
  229         try:
  230             # Raid configuration in progress, checking status
  231             if not driver_internal_info.get('ilo_raid_delete_in_progress'):
  232                 ilo_object.delete_raid_configuration()
  233                 self._prepare_for_read_raid(task, 'delete_raid')
  234                 return deploy_utils.get_async_step_return_state(node)
  235             else:
  236                 # Raid configuration is done, updating raid_config
  237                 raid_conf = ilo_object.read_raid_configuration()
  238                 fields = ['ilo_raid_delete_in_progress']
  239                 if node.clean_step:
  240                     fields.append('skip_current_clean_step')
  241                 else:
  242                     fields.append('skip_current_deploy_step')
  243                 self._pop_driver_internal_values(task, *fields)
  244                 if not len(raid_conf['logical_disks']):
  245                     node.raid_config = {}
  246                     LOG.debug("Node %(uuid)s raid delete clean step is done.",
  247                               {'uuid': node.uuid})
  248                 else:
  249                     # Raid configuration failed
  250                     err_msg = (_("Step delete_configuration failed "
  251                                  "on node %(node)s with error: "
  252                                  "Unable to delete these logical disks: "
  253                                  "%(disks)s")
  254                                % {'node': node.uuid,
  255                                   'disks': raid_conf['logical_disks']})
  256                     if node.clean_step:
  257                         raise exception.NodeCleaningFailure(err_msg)
  258                     else:
  259                         raise exception.InstanceDeployFailure(reason=err_msg)
  260         except ilo_error.IloLogicalDriveNotFoundError:
  261             LOG.info("No logical drive found to delete on node %(node)s",
  262                      {'node': node.uuid})
  263         except ilo_error.IloError as ilo_exception:
  264             operation = (_("Failed to delete raid configuration on node %s")
  265                          % node.uuid)
  266             self._pop_driver_internal_values(task,
  267                                              'ilo_raid_delete_in_progress',
  268                                              'skip_current_clean_step')
  269             fields = ['ilo_raid_delete_in_progress']
  270             if node.clean_step:
  271                 fields.append('skip_current_clean_step')
  272             else:
  273                 fields.append('skip_current_deploy_step')
  274             self._pop_driver_internal_values(task, *fields)
  275             self._set_step_failed(task, operation, ilo_exception)