From 1ccea916c3eec4d38125b2380d5e405543527940 Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Sat, 5 Sep 2026 00:46:37 +0800 Subject: [PATCH] docs: roadmap for docker image types (vendor profiles) Design proposal for an image_type discriminator on Docker templates plus a compute-side profile registry: vendor parameters graduate from environment markers into schema-gated fields, generic-feature applicability becomes declared capability data, existing markers stay as a compatibility fallback. Explicitly not a new node type. Four profiles already exist to shape it (iol-runner, XRd, SR Linux prototype, FRR appliance); implementation follows the current PR series. --- docs/README.md | 9 ++ docs/design/docker-image-type.md | 144 +++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 docs/design/docker-image-type.md diff --git a/docs/README.md b/docs/README.md index 55b7a9155..ea1581292 100644 --- a/docs/README.md +++ b/docs/README.md @@ -39,6 +39,8 @@ docs/ │ ├── statistics-api.md # Aggregated statistics API for monitoring │ ├── vnc-websocket-console.md # Browser-based VNC console via WebSocket │ └── web-wireshark-business-process.md # Web Wireshark (Docker + xpra packet capture) +├── design/ # Design proposals & roadmaps (not yet implemented) +│ └── docker-image-type.md # Docker image types: vendor profile discriminator + registry ├── gns3-copilot/ # AI Copilot feature documentation │ ├── netmiko_devices.md # Netmiko supported devices (366 types) │ ├── template-based-configuration-roadmap.md # Future: template-based config with HITL @@ -89,6 +91,13 @@ Cisco CML containerized IOL (e.g. `iol-xe/iol-xe:17-18-02`) as GNS3 Docker route --- +## Design & Roadmaps (`design/`) + +### Docker Image Types (`design/docker-image-type.md`) +Proposed `image_type` discriminator on Docker templates plus a compute-side profile registry: vendor parameters graduate from environment markers into schema-gated fields, generic-feature applicability becomes declared capability data, and the existing markers remain as a compatibility fallback. Not a new node type — vendor images are content, not mechanism. + +--- + ## GNS3 AI Copilot (`gns3-copilot/`) ### Implemented Features diff --git a/docs/design/docker-image-type.md b/docs/design/docker-image-type.md new file mode 100644 index 000000000..db00cc345 --- /dev/null +++ b/docs/design/docker-image-type.md @@ -0,0 +1,144 @@ +# Docker Image Types (Vendor Profiles) — Roadmap + +Status: **proposal, not implemented**. This is the agreed direction for the +next iteration of vendor Docker support. Four vendor profiles already +exist across branches and prototypes — iol-runner (this branch), XRd and +the SR Linux prototype (vendor/skip-init family), and the FRR registry +appliance — enough evidence to justify the registry. Implement it as a +follow-up to the current PR series, shaped by all four rather than by +iol-runner alone. + +## Problem + +All Docker nodes share one template type (`template_type: "docker"`) and +one template schema. Vendor images (iol-runner, SR Linux, XRd, …) are +selected and configured today through **environment markers** — free-form +strings parsed by the compute (`GNS3_IOL_RUNNER`, `GNS3_IOL_MEMORY`, +`GNS3_IOL_STARTUP_CONFIG`, `GNS3_SKIP_INIT`, `GNS3_UNIX_SOCKET_NIO`, …). +Three pains have already surfaced: + +1. **Invisible and unvalidated.** The markers do not exist in the API + schema: no OpenAPI documentation, no validation, typo or bad value + silently falls back to a default (`GNS3_IOL_MEMORY=notanumber` → 2048). +2. **The shared-schema dilemma.** Adding a vendor-specific field to the + Docker template schema pollutes every Docker template with a field only + one vendor reads; not adding it pushes everything into environment + strings. The `startup_config` discussion (ended in the + `GNS3_IOL_STARTUP_CONFIG` knob) is the canonical example — the tension + exists because there is no legitimate discriminator dimension. +3. **Generic-feature applicability is implicit.** Which generic Docker + features apply to which image is only documented in code comments: + `mac_address` is meaningless under unix-socket NIO, `/etc/network` + seeding is dead weight for skip-init images, `extra_configs` targets + under persisted volumes get a (correct-but-noisy) shadow warning. + +## Non-goal: new node types + +A `template_type`/`node_type` per vendor (`"iol"`, `"srlinux"`, …) is +explicitly rejected. `node_type` is a top-level concept: it drives compute +module routing (`/projects/{id}/{node_type}/nodes`), capability +reporting, GUI node types and link handling. N vendor types that are all +Docker underneath would multiply routing and schema surface for zero +mechanism — vendor images are *content*, not mechanism, and GNS3's +appliance/template system is where content belongs. + +## Design + +### One discriminator field on Docker templates + +```json +{ + "template_type": "docker", + "image_type": "iol-runner", + "image": "iol-xe/iol-xe:17-18-02" +} +``` + +`image_type` is optional; absent (or `"generic"`) keeps today's plain +`DockerVM` behavior and marker sniffing. The profiles that exist today, +mapped to their current mechanisms and archetypes: + +| Profile | Current mechanism | Archetype | +|---|---|---| +| FRR appliance | plain `DockerVM`: init.sh `/etc/network` + `start_command` (frrinit.sh), console on PID 1 | generic | +| XRd | `VendorDockerVM` skip-init + `GNS3_SHM_SIZE`/`GNS3_DEVICES`, `extra_configs`, udev masking | vendor skip-init | +| SR Linux (prototype) | `VendorDockerVM` skip-init + `docker_exec` console + `GNS3_INTERFACE_NAMES` | vendor skip-init | +| iol-runner | `IOLDockerVM`: unix-socket NIO, per-start config generation, NVRAM startup-config | iol-runner | + +Possible first values: `generic`, `iol-runner`, and a value for the +skip-init vendor NOS family once its common shape settles (XRd and SR +Linux may end up sharing it or splitting — that is exactly what the +registry should decide with all four in front of us). + +### A compute-side registry + +```python +IMAGE_PROFILES = { + "iol-runner": { + "class": IOLDockerVM, + "fields": ("iol_memory", "startup_config"), # schema-gated + "capabilities": {...}, # see below + }, + ... +} +``` + +* **Class selection** moves from environment sniffing + (`Docker._select_node_class`) to the field, with the existing markers + kept as a fallback for templates created before the field existed + (zero-migration compatibility). +* **Vendor parameters graduate into schema fields**, gated by pydantic + conditional validation (accepted — and validated — only when + `image_type` matches). This resolves the shared-schema dilemma properly: + the field exists, but only means something for its profile. The + environment knobs remain as the wire-level compatibility entry. +* **Capability declaration** makes generic-feature applicability data + instead of comments: + + | Capability | plain Docker | vendor skip-init | iol-runner | + |---|---|---|---| + | `mac_address` honored | yes | yes | **no** (IOL derives MACs from the app id) | + | `/etc/network` seeding | yes | no | no | + | `extra_configs` targets under volumes | shadowed | works (real-path binds) | works | + | console | telnet/http/… | `docker_exec` | PID 1 stdio (telnet) | + | startup config | `extra_configs` injection | image-specific | nvram build (`nvram_import`) | + + Consumers: error/warning quality (don't warn about inapplicable + features), the WebUI (vendor-aware template forms — a bonus, not a + driver), and documentation generation. + +The existing class hierarchy (`DockerVM` → `VendorDockerVM` → +`IOLDockerVM`) is unchanged — the registry only externalizes selection +and declaration. + +## Migration & compatibility + +* Old templates (markers only) keep working via the fallback; a one-time + optional converter can rewrite markers → `image_type` + fields. +* The controller-side materialization conventions + (`GNS3_IOL_STARTUP_CONFIG` file → `startup_config_content`, sent once) + carry over unchanged — the field version references the same content + pipeline. + +## Roadmap steps + +1. Add `image_type` to the Docker template schema (+ DB column + + Alembic migration — see the three-place rule for template fields) and + wire class selection through the registry, markers as fallback. +2. Move iol-runner knobs to gated fields (`iol_memory`, + `startup_config`), deprecating-but-supporting the env forms. +3. Introduce the capability table and use it to silence inapplicable + warnings (`mac_address`, `/etc/network`, extra-config shadowing). +4. Revisit per-vendor *schemas* (a sub-model per profile) only if a + profile grows more than a handful of fields — not before. + +## Open questions + +* Field name: `image_type` vs `vendor` vs `runner` — decide when the + second profile lands; the value vocabulary should name the *runtime + contract*, not the vendor. +* Should appliances (`.gns3a`) carry `image_type` explicitly, or should + installation keep deriving it from the appliance's environment block? +* Where the gated vendor fields live long-term: flat on the Docker + template (simple, gated) vs nested `{"image_type": ..., "settings": + {...}}` (cleaner, more schema churn).