Пример #1
0
    def test__finds_power_address_from_mac_address(self):
        context = make_context()
        driver = IPMIPowerDriver()
        ip_address = factory.make_ipv4_address()
        find_ip_via_arp = self.patch(ipmi_module, 'find_ip_via_arp')
        find_ip_via_arp.return_value = ip_address
        power_change = random.choice(("on", "off"))

        context['mac_address'] = factory.make_mac_address()
        context['power_address'] = random.choice((None, "", "   "))

        self.patch_autospec(driver, "_issue_ipmi_chassis_config_command")
        self.patch_autospec(driver, "_issue_ipmipower_command")
        driver._issue_ipmi_command(power_change, **context)

        # The IP address is passed to _issue_ipmi_chassis_config_command.
        self.assertThat(
            driver._issue_ipmi_chassis_config_command,
            MockCalledOnceWith(ANY,
                               power_change,
                               ip_address,
                               power_boot_type=None))
        # The IP address is also within the command passed to
        # _issue_ipmi_chassis_config_command.
        self.assertThat(driver._issue_ipmi_chassis_config_command.call_args[0],
                        Contains(ip_address))
        # The IP address is passed to _issue_ipmipower_command.
        self.assertThat(driver._issue_ipmipower_command,
                        MockCalledOnceWith(ANY, power_change, ip_address))
        # The IP address is also within the command passed to
        # _issue_ipmipower_command.
        self.assertThat(driver._issue_ipmipower_command.call_args[0],
                        Contains(ip_address))
Пример #2
0
    def test_power_query_retires_on_kg_error(self):
        context = make_context()
        k_g = context.pop("k_g", factory.make_name("k_g"))
        ipmi_power_driver = IPMIPowerDriver()
        mock_issue_ipmi_command = self.patch(ipmi_power_driver,
                                             "_issue_ipmi_command")
        k_g_error = IPMI_ERRORS["k_g invalid"]
        mock_issue_ipmi_command.side_effect = (
            k_g_error["exception"](k_g_error["message"]),
            None,
        )
        system_id = factory.make_name("system_id")

        ipmi_power_driver.power_query(system_id, {"k_g": k_g, **context})

        self.assertThat(
            mock_issue_ipmi_command,
            MockCallsMatch(
                call("query", **{
                    "k_g": k_g,
                    **context
                }),
                call("query", **context),
            ),
        )
Пример #3
0
    def test__issue_ipmi_command_issues_power_on(self):
        context = make_context()
        ipmi_chassis_config_command = make_ipmi_chassis_config_command(
            **context, tmp_config_name=ANY)
        ipmipower_command = make_ipmipower_command(**context)
        ipmipower_command += ("--cycle", "--on-if-off")
        ipmi_power_driver = IPMIPowerDriver()
        env = get_env_with_locale()
        popen_mock = self.patch(ipmi_module, "Popen")
        process = popen_mock.return_value
        process.communicate.side_effect = [(b"", b""), (b"on", b"")]
        process.returncode = 0

        result = ipmi_power_driver._issue_ipmi_command("on", **context)

        self.expectThat(
            popen_mock,
            MockCallsMatch(
                call(
                    ipmi_chassis_config_command,
                    stdout=PIPE,
                    stderr=PIPE,
                    env=env,
                ),
                call(ipmipower_command, stdout=PIPE, stderr=PIPE, env=env),
            ),
        )
        self.expectThat(result, Equals("on"))
Пример #4
0
    def test__issue_ipmi_command_issues_power_off_soft_mode(self):
        context = make_context()
        context['power_off_mode'] = 'soft'
        ipmi_chassis_config_command = make_ipmi_chassis_config_command(
            **context, tmp_config_name=ANY)
        ipmipower_command = make_ipmipower_command(**context)
        ipmipower_command += ('--soft', )
        ipmi_power_driver = IPMIPowerDriver()
        env = get_env_with_locale()
        popen_mock = self.patch(ipmi_module, 'Popen')
        process = popen_mock.return_value
        process.communicate.side_effect = [(b'', b''), (b'off', b'')]
        process.returncode = 0

        result = ipmi_power_driver._issue_ipmi_command('off', **context)

        self.expectThat(
            popen_mock,
            MockCallsMatch(
                call(ipmi_chassis_config_command,
                     stdout=PIPE,
                     stderr=PIPE,
                     env=env),
                call(ipmipower_command, stdout=PIPE, stderr=PIPE, env=env)))
        self.expectThat(result, Equals('off'))
