~ubuntu-branches/ubuntu/vivid/ironic/vivid-updates

« back to all changes in this revision

Viewing changes to ironic/drivers/modules/irmc/management.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2015-03-30 11:14:57 UTC
  • mfrom: (1.2.6)
  • Revision ID: package-import@ubuntu.com-20150330111457-kr4ju3guf22m4vbz
Tags: 2015.1~b3-0ubuntu1
* New upstream release.
  + d/control: 
    - Align with upstream dependencies.
    - Add dh-python to build-dependencies.
    - Add psmisc as a dependency. (LP: #1358820)
  + d/p/fix-requirements.patch: Rediffed.
  + d/ironic-conductor.init.in: Fixed typos in LSB headers,
    thanks to JJ Asghar. (LP: #1429962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Licensed under the Apache License, Version 2.0 (the "License"); you may
 
3
# not use this file except in compliance with the License. You may obtain
 
4
# a copy of the License at
 
5
#
 
6
#      http://www.apache.org/licenses/LICENSE-2.0
 
7
#
 
8
# Unless required by applicable law or agreed to in writing, software
 
9
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
10
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
11
# License for the specific language governing permissions and limitations
 
12
# under the License.
 
13
"""
 
14
iRMC Management Driver
 
15
"""
 
16
 
 
17
from oslo_utils import importutils
 
18
 
 
19
from ironic.common import boot_devices
 
20
from ironic.common import exception
 
21
from ironic.common.i18n import _
 
22
from ironic.common.i18n import _LE
 
23
from ironic.conductor import task_manager
 
24
from ironic.drivers.modules import ipmitool
 
25
from ironic.drivers.modules.irmc import common as irmc_common
 
26
from ironic.drivers import utils as driver_utils
 
27
from ironic.openstack.common import log as logging
 
28
 
 
29
scci = importutils.try_import('scciclient.irmc.scci')
 
30
 
 
31
LOG = logging.getLogger(__name__)
 
32
 
 
33
# Boot Option Parameters #5 Data2 defined in
 
34
# Set/Get System Boot Options Command, IPMI spec v2.0.
 
35
_BOOTPARAM5_DATA2 = {boot_devices.PXE: '0x04',
 
36
                     boot_devices.DISK: '0x08',
 
37
                     boot_devices.CDROM: '0x14',
 
38
                     boot_devices.BIOS: '0x18',
 
39
                     boot_devices.SAFE: '0x0c',
 
40
                     }
 
41
 
 
42
 
 
43
def _get_sensors_data(task):
 
44
    """Get sensors data method.
 
45
 
 
46
    It gets sensor data from the task's node via SCCI, and convert the data
 
47
    from XML to the dict format.
 
48
 
 
49
    :param task: A TaskManager instance.
 
50
    :raises: FailedToGetSensorData when getting the sensor data fails.
 
51
    :returns: Returns a consistent formatted dict of sensor data grouped
 
52
              by sensor type, which can be processed by Ceilometer.
 
53
    """
 
54
 
 
55
    try:
 
56
        report = irmc_common.get_irmc_report(task.node)
 
57
        sensor = scci.get_sensor_data(report)
 
58
 
 
59
    except Exception as e:
 
60
        LOG.error(_LE("SCCI get sensor data failed for node %(node_id)s "
 
61
                  "with the following error: %(error)s"),
 
62
                  {'node_id': task.node.uuid, 'error': e})
 
63
        raise exception.FailedToGetSensorData(
 
64
                    node=task.node.uuid, error=e)
 
65
 
 
66
    sensors_data = {}
 
67
    for sdr in sensor:
 
68
        sensor_type_name = sdr.find('./Data/Decoded/Sensor/TypeName')
 
69
        sensor_type_number = sdr.find('./Data/Decoded/Sensor/Type')
 
70
        entity_name = sdr.find('./Data/Decoded/Entity/Name')
 
71
        entity_id = sdr.find('./Data/Decoded/Entity/ID')
 
72
 
 
73
        if None in (sensor_type_name, sensor_type_number,
 
74
                    entity_name, entity_id):
 
75
            continue
 
76
 
 
77
        sensor_type = ('%s (%s)' %
 
78
                       (sensor_type_name.text, sensor_type_number.text))
 
79
        sensor_id = ('%s (%s)' %
 
80
                     (entity_name.text, entity_id.text))
 
81
        reading_value = sdr.find(
 
82
            './Data/Decoded/Sensor/Thresholds/*/Normalized')
 
83
        reading_value_text = "None" if (
 
84
            reading_value is None) else str(reading_value.text)
 
85
        reading_units = sdr.find('./Data/Decoded/Sensor/BaseUnitName')
 
86
        reading_units_text = "None" if (
 
87
            reading_units is None) else str(reading_units.text)
 
88
        sensor_reading = '%s %s' % (reading_value_text, reading_units_text)
 
89
 
 
90
        sensors_data.setdefault(sensor_type, {})[sensor_id] = {
 
91
            'Sensor Reading': sensor_reading,
 
92
            'Sensor ID': sensor_id,
 
93
            'Units': reading_units_text,
 
94
        }
 
95
 
 
96
    return sensors_data
 
97
 
 
98
 
 
99
class IRMCManagement(ipmitool.IPMIManagement):
 
100
 
 
101
    def get_properties(self):
 
102
        """Return the properties of the interface.
 
103
 
 
104
        :returns: Dictionary of <property name>:<property description> entries.
 
105
        """
 
106
        return irmc_common.COMMON_PROPERTIES
 
107
 
 
108
    def validate(self, task):
 
109
        """Validate the driver-specific management information.
 
110
 
 
111
        This method validates whether the 'driver_info' property of the
 
112
        supplied node contains the required information for this driver.
 
113
 
 
114
        :param task: A TaskManager instance containing the node to act on.
 
115
        :raises: InvalidParameterValue if required parameters are invalid.
 
116
        :raises: MissingParameterValue if a required parameter is missing.
 
117
        """
 
118
        irmc_common.parse_driver_info(task.node)
 
119
        irmc_common.update_ipmi_properties(task)
 
120
        super(IRMCManagement, self).validate(task)
 
121
 
 
122
    @task_manager.require_exclusive_lock
 
123
    def set_boot_device(self, task, device, persistent=False):
 
124
        """Set the boot device for a node.
 
125
 
 
126
        Set the boot device to use on next reboot of the node.
 
127
 
 
128
        :param task: A task from TaskManager.
 
129
        :param device: The boot device, one of the supported devices
 
130
                       listed in :mod:`ironic.common.boot_devices`.
 
131
        :param persistent: Boolean value. True if the boot device will
 
132
                           persist to all future boots, False if not.
 
133
                           Default: False.
 
134
        :raises: InvalidParameterValue if an invalid boot device is
 
135
                 specified.
 
136
        :raises: MissingParameterValue if a required parameter is missing.
 
137
        :raises: IPMIFailure on an error from ipmitool.
 
138
 
 
139
        """
 
140
        if driver_utils.get_node_capability(task.node, 'boot_mode') == 'uefi':
 
141
            if device not in self.get_supported_boot_devices():
 
142
                raise exception.InvalidParameterValue(_(
 
143
                    "Invalid boot device %s specified.") % device)
 
144
            timeout_disable = "0x00 0x08 0x03 0x08"
 
145
            ipmitool.send_raw(task, timeout_disable)
 
146
 
 
147
            # note(naohirot): As of ipmitool version 1.8.13,
 
148
            # in case of chassis command, the efiboot option doesn't
 
149
            # get set with persistent at the same time.
 
150
            # $ ipmitool chassis bootdev pxe options=efiboot,persistent
 
151
            # In case of raw command, however, both can be set at the
 
152
            # same time.
 
153
            # $ ipmitool raw 0x00 0x08 0x05 0xe0 0x04 0x00 0x00 0x00
 
154
            #                           data1^^  ^^data2
 
155
            # ipmi cmd '0x08' : Set System Boot Options
 
156
            # data1    '0xe0' : persistent and uefi
 
157
            # data1    '0xa0' : next boot only and uefi
 
158
            #
 
159
            data1 = '0xe0' if persistent else '0xa0'
 
160
            bootparam5 = '0x00 0x08 0x05 %s %s 0x00 0x00 0x00'
 
161
            cmd08 = bootparam5 % (data1, _BOOTPARAM5_DATA2[device])
 
162
            ipmitool.send_raw(task, cmd08)
 
163
 
 
164
        else:
 
165
            super(IRMCManagement, self).set_boot_device(
 
166
                task, device, persistent)
 
167
 
 
168
    def get_sensors_data(self, task):
 
169
        """Get sensors data method.
 
170
 
 
171
        It gets sensor data from the task's node via SCCI, and convert the data
 
172
        from XML to the dict format.
 
173
 
 
174
        :param task: A TaskManager instance.
 
175
        :raises: FailedToGetSensorData when getting the sensor data fails.
 
176
        :raises: FailedToParseSensorData when parsing sensor data fails.
 
177
        :raises: InvalidParameterValue if required parameters are invalid.
 
178
        :raises: MissingParameterValue if a required parameter is missing.
 
179
        :returns: Returns a consistent formatted dict of sensor data grouped
 
180
                  by sensor type, which can be processed by Ceilometer.
 
181
 
 
182
                      {
 
183
                        'Sensor Type 1': {
 
184
                          'Sensor ID 1': {
 
185
                            'Sensor Reading': 'Value1 Units1',
 
186
                            'Sensor ID': 'Sensor ID 1',
 
187
                            'Units': 'Units1'
 
188
                          },
 
189
                          'Sensor ID 2': {
 
190
                            'Sensor Reading': 'Value2 Units2',
 
191
                            'Sensor ID': 'Sensor ID 2',
 
192
                            'Units': 'Units2'
 
193
                          }
 
194
                        },
 
195
                        'Sensor Type 2': {
 
196
                          'Sensor ID 3': {
 
197
                            'Sensor Reading': 'Value3 Units3',
 
198
                            'Sensor ID': 'Sensor ID 3',
 
199
                            'Units': 'Units3'
 
200
                          },
 
201
                          'Sensor ID 4': {
 
202
                            'Sensor Reading': 'Value4 Units4',
 
203
                            'Sensor ID': 'Sensor ID 4',
 
204
                            'Units': 'Units4'
 
205
                          }
 
206
                        }
 
207
                      }
 
208
 
 
209
        """
 
210
        # irmc_common.parse_driver_info() makes sure that
 
211
        # d_info['irmc_sensor_method'] is either 'scci' or 'ipmitool'.
 
212
        d_info = irmc_common.parse_driver_info(task.node)
 
213
        sensor_method = d_info['irmc_sensor_method']
 
214
        if sensor_method == 'scci':
 
215
            return _get_sensors_data(task)
 
216
        elif sensor_method == 'ipmitool':
 
217
            return super(IRMCManagement, self).get_sensors_data(task)