Skip to content

Navigation Menu

Sign in
Sign up

NetworkPowerPort in exporter yaml config #1515

Unanswered
wojciiii asked this question in Q&A
Discussion options

I defined the following in the exporter.yaml file used by the labgrid exporter.

 NetworkPowerPort:
 model: 'apc'
 host: 'IPv4Address'
 index: 1

On my client I used this:

targets:
 main:
 drivers:
 resources:
 ..
 - NetworkPowerDriver:
 name: "dut_power"
 delay: 5.0
 bindings:
 port: 'NetworkPowerPort'

I have set LG_PROXY to connect to the exporter using SSH and enabled isolation mode in the exporter.

I was expecting the client to use the configured NetworkPowerPort from the same host as the exporter.
I was expecting to see the SNMP packets from the same host as the exporter runs on.
Instead I see SNMP packets from the host the Labgrid client runs on which is on a different network from my test network.

How can I configure Labgrid for using a client which doesn't have direct access to HW such as a network power port?

You must be logged in to vote

Replies: 5 comments

Comment options

Proxy forwarding is currently not implemented for transports which use UDP (which inlcudes the apc driver since it uses SNMP in the background).
We support isolated exporters by opening an SSH tunnel from the client to the exporter and forwarding the TCP connection which is not as easily implemented for UDP.

You must be logged in to vote
0 replies
Comment options

@Emantor what are your thoughts on running snmpcmd on the exporter via ssh instead of on the localhost? For example, instead of:

f"snmpget -v1 -c private -O qn {host} {oid}".split()

it would be something like:

ssh {exporter} snmpget -v1 -c private -O qn {host} {oid}

One problem with this is that the driver doesn't currently have the exporter information.

You must be logged in to vote
0 replies
Comment options

A simple solution would be to use PDUdaemon for this.

You must be logged in to vote
0 replies
Comment options

@jluebbe thank you! TIL. PDUDaemon looks promising. I'll try that.

You must be logged in to vote
0 replies
Comment options

PDUDaemon

I evaluated PDUDaemon. It works with a proxy but unfortunately does not support getting power status.

def get(self):
raise NotImplementedError("pdudaemon does not support retrieving the port's state")

This is a fundamental limitation of PDUDaemon itself (see pdudaemon/pdudaemon#97).

Custom Power Driver (ProxySMTPPowerDriver)

I implemented my own power driver that runs snmpcmd on the proxy via ssh. E.g., ssh {proxy} snmpget -v1 -c private -Onqe {host} {oid}.

Source

proxysmtppowerdriver.py

import attr
from labgrid.factory import target_factory
from labgrid.step import step
from labgrid.driver import Driver
from labgrid.driver.exception import ExecutionError
from labgrid.driver.powerdriver import PowerResetMixin
from labgrid.protocol import PowerProtocol
from labgrid.resource.power import NetworkPowerPort
from labgrid.util.helper import processwrapper
from labgrid.util.proxy import proxymanager
OID = ".1.3.6.1.4.1.318.1.1.4.4.2.1.3"
@target_factory.reg_driver
@attr.s(eq=False)
class ProxySMTPPowerDriver(Driver, PowerResetMixin, PowerProtocol):
 bindings = {
 "port": NetworkPowerPort,
 }
 delay = attr.ib(default=2.0, validator=attr.validators.instance_of(float))
 def on_activate(self):
 self._host = self.port.host
 self._index = self.port.index
 self._proxy = proxymanager._force_proxy
 @Driver.check_active
 @step()
 def on(self):
 self._set(self._host, self._index, True)
 @Driver.check_active
 @step()
 def off(self):
 self._set(self._host, self._index, False)
 @Driver.check_active
 @step()
 def cycle(self):
 self.off()
 time.sleep(self.delay)
 self.on()
 @Driver.check_active
 def get(self):
 return self._get(
 self._host,
 self._index,
 )
 def _set(self, host: str, index: int, value: bool):
 value = 1 if value else 2
 try:
 processwapper.check_output(
 f"ssh {self._proxy} snmpset -v1 -c private -Onqe {host} {OID}.{index} {value}".split()
 )
 except Exception as e:
 raise ExecutionError("failed to set snmp value") from e
 def _get(self, host: str, index: int) -> bool:
 oid = f"{OID}.{index}"
 out = processwrapper.check_output(
 f"ssh {self._proxy} snmpget -v1 -c private -Onqe {host} {oid}".split()
 ).decode("ascii")
 out_oid, value = out.strip().split(" ", 1)
 assert oid == out_oid
 match value:
 case "1":
 return True
 case "2":
 return False
 case _:
 raise ExecutionError("failed to get snmp value")

However, the custom driver approach is a bit cumbersome because labgrid-client isn't aware of this driver. I need to explicitly import the driver and specify the driver for the target via a config file. E.g.,

Command:

labgrid-client -c env.yml power get

env.yml:

targets:
 main:
 resources:
 RemotePlace:
 name: myplace
 drivers:
 ProxySMTPPowerDriver: {}
imports:
 - proxysmtppowerdriver.py

Contrast this to the native NetworkPowerDriver which allows power to be get/set without a config file.

Command:

labgrid-client -p myplace power get

The native driver is much more ergonomic but doesn't support SMTP + proxy.

Add proxy support to native NetworkPowerDriver

Is the labgrid project open to adding SMTP proxy support to NetworkPowerDriver as done in the custom ProxySMTPPowerDriver above?

This approach doesn't align with labgrid's current remote model which seems to be tunnelling network requests to remote daemons instead of remote command execution but I'm not sure this is a blocker to this approach.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /