Hi folks,

The 2026.04 tag has been pushed to master on gitlab.com/lava/lava.
.deb packages have been built in GitLab CI and are published at

  https://apt.lavasoftware.org/release

Docker images for amd64 and arm64 have been built in GitLab CI and
are available from

  https://registry.gitlab.com/

and

  https://hub.docker.com/u/lavasoftware


Changes in this release
==================

# Security fixes

## Private job information leaked in device table

The device table was displaying the submitter and description of the
currently running job even when the user did not have permission to view
that job.
Now users without view permission will only see that the device is "Running" a
job, without any job details.

# Breaking changes

## LXC support dropped

LXC support has been removed. It has been unmaintained and deprecated for several years.

Users of LXC jobs must migrate to [Docker-based alternatives](https://lava.readthedocs.io/en/latest/user/advanced-tutorials/running-arbitrary-code-with-docker.html).

## Database migrations squashed (upgrade path limited)

`lava_results_app` migrations have been squashed to remove non-portable
PostgreSQL-specific SQL and Python. The squashed migration is now the
new initial migration.

**Direct upgrades from LAVA 2020.09 or earlier are no longer supported.**

The oldest supported upgrade path is from LAVA 2020.12 (the version
shipped with Debian 11 Bullseye). Administrators running older instances
must upgrade to at least 2020.12 before upgrading to this release.

## Worker auto-registration disabled by default

Worker auto-registration is now disabled by default due to security implications.
If `WORKER_AUTO_REGISTER_NETMASK` is set and a HTTP proxy is in use, LAVA sees
the proxy's IP address (possibly localhost), which could allow unauthorized
workers to register and obtain tokens.

To re-enable auto-registration, explicitly configure `WORKER_AUTO_REGISTER_NETMASK`
in your settings.

## Debian 11 support

As of 2026.04 release Debian 11 (Bullseye) is no longer supported. Administrators are requested to migrate to at least Debian 12 (Bookworm).

# LAVA Server

## REST API

New endpoints for managing groups and users are available in the v0.2 REST API:

* `GET/POST /api/v0.2/groups/`
* `GET/PUT/PATCH/DELETE /api/v0.2/groups/<id>/`
* `GET/POST /api/v0.2/users/`
* `GET/PUT/PATCH/DELETE /api/v0.2/users/<id>/`

## XMLRPC API

Fix device owner not being updated when calling `lavacli devices update --user`.
The `physical_owner` field was not being updated by the API call.

# LAVA Worker

## Test services

LAVA now supports running test services on the worker. Test services are
Docker Compose-based containers started on the LAVA worker, enabling custom
services for test definitions. For example, LAVA can now start an OTA server
that a DUT under test can connect to.

Job definition example:

```yaml
- test:
    services:
      - name: my-service
        compose:
          version: "3"
          services:
            ota-server:
              image: my-ota-server:latest
              ports:
                - "8080:8080"
    definitions:
      - repository: https://example.com/tests.git
        from: git
        path: testdefs/ota.yaml
        name: ota-test
```

## Expected test results

When an expected test list is provided, any test case not in that list now
results in a **fail** (previously it was only logged). This makes it easier
for regression-detection tools to spot unexpected test cases that should be
investigated.

## GRUB

## Overriding `net_commands`

Device dictionaries can now override `net_commands` to set custom GRUB network
commands. This is useful for debugging network boot issues (e.g. adding
`net_ls_addr`):

```jinja2
{% set net_commands = ['net_ls_addr', 'dhcp'] %}
```

### Error detection

LAVA will now automatically catch a large set of error raised by Grub while
trying to boot a kernel.

The following error patterns are now matched:

* `missing (.*) symbol.`
* `couldn't send network packet`
* `destination unreachable`
* `couldn't autoconfigure`
* `timeout reading`
* `file '(.*)' not found`
* `no such device`
* `disk '(.*)' not found`
* `unknown filesystem`

## udev: kernel netlink fallback for containers

The udev monitoring code now falls back to kernel netlink if no udev
events are received. This allows containerized dispatchers to detect
USB devices without requiring `--network=host` or `CAP_NET_ADMIN`, since
containers don't propagate udev events across namespaces.
sysfs attributes are used as a fallback for `ID_SERIAL_SHORT` when udev
properties are unavailable.

## LAVA_JOB_ID environment variable

`LAVA_JOB_ID` is now available in the `lava-run` environment, accessible
to `user_commands` the same way as secrets declared in the job definition.
This is useful for running commands that are job-specific.

# Documentation

The documentation has been again vastly improved with changes to:

* Admin docs: hardware recommendations, typical deployment topologies,
  LDAP configuration, first steps, recommended security settings
* Developer docs: contribution guide, code of conduct, guide for adding
  new actions, new device type guide, developer first steps
* User docs: job debugging guide, job results, LAVA auth, user permissions,
  common LAVA use cases

# CI

More pylint checks enabled and code brought into compliance:
`W1510`, `W0611`, `W1115`, `E0307`, `E0611`, `E1136`.

The minimum checked Python version has been increased to **3.11**.


Rgds

--
Rémi Duraffort
Principal Tech Lead
LAVA Tech Lead
Automation Software Team
Linaro