5.2 KiB
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:
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:
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→ USBusrp,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:
[
{
"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.:latesttag is pushed for main-branch builds.- Running
ria-app run <app>on a user's machine starts the container with the right--gpus/--device/--netflags without the user passing anything beyond the app name.
Out of scope
- Anything on the
ria-toolkit-ossside — the CLI is already implemented on branchscreens-connection. - Changes to the generated C++ code, CMakeLists, or runtime config lookup.
- Artifact downloads — we're distributing via the container registry only.