pyghmi 1.5.59__tar.gz → 1.5.61__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {pyghmi-1.5.59 → pyghmi-1.5.61}/ChangeLog +14 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/PKG-INFO +1 -1
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/energy.py +20 -1
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/handler.py +23 -22
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/imm.py +41 -35
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/nextscale.py +7 -2
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/lenovo/xcc.py +27 -7
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi.egg-info/PKG-INFO +1 -1
- pyghmi-1.5.61/pyghmi.egg-info/pbr.json +1 -0
- pyghmi-1.5.59/pyghmi.egg-info/pbr.json +0 -1
- {pyghmi-1.5.59 → pyghmi-1.5.61}/.coveragerc +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/.stestr.conf +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/AUTHORS +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/CONTRIBUTING.rst +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/LICENSE +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/MANIFEST.in +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/README +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/README.md +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/builddeb +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/buildrpm +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/doc/requirements.txt +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/doc/source/conf.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/doc/source/contributor/index.rst +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/doc/source/index.rst +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/doc/source/install/index.rst +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/doc/source/reference/index.rst +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/makesetup +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/playbooks/legacy/tempest-devstack-ironic-pxe_ipmitool-pyghmi-src/post.yaml +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/playbooks/legacy/tempest-devstack-ironic-pxe_ipmitool-pyghmi-src/run.yaml +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/py27-constraints.txt +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/cmd/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/cmd/fakebmc.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/cmd/pyghmicons.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/cmd/pyghmiutil.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/cmd/virshbmc.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/constants.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/exceptions.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/bmc.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/command.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/console.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/events.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/fru.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/generic.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/config.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/cpu.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/dimm.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/drive.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/firmware.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/inventory.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/pci.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/psu.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/raid_controller.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lenovo/raid_drive.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/oem/lookup.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/private/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/private/constants.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/private/localsession.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/private/serversession.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/private/session.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/private/simplesession.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/private/spd.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/private/util.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/ipmi/sdr.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/media.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/command.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/dell/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/dell/idrac.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/dell/main.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/generic.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/lenovo/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/lenovo/main.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/lenovo/tsma.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/redfish/oem/lookup.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/storage.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/tests/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/tests/unit/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/tests/unit/base.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/tests/unit/ipmi/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/tests/unit/ipmi/test_sdr.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/util/__init__.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/util/parse.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/util/webclient.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi/version.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi.egg-info/SOURCES.txt +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi.egg-info/dependency_links.txt +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi.egg-info/entry_points.txt +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi.egg-info/not-zip-safe +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi.egg-info/requires.txt +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/pyghmi.egg-info/top_level.txt +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/python-pyghmi.spec +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/python-pyghmi.spec.tmpl +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/requirements.txt +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/setup.cfg +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/setup.py +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/setup.py.tmpl +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/test-requirements.txt +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/tox.ini +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/wheezy.patch +0 -0
- {pyghmi-1.5.59 → pyghmi-1.5.61}/zuul.d/project.yaml +0 -0
@@ -1,6 +1,20 @@
|
|
1
1
|
CHANGES
|
2
2
|
=======
|
3
3
|
|
4
|
+
1.5.61
|
5
|
+
------
|
6
|
+
|
7
|
+
* Follow state of validate job when updating firmware
|
8
|
+
* Handle FRU with blank mac area
|
9
|
+
* Stage alternate power meter support
|
10
|
+
|
11
|
+
1.5.60
|
12
|
+
------
|
13
|
+
|
14
|
+
* Avoid doing extra AddNewVolWithNaAsync calls
|
15
|
+
* Update storage code to handle 2023 XCC FW
|
16
|
+
* Fix for newer SMMv2 firmware
|
17
|
+
|
4
18
|
1.5.59
|
5
19
|
------
|
6
20
|
|
@@ -31,7 +31,9 @@ class EnergyManager(object):
|
|
31
31
|
try:
|
32
32
|
rsp = ipmicmd.xraw_command(netfn=0x3a, command=0x32, data=[4, 2, 0, 0, 0])
|
33
33
|
if len(rsp['data']) >= 8:
|
34
|
-
self.supportedmeters = ('DC Energy',)
|
34
|
+
self.supportedmeters = ('DC Energy',) # 'GPU Power',
|
35
|
+
# 'Node Power', 'Total Power')
|
36
|
+
self._mypowermeters = ('node power', 'total power', 'gpu power', 'riser 1 power', 'riser 2 power')
|
35
37
|
self._usefapm = True
|
36
38
|
return
|
37
39
|
except pygexc.IpmiException:
|
@@ -57,6 +59,23 @@ class EnergyManager(object):
|
|
57
59
|
else:
|
58
60
|
self.supportedmeters = ('DC Energy',)
|
59
61
|
|
62
|
+
def supports(self, name):
|
63
|
+
if name.lower() in self._mypowermeters:
|
64
|
+
return True
|
65
|
+
return False
|
66
|
+
|
67
|
+
def get_sensor(self, name, ipmicmd):
|
68
|
+
if name.lower() not in self._mypowermeters:
|
69
|
+
raise pygexc.UnsupportedFunctionality('Unrecogcized sensor')
|
70
|
+
rsp = ipmicmd.xraw_command(netfn=0x3a, command=0x32, data=[4, 8, 0, 0, 0])
|
71
|
+
npow, gpupow, r1pow, r2pow = struct.unpack('<HHHH', rsp['data'][6:10])
|
72
|
+
if name.lower().startswith('node'):
|
73
|
+
return npow, 'W'
|
74
|
+
elif name.lower().startswith('gpu'):
|
75
|
+
return gpupow, 'W'
|
76
|
+
elif name.lower().startswith('total'):
|
77
|
+
return npow + gpupow, 'W'
|
78
|
+
|
60
79
|
def get_fapm_energy(self, ipmicmd):
|
61
80
|
rsp = ipmicmd.xraw_command(netfn=0x3a, command=0x32, data=[4, 2, 0, 0, 0])
|
62
81
|
j, mj = struct.unpack('<IH', rsp['data'][2:8])
|
@@ -718,27 +718,28 @@ class OEMHandler(generic.OEMHandler):
|
|
718
718
|
fru['FRU Number'] = bextra[0]
|
719
719
|
fru['Revision'] = bextra[4]
|
720
720
|
macs = bextra[6]
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
macprefix
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
721
|
+
if macs:
|
722
|
+
macprefix = None
|
723
|
+
idx = 0
|
724
|
+
endidx = len(macs) - 5
|
725
|
+
macprefix = None
|
726
|
+
while idx < endidx:
|
727
|
+
currmac = macs[idx:idx + 6]
|
728
|
+
if not isinstance(currmac, bytearray):
|
729
|
+
# invalid vpd format, abort attempts to extract
|
730
|
+
# mac in this way
|
731
|
+
break
|
732
|
+
if currmac == b'\x00\x00\x00\x00\x00\x00':
|
733
|
+
break
|
734
|
+
# VPD may veer off, detect and break off
|
735
|
+
if macprefix is None:
|
736
|
+
macprefix = currmac[:3]
|
737
|
+
elif currmac[:3] != macprefix:
|
738
|
+
break
|
739
|
+
ms = mac_format.format(*currmac)
|
740
|
+
ifidx = idx / 6 + 1
|
741
|
+
fru['MAC Address {0}'.format(ifidx)] = ms
|
742
|
+
idx = idx + 6
|
742
743
|
except (AttributeError, KeyError, IndexError):
|
743
744
|
pass
|
744
745
|
if self.has_xcc and name and name.startswith('PSU '):
|
@@ -1202,7 +1203,7 @@ class OEMHandler(generic.OEMHandler):
|
|
1202
1203
|
if self.has_xcc:
|
1203
1204
|
return self.immhandler.get_bmc_configuration()
|
1204
1205
|
if self.is_fpc:
|
1205
|
-
return self.smmhandler.get_bmc_configuration()
|
1206
|
+
return self.smmhandler.get_bmc_configuration(self._fpc_variant)
|
1206
1207
|
if self.has_tsma:
|
1207
1208
|
return self.tsmahandler.get_bmc_configuration()
|
1208
1209
|
return super(OEMHandler, self).get_bmc_configuration()
|
@@ -684,8 +684,13 @@ class IMMClient(object):
|
|
684
684
|
return ()
|
685
685
|
|
686
686
|
def get_oem_sensor_descriptions(self, ipmicmd):
|
687
|
-
|
688
|
-
|
687
|
+
desc = []
|
688
|
+
for x in self.get_oem_sensor_names(ipmicmd):
|
689
|
+
desc.append({
|
690
|
+
'name': x,
|
691
|
+
'type': 'Power' if 'Power' in x else 'Energy'
|
692
|
+
})
|
693
|
+
return desc
|
689
694
|
|
690
695
|
def get_oem_sensor_reading(self, name, ipmicmd):
|
691
696
|
if self._energymanager is None:
|
@@ -694,8 +699,15 @@ class IMMClient(object):
|
|
694
699
|
kwh = self._energymanager.get_ac_energy(ipmicmd)
|
695
700
|
elif name == 'DC Energy':
|
696
701
|
kwh = self._energymanager.get_dc_energy(ipmicmd)
|
702
|
+
elif self._energymanager.supports(name):
|
703
|
+
value, units = self._energymanager.get_sensor(name, ipmicmd)
|
704
|
+
return sdr.SensorReading({
|
705
|
+
'name': name, 'imprecision': None,
|
706
|
+
'value': value,
|
707
|
+
'states': [], 'state_ids': [], 'health': pygconst.Health.Ok,
|
708
|
+
'type': 'Power'}, units)
|
697
709
|
else:
|
698
|
-
raise pygexc.UnsupportedFunctionality('No
|
710
|
+
raise pygexc.UnsupportedFunctionality('No such sensor ' + name)
|
699
711
|
return sdr.SensorReading({'name': name, 'imprecision': None,
|
700
712
|
'value': kwh, 'states': [],
|
701
713
|
'state_ids': [],
|
@@ -1489,12 +1501,23 @@ class XCCClient(IMMClient):
|
|
1489
1501
|
def _create_array(self, pool):
|
1490
1502
|
params = self._parse_array_spec(pool)
|
1491
1503
|
cid = params['controller'].split(',')[0]
|
1504
|
+
cslotno = params['controller'].split(',')[1]
|
1492
1505
|
url = '/api/function/raid_conf?params=raidlink_GetDefaultVolProp'
|
1493
1506
|
args = (url, cid, 0, params['drives'])
|
1494
1507
|
props = self.wc.grab_json_response(','.join([str(x) for x in args]))
|
1508
|
+
usesctrlslot = False
|
1495
1509
|
if not props: # newer firmware requires raidlevel too
|
1496
1510
|
args = (url, cid, params['raidlevel'], 0, params['drives'])
|
1497
1511
|
props = self.wc.grab_json_response(','.join([str(x) for x in args]))
|
1512
|
+
elif 'return' in props and props['return'] == 22:
|
1513
|
+
# Jan 2023 XCC FW - without controller slot number
|
1514
|
+
args = (url, cid, params['raidlevel'], 0, params['drives'])
|
1515
|
+
props = self.wc.grab_json_response(','.join([str(x) for x in args]))
|
1516
|
+
if 'return' in props and props['return'] == 22:
|
1517
|
+
usesctrlslot = True
|
1518
|
+
# Jan 2023 XCC FW - with controller slot number
|
1519
|
+
args = (url, cid, params['raidlevel'], 0, params['drives'], cslotno)
|
1520
|
+
props = self.wc.grab_json_response(','.join([str(x) for x in args]))
|
1498
1521
|
props = props['items'][0]
|
1499
1522
|
volumes = pool.volumes
|
1500
1523
|
remainingcap = params['capacity']
|
@@ -1565,14 +1588,14 @@ class XCCClient(IMMClient):
|
|
1565
1588
|
parms = {'raidlink_AddNewVolWithNaAsync': arglist}
|
1566
1589
|
rsp = self.wc.grab_json_response(url, parms)
|
1567
1590
|
if rsp['return'] == 14: # newer firmware
|
1568
|
-
if 'supported_cpwb' in props: #
|
1591
|
+
if 'supported_cpwb' in props and not usesctrlslot: # no ctrl_type
|
1569
1592
|
arglist = '{0},{1},{2},{3},{4},{5},{6},'.format(
|
1570
1593
|
cnum, params['raidlevel'], params['spans'],
|
1571
1594
|
params['perspan'], 0, params['drives'], params['hotspares'])
|
1572
1595
|
arglist += ''.join(vols)
|
1573
1596
|
parms = {'raidlink_AddNewVolWithNaAsync': arglist}
|
1574
1597
|
rsp = self.wc.grab_json_response(url, parms)
|
1575
|
-
else: #
|
1598
|
+
else: # with ctrl_type
|
1576
1599
|
if cid[2] == 2:
|
1577
1600
|
cnum = cid[1]
|
1578
1601
|
arglist = '{0},{1},{2},{3},{4},{5},'.format(
|
@@ -1615,32 +1638,6 @@ class XCCClient(IMMClient):
|
|
1615
1638
|
# oemsensornames = oemsensornames + (name,)
|
1616
1639
|
# return oemsensornames
|
1617
1640
|
|
1618
|
-
def get_oem_sensor_descriptions(self, ipmicmd):
|
1619
|
-
oemdesc = [{'name': x, 'type': 'Energy'} for x in super(
|
1620
|
-
XCCClient, self).get_oem_sensor_names(ipmicmd)]
|
1621
|
-
return oemdesc
|
1622
|
-
# therminfo = self.grab_cacheable_json(
|
1623
|
-
# '/api/dataset/pwrmgmt?params=GetThermalRealTimeData', 1)
|
1624
|
-
# if therminfo:
|
1625
|
-
# for name in sorted(therminfo['items'][0]):
|
1626
|
-
# if 'DIMM' in name and 'Temp' in name:
|
1627
|
-
# oemdesc.append({'name': name, 'type': 'Temperature'})
|
1628
|
-
# return oemdesc
|
1629
|
-
|
1630
|
-
def get_oem_sensor_reading(self, name, ipmicmd):
|
1631
|
-
if 'Energy' in name:
|
1632
|
-
return super(XCCClient, self).get_oem_sensor_reading(name, ipmicmd)
|
1633
|
-
therminfo = self.grab_cacheable_json(
|
1634
|
-
'/api/dataset/pwrmgmt?params=GetThermalRealTimeData', 1)
|
1635
|
-
temp = therminfo.get('items', [{}])[0].get(name, None)
|
1636
|
-
if temp is None:
|
1637
|
-
raise pygexc.UnsupportedFunctionality('No sunch sensor ' + name)
|
1638
|
-
return sdr.SensorReading({'name': name, 'imprecision': None,
|
1639
|
-
'value': temp, 'states': [],
|
1640
|
-
'state_ids': [],
|
1641
|
-
'health': pygconst.Health.Ok,
|
1642
|
-
'type': 'Temperature'}, '°C')
|
1643
|
-
|
1644
1641
|
def get_storage_configuration(self, logout=True):
|
1645
1642
|
rsp = self.wc.grab_json_response(
|
1646
1643
|
'/api/function/raid_alldevices?params=storage_GetAllDevices,0')
|
@@ -2021,8 +2018,10 @@ class XCCClient(IMMClient):
|
|
2021
2018
|
raise Exception(uploadthread.rsp)
|
2022
2019
|
raise Exception(errmsg)
|
2023
2020
|
rsp = json.loads(uploadthread.rsp)
|
2024
|
-
monitorurl = rsp['
|
2021
|
+
monitorurl = rsp['@odata.id']
|
2025
2022
|
complete = False
|
2023
|
+
phase = "apply"
|
2024
|
+
statetype = 'TaskState'
|
2026
2025
|
while not complete:
|
2027
2026
|
pgress, status = self.grab_redfish_response_with_status(
|
2028
2027
|
monitorurl)
|
@@ -2033,14 +2032,21 @@ class XCCClient(IMMClient):
|
|
2033
2032
|
for msg in pgress.get('Messages', []):
|
2034
2033
|
if 'Verify failed' in msg.get('Message', ''):
|
2035
2034
|
raise Exception(msg['Message'])
|
2036
|
-
state = pgress[
|
2035
|
+
state = pgress[statetype]
|
2037
2036
|
if state in ('Cancelled', 'Exception',
|
2038
2037
|
'Interrupted', 'Suspended'):
|
2039
2038
|
raise Exception(json.dumps(pgress['Messages']))
|
2040
2039
|
pct = float(pgress['PercentComplete'])
|
2041
2040
|
complete = state == 'Completed'
|
2042
|
-
progress({'phase':
|
2043
|
-
if
|
2041
|
+
progress({'phase': phase, 'progress': pct})
|
2042
|
+
if complete:
|
2043
|
+
if 'OperationTransitionedToJob' in pgress['Messages'][0]['MessageId']:
|
2044
|
+
monitorurl = pgress['Messages'][0]['MessageArgs'][0]
|
2045
|
+
phase = 'validating'
|
2046
|
+
statetype = 'JobState'
|
2047
|
+
complete = False
|
2048
|
+
ipmisession.Session.pause(3)
|
2049
|
+
else:
|
2044
2050
|
ipmisession.Session.pause(3)
|
2045
2051
|
if bank == 'backup':
|
2046
2052
|
return 'complete'
|
@@ -415,7 +415,7 @@ class SMMClient(object):
|
|
415
415
|
5: 'Boosted',
|
416
416
|
}
|
417
417
|
|
418
|
-
def get_bmc_configuration(self):
|
418
|
+
def get_bmc_configuration(self, variant):
|
419
419
|
settings = {}
|
420
420
|
wc = self.wc
|
421
421
|
wc.request(
|
@@ -453,7 +453,10 @@ class SMMClient(object):
|
|
453
453
|
powercfg = self.ipmicmd.xraw_command(0x32, 0xa2)
|
454
454
|
powercfg = bytearray(powercfg['data'])
|
455
455
|
if len(powercfg) == 5:
|
456
|
-
|
456
|
+
if variant and variant >> 5:
|
457
|
+
powercfg = powercfg[-2:]
|
458
|
+
else:
|
459
|
+
powercfg = powercfg[1:]
|
457
460
|
val = powercfg[0]
|
458
461
|
if val == 2:
|
459
462
|
val = 'N+N'
|
@@ -700,6 +703,8 @@ class SMMClient(object):
|
|
700
703
|
if None in powercfg:
|
701
704
|
currcfg = self.ipmicmd.xraw_command(0x32, 0xa2)
|
702
705
|
currcfg = bytearray(currcfg['data'])
|
706
|
+
if variant and variant >> 5 and len(currcfg) == 5:
|
707
|
+
currcfg = currcfg[-2:]
|
703
708
|
if powercfg[0] is None:
|
704
709
|
powercfg[0] = currcfg[0]
|
705
710
|
if powercfg[1] is None:
|
@@ -811,12 +811,23 @@ class OEMHandler(generic.OEMHandler):
|
|
811
811
|
def _create_array(self, pool):
|
812
812
|
params = self._parse_array_spec(pool)
|
813
813
|
cid = params['controller'].split(',')[0]
|
814
|
+
cslotno = params['controller'].split(',')[1]
|
814
815
|
url = '/api/function/raid_conf?params=raidlink_GetDefaultVolProp'
|
815
816
|
args = (url, cid, 0, params['drives'])
|
816
817
|
props = self.wc.grab_json_response(','.join([str(x) for x in args]))
|
817
|
-
|
818
|
+
usesctrlslot = False
|
819
|
+
if not props: # newer firmware requires raidlevel too
|
818
820
|
args = (url, cid, params['raidlevel'], 0, params['drives'])
|
819
821
|
props = self.wc.grab_json_response(','.join([str(x) for x in args]))
|
822
|
+
elif 'return' in props and props['return'] == 22:
|
823
|
+
# Jan 2023 XCC FW - without controller slot number
|
824
|
+
args = (url, cid, params['raidlevel'], 0, params['drives'])
|
825
|
+
props = self.wc.grab_json_response(','.join([str(x) for x in args]))
|
826
|
+
if 'return' in props and props['return'] == 22:
|
827
|
+
usesctrlslot = True
|
828
|
+
# Jan 2023 XCC FW - with controller slot number
|
829
|
+
args = (url, cid, params['raidlevel'], 0, params['drives'], cslotno)
|
830
|
+
props = self.wc.grab_json_response(','.join([str(x) for x in args]))
|
820
831
|
props = props['items'][0]
|
821
832
|
volumes = pool.volumes
|
822
833
|
remainingcap = params['capacity']
|
@@ -888,14 +899,14 @@ class OEMHandler(generic.OEMHandler):
|
|
888
899
|
parms = {'raidlink_AddNewVolWithNaAsync': arglist}
|
889
900
|
rsp = self.wc.grab_json_response(url, parms)
|
890
901
|
if rsp['return'] == 14: # newer firmware
|
891
|
-
if 'supported_cpwb' in props: #
|
902
|
+
if 'supported_cpwb' in props and not usesctrlslot: # no ctrl_type
|
892
903
|
arglist = '{0},{1},{2},{3},{4},{5},{6},'.format(
|
893
904
|
cnum, params['raidlevel'], params['spans'],
|
894
905
|
params['perspan'], 0, params['drives'], params['hotspares'])
|
895
906
|
arglist += ''.join(vols)
|
896
907
|
parms = {'raidlink_AddNewVolWithNaAsync': arglist}
|
897
908
|
rsp = self.wc.grab_json_response(url, parms)
|
898
|
-
else: #
|
909
|
+
else: # with ctrl_type
|
899
910
|
if cid[2] == 2:
|
900
911
|
cnum = cid[1]
|
901
912
|
arglist = '{0},{1},{2},{3},{4},{5},'.format(
|
@@ -1145,8 +1156,10 @@ class OEMHandler(generic.OEMHandler):
|
|
1145
1156
|
raise Exception(uploadthread.rsp)
|
1146
1157
|
raise Exception(errmsg)
|
1147
1158
|
rsp = json.loads(uploadthread.rsp)
|
1148
|
-
monitorurl = rsp['
|
1159
|
+
monitorurl = rsp['@odata.id']
|
1149
1160
|
complete = False
|
1161
|
+
phase = "apply"
|
1162
|
+
statetype = 'TaskState'
|
1150
1163
|
while not complete:
|
1151
1164
|
pgress = self._do_web_request(monitorurl, cache=False)
|
1152
1165
|
if not pgress:
|
@@ -1154,15 +1167,22 @@ class OEMHandler(generic.OEMHandler):
|
|
1154
1167
|
for msg in pgress.get('Messages', []):
|
1155
1168
|
if 'Verify failed' in msg.get('Message', ''):
|
1156
1169
|
raise Exception(msg['Message'])
|
1157
|
-
state = pgress[
|
1170
|
+
state = pgress[statetype]
|
1158
1171
|
if state in ('Cancelled', 'Exception', 'Interrupted',
|
1159
1172
|
'Suspended'):
|
1160
1173
|
raise Exception(
|
1161
1174
|
json.dumps(json.dumps(pgress['Messages'])))
|
1162
1175
|
pct = float(pgress['PercentComplete'])
|
1163
1176
|
complete = state == 'Completed'
|
1164
|
-
progress({'phase':
|
1165
|
-
if
|
1177
|
+
progress({'phase': phase, 'progress': pct})
|
1178
|
+
if complete:
|
1179
|
+
if 'OperationTransitionedToJob' in pgress['Messages'][0]['MessageId']:
|
1180
|
+
monitorurl = pgress['Messages'][0]['MessageArgs'][0]
|
1181
|
+
phase = 'validating'
|
1182
|
+
statetype = 'JobState'
|
1183
|
+
complete = False
|
1184
|
+
time.sleep(3)
|
1185
|
+
else:
|
1166
1186
|
time.sleep(3)
|
1167
1187
|
if bank == 'backup':
|
1168
1188
|
return 'complete'
|
@@ -0,0 +1 @@
|
|
1
|
+
{"git_version": "537fccb", "is_release": true}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"git_version": "bb46b94", "is_release": true}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|