Hardware in the CI loopī
In this use case nobody types the commands: a pipeline or a scheduler does. The appliance becomes a permanent part of your CI infrastructure, with one DUT permanently attached to it, and jobs are dispatched to it automatically.
The LAA is designed for this. Each appliance drives exactly one DUT, on its own private network, with its own worker process and its own power and USB control. A crash, a misbehaving test image or a reboot affects that one DUT and nothing else in the lab. The reasoning behind that design is in Design goals.
Choosing a runtimeī
The appliance can run one of several runtimes, selected remotely from LMS:
Runtime |
Good fit for |
Documentation |
|---|---|---|
Single developers to mid-size teams that want hardware in an existing pipeline |
this page |
|
Teams running a lab with many DUTs and many users |
||
Contributing a board to KernelCI while keeping it in a closed network |
||
Teams already standardised on Labgrid |
this page |
One runtime per appliance
The Select Kind options in LMS (GitLab runner, KernelCI runner,
LAVA worker) are mutually exclusive: an appliance runs a single runtime at a
time. Select None to disable the runner for using the board interactively.
Before anything else: enable the DUTī
Whichever runtime you pick, the appliance first has to know how to boot your board reliably and unattended. If your DUT is already in the Devices Overview list, this is done for you. Otherwise, work through Device-Type enablement first: MIB selection, power sequencing, reset method, serial console, and the recovery path for when a job leaves the board bricked.
A CI setup is only as reliable as its recovery story. Make sure
laam dut test boots the board repeatedly before you point a pipeline at it.
GitLab and GitHub CIī
The appliance can run a GitLab runner that has full access to the attached DUT. The pipeline job then tests any part of the software stack directly on your hardware: no separate lab infrastructure, no automation framework to learn.

Select GitLab runner in the Select Kind dialog on the LAA page in LMS, the
same way as for the KernelCI runner.
Inside the job, the DUT is reachable exactly as in the
developer use case: power and USB control through
laacli, the serial console through
ser2net, and
artifacts served to the DUT over
TFTP and NFS. Anything you scripted by
hand works unchanged in the pipeline.
Gitlab use case
Using the LAA as a Gitlab runner is a good fit for single developers to mid-size teams that want to add Hardware in the CI loop without having to setup a proper automation service like LAVA.
This has been used successfully to test IOT devices directly from a gitlab pipeline: check the FOSDEM 26 presentation.
LAVAī
The appliance is a fully integrated LAVA worker, able to run any LAVA job on the attached DUT.

You do not configure the worker by hand. In LMS you select the LAVA instance and the device-type attached to the appliance; LMS creates the worker on the LAVA server, generates the device dictionary and pushes the configuration down to the appliance, which starts a worker running the matching LAVA version. If the server is later upgraded, the worker follows automatically, waiting for the running job to finish first.
The full procedure is in LAVA integration, and
laam workers lets you inspect and debug the worker from your laptop:
$ laam workers list
$ laam workers test
$ laam workers logs
LAVA use case
Using the LAA as a LAVA worker is a good fit for teams that want to have a solid and versatile automation framework that allows to manage a pull of DUTs in their lab. Linaro can help you to setup such lab.
KernelCIī
Configured as a KernelCI runner, the appliance polls the KernelCI pull-lab API endpoint for jobs targeting the attached DUT, runs them and reports the results back. Because the appliance pulls, the DUT can stay inside a closed network with no inbound connectivity.

The setup (selecting the runner kind, selecting the device, and requesting the KernelCI events that route jobs to your lab) is described in KernelCI runner (pull-lab).
Labgridī
The appliance also fits a Labgrid setup, though there is no LMS-managed Labgrid runtime: you drive the appliance from your own exporter or from the test host.
Everything Labgrid needs from lab infrastructure is exposed by the appliance over the network:
power control:
laacli power <rail> on|off|reset, run remotely withLAAPowerDriverreset and boot-mode buttons:
LAAButtonDriverUSB port power:
LAAUSBDriver, for boards that uses USBserial console: a plain TCP socket per console, published by
LAASerialDriverUSB mass-storage emulation:
LAAUSBGadgetMassStorageexposes an image to the DUT as a USB mass storage deviceartifact serving: TFTP and NFS on the DUT private network, see
LAAProvider
Labgrid example
An example labgrid configuration and pytest script is available at labgrid-laa-examples.
Operating a fleetī
Once more than one appliance is in service, the day-to-day management happens in LMS rather than on individual appliances:
OTA upgrades with automatic rollback keep the fleet on a known software version
lmscliscripts LMS itself: instances, subscriptions, deployments and releaseslaam servicesandlaam system logsgive you the logs of a single appliance without needing a shell on itremote access lets Linaro engineers help debug an appliance, with your permission
For what your IT department will want to know before appliances land in the lab (protocols, ports, outbound destinations, DUT isolation) point them at LAA Overview for IT Departments and LAA & Security.