dc8d2fa326
IPA does not send block_devices. Instead, it provides a full inventory. Support both ramdisks, with IPA being preferred. Change-Id: I85db79dd27a774ba74b4d3c17aa47fa7dc28ed21 Closes-Bug: #1497213
101 lines
4.1 KiB
Python
101 lines
4.1 KiB
Python
# 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.
|
|
|
|
"""Gather root device hint from recognized block devices."""
|
|
|
|
from oslo_log import log
|
|
|
|
from ironic_inspector.common.i18n import _LI, _LW
|
|
from ironic_inspector.plugins import base
|
|
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
class RaidDeviceDetection(base.ProcessingHook):
|
|
"""Processing hook for learning the root device after RAID creation.
|
|
|
|
The plugin can figure out the root device in 2 runs. First, it saves the
|
|
discovered block device serials in node.extra. The second run will check
|
|
the difference between the recently discovered block devices and the
|
|
previously saved ones. After saving the root device in node.properties, it
|
|
will delete the temporarily saved block device serials in node.extra.
|
|
|
|
This way, it helps to figure out the root device hint in cases when
|
|
otherwise Ironic doesn't have enough information to do so. Such a usecase
|
|
is DRAC RAID configuration where the BMC doesn't provide any useful
|
|
information about the created RAID disks. Using this plugin immediately
|
|
before and after creating the root RAID device will solve the issue of root
|
|
device hints.
|
|
|
|
In cases where there's no RAID volume on the node, the standard plugin will
|
|
fail due to the missing local_gb value. This plugin fakes the missing
|
|
value, until it's corrected during later runs. Note, that for this to work
|
|
the plugin needs to take precedence over the standard plugin.
|
|
"""
|
|
|
|
def _get_serials(self, data):
|
|
if 'inventory' in data:
|
|
return [x['serial'] for x in data['inventory'].get('disks', ())
|
|
if x.get('serial')]
|
|
elif 'block_devices' in data:
|
|
return data['block_devices'].get('serials', ())
|
|
|
|
def before_processing(self, introspection_data, **kwargs):
|
|
"""Adds fake local_gb value if it's missing from introspection_data."""
|
|
if not introspection_data.get('local_gb'):
|
|
LOG.info(_LI('No volume is found on the node. Adding a fake '
|
|
'value for "local_gb"'))
|
|
introspection_data['local_gb'] = 1
|
|
|
|
def before_update(self, introspection_data, node_info, **kwargs):
|
|
current_devices = self._get_serials(introspection_data)
|
|
if not current_devices:
|
|
LOG.warning(_LW('No block device was received from ramdisk'))
|
|
return
|
|
|
|
node = node_info.node()
|
|
|
|
if 'root_device' in node.properties:
|
|
LOG.info(_LI('Root device is already known for the node'))
|
|
return
|
|
|
|
if 'block_devices' in node.extra:
|
|
# Compare previously discovered devices with the current ones
|
|
previous_devices = node.extra['block_devices']['serials']
|
|
new_devices = [device for device in current_devices
|
|
if device not in previous_devices]
|
|
|
|
if len(new_devices) > 1:
|
|
LOG.warning(_LW('Root device cannot be identified because '
|
|
'multiple new devices were found'))
|
|
return
|
|
elif len(new_devices) == 0:
|
|
LOG.warning(_LW('No new devices were found'))
|
|
return
|
|
|
|
node_info.patch([
|
|
{'op': 'remove',
|
|
'path': '/extra/block_devices'},
|
|
{'op': 'add',
|
|
'path': '/properties/root_device',
|
|
'value': {'serial': new_devices[0]}}
|
|
])
|
|
|
|
else:
|
|
# No previously discovered devices - save the inspector block
|
|
# devices in node.extra
|
|
node_info.patch([{'op': 'add',
|
|
'path': '/extra/block_devices',
|
|
'value': {'serials': current_devices}}])
|