Пример #5
0
    def test__chassis_config_written_to_temporary_file_with_boot_type(self):
        boot_type = self.patch(ipmi_module, "power_boot_type")
        boot_type.return_value = IPMI_BOOT_TYPE.EFI
        NamedTemporaryFile = self.patch(ipmi_module, "NamedTemporaryFile")
        tmpfile = NamedTemporaryFile.return_value
        tmpfile.__enter__.return_value = tmpfile
        tmpfile.name = factory.make_name("filename")

        IPMIPowerDriver._issue_ipmi_chassis_config_command(
            ["true"],
            sentinel.change,
            sentinel.addr,
            power_boot_type=IPMI_BOOT_TYPE.EFI,
        )

        self.assertThat(NamedTemporaryFile,
                        MockCalledOnceWith("w+", encoding="utf-8"))
        self.assertThat(tmpfile.__enter__, MockCalledOnceWith())
        self.assertThat(
            tmpfile.write,
            MockCalledOnceWith(IPMI_CONFIG_WITH_BOOT_TYPE %
                               IPMI_BOOT_TYPE_MAPPING[IPMI_BOOT_TYPE.EFI]),
        )
        self.assertThat(tmpfile.flush, MockCalledOnceWith())
        self.assertThat(tmpfile.__exit__, MockCalledOnceWith(None, None, None))
Пример #6
0
 def test_issue_ipmi_command_issues_power_query(self):
     context = make_context()
     ipmipower_command = make_ipmipower_command(**context)
     ipmipower_command += ("--stat", )
     ipmi_power_driver = IPMIPowerDriver()
     run_command_mock = self.patch(ipmi_module.shell, "run_command")
     run_command_mock.return_value = ProcessResult(stdout="other")
     result = ipmi_power_driver._issue_ipmi_command("query", **context)
     run_command_mock.assert_called_once_with(*ipmipower_command)
     self.expectThat(result, Equals("other"))
Пример #7
0
    def test_power_off_calls__issue_ipmi_command(self):
        context = make_context()
        ipmi_power_driver = IPMIPowerDriver()
        _issue_ipmi_command_mock = self.patch(ipmi_power_driver,
                                              '_issue_ipmi_command')
        system_id = factory.make_name('system_id')
        ipmi_power_driver.power_off(system_id, context)

        self.assertThat(_issue_ipmi_command_mock,
                        MockCalledOnceWith('off', **context))
Пример #8
0
    def test_power_query_calls__issue_ipmi_command(self):
        context = make_context()
        ipmi_power_driver = IPMIPowerDriver()
        _issue_ipmi_command_mock = self.patch(ipmi_power_driver,
                                              "_issue_ipmi_command")
        system_id = factory.make_name("system_id")
        ipmi_power_driver.power_query(system_id, context)

        self.assertThat(_issue_ipmi_command_mock,
                        MockCalledOnceWith("query", **context))
Пример #9
0
 def test__issue_ipmi_chassis_config_command_logs_maaslog_warning(self):
     power_address = factory.make_name('power_address')
     stderr = factory.make_name('stderr')
     popen_mock = self.patch(ipmi_module, 'Popen')
     process = popen_mock.return_value
     process.communicate.return_value = (b'', stderr.encode('utf-8'))
     maaslog = self.patch(ipmi_module, 'maaslog')
     IPMIPowerDriver._issue_ipmi_chassis_config_command(
         factory.make_name('command'), factory.make_name('power_change'),
         power_address)
     self.assertThat(
         maaslog.warning, MockCalledOnceWith(
             "Failed to change the boot order to PXE %s: %s" % (
                 power_address, stderr)))
Пример #10
0
    def test__chassis_config_written_to_temporary_file(self):
        NamedTemporaryFile = self.patch(ipmi_module, "NamedTemporaryFile")
        tmpfile = NamedTemporaryFile.return_value
        tmpfile.__enter__.return_value = tmpfile
        tmpfile.name = factory.make_name("filename")

        IPMIPowerDriver._issue_ipmi_chassis_config_command(
            ["true"], sentinel.change, sentinel.addr)

        self.assertThat(
            NamedTemporaryFile, MockCalledOnceWith("w+", encoding="utf-8"))
        self.assertThat(tmpfile.__enter__, MockCalledOnceWith())
        self.assertThat(tmpfile.write, MockCalledOnceWith(IPMI_CONFIG))
        self.assertThat(tmpfile.flush, MockCalledOnceWith())
        self.assertThat(tmpfile.__exit__, MockCalledOnceWith(None, None, None))
