Features
-
LAGER_GATEWAY_TOKENauthenticates a CI job against an access-gated box. Set the variable to a token that your auth server minted, and every request carries it. The job needs nolager loginstep and no password in repository secrets. The token outranks any stored session. Lager never refreshes it, and writes nothing to~/.lager_gateway_auth, so a self-hosted runner keeps no credential and no stale box-to-server mapping between jobs. If the gateway refuses the token, the command stops at once and names the server that refused it. It does not advise a login that cannot help. The Rust crate reads this variable since 0.2.0, and the Python CLI now matches it. -
The reference docs cover what shipped from v0.40.0 through v0.47.0. Each claim
matches the v0.47.0 source rather than the release notes. New or expanded sections:
lager nets state, which shipped in 0.34.0 and appeared on no page. The section covers state strings, the shared 8 s budget, reason codes with their remedy lines, and the--jsonfields.- The LabJack U3 across the adc, dac, gpi, gpo, spi, i2c, nets, instruments and
supported-instruments pages. These pages cover the pins and the SPI pin order, the
50-byte transfer limit, approximate clock rates, and the 0.04-4.95 V DAC range. They
also cover external I2C pull-ups, the refused chip-select options, and the LJM
"ANY"limitation. lager box-config: theapplyexit codes, every refusal of the host-network pre-flight,network-mode showoutput, switching back,pip import-legacy, andLAGER_DISABLE_UART_SERVICE.- DA1469x flash and erase on both debug backends,
DebugNet.connect()errors and backend-specific parameters, and theeraseandflashexit codes. lager uart --sessionsand--force,lager usb cycleverdicts per hub,lager webcam snapshot,lager execinside a CI job withLAGER_CI_OVERRIDE, and robot-arm detection withLAGER_ARM_PROBE./etc/lager/ref,update --checkexit codes, the install deploy timeout, and the pre-built image rules. The host CLI, how a command recognizes its own lock,setup_battery(), and where the box services write their logs.
Bug Fixes
-
lager installno longer hangs for two minutes at the end, and no longer garbles the terminal. The step that records the deployed version and ref forced an SSH pseudo-terminal. When itssudowas not passwordless, that step waited on a password that no one can type, until a 120-second timeout. The killed pseudo-terminal then left the local shell in raw mode, and every line after it staircased. The writes now run underBatchModewith a short timeout, so an ungrantedsudofails at once and cleanly. The box’s sudoers grant now also covers/etc/lager/ref, which it never covered before, so on a properly provisioned box the write simply succeeds. -
lager installandlager updateno longer take ownership of the SSH key directory (/etc/lager/authorized_keys.d). The permission repair that makes/etc/lagerwritable for the box-config renderers used tochown -Rthe whole tree. That swept the key directory into the container’s ownership. On a box that runs untrusted code, that code can then authorize its own SSH key. The repair now skips that one directory, and leaves its ownership as it found it. -
lager installandlager updateno longer abort on a box whose clone holds a divergent tag. A box cloned before a tag was re-created upstream keeps that tag at the old object. An unforcedgit fetchthen refuses the tag with a non-zero exit, and reports that the fetch clobbers an existing tag. The install’s fetch sits in an&&chain underset -e, so the deploy died at [5/8] Deploying Box Code. It stayed dead, because every later attempt fetched the same way. The only way out was a force-fetch on the box by hand. Both fetches now force. Origin is authoritative for a checkout that the very next commandsgit reset --hardandgit clean -fd. -
lager arm set-accelerationset travel acceleration to the retract value. It sentM204 P T T, and the arm firmware reads retract acceleration fromR. The command andDexarm.set_acceleration()now sendM204 P T R. -
lager arm read-and-save-positionasks for confirmation. The command sendsM889, which replaces the stored calibration of the arm with its current pose. Pass--yesto skip the prompt. -
An arm net opens the arm that it names.
lager nets add-allrecords the USB serial number of the arm only in the net address. The box ignored that number and opened the first0483:5740serial device. Other STM32 boards use that USB ID. -
lager armworks again after the USB connection to the arm drops. Before, every command failed until the box hardware service restarted. Now the next command opens the port again, andpositionretries once. -
An instrument scan no longer breaks a running
lager armcommand. The scan sentM105to an arm that a saved arm net uses, and the arm reply can go to the scan instead. The scan now lists that arm from its USB serial number, without a probe. -
lager arm moveandmove-byrefuse a timeout longer than 25 seconds. A longer move outlived the 30-second limit on a box hardware call, and the box hardware service restarted. -
Dexarm.move_to()andmove_relative()check the workspace bounds. They raiseOutOfBoundsErrorand send nothing, aslager armdoes. -
lager arm --boxlists arm nets without locking the box. -
lager arm go-homeandDexarm.go_home()wait for the arm to reach home. They returned after half a second, before the arm reached home. Now they return when the arm firmware reports that the move is done. -
lager arm moveandmove-byrefuse an arm on firmware older than V2.1.4. Rotrics swapped the X and Y axes in V2.1.4, so on older firmware a move turned the arm to the side. The error tells you to update the firmware.positionandgo-homestill work. -
A move before the arm is homed fails at once. After power-on the firmware ignores
motion until
go-homeruns, and the move timed out after 15 seconds with a message about an obstruction. It now raisesNotHomedError. - A move that times out no longer blames the workspace bounds. The command checks the bounds before it sends a move. The error now says that the arm did not arrive, and that a long move can need a larger timeout.
-
lager arm positionshows the arm error when the arm stops answering. It failed with “hardware service did not respond” after 10 seconds. The box now stops a position read after three attempts of 3 seconds each.
Improvements
-
Four pages said that the host firewall limits the Lager ports to the VPN. On the
default network, Docker publishes those ports ahead of the host firewall, as
SECURITY.mdstates. The install, update, setup and architecture pages now say so, and link the Security Model.update.mdxalso documented a firewall step and a script invocation that do not exist. - The Logic Analyzer pages said that the feature was not available. The commands run. Both pages, and the scope page, now carry one callout for the MSO5000 triggers and bus decoders that still fail. The pages also list exit codes and valid ranges, and drop the examples that cannot run.
-
Examples that cannot run are corrected.
lager debug flash --bintakesFILE,ADDRESS, notADDRESS FILE.lager python --killneeds the process ID.lager uarttakes a net name, not/dev/ttyUSB0.lager execneeds--before extra arguments that start with a dash.UARTNet.connect()ignorestimeout.lager nets addexamples used channel0where the box listsI2C0,SPI0orFIO4-FIO5. -
Stale claims are corrected.
- pyOCD appeared as a debug backend. J-Link and OpenOCD are the only two.
- Webcam ports start at 8086, not 8081.
lager usbcommands are case-sensitive, and thecycletiming and hub hold apply to Plugable docks only.- A LabJack U3 supports SPI and I2C.
- A second role on a Keithley or EA instrument raises a notice, not a block, and two Acroname hubs of one model both work.
- The
.lagerdefaults are JSON in~/.lager, not INI in the project. - Sample output for
lager hello,lager boxes,lager defaults list,lager instruments,lager logsandlager binaries listmatches the CLI. - The box runs one
lagercontainer, notcontroller. - The MCP server is read-only only while both opt-in gates are off.
- Top-level
lageroptions are--version,--debugand--colorize.--boxbelongs to each command.
-
The README describes what the software does. The Python example calls
psu.set_voltage(3.3), becausevoltage()only reads the measured value. The MCP section lists the read-only discovery and planning tools that the server exposes by default, and names the two opt-in gates. The Rust section places thelager-netcrate in a firmware project, not on the box. The CI section passes--yesto the commands that ask for confirmation. The Supported Hardware table covers the vendor families that the supported-instruments page lists.

