.. _usage:

Usage
#####

Here is the list of available commands and sub-commands.

Aliases
=======

LAVA aliases can be managed by:

.. code-block:: shell

    lavacli aliases add <alias> <device-type>
    lavacli aliases delete <alias>
    lavacli aliases list
    lavacli aliases show <alias>

Device types
============

LAVA device types can be managed by:

.. code-block:: shell

    lavacli device-types add <name> [...]
    lavacli device-types aliases add <name> <alias>
    lavacli device-types aliases delete <name> <alias>
    lavacli device-types aliases list <name>
    lavacli device-types devices <name> [--health <health>]
    lavacli device-types health-check delete <name>
    lavacli device-types health-check get <name>
    lavacli device-types health-check set <name> <health-check.yaml>
    lavacli device-types list [--all]
    lavacli device-types perms add <name> <group> <permission>
    lavacli device-types perms delete <name> <group> <permission>
    lavacli device-types perms list <name>
    lavacli device-types show <name>
    lavacli device-types template delete <name>
    lavacli device-types template get <name>
    lavacli device-types template set <name> <template.jinja2>
    lavacli device-types update <name> [...]

Devices
=======

LAVA devices can be managed by:

.. code-block:: shell

    lavacli devices add <hostname> [...]
    lavacli devices control <hostname> (on|off|reset|connect) [--dry-run]
    lavacli devices dict delete <hostname>
    lavacli devices dict get <hostname> [<field>] [--render] [--context <context>]
    lavacli devices dict set <hostname> <dict.jinja2>
    lavacli devices list [--all]
    lavacli devices maintenance <hostname> [--force] [--no-wait] [--reason <text>]
    lavacli devices perms add <hostname> <group> <permission>
    lavacli devices perms delete <hostname> <group> <permission>
    lavacli devices perms list <hostname>
    lavacli devices show <hostname>
    lavacli devices tags add <hostname> <tag>
    lavacli devices tags delete <hostname> <tag>
    lavacli devices tags list <hostname>
    lavacli devices update <hostname> [...]

The **control** command allows controlling the device power and serial
connection directly from the workstation, using the commands defined in the
device dictionary:

* **on**: turn the device on (``commands.power_on``)
* **off**: turn the device off (``commands.power_off``)
* **reset**: hard reset the device (``commands.hard_reset``)
* **connect**: connect to the device primary serial port (``commands.connections.<primary>.connect``)

Use ``--dry-run`` (or ``-n``) to print the command that would be run without
executing it.

Events
======

LAVA events can be used by:

.. code-block:: shell

    lavacli events listen [--filter (device|event|testjob|worker)]
    lavacli events wait device <hostname> [--state <state>] [--health <health>]
    lavacli events wait job <job_id> [--state <state>] [--health <health>]
    lavacli events wait worker <hostname> [--state <state>] [--health <health>]

Groups
======

LAVA groups can be managed by:

.. code-block:: shell

    lavacli groups add <group>
    lavacli groups delete <group>
    lavacli groups list
    lavacli groups perms add <group> <app> <model> <codename>
    lavacli groups perms delete <group> <app> <model> <codename>
    lavacli groups perms list <group>
    lavacli groups show <group>

Identities
==========

lavacli identities can be managed by:

.. code-block:: shell

    lavacli identities add <id> --uri <uri> [--username <username>] [--token <token>] [--proxy <proxy>]
    lavacli identities delete <id>
    lavacli identities list
    lavacli identities show <id>

Jobs
====

LAVA jobs can be managed by:

.. code-block:: shell

    lavacli jobs autocancel --duration <minutes> [--dry-run]
    lavacli jobs cancel <job_id> [<job_id> ...]
    lavacli jobs config <job_id> [--dest <directory>]
    lavacli jobs definition <job_id>
    lavacli jobs find-errors [--limit <count>] [--since <minutes>]
    lavacli jobs list [...]
    lavacli jobs logs <job_id> [...]
    lavacli jobs queue [<device-type> ...]
    lavacli jobs resubmit <job_id> [--follow] [...]
    lavacli jobs run <definition.yaml> [...]
    lavacli jobs show <job_id>
    lavacli jobs submit <definition.yaml> [<definition.yaml> ...] [--follow] [...]
    lavacli jobs validate <definition.yaml> [--strict]
    lavacli jobs wait <job_id> [--polling <seconds>] [--timeout <seconds>]

The commands printing logs (**logs**, **run** and **submit** or **resubmit**
with **--follow**) accept the **--filters**, **--quiet** and **--raw** options
described in `Printing logs`_.

Lab
===

LAVA lab can be managed by:

.. code-block:: shell

    lavacli lab apply <config> [--dry-run] [--resources <resource>] [--delete]
    lavacli lab import <config> [--resources <resource>] [--exclude <resource>]
    lavacli lab validate <config>

**--resources** can be given multiple times to restrict the command to some
resources (groups, users, devices, device-types and workers).

MCP
===

Start an MCP server for the selected LAVA instance. You can then connect your
LLM to LAVA via this MCP server:

.. code-block:: shell

    lavacli mcp
    lavacli mcp --transport streamable-http [--host <address>] [--port <port>]

The instance is the one selected by **--identity** or **--uri**, reached over
the same XML-RPC calls as every other lavacli command.

