diff --git a/ironic/drivers/modules/ssh.py b/ironic/drivers/modules/ssh.py index 8d0e87723c..a8b346f6e1 100644 --- a/ironic/drivers/modules/ssh.py +++ b/ironic/drivers/modules/ssh.py @@ -349,10 +349,18 @@ def _get_power_status(ssh_obj, driver_info): driver_info['cmd_set']['list_running']) cmd_to_exec = cmd_to_exec.replace('{_NodeName_}', node_name) running_list = _ssh_execute(ssh_obj, cmd_to_exec) + + # Command should return a list of running vms. If the current node is + # not listed then we can assume it is not powered on. + quoted_node_name = '"%s"' % node_name for node in running_list: if not node: continue - if node_name in node: + # 'node' here is an formatted output from the virt cli's. The + # node name is always quoted but can contain other information. + # vbox returns '"NodeName" {b43c4982-110c-4c29-9325-d5f41b053513}' + # so we must use the 'in' comparison here and not '==' + if quoted_node_name in node: power_state = states.POWER_ON break if not power_state: diff --git a/ironic/tests/drivers/test_ssh.py b/ironic/tests/drivers/test_ssh.py index 3e3cebf304..b8421e5642 100644 --- a/ironic/tests/drivers/test_ssh.py +++ b/ironic/tests/drivers/test_ssh.py @@ -297,6 +297,19 @@ class SSHPrivateMethodsTestCase(db_base.DbTestCase): exec_ssh_mock.assert_called_once_with( self.sshclient, ssh_cmd) + @mock.patch.object(processutils, 'ssh_execute') + @mock.patch.object(ssh, '_get_hosts_name_for_node') + def test__get_power_status_correct_node(self, get_hosts_name_mock, + exec_ssh_mock): + # Bug: #1397834 test that get_power_status return status of + # baremeta_1 (off) and not baremetal_11 (on) + info = ssh._parse_driver_info(self.node) + exec_ssh_mock.return_value = ('"baremetal_11"\n"seed"\n', '') + get_hosts_name_mock.return_value = "baremetal_1" + + pstate = ssh._get_power_status(self.sshclient, info) + self.assertEqual(states.POWER_OFF, pstate) + @mock.patch.object(processutils, 'ssh_execute') def test__get_hosts_name_for_node_match(self, exec_ssh_mock): info = ssh._parse_driver_info(self.node) @@ -916,7 +929,8 @@ class SSHDriverTestCase(db_base.DbTestCase): nodename = 'fakevm' mock_h.return_value = nodename mock_get_conn.return_value = self.sshclient - mock_exc.return_value = (nodename, '') + # list_running quotes names + mock_exc.return_value = ('"%s"' % nodename, '') with task_manager.acquire(self.context, self.node.uuid) as task: task.node['driver_info']['ssh_virt_type'] = 'vmware' power_state = self.driver.power.get_power_state(task)