def setUp(self):
     self.cmd = Command(
         bmc=self.bmc,
         userid=self.username,
         password=self.password,
         port=623
     )
Exemple #2
0
    def get_ipmi_session(self, node):
        """Initialize a Pyghmi IPMI session to the node.

        :param node: instance of objects.BaremetalNode
        :return: An instance of pyghmi.ipmi.command.Command initialized to nodes' IPMI interface
        """
        if node.oob_type != 'ipmi':
            raise errors.DriverError("Node OOB type is not IPMI")

        ipmi_network = node.oob_parameters['network']
        ipmi_address = node.get_network_address(ipmi_network)

        if ipmi_address is None:
            raise errors.DriverError("Node %s has no IPMI address" %
                                     (node.name))

        ipmi_account = node.oob_parameters['account']
        ipmi_credential = node.oob_parameters['credential']

        self.logger.debug("Starting IPMI session to %s with %s/%s" %
                          (ipmi_address, ipmi_account, ipmi_credential[:1]))
        ipmi_session = Command(
            bmc=ipmi_address, userid=ipmi_account, password=ipmi_credential)

        return ipmi_session
def main(host=None, port=None, user=None, password=None, command=None):

    c = Command(host, user, password, port=port)

    if command == "start":
        c.set_bootdev("network")
        c.set_power("on", wait=True)
    elif command == "stop":
        c.set_power("off", wait=True)
    elif command == "restart":
        c.set_power("reset", wait=True)
    elif command == "status":
        result = c.get_power()["powerstate"]
        if result == "on":
            return status.ON
        elif result == "off":
            return status.OFF
        else:
            return status.UNKNOWN
    else:
        raise exception("unknown command: %s" % command)
Exemple #4
0
def __reboot_all(boot_conf, boot_order):
    creds = get_ipmi_creds(boot_conf)
    for ip, user, password in creds:
        try:
            command = Command(ip, user, password)
            __set_boot_order(command, boot_order)
            __reboot(command)
            logger.info('Successfully rebooted server with BMC IP: %s', ip)
        except IpmiException as e:
            # print the error message and server bmc information
            # will continue to reboot the rest of servers
            logger.error(
                'Failed to reboot server with BMC IP: %s, user: %s, error: %s',
                ip, user, e)
            logger.debug('BMC password: %s', password)
Exemple #5
0
    def gen_ghmi_cmd(self):
        ''' 获取 pyghmi 的 Command 对象
        '''

        from pyghmi.ipmi.private.session import Session

        # 这块代码用于修复 pyghmi 的 Command 类在程序中只能使用一次的问题
        #
        # 出于某些未知原因,pyghmi 的 session 管理机制在 Python3 环境中无法
        # 正常工作,Session 类会使用一些类级成员变量来保存一些历史 session,
        # 但由于其管理机制失效,导致一些已经死亡的 session 仍然会驻留在session
        # 容器中,而 Session 类本身又存在一种类似于重复利用 session 的机制,
        # 导致其在 Session.__init__ 中无底线地等待已死亡的 session 获得服务端
        # 的响应。于是程序就会在第二次实例化 Session 类的时候卡死。
        #
        # 在我们的程序中,我们不需要重复利用旧有的 Session,每次发出 ipmi 指令
        # 时重新建立新的会话即可。所以,我们可以在实例化 Command 类的时候手动
        # 清除 Session 类中所保留的这些历史信息。如此,每次实例化 Command 类的
        # 时候 pyghmi 都会被迫建立新的 Session 以规避 Python3 环境下由 Session
        # 管理机制失效而导致的种种问题。
        Session.bmc_handlers = {}
        Session.waiting_sessions = {}
        Session.initting_sessions = {}
        Session.keepalive_sessions = {}
        Session.peeraddr_to_nodes = {}
        Session.iterwaiters = []
        Session.socketpool = {}
        Session.socketchecking = None

        return Command(
            self.host,
            self.user,
            self.pwd,
            self.port,
            privlevel=self.level,
        )
Exemple #6
0
def kick_via_ipmi(lom_ip, username, password):
    ipmi_session = Command(lom_ip, username, password)
    ipmi_session.set_power('off', wait=True)
    ipmi_session.set_bootdev('network')
    ipmi_session.set_power('on')
class IPMIEmulatorTestCase(unittest.TestCase):
    """ Basic tests for the IPMI emulator - this uses the default built-in
    configuration for the IPMI emulator and just tests that pyghmi can properly
    connect and get data back from the emulator.
    """
    @classmethod
    def setUpClass(cls):
        cls.username = '******'
        cls.password = '******'
        cls.bmc = 'ipmi-emulator'
        cls.sensors = []

    def setUp(self):
        self.cmd = Command(
            bmc=self.bmc,
            userid=self.username,
            password=self.password,
            port=623
        )

    def tearDown(self):
        if self.cmd:
            self.cmd.ipmi_session.logout()

    def test_000_get_power(self):
        """ Test getting power status from the emulator.
        """
        res = self.cmd.get_power()
        self.assertIn('powerstate', res)
        self.assertEqual(res['powerstate'], 'on')

    def test_001_set_power(self):
        """ Test setting power status from the emulator. In this case, turn the power
        on even though it is already on.
        """
        res = self.cmd.set_power('on', wait=True)
        self.assertIn('powerstate', res)
        self.assertEqual(res['powerstate'], 'on')

    def test_002_get_power(self):
        """ Test getting power status from the emulator, which should still be 'on'
        """
        res = self.cmd.get_power()
        self.assertIn('powerstate', res)
        self.assertEqual(res['powerstate'], 'on')

    def test_003_set_power(self):
        """ Test setting power status from the emulator. In this case, turn the power
        off from an on state
        """
        res = self.cmd.set_power('off', wait=True)
        self.assertIn('powerstate', res)
        self.assertEqual(res['powerstate'], 'off')

    def test_004_get_power(self):
        """ Test getting power status from the emulator, which should now be 'off'
        """
        res = self.cmd.get_power()
        self.assertIn('powerstate', res)
        self.assertEqual(res['powerstate'], 'off')

    def test_005_get_sensor_descriptions(self):
        """ Test getting sensor descriptions from the BMC
        """
        res = self.cmd.get_sensor_descriptions()

        types = [
            'Voltage',
            'Fan',
            'Temperature',
            'Physical Security',
            'Power Supply'
        ]

        for item in res:
            self.assertIsInstance(item, dict)
            self.assertIn('type', item)
            self.assertIn('name', item)

            self.assertIn(item['type'], types)

    def test_006_get_sensor_numbers(self):
        """ Test getting sensor numbers from the BMC
        """
        # we will first want to initialize the SDR since it doesn't seem to do it on its own
        sdr = self.cmd.init_sdr()
        res = sdr.get_sensor_numbers()

        for item in res:
            self.assertIsInstance(item, int)
            self.assertIn(item, sdr.sensors)

            # for following tests, store the sensor name
            self.sensors.append(sdr.sensors[item].name)

    def test_007_read_sensor(self):
        """ Test reading a sensor from the emulator.

        At this point, the emulator's power is off, so we should get back readings
        of 0 for sensor reads.
        """
        self.assertGreater(len(self.sensors), 0)

        for sensor in self.sensors[:12]:
            with self.assertRaises(IpmiException):
                self.cmd.get_sensor_reading(sensor)

    def test_008_set_power(self):
        """ Test setting power status from the emulator. In this case, turn the power
        on from an off state
        """
        res = self.cmd.set_power('on', wait=True)
        self.assertIn('powerstate', res)
        self.assertEqual(res['powerstate'], 'on')

    def test_009_get_power(self):
        """ Test getting power status from the emulator, which should now be 'on'
        """
        res = self.cmd.get_power()
        self.assertIn('powerstate', res)
        self.assertEqual(res['powerstate'], 'on')

    def test_010_read_sensor(self):
        """ Test reading a sensor from the emulator.

        With the power back on, we should get sensor readings now. This sensor should
        have 5 values before it loops around again.
        """
        self.assertGreater(len(self.sensors), 0)
        sensor = self.sensors[0]

        for i in range(3):
            res = self.cmd.get_sensor_reading(sensor)
            self.assertIsInstance(res, SensorReading)
            self.assertAlmostEqual(res.value, 1.16, delta=0.0001)

            res = self.cmd.get_sensor_reading(sensor)
            self.assertIsInstance(res, SensorReading)
            self.assertAlmostEqual(res.value, 1.184, delta=0.0001)

            res = self.cmd.get_sensor_reading(sensor)
            self.assertIsInstance(res, SensorReading)
            self.assertAlmostEqual(res.value, 1.168, delta=0.0001)

            res = self.cmd.get_sensor_reading(sensor)
            self.assertIsInstance(res, SensorReading)
            self.assertAlmostEqual(res.value, 1.152, delta=0.0001)

            res = self.cmd.get_sensor_reading(sensor)
            self.assertIsInstance(res, SensorReading)
            self.assertAlmostEqual(res.value, 1.152, delta=0.0001)

    def test_011_read_sensor(self):
        """ Test reading a sensor from the emulator.

        This sensor should have 2 values before it loops around again.
        """
        self.assertGreater(len(self.sensors), 2)
        sensor = self.sensors[2]

        for i in range(3):
            res = self.cmd.get_sensor_reading(sensor)
            self.assertIsInstance(res, SensorReading)
            self.assertAlmostEqual(res.value, 3.28, delta=0.0001)

            res = self.cmd.get_sensor_reading(sensor)
            self.assertIsInstance(res, SensorReading)
            self.assertAlmostEqual(res.value, 3.216, delta=0.0001)

    def test_012_read_sensor(self):
        """ Test reading a sensor from the emulator.

        This sensor should have 1 value before it loops around again.
        """
        self.assertGreater(len(self.sensors), 4)
        sensor = self.sensors[4]

        for i in range(3):
            res = self.cmd.get_sensor_reading(sensor)
            self.assertIsInstance(res, SensorReading)
            self.assertAlmostEqual(res.value, 5.152, delta=0.0001)

    def test_013_get_boot(self):
        """ Test getting boot target
        """
        res = self.cmd.get_bootdev()

        self.assertIsInstance(res, dict)
        self.assertEqual(len(res), 3)
        self.assertIn('bootdev', res)
        self.assertIn('uefimode', res)
        self.assertIn('persistent', res)

        # we only care about boot target right now
        self.assertEqual(res['bootdev'], 'default')

    def test_014_set_boot(self):
        """ Test setting boot target to the value it already is set at.
        """
        res = self.cmd.set_bootdev('default')

        self.assertIsInstance(res, dict)
        self.assertEqual(len(res), 1)
        self.assertIn('bootdev', res)
        self.assertEqual(res['bootdev'], 'default')

    def test_015_get_boot(self):
        """ Test getting boot target, which should not have changed
        """
        res = self.cmd.get_bootdev()

        self.assertIsInstance(res, dict)
        self.assertEqual(len(res), 3)
        self.assertIn('bootdev', res)
        self.assertIn('uefimode', res)
        self.assertIn('persistent', res)

        # we only care about boot target right now
        self.assertEqual(res['bootdev'], 'default')

    def test_016_set_boot(self):
        """ Test setting boot target to a new value.
        """
        res = self.cmd.set_bootdev('hd')

        self.assertIsInstance(res, dict)
        self.assertEqual(len(res), 1)
        self.assertIn('bootdev', res)
        self.assertEqual(res['bootdev'], 'hd')

    def test_017_get_boot(self):
        """ Test getting boot target, which should now have changed
        """
        res = self.cmd.get_bootdev()

        self.assertIsInstance(res, dict)
        self.assertEqual(len(res), 3)
        self.assertIn('bootdev', res)
        self.assertIn('uefimode', res)
        self.assertIn('persistent', res)

        # we only care about boot target right now
        self.assertEqual(res['bootdev'], 'hd')

    def test_018_get_inventory(self):
        """ Test getting the inventory information from the FRU
        """
        res = self.cmd.get_inventory_of_component('System')

        self.assertIsInstance(res, dict)
        keys = [
            'board_extra', 'Manufacturer', 'Product ID', 'Board model',
            'UUID', 'oem_parser', 'Hardware Version', 'Manufacturer ID',
            'Board product name', 'Board manufacturer', 'Device Revision',
            'Serial Number', 'Product name', 'Asset Number', 'Device ID',
            'Model', 'Board manufacture date', 'Board serial number',
            'product_extra'
        ]
        for k in keys:
            self.assertIn(k, res)

    def test_019_get_identify(self):
        """ Retrieve the remote system LED status
        """
        res = self.cmd.raw_command(netfn=0, command=1, data=[])

        # here, we expect the raw response back, so need to make sure it
        # matches with what is expected
        self.assertIn('command', res)
        self.assertEqual(res['command'], 1)

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0)

        self.assertIn('netfn', res)
        self.assertEqual(res['netfn'], 1)

        self.assertIn('data', res)
        self.assertIsInstance(res['data'], list)
        # validate that the LED is on
        self.assertFalse((res['data'][2] >> 5) & 0x01 or (res['data'][2] >> 4) & 0x01)

    def test_020_set_identify(self):
        """ Set the remote system LED status, here we set it to the same state it is
        already in.
        """
        # this will not have a return, so we expect 'None' - the effect
        # of this command is tested in the next test method
        res = self.cmd.set_identify(on=False)
        self.assertEqual(res, None)

    def test_021_get_identify(self):
        """ Retrieve the remote system LED status, here is should be the same.
        """
        res = self.cmd.raw_command(netfn=0, command=1, data=[])

        # here, we expect the raw response back, so need to make sure it
        # matches with what is expected
        self.assertIn('command', res)
        self.assertEqual(res['command'], 1)

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0)

        self.assertIn('netfn', res)
        self.assertEqual(res['netfn'], 1)

        self.assertIn('data', res)
        self.assertIsInstance(res['data'], list)
        # validate that the LED is on
        self.assertFalse((res['data'][2] >> 5) & 0x01 or (res['data'][2] >> 4) & 0x01)

    def test_022_set_identify(self):
        """ Set the remote system LED status, here we set it to a new state.
        """
        # this will not have a return, so we expect 'None' - the effect
        # of this command is tested in the next test method
        res = self.cmd.set_identify(on=True)
        self.assertEqual(res, None)

    def test_023_get_identify(self):
        """ Retrieve the remote system LED status, now it should have changed.
        """
        res = self.cmd.raw_command(netfn=0, command=1, data=[])

        # here, we expect the raw response back, so need to make sure it
        # matches with what is expected
        self.assertIn('command', res)
        self.assertEqual(res['command'], 1)

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0)

        self.assertIn('netfn', res)
        self.assertEqual(res['netfn'], 1)

        self.assertIn('data', res)
        self.assertIsInstance(res['data'], list)
        # validate that the LED is on
        self.assertTrue((res['data'][2] >> 5) & 0x01 or (res['data'][2] >> 4) & 0x01)

    def test_024_get_dcmi_power_reading(self):
        """ Get a DCMI power reading.
        """
        res = self.cmd.raw_command(netfn=0x2c, command=0x02, data=(0xdc, 0x01, 0x00, 0x00))

        # here, we expect the raw response back, so need to make sure it
        # matches with what is expected
        self.assertIn('command', res)
        self.assertEqual(res['command'], 0x02)

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0x00)

        self.assertIn('netfn', res)
        self.assertEqual(res['netfn'], 0x2d)

        self.assertIn('data', res)
        self.assertIsInstance(res['data'], list)

        # here we will only check the current, min, max and avg
        self.assertEqual(res['data'][1:3], [0xb9, 0x00])  # current watts
        self.assertEqual(res['data'][3:5], [0x96, 0x00])  # min watts
        self.assertEqual(res['data'][5:7], [0xfa, 0x00])  # max watts
        self.assertEqual(res['data'][7:9], [0xc8, 0x00])  # avg watts

    def test_025_get_dcmi_general_capabilities(self):
        """ Get DCMI capabilities for general capabilities support parameter (0x01).
        """
        res = self.cmd.raw_command(netfn=0x2c, command=0x01, data=(0xdc, 0x01))

        # here, we expect the raw response back, so need to make sure it
        # matches with what is expected
        self.assertIn('command', res)
        self.assertEqual(res['command'], 0x01)

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0x00)

        self.assertIn('netfn', res)
        self.assertEqual(res['netfn'], 0x2d)

        self.assertIn('data', res)
        self.assertIsInstance(res['data'], list)

        # check the response bytes for parameter 1
        self.assertEqual(res['data'][0:4], [0xdc, 0x01, 0x05, 0x02])  # dcmi 1.5 param rev 02
        self.assertEqual(res['data'][4:7], [0x00, 0x01, 0x07])  # reserved, power enabled, all mgt cap enabled

    def test_026_get_dcmi_mandatory_capabilities(self):
        """ Get DCMI capabilities for mandatory capabilities support parameter (0x02).
        """
        res = self.cmd.raw_command(netfn=0x2c, command=0x01, data=(0xdc, 0x02))

        # here, we expect the raw response back, so need to make sure it
        # matches with what is expected
        self.assertIn('command', res)
        self.assertEqual(res['command'], 0x01)

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0x00)

        self.assertIn('netfn', res)
        self.assertEqual(res['netfn'], 0x2d)

        self.assertIn('data', res)
        self.assertIsInstance(res['data'], list)

        # check the response bytes for parameter 2
        self.assertEqual(res['data'][0:4], [0xdc, 0x01, 0x05, 0x02])        # dcmi 1.5 param rev 02
        self.assertEqual(res['data'][4:9], [0x00, 0x00, 0x00, 0x00, 0x00])  # nothing supported for now (ignored)

    def test_027_get_dcmi_optional_capabilities(self):
        """ Get DCMI capabilities for optional capabilities support parameter (0x03).
        """
        res = self.cmd.raw_command(netfn=0x2c, command=0x01, data=(0xdc, 0x03))

        # here, we expect the raw response back, so need to make sure it
        # matches with what is expected
        self.assertIn('command', res)
        self.assertEqual(res['command'], 0x01)

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0x00)

        self.assertIn('netfn', res)
        self.assertEqual(res['netfn'], 0x2d)

        self.assertIn('data', res)
        self.assertIsInstance(res['data'], list)

        # check the response bytes for parameter 3
        self.assertEqual(res['data'][0:4], [0xdc, 0x01, 0x05, 0x02])    # dcmi 1.5 param rev 02
        self.assertEqual(res['data'][4:7], [0x20, 0x00])                # 0x20=BMC, primary/rev0

    def test_028_get_dcmi_mgmt_capabilities(self):
        """ Get DCMI capabilities for management controller addresses parameter (0x04).
        """
        res = self.cmd.raw_command(netfn=0x2c, command=0x01, data=(0xdc, 0x04))

        # here, we expect the raw response back, so need to make sure it
        # matches with what is expected
        self.assertIn('command', res)
        self.assertEqual(res['command'], 0x01)

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0x00)

        self.assertIn('netfn', res)
        self.assertEqual(res['netfn'], 0x2d)

        self.assertIn('data', res)
        self.assertIsInstance(res['data'], list)

        # check the response bytes for parameter 4
        self.assertEqual(res['data'][0:4], [0xdc, 0x01, 0x05, 0x02])    # dcmi 1.5 param rev 02
        self.assertEqual(res['data'][4:7], [0xff, 0xff, 0xff])          # 0xff - nothing supported (ignored)

    def test_029_get_dcmi_enhanced_power_capabilities(self):
        """ Get DCMI capabilities for enhanced power parameter (0x05).
        """
        res = self.cmd.raw_command(netfn=0x2c, command=0x01, data=(0xdc, 0x05))

        # here, we expect the raw response back, so need to make sure it
        # matches with what is expected
        self.assertIn('command', res)
        self.assertEqual(res['command'], 0x01)

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0x00)

        self.assertIn('netfn', res)
        self.assertEqual(res['netfn'], 0x2d)

        self.assertIn('data', res)
        self.assertIsInstance(res['data'], list)

        # check the response bytes for parameter 5
        self.assertEqual(res['data'][0:4], [0xdc, 0x01, 0x05, 0x02])    # dcmi 1.5 param rev 02
        self.assertEqual(res['data'][4:6], [0x01, 0x00])                # 0x01 - 1 avg period, 0x00 "now"

    def test_030_get_dcmi_bad_capabilities(self):
        """ Get DCMI capabilities where the parameter selector is invalid, so we timeout.
            (IRL, there would likely be a proper IPMI error returned here, but we can at least test timout here).
        """
        res = self.cmd.raw_command(netfn=0x2c, command=0x01, data=(0xdc, 0x06))

        # for now we expect a timeout error, with code of 65535 (0xffff)
        self.assertIn('error', res)
        self.assertEqual(res['error'], 'timeout')

        self.assertIn('code', res)
        self.assertEqual(res['code'], 0xffff)