Skip to content

Commit aaf0b86

Browse files
hthieryphirince
andcommitted
rmcp+: initial version
This implementation is base on the work done by Phirince Philip. Co-Authored-by: Phirince Philip <[email protected]> Signed-off-by: Heiko Thiery <[email protected]>
1 parent 5566c7b commit aaf0b86

File tree

14 files changed

+795
-12
lines changed

14 files changed

+795
-12
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99

1010
strategy:
1111
matrix:
12-
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.8", "pypy3.9", "pypy3.10"]
12+
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.9", "pypy3.10"]
1313

1414
steps:
1515
- uses: actions/checkout@v3
@@ -19,7 +19,7 @@ jobs:
1919
python-version: ${{ matrix.python-version }}
2020

2121
- name: Install dependencies
22-
run: pip install python-coveralls coverage pytest pytest-cov flake8
22+
run: pip install python-coveralls coverage pytest pytest-cov flake8 cryptography
2323

2424
# - name: Setup and run tests
2525
# run: python setup.py test

README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Pure Python IPMI Library
66
Features
77
--------
88
* native RMCP interface
9+
* native RMCP+ interface (beta)
910
* legacy RMCP interface (using ipmitool as backend)
1011
* RMCP+ interface (using ipmitool as backend)
1112
* system (KCS) interface (using ipmitool as backend)

examples/interface_rmcpplus.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python
2+
3+
import sys
4+
5+
import pyipmi
6+
import pyipmi.interfaces
7+
8+
host = sys.argv[1]
9+
user = sys.argv[2]
10+
password = sys.argv[3]
11+
12+
intf = pyipmi.interfaces.create_interface('rmcp+')
13+
14+
sess = pyipmi.Session()
15+
sess.set_session_type_rmcp(host, 623)
16+
sess.set_auth_type_user(user, password)
17+
target = pyipmi.Target(ipmb_address=0x20)
18+
19+
# (1) The device connection can either be opened and closed
20+
ipmi = pyipmi.Ipmi(interface=intf, session=sess, target=target)
21+
ipmi.open()
22+
device_id = ipmi.get_device_id()
23+
ipmi.close()
24+
25+
# (2) or the 'with' statement can be used
26+
with pyipmi.Ipmi(interface=intf, session=sess, target=target) as ipmi:
27+
device_id = ipmi.get_device_id()
28+
29+
print('''
30+
Device ID: %(device_id)s
31+
Device Revision: %(revision)s
32+
Firmware Revision: %(fw_revision)s
33+
IPMI Version: %(ipmi_version)s
34+
Manufacturer ID: %(manufacturer_id)d (0x%(manufacturer_id)04x)
35+
Product ID: %(product_id)d (0x%(product_id)04x)
36+
Device Available: %(available)d
37+
Provides SDRs: %(provides_sdrs)d
38+
Additional Device Support:
39+
'''[1:-1] % device_id.__dict__)
40+
41+
functions = (
42+
('SENSOR', 'Sensor Device'),
43+
('SDR_REPOSITORY', 'SDR Repository Device'),
44+
('SEL', 'SEL Device'),
45+
('FRU_INVENTORY', 'FRU Inventory Device'),
46+
('IPMB_EVENT_RECEIVER', 'IPMB Event Receiver'),
47+
('IPMB_EVENT_GENERATOR', 'IPMB Event Generator'),
48+
('BRIDGE', 'Bridge'),
49+
('CHASSIS', 'Chassis Device')
50+
)
51+
for n, s in functions:
52+
if device_id.supports_function(n):
53+
print(' %s' % s)
54+
55+
if device_id.aux is not None:
56+
print('Aux Firmware Rev Info: [%s]' % (
57+
' '.join('0x%02x' % d for d in device_id.aux)))

pyipmi/errors.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
# License along with this library; if not, write to the Free Software
1515
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1616

17-
from .msgs.constants import COMPLETION_CODE_DESCR, CC_ERR_CMD_SPECIFIC_DESC
17+
from .msgs.constants import (COMPLETION_CODE_DESCR, CC_ERR_CMD_SPECIFIC_DESC,
18+
MESSAGE_STATUS_CODE_DESCR)
1819

1920

2021
class DecodingError(Exception):
@@ -51,6 +52,7 @@ def find_cc_desc(error_cc, cmdid=None, netfn=None, group_extension=None):
5152
return cc[1]
5253
# Then search in command specific completion codes
5354
if cmdid is not None:
55+
print(netfn, cmdid, group_extension)
5456
command_cc = CC_ERR_CMD_SPECIFIC_DESC.get((netfn, cmdid, group_extension), {})
5557
descr = command_cc.get(error_cc, "Unknown error description")
5658
return descr
@@ -99,3 +101,22 @@ def __init__(self, msg=None):
99101

100102
def __str__(self):
101103
return "{}".format(self.msg)
104+
105+
106+
class MessageStatusCodeError(Exception):
107+
"""IPMI Message Status code not OK."""
108+
109+
def __init__(self, msc):
110+
self.msc = msc
111+
self.msc_desc = self.find_msc_desc(msc)
112+
113+
def __str__(self):
114+
return "%s cc=0x%02x desc=%s" \
115+
% (self.__class__.__name__, self.msc, self.msc_desc)
116+
117+
@staticmethod
118+
def find_msc_desc(error_msc):
119+
for msc in MESSAGE_STATUS_CODE_DESCR:
120+
if error_msc == msc[0]:
121+
return msc[1]
122+
return "Unknown error description"

pyipmi/interfaces/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
from .aardvark import Aardvark
1919
from .ipmbdev import IpmbDev
2020
from .mock import Mock
21-
from .rmcp import Rmcp
21+
from .rmcp import (Rmcp, RmcpPlus)
2222

2323
INTERFACES = [
2424
Ipmitool,
2525
Aardvark,
2626
IpmbDev,
2727
Mock,
2828
Rmcp,
29+
RmcpPlus,
2930
]
3031

3132

0 commit comments

Comments
 (0)