Skip to content

Commit 63bdbd9

Browse files
committed
client: Allow fetching the env from the coordinator
Remote users have to keep a local copy of the lab env file in sync with the coordinator before they can run labgrid-client against it. This is friction for casual workflows like triage or console access from a laptop, and is awkward to maintain across many client machines. Provide a way for clients to fetch the env from the coordinator on startup. Setting LG_ENV (or --config) to the literal string 'coordinator:' issues a one-shot GetEnvironment RPC against the coordinator. The returned YAML is written under $XDG_CACHE_HOME/labgrid (or ~/.cache/labgrid) and loaded exactly as if the user had pointed at a local file, so the rest of the client is untouched. The cache file is overwritten on each fetch so users can inspect what env the client just loaded. Remote users then only need labgrid, network access to the coordinator and three environment variables (PATH, LG_COORDINATOR, LG_ENV=coordinator:) to run labgrid-client console -p <board> from anywhere. Per-user paths inside the served env (build dirs, log dirs, source trees) are still resolvable via the existing LG_* template substitution, so individual clients can override only the few values that matter to them without forking the env file. The coordinator address used for the fetch comes from --coordinator on the command line if given, otherwise LG_COORDINATOR, with 127.0.0.1:20408 as the final default - matching the fallback chain main() uses elsewhere. Signed-off-by: Simon Glass <sjg@chromium.org>
1 parent 18c310b commit 63bdbd9

4 files changed

Lines changed: 93 additions & 0 deletions

File tree

doc/man/client.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ LG_ENV
4949
This variable can be used to specify the configuration file to use without
5050
using the ``--config`` option, the ``--config`` option overrides it.
5151

52+
The special value ``coordinator:`` (or ``--config coordinator:``) tells the
53+
client to fetch the environment from the coordinator over the ``GetEnvironment``
54+
RPC instead of reading a local file, which is useful when working from a remote
55+
machine that does not have the lab env file available locally. The fetched
56+
YAML is cached under ``$XDG_CACHE_HOME/labgrid/env.cfg`` (or
57+
``~/.cache/labgrid/env.cfg``) so it can be inspected after the fact. The
58+
coordinator must have been started with ``--environment``; see
59+
``labgrid-coordinator``\(1).
60+
5261
LG_COORDINATOR
5362
~~~~~~~~~~~~~~
5463
This variable can be used to set the default coordinator in the format

doc/usage.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,37 @@ allocated before returning.
166166
A reservation will time out after a short time, if it is neither refreshed nor
167167
used by locked places.
168168

169+
Fetching the Environment from the Coordinator
170+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
171+
172+
When several developers (or CI jobs) share a lab, distributing the env file out
173+
of band - via a shared filesystem, git checkout or scp - is awkward duplication.
174+
``labgrid-coordinator`` can serve a curated env to clients on demand, so a
175+
remote user only needs network access to the coordinator and a labgrid install.
176+
177+
Start the coordinator with ``--environment`` pointing at a YAML file:
178+
179+
.. code-block:: bash
180+
181+
$ labgrid-coordinator --environment /etc/labgrid/lab.cfg
182+
183+
On the client side, set ``LG_ENV=coordinator:`` (or ``--config coordinator:``)
184+
to fetch the env via the ``GetEnvironment`` RPC instead of reading a local file.
185+
The returned YAML is cached under ``$XDG_CACHE_HOME/labgrid/env.cfg`` (or
186+
``~/.cache/labgrid/env.cfg``), overwritten on each fetch so a user can inspect
187+
what env the client just loaded.
188+
189+
.. code-block:: bash
190+
191+
$ export LG_COORDINATOR=lab-host:20408
192+
$ export LG_ENV=coordinator:
193+
$ labgrid-client console -p <board>
194+
195+
Per-user paths inside the served env (build dirs, log dirs, source trees) are
196+
still resolvable via the existing ``LG_*`` template substitution, so individual
197+
clients can override only the few values that matter to them without forking the
198+
env file.
199+
169200
Library
170201
-------
171202
labgrid can be used directly as a Python library, without the infrastructure

