def setUp(self): self.cmd = Command( bmc=self.bmc, userid=self.username, password=self.password, port=623 )
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)
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)
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, )
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)