Skip to content

Commit 030f046

Browse files
committed
AMTPowerPort: add status polling into exporter
1 parent 0acac11 commit 030f046

3 files changed

Lines changed: 73 additions & 2 deletions

File tree

doc/configuration.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,8 @@ A :any:`AMTPowerPort` describes a AMT port accessible via `amtctrl`.
311311
Arguments:
312312
- host (str): hostname or ip the AMT interface of the PC is reachable
313313
- password (str): password to use for AMT login
314-
- timeout (int): timeout to use when polling the resource
314+
- timeout (int): time to wait for the command to finish
315+
- polling (int): interval to poll resource in exporter (disabled if 0)
315316

316317
Used by:
317318
- `AMTPowerDriver`_

labgrid/remote/exporter.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,74 @@ def _get_params(self):
10441044
exports["IPMIPowerPort"] = IPMIPowerPortExport
10451045

10461046

1047+
@attr.s(eq=False)
1048+
class AMTPowerPortExport(ResourceExport):
1049+
"""ResourceExport for AMTPowerPort devices"""
1050+
1051+
def __attrs_post_init__(self):
1052+
super().__attrs_post_init__()
1053+
self.data["cls"] = self.cls
1054+
from ..resource.power import AMTPowerPort
1055+
self.local = AMTPowerPort(target=None, name=None, **self.local_params)
1056+
1057+
self.lastpoll = 0
1058+
self.job = None
1059+
self.local.avail = False
1060+
self.status = None
1061+
1062+
def poll(self):
1063+
now = time.monotonic()
1064+
if self.job:
1065+
self.lastpoll = now
1066+
if self.job.poll() is None:
1067+
return super().poll()
1068+
self.status = self._amt_parse(self.job.returncode)
1069+
1070+
if self.job.returncode != 0:
1071+
self.local.avail = False
1072+
else:
1073+
self.local.avail = True
1074+
self.job = None
1075+
return super().poll()
1076+
1077+
if now - self.lastpoll < self.local.polling:
1078+
return super().poll()
1079+
self.lastpoll = now
1080+
1081+
if self.local.polling > 0:
1082+
self.job = self._amt_power('status')
1083+
1084+
return super().poll()
1085+
1086+
def _amt_power(self, cmd):
1087+
runstr = f"amtctrl {self.local.host} {cmd} -p"
1088+
p = subprocess.Popen(runstr.split(' '), text=True,
1089+
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
1090+
stdin=subprocess.PIPE)
1091+
p.stdin.write(self.local.password)
1092+
p.stdin.close()
1093+
return p
1094+
1095+
def _amt_parse(self, ret):
1096+
out = self.job.stdout.read() + self.job.stderr.read()
1097+
if ret != 0:
1098+
out = out.split(']')[-1]
1099+
out = ''.join(x for x in out if not x in ['(',')','"', "'"])
1100+
return out.strip().upper()
1101+
1102+
def _get_params(self):
1103+
"""Helper function to return parameters"""
1104+
return {
1105+
**self.local_params,
1106+
"extra": {
1107+
"status": self.status,
1108+
}
1109+
}
1110+
1111+
1112+
exports["AMTPowerPort"] = AMTPowerPortExport
1113+
1114+
10471115
class ExporterSession(ApplicationSession):
10481116
def onConnect(self):
10491117
"""Set up internal datastructures on successful connection:

labgrid/resource/power.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ class AMTPowerPort(Resource):
4343
Args:
4444
host (str): hostname or ip the AMT interface of the PC is reachable
4545
password (str): password to use for AMT login
46-
timeout (int): timeout to use when polling the resource
46+
timeout (int): time to wait for command to finish
47+
polling (int): interval to poll resource in exporter (disabled if 0)
4748
"""
4849
host = attr.ib(validator=attr.validators.instance_of(str))
4950
password = attr.ib(validator=attr.validators.instance_of(str))
5051
timeout = attr.ib(default=30, validator=attr.validators.instance_of(int))
52+
polling = attr.ib(default=0, validator=attr.validators.instance_of(int))
5153

5254

5355
@target_factory.reg_resource

0 commit comments

Comments
 (0)