Пример #11
0
 def test_issue_ipmi_command_issues_power_on(self):
     context = make_context()
     ipmi_chassis_config_command = make_ipmi_chassis_config_command(
         **context, tmp_config_name=ANY)
     ipmipower_command = make_ipmipower_command(**context)
     ipmipower_command += ("--cycle", "--on-if-off")
     ipmi_power_driver = IPMIPowerDriver()
     run_command_mock = self.patch(ipmi_module.shell, "run_command")
     run_command_mock.side_effect = [
         ProcessResult(),
         ProcessResult(stdout="on"),
     ]
     result = ipmi_power_driver._issue_ipmi_command("on", **context)
     run_command_mock.assert_has_calls(
         [call(*ipmi_chassis_config_command),
          call(*ipmipower_command)])
     self.expectThat(result, Equals("on"))
Пример #12
0
 def test_issue_ipmi_chassis_config_command_logs_maaslog_warning(self):
     power_address = factory.make_name("power_address")
     stderr = factory.make_name("stderr")
     run_command_mock = self.patch(ipmi_module.shell, "run_command")
     run_command_mock.return_value = ProcessResult(stderr=stderr,
                                                   returncode=1)
     maaslog = self.patch(ipmi_module, "maaslog")
     IPMIPowerDriver._issue_ipmi_chassis_config_command(
         [factory.make_name("command")],
         factory.make_name("power_change"),
         power_address,
     )
     self.assertThat(
         maaslog.warning,
         MockCalledOnceWith(
             "Failed to change the boot order to PXE %s: %s" %
             (power_address, stderr)),
     )
Пример #13
0
 def test__issue_ipmi_chassis_config_command_logs_maaslog_warning(self):
     power_address = factory.make_name("power_address")
     stderr = factory.make_name("stderr")
     popen_mock = self.patch(ipmi_module, "Popen")
     process = popen_mock.return_value
     process.communicate.return_value = (b"", stderr.encode("utf-8"))
     maaslog = self.patch(ipmi_module, "maaslog")
     IPMIPowerDriver._issue_ipmi_chassis_config_command(
         factory.make_name("command"),
         factory.make_name("power_change"),
         power_address,
     )
     self.assertThat(
         maaslog.warning,
         MockCalledOnceWith(
             "Failed to change the boot order to PXE %s: %s" %
             (power_address, stderr)),
     )
Пример #14
0
    def test__issue_ipmi_command_issues_power_query(self):
        context = make_context()
        ipmipower_command = make_ipmipower_command(**context)
        ipmipower_command += ('--stat', )
        ipmi_power_driver = IPMIPowerDriver()
        env = select_c_utf8_locale()
        popen_mock = self.patch(ipmi_module, 'Popen')
        process = popen_mock.return_value
        process.communicate.return_value = (b'other', b'')
        process.returncode = 0

        result = ipmi_power_driver._issue_ipmi_command('query', **context)

        self.expectThat(
            popen_mock, MockCalledOnceWith(
                ipmipower_command, stdout=PIPE,
                stderr=PIPE, env=env))
        self.expectThat(result, Equals('other'))
Пример #15
0
 def test__issue_ipmipower_command_does_not_mistake_host_for_status(self):
     popen_mock = self.patch(ipmi_module, 'Popen')
     process = popen_mock.return_value
     # "cameron" contains the string "on", but the machine is off.
     process.communicate.return_value = (b'cameron: off', b'')
     process.returncode = 0
     self.assertThat(
         IPMIPowerDriver._issue_ipmipower_command(
             factory.make_name('command'), 'query',
             factory.make_name('address')), Equals("off"))
