Remove stale ubuntu-core-plan.md from distro/ubuntuCore.

The working snap and image scripts supersede the planning doc.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-25 23:14:21 -04:00
parent 038d59f972
commit 4f4a782245
-276
View File
@@ -1,276 +0,0 @@
# Salmanoff on Ubuntu Core — Plan (derived from Yocto work)
## Purpose of this document
This plan is **not** a translation of an original Yocto design doc. It reflects **what we actually built and validated** in the Yocto path, reframed as goals for Ubuntu Core. Use it as primary context when scaffolding snaps, gadget/model, and dev VM workflow.
When done, snap definitions and support files land in the SMO repo under:
```
smo/distro/ubuntuCore/
```
(parallel to the existing `smo/distro/yocto/meta-salmanoff/`).
---
## What we proved in Yocto (facts, not aspirations)
We shipped a **minimal headless image** that runs the Salmanoff (SMO) cognitive robotics runtime on **QEMU x86-64**, bridged onto a lab LAN, talking to a **Livox LiDAR** on a fixed IP.
### Lab network (canonical — carry forward unchanged)
| Host | IP | Role |
|---|---|---|
| Laptop / gateway | `10.42.0.1` | Gateway + DNS |
| RPi5 (production target) | `10.42.0.2` | Future production node |
| **Dev guest (QEMU / UC VM)** | **`10.42.0.16`** | SMO dev runtime |
| Livox Avia | `10.42.0.139` | LiDAR sensor |
### Runtime configuration we validated
- **Body file**: `yocto-qemu-x86-headless.dapss` — Livox-only, headless (no win0/camera), `smo-ip=10.42.0.16`, includes `avia0.dapss`.
- **SMO build profile** (CMake):
- `RelWithDebInfo`
- `ENABLE_LIB_lcameraDev=ON`, `ENABLE_STIMBUFFAPI_lcameraBuff=ON` (libcamera + OpenCL YUV path compiled in; no camera passthrough needed in QEMU)
- `ENABLE_LIB_xcbXorg=OFF`, `COMPILE_PCL_TOOLS=OFF`, `ENABLE_TESTS=OFF`, `ENABLE_LCAMERADEV_TOOLS=OFF`
- Git submodules required (`libspinscale`, etc.)
- **Runtime command shape** (approximate):
```bash
salmanoff -d /usr/share/salmanoff/devices/bodies/body_yocto_qemu_x86_headless.daps -p /usr/lib -v
```
(exact installed `.daps` filename follows DAPSS build output naming)
### Platform services / packages we pulled into the image
| Need | What we used in Yocto |
|---|---|
| SMO runtime + libs | `salmanoff` recipe (`libspinscale`, `liblcameraDev`, `liblcameraBuff`, `liblivoxGen1`, …) |
| Boost | Pinned **1.86** (shared `boost-system`; must stay **< 1.89**) |
| liburing | Runtime dep |
| libcamera + v4l-utils | Present on image; camera optional at runtime |
| OpenCL | Mesa Rusticl via `opencl` distro feature; **needs `RUSTICL_ENABLE=llvmpipe`** or platform shows 0 devices |
| OpenCL verify | `clinfo` (also discovered **256M RAM OOMs** OpenCL probe — use **≥ 2G** for dev VM) |
| Network | Static `eth0`: `10.42.0.16/24`, gw `10.42.0.1` |
| Dev access | SSH (openssh on Yocto image) |
| Kernel probe | `rseqsliceprobe` + kernel config append for rseq slice extension |
| QEMU dev | Host bridge `br-smo`, `runqemu` with `bridge=br-smo`, `nographic`, `-m 2048` |
### Repo / packaging decisions already made in SMO
- Yocto layer vendored at `smo/distro/yocto/meta-salmanoff/` (committed on `clast`).
- SMO source changes on `clast`: headless body, flex/bison repo-relative `#line` paths, etc.
- Fetch uses private Gitea (`hayodea/salmanoff`, branch `clast`, submodules via `libspinscale` on separate SSH host alias).
---
## Conceptual goals (portable to Ubuntu Core)
These are the **intent** items — independent of BitBake:
1. **Repeatable dev environment** — headless guest on `10.42.0.16`, reachable from laptop, Livox at `10.42.0.139`.
2. **SMO as first-class payload** — not “install deps manually”; runtime + `.daps` bodies + plugin `.so`s packaged and startable.
3. **Same CMake feature profile** as Yocto (lcamera + OpenCL enabled; xcb/PCL tools off).
4. **OpenCL that actually works headless** — Rusticl/llvmpipe with env var set before SMO starts.
5. **libcamera stack present** — libraries available even when no camera device is passed through (QEMU/UC dev).
6. **Boost version constraint honored** — do not silently pick Boost ≥ 1.89.
7. **Production path to RPi5** — same snap(s), different body/IP (`10.42.0.2`), gadget/kernel for Pi hardware.
8. **Distro metadata lives in SMO** — `distro/ubuntuCore/` committed back into SMO when stable (mirrors Yocto layout).
---
## Yocto → Ubuntu Core mapping
| Yocto (what we did) | Ubuntu Core (target) |
|---|---|
| `meta-salmanoff/` layer | `distro/ubuntuCore/` — snaps, gadget, model, helper scripts |
| `salmanoff-image.bb` | **Model assertion** + `core` + gadget snap + app snaps on seeded image |
| `salmanoff.bb` recipe | **`salmanoff` snap** (`snapcraft.yaml`: cmake build, submodules, organize libs + daps) |
| `IMAGE_INSTALL` | Snap `stage-packages` / parts / content snaps (`mesa`, libcamera deps) |
| `salmanoff-rusticl-env` recipe | Snap `environment:` block or wrapper script: `RUSTICL_ENABLE=llvmpipe` |
| `init-ifupdown` static IP | **Netplan** via gadget default config, `network-setup` snap, or `system-connections` on UC |
| `runqemu-salmanoff-bridge` | **Dev VM script**: UC image in QEMU/LXD/multipass on `br-smo`, static `10.42.0.16`, 2G RAM |
| `DISTRO_FEATURES += opencl` | Ensure Mesa/OpenCL ICD available to snap (layout + plugs or bundled libs) |
| `DEPENDS` / `RDEPENDS` | Snapcraft `build-packages`, `stage-packages`, `slots`/`plugs`, `layout:` for `/usr/lib` ICD paths |
| `gitsm://` + `SRCREV` | Snapcraft `source` + `source-submodules` or `override-pull` git submodule update |
| `yocto-qemu-x86-headless.dapss` | Installed by salmanoff snap; UC-specific body can be `ubuntu-core-x86-headless.dapss` later |
| `rseqsliceprobe` | Validate UC kernel/base; custom kernel snap only if probe fails on stock UC kernel |
| SSH on image | UC: serial console, `ssh-keys` in model, or dedicated snap — **dont assume openssh like Yocto** |
| Boost 1.86 pin | Pin in snapcraft (`stage-packages` version) or build Boost part from source |
| `RelWithDebInfo` + debug maps | Snapcraft `override-build` cmake flags; consider `debug` snap or stripped separate artifact |
---
## Proposed Ubuntu Core architecture
```
Host (10.42.0.1)
└── bridge br-smo (10.42.0.0/24)
└── UC dev VM / RPi5 (10.42.0.16 or .2)
├── snap: core (or core24)
├── snap: gadget-<platform> (boot, partitions, default netplan)
├── snap: salmanoff (daemon — main payload)
└── optional: mesa-support / libcamera-support content snaps if not bundled
```
### `salmanoff` snap (primary deliverable)
**Type**: likely `daemon` (simple) or `daemon` (notify) once startup semantics are known.
**Build** (mirror Yocto recipe intent):
- Source: SMO repo `clast` (submodules!)
- CMake options: same as Yocto `EXTRA_OECMAKE` block
- Install: `salmanoff` binary, `lib*.so*`, `/usr/share/salmanoff/devices/**`
- Apps: main daemon + optional `salmanoff.probe` for debugging
**Runtime environment**:
```yaml
environment:
RUSTICL_ENABLE: llvmpipe
```
**Interfaces to evaluate early** (exact set TBD by confinement testing):
- `network` / `network-bind` — Livox UDP/TCP to `10.42.0.139`
- `hardware-observe` — may be needed for camera discovery on Pi
- `camera` — for libcamera on production Pi
- `opengl` — if Mesa GL stack needed beyond OpenCL ICD
- `raw-usb` / `serial-port` — only if Livox path requires it on some platforms
- `home` — usually **avoid**; use `$SNAP_DATA` for state
**Layouts** (likely needed):
- OpenCL ICD loader expects `/etc/OpenCL/vendors` or known `LD_LIBRARY_PATH`
- May need `layout:` bind mounts for Mesa `libRusticlOpenCL.so` / gallium stack
### Platform snaps
| Platform | Gadget | Notes |
|---|---|---|
| **QEMU x86 dev** | `pc` or custom gadget | Static IP `10.42.0.16`, 2G RAM, bridged NIC |
| **RPi5 production** | `pi` gadget (22+ arm64) | Static IP `10.42.0.2`, libcamera, Livox |
### Bodies / config
- **Dev (UC VM)**: start from Yocto body or add `ubuntu-core-x86-headless.dapss` with same Livox-only intent and `smo-ip=10.42.0.16`.
- **Production (RPi5)**: reuse/adapt existing `rpi5-persys-headless.dapss` pattern with `smo-ip=10.42.0.2`.
Body files stay in SMO `devices/bodies/`; snap selects default via config or snap config hook.
---
## Phased plan (recommended order)
### Phase 0 — Repo scaffold
- [ ] New repo (or `distro/ubuntuCore/` in SMO) with `snapcraft.yaml` skeleton
- [ ] Document lab IP table and bridge prerequisites (port `runqemu-salmanoff-bridge` concepts)
- [ ] Link to SMO `clast` branch + submodule SSH host requirements
### Phase 1 — Build snap on host (no hardware)
- [ ] `snapcraft` / `craft` builds SMO with same CMake profile as Yocto
- [ ] Confirm submodule pull (`libspinscale`) in clean CI/local environment
- [ ] Resolve Boost < 1.89 (stage-package pin or source part)
- [ ] Package `.daps` + shared libs; verify `salmanoff -v` / dry-run in snap run environment
### Phase 2 — OpenCL + libcamera in confinement
- [ ] Replicate Yocto OpenCL stack inside snap (bundled vs system Mesa)
- [ ] Confirm `RUSTICL_ENABLE=llvmpipe` → `clinfo` shows ≥1 device **inside snap**
- [ ] Confirm `liblcameraDev` / `liblcameraBuff` load; no crash without camera device
- [ ] Document RAM requirement (≥ 2G for dev VM)
### Phase 3 — UC dev VM on lab LAN
- [ ] Boot Ubuntu Core x86 VM bridged to `br-smo`
- [ ] Static IP **10.42.0.16** (netplan/gadget)
- [ ] Install seeded `salmanoff` snap (devmode first, then strict)
- [ ] Ping gateway; reach Livox at `10.42.0.139`
- [ ] Run headless body; validate Livox traffic / SMO logs
### Phase 4 — Production path (RPi5)
- [ ] Model assertion for Pi5 + arm64 core
- [ ] Gadget with `10.42.0.2` netplan
- [ ] libcamera plug + Pi body file
- [ ] OTA refresh via snap channels
### Phase 5 — Commit back to SMO
- [ ] Move stable `distro/ubuntuCore/` into SMO repo
- [ ] Commit on `clast` (or dedicated branch); do **not** block on unfinished WIP snaps
---
## Known constraints & pitfalls (from Yocto — expect repeats)
1. **OpenCL**: platform visible but **0 devices** until `RUSTICL_ENABLE=llvmpipe`.
2. **Memory**: 256M insufficient for Rusticl/`clinfo`; use **2G** for dev VM.
3. **Boost**: must stay **< 1.89** (shared `boost-system` linkage).
4. **Submodules**: `libspinscale` is mandatory; fetch must be recursive; separate SSH host alias on Gitea.
5. **lcamera without hardware**: compile and ship libs; no QEMU camera passthrough required for basic bring-up.
6. **PCL / xcb**: keep off unless explicitly needed (MPI/cmake pain in Yocto).
7. **Private git**: snapcraft build needs SSH keys / credentials for Gitea fetch (or vendored source tarball part).
8. **Strict confinement**: biggest unknown vs Yocto — plan devmode → strict iteration; interfaces will take multiple passes.
9. **rseq kernel feature**: validate on UC base; custom kernel snap is expensive — only if probe fails.
---
## Success criteria (match Yocto milestone)
Minimum “were at parity” for UC dev:
- [ ] UC VM at `10.42.0.16` on `10.42.0.0/24` via host bridge
- [ ] `salmanoff` snap installed and daemon running (or manual `snap run` equivalent)
- [ ] Headless Livox body loaded; SMO stable with Livox on `10.42.0.139`
- [ ] OpenCL initialized (llvmpipe); lcamera libs present
- [ ] Snap definitions committed under `smo/distro/ubuntuCore/`
Stretch (production):
- [ ] Same snap on RPi5 at `10.42.0.2` with Pi-appropriate body
---
## Explicit non-goals (for now)
- Re-implement Yocto layer / BitBake in UC repo
- Camera passthrough in QEMU/UC x86 dev
- PCL tools / xcb window stack
- lcameraDev probe tools (need test support libs — off in Yocto too)
- Full OTA/signing production pipeline (Phase 4+)
---
## Reference: Yocto artifacts in SMO repo
When unsure, read the working Yocto implementation:
```
smo/distro/yocto/meta-salmanoff/
conf/layer.conf
conf/salmanoff-local.inc # opencl distro feature
recipes-salmanoff/salmanoff/salmanoff.bb
recipes-core/images/salmanoff-image.bb
recipes-core/init-ifupdown/... # 10.42.0.16 static IP
recipes-support/salmanoff-rusticl-env/
scripts/runqemu-salmanoff-bridge
smo/devices/bodies/yocto-qemu-x86-headless.dapss
```
SMO branch: **`clast`** on `hayodea/salmanoff` (Gitea).
---
## Instructions for the LLM in the Ubuntu Core repo
1. **Treat Yocto work as validated reference**, not something to re-derive from scratch.
2. **Preserve lab IP plan and CMake profile** unless user says otherwise.
3. **Start with snapcraft build on host**, then UC VM, then strict confinement — same order we used (build → package QA → runtime).
4. **Plan for `distro/ubuntuCore/` in SMO** as the final home of snaps/gadget/model/scripts.
5. **Ask before** committing snaps into SMO; user will commit when done.
6. **Do not** assume UC has openssh or classic Ubuntu package management — everything is snaps + interfaces.