labgrid/remote/client.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,39 @@ def start_session(
17251725
return session
17261726

17271727

1728+
def fetch_coordinator_environment(address):
1729+
"""Fetch the env file served by the coordinator and cache it on disk
1730+
1731+
Used when the user sets ``LG_ENV=coordinator:`` (or
1732+
``--config coordinator:``) instead of pointing at a local file.
1733+
1734+
Returns the path to the cached file (under ``$XDG_CACHE_HOME`` or
1735+
``~/.cache/labgrid/env.cfg``), overwritten on each call so users
1736+
can inspect what env the client just loaded. Raises UserError if
1737+
the coordinator is not configured to serve an environment.
1738+
"""
1739+
address = proxymanager.get_grpc_address(address, default_port=20408)
1740+
with grpc.insecure_channel(address) as channel:
1741+
stub = labgrid_coordinator_pb2_grpc.CoordinatorStub(channel)
1742+
try:
1743+
response = stub.GetEnvironment(
1744+
labgrid_coordinator_pb2.GetEnvironmentRequest(),
1745+
timeout=10.0,
1746+
)
1747+
except grpc.RpcError as e:
1748+
raise UserError(f"failed to fetch environment from coordinator at {address}: {e.details() or e}") from e
1749+
if not response.config:
1750+
raise UserError(
1751+
f"coordinator at {address} has no environment configured (start coordinator with --environment <file>)"
1752+
)
1753+
cache_dir = os.path.join(os.environ.get("XDG_CACHE_HOME", os.path.expanduser("~/.cache")), "labgrid")
1754+
os.makedirs(cache_dir, exist_ok=True)
1755+
path = os.path.join(cache_dir, "env.cfg")
1756+
with open(path, "w", encoding="utf-8") as f:
1757+
f.write(response.config)
1758+
return path
1759+
1760+
17281761
def find_role_by_place(config, place):
17291762
for role, role_config in config.items():
17301763
resources, _ = target_factory.normalize_config(role_config)
@@ -2305,6 +2338,17 @@ def main():
23052338
if args.proxy:
23062339
proxymanager.force_proxy(args.proxy)
23072340

2341+
if args.config == "coordinator:":
2342+
# Fetch the env from the coordinator. The address can't be taken from
2343+
# env.config yet (no env loaded), so use the same fallback chain the
2344+
# rest of main() uses, minus that.
2345+
addr = args.coordinator or os.environ.get("LG_COORDINATOR", "127.0.0.1:20408")
2346+
try:
2347+
args.config = fetch_coordinator_environment(addr)
2348+
except UserError as e:
2349+
print(e, file=sys.stderr)
2350+
exit(1)
2351+
23082352
env = None
23092353
if args.config:
23102354
env = Environment(config_file=args.config)

man/labgrid-client.1

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,15 @@ A desired state must be set using \fBLG_STATE\fP or \fB\-s\fP/\fB\-\-state\fP\&.
11451145
.sp
11461146
This variable can be used to specify the configuration file to use without
11471147
using the \fB\-\-config\fP option, the \fB\-\-config\fP option overrides it.
1148+
.sp
1149+
The special value \fBcoordinator:\fP (or \fB\-\-config coordinator:\fP) tells the
1150+
client to fetch the environment from the coordinator over the \fBGetEnvironment\fP
1151+
RPC instead of reading a local file, which is useful when working from a remote
1152+
machine that does not have the lab env file available locally. The fetched
1153+
YAML is cached under \fB$XDG_CACHE_HOME/labgrid/env.cfg\fP (or
1154+
\fB~/.cache/labgrid/env.cfg\fP) so it can be inspected after the fact. The
1155+
coordinator must have been started with \fB\-\-environment\fP; see
1156+
\fBlabgrid\-coordinator\fP(1).
11481157
.SS LG_COORDINATOR
11491158
.sp
11501159
This variable can be used to set the default coordinator in the format

0 commit comments

Comments
 (0)