Пример #16
0
    def test__issue_ipmi_command_issues_power_off_soft_mode(self):
        context = make_context()
        context["power_off_mode"] = "soft"
        ipmipower_command = make_ipmipower_command(**context)
        ipmipower_command += ("--soft", )
        ipmi_power_driver = IPMIPowerDriver()
        env = get_env_with_locale()
        popen_mock = self.patch(ipmi_module, "Popen")
        process = popen_mock.return_value
        process.communicate.side_effect = [(b"off", b"")]
        process.returncode = 0

        result = ipmi_power_driver._issue_ipmi_command("off", **context)

        self.expectThat(
            popen_mock,
            MockCallsMatch(
                call(ipmipower_command, stdout=PIPE, stderr=PIPE, env=env)),
        )
        self.expectThat(result, Equals("off"))
Пример #17
0
    def test__issue_ipmi_command_issues_power_query(self):
        context = make_context()
        ipmipower_command = make_ipmipower_command(**context)
        ipmipower_command += ("--stat", )
        ipmi_power_driver = IPMIPowerDriver()
        env = get_env_with_locale()
        popen_mock = self.patch(ipmi_module, "Popen")
        process = popen_mock.return_value
        process.communicate.return_value = (b"other", b"")
        process.returncode = 0

        result = ipmi_power_driver._issue_ipmi_command("query", **context)

        self.expectThat(
            popen_mock,
            MockCalledOnceWith(ipmipower_command,
                               stdout=PIPE,
                               stderr=PIPE,
                               env=env),
        )
        self.expectThat(result, Equals("other"))
Пример #18
0
 def test_issue_ipmipower_command_does_not_mistake_host_for_status(self):
     run_command_mock = self.patch(ipmi_module.shell, "run_command")
     # "cameron" contains the string "on", but the machine is off.
     run_command_mock.return_value = ProcessResult(stdout="cameron: off")
     self.assertThat(
         IPMIPowerDriver._issue_ipmipower_command(
             factory.make_name("command"),
             "query",
             factory.make_name("address"),
         ),
         Equals("off"),
     )
Пример #19
0
    def test__issue_ipmi_chassis_config_with_power_boot_type(self):
        context = make_context()
        driver = IPMIPowerDriver()
        ip_address = factory.make_ipv4_address()
        find_ip_via_arp = self.patch(ipmi_module, "find_ip_via_arp")
        find_ip_via_arp.return_value = ip_address
        power_change = "on"

        context["mac_address"] = factory.make_mac_address()
        context["power_address"] = random.choice((None, "", "   "))
        context["power_boot_type"] = IPMI_BOOT_TYPE.EFI

        self.patch_autospec(driver, "_issue_ipmi_chassis_config_command")
        self.patch_autospec(driver, "_issue_ipmipower_command")
        driver._issue_ipmi_command(power_change, **context)

        # The IP address is passed to _issue_ipmi_chassis_config_command.
        self.assertThat(
            driver._issue_ipmi_chassis_config_command,
            MockCalledOnceWith(
                ANY,
                power_change,
                ip_address,
                power_boot_type=IPMI_BOOT_TYPE.EFI,
            ),
        )
        # The IP address is also within the command passed to
        # _issue_ipmi_chassis_config_command.
        self.assertThat(
            driver._issue_ipmi_chassis_config_command.call_args[0],
            Contains(ip_address),
        )
        # The IP address is passed to _issue_ipmipower_command.
        self.assertThat(
            driver._issue_ipmipower_command,
            MockCalledOnceWith(ANY, power_change, ip_address),
        )
Пример #20
0
        # is to be performed.
        schemas = [
            driver.get_schema(detect_missing_packages=detect_missing_packages)
            for _, driver in cls
        ]
        validate(schemas, JSON_POWER_DRIVERS_SCHEMA)
        return schemas


# Register all the power drivers.
power_drivers = [
    AMTPowerDriver(),
    APCPowerDriver(),
    DLIPowerDriver(),
    HMCPowerDriver(),
    IPMIPowerDriver(),
    LXDPowerDriver(),
    ManualPowerDriver(),
    MoonshotIPMIPowerDriver(),
    MSCMPowerDriver(),
    MicrosoftOCSPowerDriver(),
    NovaPowerDriver(),
    OpenBMCPowerDriver(),
    RECSPowerDriver(),
    RedfishPowerDriver(),
    SeaMicroPowerDriver(),
    UCSMPowerDriver(),
    VirshPowerDriver(),
    VMwarePowerDriver(),
    WedgePowerDriver(),
]