Skip to content

Allow LAVA jobs to pass artifacts back to the runner - #132

Open
tintou wants to merge 6 commits into
collabora:mainfrom
tintou:tintou/artifact_upload
Open

Allow LAVA jobs to pass artifacts back to the runner#132
tintou wants to merge 6 commits into
collabora:mainfrom
tintou:tintou/artifact_upload

Conversation

@tintou

@tintou tintou commented Aug 6, 2026

Copy link
Copy Markdown

This is a rebase of #116 which is a rework of #17

We'd like to potentially add artifacts created by LAVA jobs to the archive stored by Gitlab. To achieve this, we run a cut-down web server on the lava-gitlab-runner that is able to respond to POST requests at

   http://<host>:<port>/artifacts/<key>/<path>

The LAVA job is able to know the upload URL because we introduce a new namespace for templated variables runner in the lava-gitlab-runner and add ARTIFACT_UPLOAD_URL to it.

It's still relatively complicated to get variables into LAVA tests; the pattern I used in my test repository

https://gitlab.collabora.com/tintou/callback-tests

is to create a parameter called CALLBACK_URL in the test itself, and then in the job we can use a stanza like:

   test: foo
     parameters:
       CALLBACK_URL: {{ '{{ runner.ARTIFACT_UPLOAD_URL }}' }}

to make it available to the test. Bear in mind, if you use this that LAVA does not automatically export parameters from environment variables so you will need to export it inside your steps: in your test if you want to use it in scripts.

The key part of the upload URL is a long random string. It's generated uniquely per Gitlab job, not per LAVA job, although this detail is not important unless you are performing multi-node tests.

Because of the dynamic nature of the key, and the runner's port and IP, artifact upload is only possible for submit jobs. For monitor jobs, there's simply no way to communicate the necessary URL to them.

Backing the webserver, there is a shared UploadServer that stores the uploaded artifacts, and bridges between the web server thread and the job thread. It stores a JobArtifacts for each active job, which the ArtifactStore can query when we come to upload files. Uploaded artifacts are placed in the archive under exactly the relative <path> given in the upload URL (not automatically prefixed with the job ID, unlike the log/JUnit uploads), alongside the log/JUnit output, once the LAVA job finishes. Note however that it will require some significant reworking to support distinct directories for multi-node jobs. That's because we do not know how many nodes there are in the job until after we submit, at which point it's too late to create new keys for the other jobs. We could speculatively create a surplus, for example, but we couldn't then tie them to job IDs anyway.

Uploads are disabled unless LAVA_ARTIFACT_UPLOAD_BASE_URL is set on the runner; this is the externally reachable base URL of the upload endpoint (e.g. https://my-runner-host:8443/artifacts), for example for an appropriate reverse proxy. Optionally, LAVA_ARTIFACT_UPLOAD_LISTEN_ADDR can be set to control the local address the upload server binds to (e.g. 0.0.0.0:8443); it defaults to 0.0.0.0:0 (a random port). Uploads are capped at 1 GB per job.

Copilot AI and others added 3 commits August 6, 2026 09:19
- Add axum = "0.8" dependency; enable full tokio features
- New src/upload.rs: UploadServer, UploadStore, JobArtifacts (RAII-based,
  auto-deregisters on drop, no global static, no periodic cleanup)
- Add runner.ARTIFACT_UPLOAD_URL template variable via TransformVariables.runner
- Add Artifact{path, data} to LavaUploadableFileType (path only, no id prefix)
- Run struct gains upload_server and artifacts fields
- transform() takes upload_url param; submit command creates JobArtifacts
- get_uploadable_files() includes artifacts from submit jobs
- upload_artifact axum handler uses State<Arc<Mutex<UploadStore>>>
- main() starts server only if LAVA_ARTIFACT_UPLOAD_BASE_URL is set
- Single env var replaces separate host/port; uses TcpListener::bind + axum::serve

Agent-Logs-Url: https://github.com/collabora/lava-gitlab-runner/sessions/831d8c7f-5dc6-47d2-82c1-7e79eed0c6bf

Co-authored-by: sjoerdsimons <[email protected]>
@tintou
tintou marked this pull request as draft August 7, 2026 17:36
@tintou
tintou marked this pull request as ready for review August 26, 2026 14:05
@tintou

tintou commented Aug 27, 2026

Copy link
Copy Markdown
Author

I did test that the artifacts are being published with https://gitlab.collabora.com/tintou/callback-tests
This job has a test_data.txt that is an artifact from the job directly.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an HTTP upload service so submitted LAVA jobs can return files for inclusion in GitLab artifact archives.

Changes:

  • Adds per-job upload URLs and artifact storage.
  • Integrates uploaded files into runner artifacts.
  • Documents configuration and adds axum dependencies.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/upload.rs Implements upload storage and quotas.
src/main.rs Integrates server, templates, and artifacts.
README.md Documents artifact uploads.
Cargo.toml Adds axum and Tokio features.
Cargo.lock Locks new dependencies.
Suppressed comments (1)

README.md:137

  • curl -T sends a PUT request, while the router only registers POST, so this documented example receives 405 Method Not Allowed. Use a POST-producing curl option (or explicitly support PUT on the route).
              - curl -T my-large-log.txt "{{ runner.ARTIFACT_UPLOAD_URL }}my-large-log.txt"

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/main.rs Outdated
Comment thread src/main.rs
Comment thread src/upload.rs
Comment thread README.md Outdated
Comment thread src/main.rs Outdated
Comment thread README.md
run:
steps:
- curl -T my-large-log.txt "{{ runner.ARTIFACT_UPLOAD_URL }}my-large-log.txt"
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also test this documention in your test repo :) (basically for inline jobs)

@sjoerdsimons

Copy link
Copy Markdown
Contributor

Can you make your test repo public? No reason for it to be private :)

I'm confused by this comment: "Also the upload URL will always be https, even though the service itself does not have TLS support" ; From a quick look i don't see https being enforced and really it shouldn't be. If i have a purely local network setup i should have the freedom to use http instead.

For documentation going via the secrets mechanism makes a lot of sense even if lava secrets aren't as secretive as they should be.

@sjoerdsimons

Copy link
Copy Markdown
Contributor

Also your MR talks about LAVA_GITLAB_RUNNER_ROUTABLE_HOST but i don't see that in the code? Fwiw you indeed don't want a host and port but a base url which it looks like the code got right, so this is more about ensure your MR descriptoin actually matches your code

tintou and others added 2 commits August 31, 2026 16:05
Add README sections describing:
- How to enable the upload server (LAVA_ARTIFACT_UPLOAD_BASE_URL /
  LAVA_ARTIFACT_UPLOAD_LISTEN_ADDR env vars)
- The runner.ARTIFACT_UPLOAD_URL template variable and how to use it
  from a LAVA job definition
- How uploaded artifacts get included in GitLab job artifacts

Co-authored-by: Copilot <[email protected]>
@tintou
tintou force-pushed the tintou/artifact_upload branch from e3c141d to fed7d50 Compare August 31, 2026 14:05
Do not keep the lock on the UploadStore but on the job directly.
@tintou
tintou force-pushed the tintou/artifact_upload branch from 300555c to 49a579f Compare August 31, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants