Push Tracker
ria-toolkit-oss/docs/ria_app_hub_handoff.md

105 lines
5.2 KiB
Markdown
Raw Permalink Normal View History

J
2026-06-16 11:54:05 -04:00
# `ria-app` Hub-Side Handoff
**Repo:** `ria-hub`
**Goal:** Make containerized apps built by Application Composer self-describing so the new `ria-app` CLI in `ria-toolkit-oss` can auto-configure GPU/USB/network flags at `docker run` time. No user copy-paste of flags.
---
## Context — what exists today
In `ria-toolkit-oss` (branch `screens-connection`) there is now a `ria-app` CLI:
```bash
ria-app configure --registry registry.riahub.ai --namespace qoherent
ria-app pull <app>[:tag]
ria-app run <app>[:tag] [--config config.yaml]
ria-app list
ria-app logs <app> [-f]
ria-app stop <app>
```
`ria-app run` inspects OCI image labels and auto-adds runtime flags:
| Label | Value (example) | Effect |
|---|---|---|
| `ria.profile` | `native-x86`, `nvidia-x86`, `holoscan` | `nvidia`/`holoscan`/`cuda` → adds `--gpus all` |
| `ria.hardware` | comma list: `pluto,usrp,rtlsdr,hackrf,bladerf,thinkrf` | USB-attached SDRs → `--device /dev/bus/usb`; networked SDRs → `--net host` |
| `ria.app` | `<app-name>` | Used by `ria-app list` to filter images |
| `ria.version` | `<git sha or semver>` | Informational |
If the labels are missing, `ria-app run` still works but can't auto-configure — the user has to pass `--docker-args ...` themselves. So the value here is entirely in getting CI to stamp the labels.
---
## What to change in `ria-hub`
### 1. Stamp OCI labels on every built image
In the Application Composer build flow (follow the path from `application_composer.go:172` `ComposerBuildTrigger` → generated `.riahub/workflows/*.yml``sample-build-tools` `full_generator.py``Dockerfile` emission), add `LABEL` instructions to the generated Dockerfile. The values should be computed from the app JSON the user submitted, not hard-coded:
```dockerfile
LABEL ria.app="${APP_NAME}"
LABEL ria.profile="${PROFILE}" # native-x86 | nvidia-x86 | holoscan | ...
LABEL ria.hardware="${HARDWARE_CSV}" # e.g. "pluto,usrp" (empty string if none)
LABEL ria.version="${GIT_SHA}"
LABEL ria.operators="${OPERATORS_CSV}" # optional, nice for debugging
```
`HARDWARE_CSV` derivation: walk the operator graph in the submitted app JSON and collect the set of hardware backends that any operator requires. The mapping from operator → hardware tag should live next to the existing `operator_generator.py` apt-dep resolution (that code already knows, per operator, whether it needs `libuhd-dev`, `libad9361-dev`, `libhackrf-dev`, `librtlsdr-dev`, etc.). Reuse that table — just emit the short tag (`usrp`, `pluto`, `hackrf`, `rtlsdr`) alongside the apt package name.
Allowed hardware tags (must match what `ria-app` recognizes):
- `pluto`, `rtlsdr`, `hackrf`, `bladerf` → USB
- `usrp`, `thinkrf` → network
- (extend here when new SDR backends are added)
If an operator needs both (e.g. Pluto over USB *and* its iio network endpoint), list it once — `ria-app` already applies both USB and host-net when `pluto` appears.
### 2. Prefer `LABEL` over `ARG`-only
The CI job likely already passes things like `APP_NAME` and `GIT_SHA` as build args. Those args disappear after build unless promoted to `LABEL`. Make sure each of the five labels above ends up in the final image layer (verify with `docker image inspect --format '{{json .Config.Labels}}' <ref>`).
### 3. Push with both `:<sha>` and `:latest` tags
`ria-app` defaults to `:latest` when the user omits a tag. If CI only pushes immutable SHA tags today, also push `:latest` on main-branch builds so `ria-app run my-classifier` Just Works.
### 4. (Optional but recommended) App index endpoint
Add `GET /apps` to the hub API returning something like:
```json
[
{
"name": "my-classifier",
"image": "registry.riahub.ai/qoherent/my-classifier:latest",
"profile": "nvidia-x86",
"hardware": ["pluto"],
"updated_at": "2026-04-14T10:00:00Z"
}
]
```
This lets `ria-app list --remote` show available apps without the user knowing image names. Not required for MVP — skip if it adds scope.
### 5. (Optional) Ship a default `config.yaml` inside the image at a known path
`ria-app run --config <path>` mounts the user's config to `/config/config.yaml` and sets `RIA_CONFIG=/config/config.yaml`. The runtime already falls back to an embedded config per your handoff notes, so this just needs to keep working — no change unless you want to standardize the embedded path.
---
## Acceptance checklist
- [ ] A Composer-built image for a native-x86 app with a Pluto operator has labels: `ria.profile=native-x86`, `ria.hardware=pluto`, `ria.app=<name>`, `ria.version=<sha>`.
- [ ] A Composer-built image for an nvidia-x86 app has `ria.profile=nvidia-x86`.
- [ ] `docker image inspect --format '{{json .Config.Labels}}' <ref>` shows all five labels.
- [ ] `:latest` tag is pushed for main-branch builds.
- [ ] Running `ria-app run <app>` on a user's machine starts the container with the right `--gpus` / `--device` / `--net` flags without the user passing anything beyond the app name.
---
## Out of scope
- Anything on the `ria-toolkit-oss` side — the CLI is already implemented on branch `screens-connection`.
- Changes to the generated C++ code, CMakeLists, or runtime config lookup.
- Artifact downloads — we're distributing via the container registry only.