Hi folks,
The 2026.10 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
and
https://hub.docker.com/u/lavasoftware
Changes in this release ==================
# Migrations
## New migrations
4 database migrations are applied by this release:
* lava_scheduler_app.0071_lava_log_entry * lava_scheduler_app.0072_testjob_pool_pattern * lava_scheduler_app.0073_testjob_view_permission_and_device_id_index * lava_scheduler_app.0074_testjob_add_missing_permissions
`0071_lava_log_entry` moves the Device, Worker and TestJob history from Django's `LogEntry` table to dedicated LAVA tables. On instances with a long history, this migration can take some time as every log entry is copied.
`0073_testjob_view_permission_and_device_id_index` adds an index on `(actual_device, -id)`. On PostgreSQL, the index is built concurrently so job submission is not blocked on large instances.
# Distributions
This release drops support for Django 4.2 and requires **Django 5.2** or later.
Debian 12 (bookworm) is no longer supported. On Debian 13 (trixie), `python3-django` has to be installed from trixie-backports. The docker images have been updated accordingly.
# Breaking changes
Job cancel, fail, resubmit and toggle_favorite in the web UI, job cancel in the REST API, remote-artifact token delete, and the saved query and chart endpoints (delete, toggle published, omit, include, refresh, reorder, per-user settings, and removing a query from a chart) all answered GET. The hardening fix (introduced in https://gitlab.com/lava/lava/-/merge_requests/3516) made the state-changing endpoints `POST`-only. `GET` on these endpoints now returns 405 instead of acting. chart_query_order_update and settings_update returned 403 before. **Clients must use `POST`**.
# Documentation
## Security
The security documentation has been extended:
* a [threat model]( https://gitlab.com/lava/lava/-/blob/master/doc/threat-models/THREAT_MODEL.md...) for LAVA covering assets, entry points, threats and recommended mitigations * a [vulnerability handling page]( https://lava.readthedocs.io/en/latest/admin/vulnerability-handling.html) documenting how security issues are reported and handled under the Linaro VDP * the [SECURITY.md]( https://gitlab.com/lava/lava/-/blob/master/SECURITY.md?ref_type=heads) file now covers the EU Cyber Resilience Act duties: supported-versions policy, safe harbor statement and PSIRT reporting duties
## lavacli MCP
Document the lavacli MCP command with an example of usage.
# Device-types
## New device-types
* frdm-imxrt1186 * frdm-mcxe31b * frdm-mcxn947 * mimxrt700-evk
## NXP MCU
Devices based on `base-nxp-mcu.jinja2`:
* support the `flasher` deploy method when `flasher_deploy_commands` is defined * support the `minimal` boot method * can override `boot_character_delay` and `test_character_delay`
# Dispatcher
## lava-signal: kmsg
When the kernel console is on the same serial line as the test shell, the kernel can print a message in the middle of a LAVA signal, corrupting it and making the job fail. LAVA now detects such corruption and suggests to use `lava-signal: kmsg`.
With `kmsg`, every signal is written to `/dev/kmsg`. The kernel prints each record as a whole, so a kernel message can only appear before or after a signal, never inside it.
```yaml - test: definitions: - name: kselftest from: git repository: https://github.com/Linaro/test-definitions path: automated/linux/kselftest/kselftest.yaml lava-signal: kmsg ```
See the [test action documentation]( https://lava.readthedocs.io/en/latest/technical-references/job-definition/ac... ).
## Cleanup order
The cleanup actions are now run in reversed order. This ensures that the DUT is always powered off before the rest of the cleanup, even when an exception is raised during the pipeline execution.
This is required, for instance, when using `usbg-ms` as the DUT should be powered off before disabling `usbg-ms` on the worker.
## Secrets
Fix a regression where the secret file was not created in the overlay.
## Multinode
The multinode protocol now reads and sends the full messages over the socket. Previously, a partial `recv` or `send` could corrupt large messages.
## Power
When a reboot is skipped because there is no connection, a warning is logged and the skip is recorded in the job results.
# Coordinator
lava-coordinator has been hardened:
* read and send the full messages * do not crash when a client drops the connection or sends invalid data * add a per-request timeout and a payload limit * fix `lava-wait-all --role` * use the same `--log-file` and `--level` arguments as the other daemons * exit cleanly on ctrl+c and set the exit code
# Server
## Multinode pool pattern
A multinode job can now require every device of the group to belong to the same *pool* of devices. A pool is described by a device tag matching a glob pattern:
```yaml protocols: lava-multinode: pool_pattern: "lab-*" roles: server: device_type: qemu count: 1 client: device_type: bcm2711-rpi-4-b count: 1 ```
With devices tagged `lab-paris` or `lab-lyon`, the group will either run entirely on `lab-paris` devices or entirely on `lab-lyon` devices, but never on a mix of both. This is useful when the devices of a group have to be physically connected together (network switch, power supply, USB hub, ...).
See the [protocols documentation]( https://lava.readthedocs.io/en/latest/technical-references/job-definition/pr... ).
## view_testjob permission
The `view_testjob` permission was never created in the database, so it was impossible to grant it. A user holding this permission can see every test job, including private jobs and jobs older than `PUBLIC_JOB_WINDOW_DAYS`.
It is not granted to any group by default. Grant it in the Django admin group editor or with the XML-RPC API.
See [the authorization documentation]( https://lava.readthedocs.io/en/latest/technical-references/authorization.htm... ).
## REST API performances
Listing jobs with `/api/v0.2/jobs/` was materializing every visible job ID in memory. On large instances this was using hundreds of MB per request and taking 20-25s. The planner issue has been fixed at the root with a new index and by filtering on the device foreign key directly.
## Log entries
Device, Worker and TestJob history is now stored in dedicated LAVA tables instead of Django's `LogEntry` table, which cannot be indexed. This fixes slow device and worker pages.
The worker page now displays both the worker transitions and the transitions of its devices in two separate tables.
## Health checks
A device dictionary extending a base template (like `base-uboot.jinja2`) made the scheduler look for the health check of the base template. The scheduler now looks for `<device-type>.yaml` first, then for the extended template.
## Job logs
* Add `scheduler.jobs.logs_count` XML-RPC API returning the number of log lines of a job. Combined with `scheduler.jobs.logs`, it allows to fetch the end of the logs. * The REST API does not send `Content-Length` anymore for running jobs, which was truncating the log of running jobs. * Job result exports (CSV and YAML) are streamed without caching the full result set in memory.
## Security fixes
* fix a stored XSS in device and worker health logs * fix `SO_PEERCRED` check in lava-dispatcher-host which was rejecting every peer, root included
# Packaging
## Apache
Static files are now served directly by Apache instead of being proxied to gunicorn, freeing gunicorn workers.
## Debian packages
* `python3-guestfs` is now a recommended dependency as the `debugfs` implementation does not require it * `iproute2` is now a required dependency * `python3-bpfcc` is now a recommended dependency
## Local development
A Makefile has been added to run LAVA locally using uv. Run `make help` to list the available targets.
```shell make init make run ```
Rgds