From f5310ff2ccca657b1a7eae3c0c14a7ac677ef898 Mon Sep 17 00:00:00 2001 From: Artem Konev Date: Tue, 9 Sep 2025 13:06:37 +0100 Subject: [PATCH] Doc: Added 'Components', 'Runtime' arch sections Co-authored-by: Dmitry Lyfar <69887876+dmitry-lyfar@users.noreply.github.com> --- docs/.custom_wordlist.txt | 1 + docs/explanation/architecture/components.rst | 413 ++++++++++++++++++ docs/explanation/architecture/index.rst | 7 +- .../explanation/architecture/installation.rst | 332 -------------- .../architecture/runtime-behavior.rst | 170 +++++++ docs/explanation/index.rst | 3 +- docs/explanation/workshops/concepts.rst | 6 +- 7 files changed, 593 insertions(+), 339 deletions(-) create mode 100644 docs/explanation/architecture/components.rst delete mode 100644 docs/explanation/architecture/installation.rst create mode 100644 docs/explanation/architecture/runtime-behavior.rst diff --git a/docs/.custom_wordlist.txt b/docs/.custom_wordlist.txt index ec1dc440d..b1f5ecf80 100644 --- a/docs/.custom_wordlist.txt +++ b/docs/.custom_wordlist.txt @@ -152,6 +152,7 @@ unmounts unparam url uv +validator wayland Wayland WAYLAND diff --git a/docs/explanation/architecture/components.rst b/docs/explanation/architecture/components.rst new file mode 100644 index 000000000..127188dd5 --- /dev/null +++ b/docs/explanation/architecture/components.rst @@ -0,0 +1,413 @@ +.. _exp_arch_system_components: + +.. meta:: + :description: Explanation article on the system architecture and components of + Workshop, detailing installation, the workshopd daemon, LXD backend, + state management, interface policy, systemd integration, and data + architecture with workshop launch processes. + +System components +================= + +|ws_markup| is designed to run on Linux systems +and is primarily distributed as a `snap `_. +It relies on LXD as its containerization backend +and ZFS for efficient storage management. + +|ws_markup|'s distributed architecture +organizes functionality across specialized subsystems, +with each handling specific aspects of workshop lifecycle management +while maintaining clear separation of concerns +and well-defined communication interfaces. + +The core subsystems include +the :ref:`workshopd daemon ` for orchestration, +the :ref:`LXD backend ` for container management, +the :ref:`state database ` for transactional jobs, +the :ref:`interface system ` for resource sharing, +and :program:`systemd` integration for service lifecycle management. +Storage is handled through the :ref:`ZFS storage component ` +with metadata persistence via the :ref:`state database `. + +.. note:: + + For a description of how these components interact at runtime, + see :ref:`exp_arch_runtime_behavior`. + + +Main components +--------------- + +.. @artefact workshop (CLI) +.. @artefact workshopd +.. @artefact workshopctl + +|ws_markup| installation on your host system includes three primary components: + +- The :program:`workshop` :ref:`CLI ` + serves as the main user interface, + providing a thin client that translates user commands + and communicates with :program:`workshopd` through a Unix domain socket. + +- The :program:`workshopd` :ref:`daemon ` runs in the background + with elevated privileges. + It manages the full workshop lifecycle + including container creation, + SDK installation, + interface coordination, + and state persistence through a REST API. + +- The :program:`workshopctl` :ref:`tool ` runs inside a workshop + and has access to a very limited subset of :program:`workshopd`'s REST API + for service-related and reporting tasks. + + +The communication architecture between these components uses a layered approach +where the CLI communicates with :program:`workshopd` via Unix domain sockets, +while :program:`workshopd` interfaces with LXD through the latter's native API. + + +.. _exp_arch_cli: + +CLI: :program:`workshop` +------------------------ + +.. @artefact workshop (CLI) + +The :program:`workshop` CLI provides a comprehensive command-line interface +for managing workshops and interacting with :program:`workshopd`. +It is organized into logical command groups +for different aspects of |ws_markup|'s operations: + +- Create, update, and delete operations +- Start and stop control +- Exploration and troubleshooting +- Interface connection management +- Workshop utilization +- SDK sketching +- Miscellaneous utilities + + +For all operations, the CLI communicates with :program:`workshopd` through a REST API +exposed over Unix domain sockets, +using a client library that handles connection management, +error handling, and request-response serialization. +The client supports both synchronous and asynchronous operations. + +For further details, +see :ref:`exp_workshop_cli`. + + +.. _exp_arch_workshopctl: + +Control interface: :program:`workshopctl` +----------------------------------------- + +.. @artefact workshopctl + +The :program:`workshopctl` tool serves as a secure bridge +between workshop containers and the host system, +sending control and status messages from inside the workshop back to the host. + +The tool is typically invoked by SDK hooks; +it operates with the workshop user's permissions (UID 1000) +and communicates with :program:`workshopd`'s :ref:`REST API ` +through a dedicated Unix domain socket inside the workshop +at :file:`/var/lib/workshop/run/workshop.socket.untrusted`. + +The tool's capabilities are intentionally limited +to minimize security risks. + + +.. _exp_arch_daemon: + +Daemon: :program:`workshopd` +---------------------------- + +The :program:`workshopd` daemon serves as the central orchestration hub, +coordinating all workshop operations and maintaining system state. + +The daemon exposes the primary REST API for CLI and external integrations +while orchestrating :ref:`workshop ` lifecycle +through transactional state management. +It coordinates :ref:`interface connections ` +and policy validation. + +Key components within the daemon include: + +- the REST API server for handling HTTP requests, + +- the state engine as central coordinator, + + +- the task runner for running tasks according to their dependencies, + +- and specialized state managers for workshops, :ref:`SDKs `, + :ref:`interfaces `, commands, and hooks. + + +During startup, the daemon initializes state managers, +establishes an LXD connection, +and starts the API server. +It supports graceful shutdown with task completion and state persistence. +Failure modes are handled through degraded mode operation for LXD unavailability +and error detection for connection issues. +The daemon provides :program:`systemd` notification support +and structured logging for telemetry. + +Authentication occurs via Unix domain socket credentials. +Privilege separation exists between trusted and untrusted API endpoints. + + +.. _exp_arch_api: + +REST API +~~~~~~~~ + +.. @artefact API + +The :program:`workshopd` daemon exposes a versioned REST API (v1) +over Unix domain sockets for secure local communication with the CLI. +The API provides endpoints for all workshop operations. + +Trusted endpoints (require Unix socket credentials): + +- Workshop lifecycle operations (:samp:`/v1/projects//workshops`) +- SDK management (:samp:`/v1/sdks`) +- Interface connection management (:samp:`/v1/connections`) +- Change tracking and monitoring (:samp:`/v1/changes`) +- Warning and error reporting (:samp:`/v1/warnings`) + + +Untrusted endpoints (accessible from within workshops): + +- Workshop control interface (:samp:`/v1/workshopctl`) + + +The API implements proper access control +and supports both synchronous and asynchronous operations. + +For data exchange, the API uses JSON with well-defined types +for workshop information, SDK details, and interface connections. + + +.. _exp_arch_lxd_backend: + +LXD backend +~~~~~~~~~~~ + +.. @artefact workshopd + +The :program:`workshopd` daemon maintains a persistent connection to LXD +through its Unix domain socket at :file:`/var/snap/lxd/common/lxd/unix.socket`, +managing container operations. + +The LXD communication layer handles projects and container lifecycle, +storage management, network configuration, +and device pass-through. + +Its responsibilities also include base image management and caching, +providing snapshot and restore capabilities for efficient workshop updates. + +.. note:: + + The term 'project' in relation to |ws_markup| + can be used in two unrelated senses: + + - LXD projects, identified by their names + (e.g., :samp:`workshop.john`). + These are created at :program:`workshopd`'s request + to provide isolation in LXD. + + - Workshop projects, identified by |ws_markup|-assigned IDs. + These are user-defined directories (e.g., :samp:`my-workshop`) + used to organize and manage workshops (e.g., :samp:`my-workshop`). + They are referenced in CLI commands and API endpoints. + + +|ws_markup| implements user isolation through LXD's project system, +automatically creating dedicated projects for each user +following the naming pattern :samp:`workshop.`. +Each user project includes a corresponding layers project +(:samp:`workshop-layers.`) +used for temporary storage during workshop rebuild operations. + + +.. _exp_arch_zfs_storage: + +ZFS storage +~~~~~~~~~~~ + +|ws_markup| uses ZFS for its storage needs, managed via LXD; +it requires a minimum pool size of 5 GiB. + +The ZFS pool manages container root filesystems, workshop-specific data volumes, +cached base images, and snapshots for efficient workshop updates and rollbacks. +This component provides copy-on-write storage utilization, LZ4 compression, +and quota management, +and is utilized by the :ref:`LXD backend ` for container operations. + + + + + +.. _exp_arch_state_database: + +State database +~~~~~~~~~~~~~~ + +The :file:`state.json` file is the authoritative database +for workshop metadata, configuration, and operational state. +It enables transactional operations with atomic updates and rollback capabilities. + +It uses a model of "changes" (high-level modification to the system state) +and "tasks" (operations with Do/Undo handlers that constitute a change) +to ensure that requests either complete fully or are rolled back. + + +.. _exp_arch_images: + +Images +~~~~~~ + +|ws_markup| containers are created from base operating system images. +By default, |ws_markup| fetches base images, +such as Ubuntu 20.04, Ubuntu 22.04, or Ubuntu 24.04, +from the official +`Ubuntu cloud image repository `_. + + + +.. _exp_arch_interface_system: + +Interfaces +~~~~~~~~~~ + +This system handles interface connections, enforces security policies, +and also manages the lifecycle of resource connections. + +First of all, the interface system validates connections between plugs and slots. +Built-in interface declarations enforcement handles auto- and manual connections. + +.. note:: + + See + `mount.go + `_ + in |ws_markup| source code for an elaborate example. + + +Key components include the interface repository +serving as a registry of available interface types, +policy validator for enforcing connection rules and security constraints, +connection manager handling connection establishment and teardown, +and security backends responsible for creating LXD profiles of established interface connections. + +For further details, +see :ref:`exp_interface_concepts`. + + +Network +~~~~~~~ + +|ws_markup| establishes a dedicated network infrastructure +through the :samp:`workshopbr0` bridge network, +providing isolated networking for workshop containers. + +This bridge network includes DNS resolution +configured with the :samp:`workshop` domain. + + +Diagrams +-------- + +The system components and their interactions: + +.. mermaid:: + :alt: System diagram showing the main architectural components in Workshop. + The CLI component communicates with the workshopd daemon, + which orchestrates state management, interface resolution, + and LXD backend operations. + The systemd integration provides service lifecycle management, + while ZFS storage handles persistent data and snapshots. + :align: center + :config: {"theme":"neutral"} + + graph TB + subgraph HOST ["Host system"] + subgraph CLI_SUBSYSTEM ["CLI"] + cli[Workshop CLI] + client[HTTP client library] + end + + subgraph LXD ["LXD"] + lxd_daemon[LXD daemon] + containers[(Workshop containers)] + end + + subgraph DAEMON_SUBSYSTEM ["workshopd"] + api[REST API server] + daemon[Daemon] + state_mgrs[State managers] + task_runner[Task runner] + hook_manager[Hook manager] + workshop_manager[Workshop manager] + sdk_manager[SDK manager] + end + + subgraph BACKEND_SUBSYSTEM ["LXD backend"] + lxd_backend[LXD backend] + end + + subgraph STATE_SUBSYSTEM ["State management"] + state_db[(state.json)] + checkpointer[Checkpoint handler] + end + + subgraph INTERFACE_SUBSYSTEM ["Interface management"] + repo[Interface repository] + connector[Connection manager] + end + + subgraph STORAGE_SUBSYSTEM ["ZFS storage"] + zfs_pool[(ZFS pool)] + snapshot_mgr[Snapshot manager] + volume_mgr[Volume manager] + end + + subgraph SYSTEMD_SUBSYSTEM ["systemd integration"] + service_unit[workshopd.service] + socket_activation[Socket activation] + watchdog[Watchdog] + end + end + + subgraph EXT_IMG [Image server] + img_server[("cloud-images.ubuntu.com")] + end + + api --> daemon + cli --> api + client --> api + connector --> lxd_backend + connector --> repo + daemon --> state_mgrs + hook_manager --> lxd_backend + lxd_backend --> lxd_daemon + lxd_backend <--> img_server + lxd_daemon --> containers + lxd_daemon --> zfs_pool + sdk_manager --> lxd_backend + service_unit --> api + socket_activation --> api + state_mgrs --> checkpointer + state_mgrs --> connector + state_mgrs --> hook_manager + state_mgrs --> sdk_manager + state_mgrs --> state_db + state_mgrs --> task_runner + state_mgrs --> workshop_manager + watchdog --> daemon + workshop_manager --> lxd_backend + zfs_pool --> snapshot_mgr + zfs_pool --> volume_mgr diff --git a/docs/explanation/architecture/index.rst b/docs/explanation/architecture/index.rst index 450d860e1..c17eaaf29 100644 --- a/docs/explanation/architecture/index.rst +++ b/docs/explanation/architecture/index.rst @@ -3,12 +3,13 @@ Architecture ============ -This section outlines the installation process for |ws_markup| -and provides a thorough overview of its core architecture. +This section provides a thorough overview of |ws_markup|'s core architecture +and runtime behavior. Understanding these fundamentals is key to effectively using and managing |ws_markup| environments. .. toctree:: :maxdepth: 1 - installation + components + runtime-behavior diff --git a/docs/explanation/architecture/installation.rst b/docs/explanation/architecture/installation.rst deleted file mode 100644 index 98330a4fe..000000000 --- a/docs/explanation/architecture/installation.rst +++ /dev/null @@ -1,332 +0,0 @@ -.. _exp_arch_install: - -.. meta:: - :description: Explanation article on installing and understanding the - architecture of Workshop, including its CLI, daemon, and - containerized components, with details on LXD, ZFS, networking, - and system isolation. - -Initial installation -==================== - -.. @artefact installation - -|ws_markup| is designed to run on Linux systems. -It is primarily distributed as a `snap `_ -and relies on LXD as its containerization backend -and ZFS for efficient storage management. - - -Main components ---------------- - -.. @artefact workshop (CLI) -.. @artefact workshopd -.. @artefact workshopctl - -|ws_markup| installation on your host system includes three primary components: - -- The :program:`workshop` CLI serves as the main user interface, - providing a thin client that translates user commands - and communicates with :program:`workshopd` through a Unix domain socket. - -- The :program:`workshopd` daemon runs as a background process - with elevated privileges, - managing the complete workshop lifecycle - including container creation, - SDK installation, - interface coordination - and state persistence through a REST API. - -- The :program:`workshopctl` tool runs inside a workshop - and has access to a very limited subset of :program:`workshopd`'s REST API - for service-related and reporting tasks. - - -The communication architecture between these components uses a layered approach -where the CLI communicates with :program:`workshopd` via Unix domain sockets, -while :program:`workshopd` interfaces with LXD through the latter's native API. - - -CLI -~~~ - -.. @artefact workshop (CLI) - -The :program:`workshop` CLI provides a comprehensive command-line interface -for managing workshops and interacting with :program:`workshopd`. -It is organized into logical command groups -for different aspects of |ws_markup|'s operations: - -- Create, update, and delete operations -- Start and stop control -- Exploration and troubleshooting -- Interface connection management -- Workshop utilization -- SDK sketching -- Miscellaneous utilities - - -For all operations, the CLI communicates with :program:`workshopd` through a REST API -exposed over Unix domain sockets, -using a client library that handles connection management, -error handling, and request-response serialization. -The client supports both synchronous and asynchronous operations, -with proper error reporting and progress tracking. - - -.. _exp_arch_install_daemon: - -Daemon -~~~~~~ - -.. @artefact workshopd - -The :program:`workshopd` daemon, a core component of |ws_markup|, -is a :program:`systemd` service responsible for the complete workshop lifecycle. -It uses LXD as its container backend -and relies on the proven state package from :program:`snapd` -to ensure that any changes to a workshop are handled in a transactional manner: -safely, consistently, and reversibly. - -When integrated with :program:`systemd`, -:program:`workshopd` implements the watchdog notification mechanism -for health monitoring -and supports socket activation to reduce memory footprint. - - -REST API -^^^^^^^^ - -.. @artefact API - -The :program:`workshopd` daemon exposes a versioned REST API (v1) over Unix domain sockets -for secure local communication with the CLI. -The API provides endpoints for all workshop operations: - -- Project management (:samp:`/v1/projects`) -- Workshop lifecycle operations (:samp:`/v1/projects//workshops`) -- Workshop execution and control (:samp:`/v1/projects//workshops//exec`) -- Interface connection management (:samp:`/v1/connections`) -- Change tracking and monitoring (:samp:`/v1/changes`) -- Warning and error reporting (:samp:`/v1/warnings`) -- Workshop control interface (:samp:`/v1/workshopctl`) - - -The API implements proper access control -and supports both synchronous and asynchronous operations. -Long-running operations return change IDs that can be used -to track progress and wait for completion. - -The API uses JSON for data exchange, with well-defined types -for workshop information, SDK details, and interface connections. -It implements proper validation of input data -and returns structured error responses -with appropriate HTTP status codes. - - -LXD communication -^^^^^^^^^^^^^^^^^ - -.. @artefact workshopd - -The :program:`workshopd` daemon maintains a persistent connection to LXD -through its Unix domain socket at :file:`/var/snap/lxd/common/lxd/unix.socket`, -managing container operations and user isolation. - -For each user, :program:`workshopd` creates dedicated LXD projects -(:samp:`workshop.` and :samp:`workshop-layers.`) -that provide complete isolation between users -on the same system. - -The LXD communication layer handles container lifecycle, -storage management, network configuration, -and device pass-through, with proper error handling -for common issues like :program:`workshopd` availability -and resource constraints. - -.. note:: - - The term 'project' in relation to |ws_markup| - can be used in two unrelated senses: - - - LXD projects, identified by their names - (e.g., :samp:`workshop.john`). - These are created at :program:`workshopd`'s request - to provide isolation in LXD. - The names are prefixed with :samp:`workshop.` or :samp:`workshop-layers.` - followed by the username. - - - Workshop projects, identified by |ws_markup|-assigned IDs. - These are user-defined directories (e.g., :samp:`my-workshop`) - used to organize and manage workshops. - They are referenced in CLI commands and API endpoints. - - -Control interface -~~~~~~~~~~~~~~~~~ - -.. @artefact workshopctl - -The :program:`workshopctl` tool serves as a secure bridge -between workshop containers and the host system. -It operates with the workshop user's permissions (UID 1000) -and communicates with :program:`workshopd` -through a dedicated Unix domain socket -at :file:`/var/lib/workshop/run/workshop.socket.untrusted`. - - - -Management and isolation ------------------------- - -.. @artefact workshopd - -The :program:`workshopd` daemon manages the complete workshop lifecycle, -including storage pool management, -image management, -network isolation, -and project isolation. - -.. _exp_arch_install_storage: - -Storage pool -~~~~~~~~~~~~ - -|ws_markup| leverages ZFS for its storage needs, managed via LXD. - -Workshop requires a minimum pool size of 5 GiB. - -The ZFS pool serves multiple purposes beyond simple container storage, -managing container root filesystems, -volumes for SDKs and SDK data persistence, -snapshots and clones for quick workshop updates and rollbacks, -and cached container images. - - -.. _exp_arch_install_images: - -Images -~~~~~~ - -|ws_markup| containers are created from base operating system images. -By default, |ws_markup| fetches base images, -such as Ubuntu 20.04, Ubuntu 22.04, or Ubuntu 24.04, -from the official -`Ubuntu cloud image repository `_, -using the -`simplestreams `_ -protocol. - -|ws_markup| uses specific aliases for these images within LXD, -typically in the format :samp:`workshop-ubuntu@-` -(e.g., :samp:`workshop-ubuntu@24.04-amd64`). -LXD caches these images locally after the first download. - - -Network -~~~~~~~ - -|ws_markup| establishes a dedicated network infrastructure -through the :samp:`workshopbr0` bridge network, -providing isolated networking for workshop containers. - -This bridge network includes DNS resolution -configured with the :samp:`workshop` domain. - - - -LXD projects -~~~~~~~~~~~~ - -|ws_markup| implements user isolation through LXD's project system, -automatically creating dedicated projects for each user -following the naming pattern :samp:`workshop.`. -Each user project includes a corresponding project -(:samp:`workshop-layers.`) -used to cache workshops for faster refreshes -and temporarily back up old workshops during rebuild operations. - -Note that this LXD project name is different from the workshop project ID: -the LXD project name (:samp:`workshop.`) provides user-level isolation, -while each workshop project gets its own unique ID for tracking and management. - - -The workshop launch includes setting up appropriate ID mapping, -ensuring that files created within workshops -maintain correct ownership when accessed from the host system. -This is achieved through LXD's ID mapping feature, -which maps the host user's UID and GID to the workshop user's IDs (1000:1000) -inside the container. - - -Diagrams --------- - -Core installation components: - -.. mermaid:: - :alt: Diagram showing the user interacting with Workshop CLI on the host. - The CLI communicates with the 'workshopd' daemon, also on the host. - The daemon interacts with the LXD daemon on the host. - LXD manages a ZFS storage pool ('workshop') - and pulls base images from an external image server. - The dependency is shown on the host. - This does not show 'workshopctl' for simplicity. - :align: center - :config: {"theme":"neutral"} - - flowchart LR - user([User]) - - subgraph HOST [Host system] - direction TB - cli([CLI]) - daemon(["workshopd"]) - lxd([LXD daemon]) - - cli <--> daemon - daemon <--> lxd - - subgraph ZFS_Store [ZFS storage] - zfs_pool[("ZFS pool
(workshop)")] - end - end - - - - subgraph EXT_IMG [Image server] - img_server[("cloud-images.ubuntu.com")] - end - - user <--> cli - lxd <--> zfs_pool - lxd <--> img_server - - -Data flow between components: - -.. mermaid:: - :alt: Diagram showing the data flow between Workshop components. - The user interacts with the CLI, which communicates with :program:`workshopd`. - workshopd manages LXD operations and handles workshop lifecycle. - LXD manages containers and storage, while the CLI provides user feedback. - This does not show 'workshopctl' interactions for simplicity. - :align: center - :config: {"theme":"neutral"} - - sequenceDiagram - participant User - participant CLI as Workshop CLI - participant Daemon as workshopd - participant LXD - participant Storage as ZFS storage - - User->>CLI: Command - CLI->>Daemon: REST API request - Daemon->>LXD: Container operation - LXD->>Storage: Storage operation - Storage-->>LXD: Operation result - LXD-->>Daemon: Operation status - Daemon-->>CLI: API response - CLI-->>User: Command result diff --git a/docs/explanation/architecture/runtime-behavior.rst b/docs/explanation/architecture/runtime-behavior.rst new file mode 100644 index 000000000..c554dbc21 --- /dev/null +++ b/docs/explanation/architecture/runtime-behavior.rst @@ -0,0 +1,170 @@ + +.. _exp_arch_runtime_behavior: + +.. meta:: + :description: Explanation article on the runtime behavior of Workshop, + detailing the workshop launch process, data architecture, + ZFS storage, and state database management. + +Runtime behavior +================ + +This section demonstrates how the system components of |ws_markup| +work together to transform a workshop definition into a running container. +It focuses on the dynamic processes and workflows +that occur during workshop operations. + +.. note:: + + For a general description of these components, + see :ref:`exp_arch_system_components`. + + +.. _exp_arch_workshop_launch: + +Workshop launch process +----------------------- + +The workshop launch process coordinates the +:ref:`workshopd daemon `, +:ref:`LXD backend `, +:ref:`state management `, +:ref:`interface policy `, +and :ref:`ZFS storage ` subsystems, +all detailed in the previous section. + +The launch sequence begins with workshop YAML validation and normalization. +The LXD container is then created from a base image. +The :ref:`system SDK ` is installed first to provide +the core integration layer with host system resources. + +Regular SDKs are installed sequentially. +SDK-specific :ref:`setup hooks ` are executed during this phase. +Workshop creates a lightweight ZFS clone after each SDK installation to enable efficient updates and rollbacks. +Interface validation performs compatibility checking and policy enforcement. +Connection establishment handles device attachment and resource binding. +The container is then started and health checks are performed to complete the launch. + +- Launch operations create new workshops from scratch + by creating new LXD containers and projects as needed, + downloading and caching base images as required, + installing all SDKs with complete hook execution, + and establishing all interface connections. + +- Refresh operations update existing workshops + by preserving LXD container identity and networking, + restoring to base snapshot before applying changes, + skipping unchanged SDKs using snapshot comparison, + running save-state and restore-state hooks for SDK data persistence, + and updating only modified interface connections. + +Workshop status transitions follow a predictable lifecycle: + +- *Off* → *Pending*: + Workshop creation is initiated by user request + +- *Pending* → *Waiting*: + Launch encounters errors requiring manual intervention + +- *Pending* → *Stopped*: + Launch succeeds but the container remains stopped + +- *Stopped* → *Ready*: + Container starts successfully and becomes available for use + + +These changes are tracked in the state management system +and can be monitored through the API. + +.. note:: + + For a complete reference guide on status transitions, + see :ref:`ref_workshop_status`. + + +.. _exp_arch_container_layout: + +Container layout +---------------- + +Container runtime setup builds on the +:ref:`LXD backend ` foundation +with runtime-specific configuration applied during workshop launch. + +Key directories inside the container include: + +- The root file system as a ZFS dataset. + +- The :file:`/project/` mount + to provide transparent access to project files on the host. + +- The :file:`/var/lib/workshop/` directory + where workshop state volume and SDK volumes are mounted. + + +The :ref:`interface system ` provisions +different resources within containers: + +- Mount interfaces appear as regular directories. +- Proxy devices handle port forwarding and services such as the SSH agent. +- GPU, audio, and camera devices are passed through to the workshop + with proper permissions and access controls. + + +Diagrams +-------- + +Workshop launch flow: + +.. mermaid:: + :alt: Sequence diagram showing the workshop launch flow from CLI command + through daemon processing, LXD container creation, SDK installation, + and interface connection establishment. + :align: center + :config: {"theme":"neutral"} + + sequenceDiagram + participant CLI + participant API as workshopd API + participant Daemon + participant TaskRunner as Task runner + participant LXD as LXD backend + participant ZFS as ZFS storage + participant Interfaces as Interface system + + CLI->>API: POST /v1/projects/{id}/workshops (workshop.yaml) + API->>Daemon: Create launch change + Daemon->>TaskRunner: Queue launch tasks + + TaskRunner->>LXD: Create workshop container + LXD->>ZFS: Create root filesystem + ZFS-->>LXD: Filesystem ready + LXD-->>TaskRunner: Container created + + TaskRunner->>LXD: Install system SDK + LXD->>ZFS: Take base snapshot + ZFS-->>LXD: Snapshot created + LXD-->>TaskRunner: System SDK installed + + loop For each SDK in definition + TaskRunner->>LXD: Install SDK + LXD->>LXD: Run setup-base hook + LXD->>ZFS: Take SDK snapshot + ZFS-->>LXD: Snapshot created + LXD-->>TaskRunner: SDK installed + end + + TaskRunner->>Interfaces: Validate connections + Interfaces->>Interfaces: Check plug/slot compatibility + Interfaces-->>TaskRunner: Validation complete + + TaskRunner->>LXD: Establish interface connections + LXD->>LXD: Configure container devices + LXD-->>TaskRunner: Connections established + + TaskRunner->>LXD: Start workshop container + LXD-->>TaskRunner: Container started + + TaskRunner-->>Daemon: Launch complete + Daemon-->>API: Change finished + API-->>CLI: HTTP 200 (workshop ready) diff --git a/docs/explanation/index.rst b/docs/explanation/index.rst index 50ec7e4b6..84a8e61aa 100644 --- a/docs/explanation/index.rst +++ b/docs/explanation/index.rst @@ -27,7 +27,8 @@ and how they work together to provide isolated development environments. architecture/index -- :doc:`architecture/installation` +- :doc:`architecture/components` +- :doc:`architecture/runtime-behavior` Workshops and projects diff --git a/docs/explanation/workshops/concepts.rst b/docs/explanation/workshops/concepts.rst index c68ef2c06..07c895dbe 100644 --- a/docs/explanation/workshops/concepts.rst +++ b/docs/explanation/workshops/concepts.rst @@ -123,7 +123,7 @@ This is the first layer of the workshop, upon which all other components are applied. For details on how the images are handled behind the scenes, -see :ref:`exp_arch_install_images`. +see :ref:`exp_arch_images`. .. _exp_workshop_definition_sdks: @@ -170,7 +170,7 @@ the workshop reverts to its previous state. The cloned file systems are used to restore the deleted snapshots. For details on how |ws_markup| leverages ZFS, -see :ref:`exp_arch_install_storage`. +see :ref:`exp_arch_zfs_storage`. .. _exp_workshop_definition_connections: @@ -273,7 +273,7 @@ right in the definition file. Actions are not part of the layered snapshot system at all. They stay in the definition, -and are parsed by the :ref:`daemon ` +and are parsed by the :ref:`daemon ` every time the :command:`workshop run` command is executed. This means the users can add or modify actions and use them immediately, without needing to refresh or restart the workshop.