The server provides tools to list and show jobs, device-types, devices and
workers, to read the job queue, a job definition, its logs, a device-type
template and health-check and a device dictionary, to browse the results of a
job (its suites, test cases and metadata), and to read the official LAVA
documentation. The documentation is read from the markdown sources of the lava
repository, at the tag of the release the instance runs when there is one,
falling back to the development branch.

The job list can be narrowed down to one device, device-type, worker,
submitter or error type, on top of the state, health and time window the
server filters on. LAVA does not know about these filters: the MCP server reads
the jobs of the time window, which is then required, a page at a time and keeps
the matching ones, reading at most 5000 jobs per call. A worker filter keeps
the jobs of the devices attached to the worker now. Another tool counts the
finished jobs of every device over a time window, optionally for one
device-type or worker, and ranks the devices by failure rate (incomplete jobs
out of the complete and incomplete ones), with the number of failures per
error type: the LLM finds the failing devices without reading every job.

The server also provides prompts, ready-made requests that walk the LLM
through a common investigation with these tools, optionally for one
device-type or worker:

* ``devices_status`` looks at the jobs of the last hours (24 by default),
  groups the failures by root cause, tells for each one whether it looks like
  an infrastructure or a test issue and ranks the devices by failure rate.
* ``device_dictionaries_review`` reads the device dictionaries and looks for
  configuration mistakes, like a command reaching the port of another device or
  a resource assigned to two devices.

A few tools change the instance: submitting and canceling a job, setting a
device-type template or a device dictionary. They are advertised as
such in their MCP annotations, so that the client can ask for a confirmation
before running them, while the other tools are flagged read-only. The tools act
with the permissions of the token used by **--identity** or **--uri**: give the
server a token without the matching permissions to keep it read-only.

This command requires the ``mcp`` python module, which is not installed by
default:

.. code-block:: shell

    pip install lavacli[mcp]

Only the FastMCP 1.x series is supported.

Results
=======

LAVA results can be managed by:

.. code-block:: shell

    lavacli results <job_id>
    lavacli results <job_id> <suite>
    lavacli results <job_id> <suite> <case>

System
======

LAVA instance can be managed by:

.. code-block:: shell

    lavacli system active
    lavacli system api
    lavacli system certificate
    lavacli system maintenance [--force] [--exclude <workers>]
    lavacli system methods list
    lavacli system methods help <method>
    lavacli system methods signature <method>
    lavacli system version
    lavacli system whoami

In order to put a full instance into maintenance, an admin could call **system
maintenance**. This function will:

* set all workers health to *MAINTENANCE*
* wait for all jobs to finish

If the instance should be put into maintenance immediately, adding **--force** will:

* set all workers health to *MAINTENANCE*
* cancel all running jobs
* wait for all jobs to finish

It is also possible to exclude some workers with **--exclude**, using a comma
separated list of workers.

When the maintenance is finished, calling **system active** will set the health
of every worker to *ACTIVE*, whatever its current health.

Tags
====

LAVA tags can be managed by:

.. code-block:: shell

    lavacli tags add <tag> [--description <description>]
    lavacli tags delete <tag>
    lavacli tags list
    lavacli tags show <tag>

Tokens
======

Manage user remote artifact tokens:

.. code-block:: shell

    lavacli tokens add <name> --token <token>
    lavacli tokens delete <name>
    lavacli tokens list
    lavacli tokens show <name>


Users
=====

Manage LAVA users with:

.. code-block:: shell

    lavacli users add <user> [...]
    lavacli users delete <user>
    lavacli users groups add <user> <group>
    lavacli users groups delete <user> <group>
    lavacli users groups list <user>
    lavacli users perms add <user> <app> <model> <codename>
    lavacli users perms delete <user> <app> <model> <codename>
    lavacli users perms list <user>
    lavacli users list
    lavacli users show <user>
    lavacli users update <user> [...]

Utils
=====

Some utilities are available with:

.. code-block:: shell

    lavacli utils logs print <output.yaml>
    lavacli utils templates render <template.jinja2> [--path <path>] [--context <key=value>] [--trim]

Printing logs
*************

When working with raw logs, lavacli might help by coloring the logs by levels.

It's also possible to filter the logs by level. To only print the serial output
and the commands sent by LAVA to the board, use:

.. code-block:: shell

    lavacli utils logs print --filters target,input <output.yaml>

Available log levels are: exception, error, warning, info, debug, target,
input, feedback, results.

To only print the job phases (deploy, boot, ...) and the DUT output, use
**--quiet**. The job definition can be given with **--job-definition** to
improve the result. Use **--raw** to print the logs as is.

Workers
=======

LAVA workers can be managed by:

.. code-block:: shell

    lavacli workers add <hostname> [--description <description>] [--disabled]
    lavacli workers config delete <hostname>
    lavacli workers config get <hostname>
    lavacli workers config set <hostname> <config.yaml>
    lavacli workers env delete <hostname>
    lavacli workers env get <hostname>
    lavacli workers env set <hostname> <env.yaml>
    lavacli workers env-dut delete <hostname>
    lavacli workers env-dut get <hostname>
    lavacli workers env-dut set <hostname> <env-dut.yaml>
    lavacli workers list [--all]
    lavacli workers maintenance <hostname> [--force] [--no-wait]
    lavacli workers show <hostname>
    lavacli workers update <hostname> [...]
