diff --git a/ironic/drivers/ilo.py b/ironic/drivers/ilo.py index 3889bb1479..ce845a638b 100644 --- a/ironic/drivers/ilo.py +++ b/ironic/drivers/ilo.py @@ -23,7 +23,6 @@ from ironic.drivers import base from ironic.drivers.modules import agent from ironic.drivers.modules.ilo import deploy from ironic.drivers.modules.ilo import power -from ironic.drivers.modules import ipmitool class IloVirtualMediaIscsiDriver(base.BaseDriver): @@ -44,8 +43,8 @@ class IloVirtualMediaIscsiDriver(base.BaseDriver): self.power = power.IloPower() self.deploy = deploy.IloVirtualMediaIscsiDeploy() - self.console = ipmitool.IPMIShellinaboxConsole() - self.management = ipmitool.IPMIManagement() + self.console = deploy.IloConsoleInterface() + self.management = deploy.IloManagement() self.vendor = deploy.VendorPassthru() @@ -67,6 +66,6 @@ class IloVirtualMediaAgentDriver(base.BaseDriver): self.power = power.IloPower() self.deploy = deploy.IloVirtualMediaAgentDeploy() - self.console = ipmitool.IPMIShellinaboxConsole() - self.management = ipmitool.IPMIManagement() + self.console = deploy.IloConsoleInterface() + self.management = deploy.IloManagement() self.vendor = agent.AgentVendorInterface() diff --git a/ironic/drivers/modules/ilo/common.py b/ironic/drivers/modules/ilo/common.py index e5ddde3a83..9749f4cd43 100644 --- a/ironic/drivers/modules/ilo/common.py +++ b/ironic/drivers/modules/ilo/common.py @@ -68,6 +68,11 @@ OPTIONAL_PROPERTIES = { 'client_port': _("port to be used for iLO operations. Optional."), 'client_timeout': _("timeout (in seconds) for iLO operations. Optional.") } +CONSOLE_PROPERTIES = { + 'console_port': _("node's UDP port to connect to. Only required for " + "console access.") +} + COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy() COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES) DEFAULT_BOOT_MODE = 'LEGACY' @@ -113,6 +118,15 @@ def parse_driver_info(node): continue d_info[param] = value + for param in CONSOLE_PROPERTIES: + value = info.get(param) + if value: + try: + value = int(value) + d_info[param] = value + except ValueError: + error_msgs.append(_("'%s' is not an integer.") % param) + if error_msgs: msg = (_("The following errors were encountered while parsing " "driver_info:\n%s") % "\n".join(error_msgs)) diff --git a/ironic/drivers/modules/ilo/deploy.py b/ironic/drivers/modules/ilo/deploy.py index 238d88178d..082ce484d9 100644 --- a/ironic/drivers/modules/ilo/deploy.py +++ b/ironic/drivers/modules/ilo/deploy.py @@ -57,6 +57,26 @@ BOOT_DEVICE_MAPPING_TO_ILO = {'pxe': 'NETWORK', 'disk': 'HDD', 'cdrom': 'CDROM', 'bios': 'BIOS', 'safe': 'SAFE'} +def _update_ipmi_properties(task): + """Update ipmi properties to node driver_info + + :param task: a task from TaskManager. + """ + node = task.node + info = node.driver_info + + #updating ipmi credentials + info['ipmi_address'] = info['ilo_address'] + info['ipmi_username'] = info['ilo_username'] + info['ipmi_password'] = info['ilo_password'] + + if 'console_port' in info: + info['ipmi_terminal_port'] = info['console_port'] + + #saving ipmi credentials to task object + task.node.driver_info = info + + def _get_boot_iso_object_name(node): """Returns the floppy image name for a given node. @@ -449,6 +469,30 @@ class IloPXEDeploy(pxe.PXEDeploy): class IloManagement(ipmitool.IPMIManagement): + # Currently adding support to set_boot_device through iLO. All other + # functionalities (get_sensors_data etc) will be used from IPMI. + + # TODO(ramineni):To support other functionalities also using iLO. + + def get_properties(self): + return ilo_common.REQUIRED_PROPERTIES + + def validate(self, task): + """Check that 'driver_info' contains ILO and IPMI credentials. + + Validates whether the 'driver_info' property of the supplied + task's node contains the required credentials information. + + :param task: a task from TaskManager. + :raises: InvalidParameterValue if required IPMI/iLO parameters + are missing. + :raises: MissingParameterValue if a required parameter is missing. + + """ + ilo_common.parse_driver_info(task.node) + _update_ipmi_properties(task) + super(IloManagement, self).validate(task) + @task_manager.require_exclusive_lock def set_boot_device(self, task, device, persistent=False): """Set the boot device for the task's node. @@ -475,6 +519,48 @@ class IloManagement(ipmitool.IPMIManagement): ilo_common.parse_driver_info(task.node) ilo_common.set_boot_device(task.node, boot_device, persistent) + def get_sensors_data(self, task): + """Get sensors data. + + :param task: a TaskManager instance. + :raises: FailedToGetSensorData when getting the sensor data fails. + :raises: FailedToParseSensorData when parsing sensor data fails. + :raises: InvalidParameterValue if required ipmi/iLO parameters + are missing. + :raises: MissingParameterValue if a required parameter is missing. + :returns: returns a dict of sensor data group by sensor type. + + """ + ilo_common.parse_driver_info(task.node) + _update_ipmi_properties(task) + super(IloManagement, self).get_sensors_data(task) + + +class IloConsoleInterface(ipmitool.IPMIShellinaboxConsole): + """A ConsoleInterface that uses ipmitool and shellinabox.""" + + def get_properties(self): + d = ilo_common.REQUIRED_PROPERTIES.copy() + d.update(ilo_common.CONSOLE_PROPERTIES) + return d + + def validate(self, task): + """Validate the Node console info. + + :param task: a task from TaskManager. + :raises: InvalidParameterValue + :raises: MissingParameterValue when a required parameter is missing + + """ + node = task.node + driver_info = ilo_common.parse_driver_info(node) + if 'console_port' not in driver_info: + raise exception.MissingParameterValue(_( + "Console port not supplied to iLO driver.")) + + _update_ipmi_properties(task) + super(IloConsoleInterface, self).validate(task) + class IloPXEVendorPassthru(pxe.VendorPassthru): diff --git a/ironic/drivers/pxe.py b/ironic/drivers/pxe.py index ceaaa19c3e..e0d9ee2b13 100644 --- a/ironic/drivers/pxe.py +++ b/ironic/drivers/pxe.py @@ -161,7 +161,7 @@ class PXEAndIloDriver(base.BaseDriver): self.power = ilo_power.IloPower() self.deploy = ilo_deploy.IloPXEDeploy() self.vendor = ilo_deploy.IloPXEVendorPassthru() - self.console = ipmitool.IPMIShellinaboxConsole() + self.console = ilo_deploy.IloConsoleInterface() self.management = ilo_deploy.IloManagement() diff --git a/ironic/tests/conductor/test_manager.py b/ironic/tests/conductor/test_manager.py index 9ea64ea2cd..f5d025d719 100644 --- a/ironic/tests/conductor/test_manager.py +++ b/ironic/tests/conductor/test_manager.py @@ -2259,21 +2259,13 @@ class ManagerTestProperties(tests_db_base.DbTestCase): def test_driver_properties_ilo_iscsi(self): expected = ['ilo_address', 'ilo_username', 'ilo_password', 'client_port', 'client_timeout', 'ilo_deploy_iso', - 'ipmi_address', 'ipmi_terminal_port', - 'ipmi_password', 'ipmi_priv_level', - 'ipmi_username', 'ipmi_bridging', 'ipmi_transit_channel', - 'ipmi_transit_address', 'ipmi_target_channel', - 'ipmi_target_address', 'ipmi_local_address'] + 'console_port'] self._check_driver_properties("iscsi_ilo", expected) def test_driver_properties_agent_ilo(self): expected = ['ilo_address', 'ilo_username', 'ilo_password', 'client_port', 'client_timeout', 'ilo_deploy_iso', - 'ipmi_address', 'ipmi_terminal_port', - 'ipmi_password', 'ipmi_priv_level', - 'ipmi_username', 'ipmi_bridging', 'ipmi_transit_channel', - 'ipmi_transit_address', 'ipmi_target_channel', - 'ipmi_target_address', 'ipmi_local_address'] + 'console_port'] self._check_driver_properties("agent_ilo", expected) def test_driver_properties_fail(self):