def get_xclarity_client(node): """Generates an instance of the XClarity client. Generates an instance of the XClarity client using the imported xclarity_client library. :param node: an ironic node object. :returns: an instance of the XClarity client :raises: XClarityError if can't get to the XClarity client """ driver_info = parse_driver_info(node) try: xclarity_client = client.Client( ip=driver_info.get('xclarity_manager_ip'), username=driver_info.get('xclarity_username'), password=driver_info.get('xclarity_password'), port=driver_info.get('xclarity_port')) except xclarity_client_exceptions.XClarityError as exc: msg = (_("Error getting connection to XClarity address: %(ip)s. " "Error: %(exc)s"), { 'ip': driver_info.get('xclarity_manager_ip'), 'exc': exc }) raise exception.XClarityError(error=msg) return xclarity_client
def test_get_power_state_fail(self, mock_xc_client): with task_manager.acquire(self.context, self.node.uuid) as task: xclarity_client_exceptions.XClarityError = Exception sys.modules['xclarity_client.exceptions'] = ( xclarity_client_exceptions) if 'ironic.drivers.modules.xclarity' in sys.modules: six.moves.reload_module( sys.modules['ironic.drivers.modules.xclarity']) ex = exception.XClarityError('E') mock_xc_client.return_value.get_node_power_status.side_effect = ex self.assertRaises(exception.XClarityError, task.driver.power.get_power_state, task)
def test_get_boot_device_fail(self, mock_xc_client): with task_manager.acquire(self.context, self.node.uuid) as task: xclarity_client_exceptions.XClarityError = Exception sys.modules['xclarity_client.exceptions'] = ( xclarity_client_exceptions) if 'ironic.drivers.modules.xclarity' in sys.modules: importlib.reload( sys.modules['ironic.drivers.modules.xclarity']) ex = exception.XClarityError('E') mock_xc_client.return_value.get_node_all_boot_info.side_effect = ex self.assertRaises(exception.XClarityError, task.driver.management.get_boot_device, task)
def get_boot_device(self, task): """Get the current boot device for the task's node. :param task: a task from TaskManager. :returns: a dictionary containing: :boot_device: the boot device, one of [PXE, DISK, CDROM, BIOS] :persistent: Whether the boot device will persist or not :raises: InvalidParameterValue if the boot device is unknown :raises: XClarityError if the communication with XClarity fails """ node = task.node client = common.get_xclarity_client(node) server_hardware_id = common.get_server_hardware_id(node) try: boot_info = (client.get_node_all_boot_info(server_hardware_id)) except xclarity_client_exceptions.XClarityError as xclarity_exc: LOG.error( "Error getting boot device from XClarity for node %(node)s. " "Error: %(error)s", { 'node': node.uuid, 'error': xclarity_exc }) raise exception.XClarityError(error=xclarity_exc) persistent = False primary = None boot_order = boot_info['bootOrder']['bootOrderList'] for item in boot_order: current = item.get('currentBootOrderDevices', None) boot_type = item.get('bootType', None) if boot_type == "SingleUse": persistent = False primary = current[0] if primary != 'None': boot_device = { 'boot_device': primary, 'persistent': persistent } self._validate_whether_supported_boot_device(primary) return boot_device elif boot_type == "Permanent": persistent = True boot_device = { 'boot_device': current[0], 'persistent': persistent } self._validate_supported_boot_device(task, primary) return boot_device
def _set_boot_device(self, task, server_hardware_id, new_primary_boot_device, singleuse=False): """Set the current boot device for xclarity :param server_hardware_id: the uri of the server hardware in XClarity :param new_primary_boot_device: boot device to be set :param task: a TaskManager instance. :param singleuse: if this device will be used only once at next boot """ boot_info = self.xclarity_client.get_node_all_boot_info( server_hardware_id) xclarity_boot_device = self._translate_ironic_to_xclarity( new_primary_boot_device) current = [] LOG.debug(("Setting boot device to %(device)s for XClarity " "node %(node)s"), { 'device': xclarity_boot_device, 'node': task.node.uuid }) for item in boot_info['bootOrder']['bootOrderList']: if singleuse and item['bootType'] == 'SingleUse': item['currentBootOrderDevices'][0] = xclarity_boot_device elif not singleuse and item['bootType'] == 'Permanent': current = item['currentBootOrderDevices'] if xclarity_boot_device == current[0]: return if xclarity_boot_device in current: current.remove(xclarity_boot_device) current.insert(0, xclarity_boot_device) item['currentBootOrderDevices'] = current try: self.xclarity_client.set_node_boot_info(server_hardware_id, boot_info, xclarity_boot_device, singleuse) except xclarity_client_exceptions.XClarityError as xclarity_exc: LOG.error( ('Error setting boot device %(boot_device)s for the XClarity ' 'node %(node)s. Error: %(error)s'), { 'boot_device': xclarity_boot_device, 'node': task.node.uuid, 'error': xclarity_exc }) raise exception.XClarityError(error=xclarity_exc)
def set_power_state(self, task, power_state, timeout=None): """Turn the current power state on or off. :param task: a TaskManager instance. :param power_state: The desired power state POWER_ON, POWER_OFF or REBOOT from :mod:`ironic.common.states`. :param timeout: timeout (in seconds). Unsupported by this interface. :raises: InvalidParameterValue if an invalid power state was specified. :raises: XClarityError if XClarity fails setting the power state. """ # TODO(rloo): Support timeouts! if timeout is not None: LOG.warning( "The 'xclarity' Power Interface's 'set_power_state' method " "doesn't support the 'timeout' parameter. Ignoring " "timeout=%(timeout)s", {'timeout': timeout}) if power_state == states.REBOOT: target_power_state = self.get_power_state(task) if target_power_state == states.POWER_OFF: power_state = states.POWER_ON node = task.node client = common.get_xclarity_client(node) server_hardware_id = common.get_server_hardware_id(node) LOG.debug( "Setting power state of node %(node_uuid)s to " "%(power_state)s", { 'node_uuid': node.uuid, 'power_state': power_state }) try: client.set_node_power_status(server_hardware_id, power_state) except xclarity_client_exceptions.XClarityError as xclarity_exc: LOG.error( "Error setting power state of node %(node_uuid)s to " "%(power_state)s", { 'node_uuid': task.node.uuid, 'power_state': power_state }) raise exception.XClarityError(error=xclarity_exc)
def get_power_state(self, task): """Gets the current power state. :param task: a TaskManager instance. :returns: one of :mod:`ironic.common.states` POWER_OFF, POWER_ON or ERROR. :raises: XClarityError if fails to retrieve power state of XClarity resource """ server_hardware_id = common.get_server_hardware_id(task.node) try: power_state = self.xclarity_client.get_node_power_status( server_hardware_id) except xclarity_client_exceptions.XClarityException as xclarity_exc: LOG.error(("Error getting power state for node %(node)s. Error: " "%(error)s"), { 'node': task.node.uuid, 'error': xclarity_exc }) raise exception.XClarityError(error=xclarity_exc) return common.translate_xclarity_power_state(power_state)
def get_xclarity_client(): """Generates an instance of the XClarity client. Generates an instance of the XClarity client using the imported xclarity_client library. :returns: an instance of the XClarity client :raises: XClarityError if can't get to the XClarity client """ try: xclarity_client = client.Client( ip=CONF.xclarity.manager_ip, username=CONF.xclarity.username, password=CONF.xclarity.password, port=CONF.xclarity.port ) except xclarity_client_exceptions.XClarityError as exc: msg = (_("Error getting connection to XClarity manager IP: %(ip)s. " "Error: %(exc)s"), {'ip': CONF.xclarity.manager_ip, 'exc': exc}) raise exception.XClarityError(error=msg) return xclarity_client
def get_boot_device(self, task): """Get the current boot device for the task's node. :param task: a task from TaskManager. :returns: a dictionary containing: :boot_device: the boot device, one of [PXE, DISK, CDROM, BIOS] :persistent: Whether the boot device will persist or not It returns None if boot device is unknown. :raises: InvalidParameterValue if the boot device is unknown :raises: XClarityError if the communication with XClarity fails """ node = task.node client = common.get_xclarity_client(node) server_hardware_id = common.get_server_hardware_id(node) try: boot_info = (client.get_node_all_boot_info(server_hardware_id)) except xclarity_client_exceptions.XClarityError as xclarity_exc: LOG.error( "Error getting boot device from XClarity for node %(node)s. " "Error: %(error)s", { 'node': node.uuid, 'error': xclarity_exc }) raise exception.XClarityError(error=xclarity_exc) persistent = False primary = None boot_order = boot_info['bootOrder']['bootOrderList'] for item in boot_order: current = item.get('currentBootOrderDevices') if current is None: LOG.warning( 'Current boot order is None from XClarity for ' 'node %(node)s. Please check the hardware and ' 'XClarity connection', { 'node': node.uuid, }) return {'boot_device': None, 'persistent': None} else: primary = current[0] boot_type = item.get('bootType') if boot_type.lower() == "singleuse": persistent = False if primary != 'None': self._validate_supported_boot_device(task, primary) boot_device = { 'boot_device': BOOT_DEVICE_MAPPING_FROM_XCLARITY.get(primary), 'persistent': persistent } return boot_device elif boot_type.lower() in ['permanent', 'bootorder']: # for System X servers, permanent boot type is 'Permanent' # for Purley servers, permanent boot type is 'BootOrder' persistent = True if primary != 'None': self._validate_supported_boot_device(task, primary) boot_device = { 'boot_device': BOOT_DEVICE_MAPPING_FROM_XCLARITY.get(primary), 'persistent': persistent } return boot_device else: return {'boot_device': None, 'persistent': None}