Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / src / builder / b-logproxy.c
Author[]agreen <Andy Green> 2026-05-25 13:03 UTC
Committer[]agreen <Andy Green> 2026-05-25 13:03 UTC
Tree6192744e1bef788080fb789bec3474b26b2381b4   Raw Patch
 
sai-virt: extras
sai-virt: extras
diff --git a/READMEs/README-sai-virt.md b/READMEs/README-sai-virt.md new file mode 100644 index 0000000..c01989b --- /dev/null +++ b/READMEs/README-sai-virt.md @@ -0,0 +1,130 @@ +# Sai Virtualization Daemon (`sai-virt`) + +`sai-virt` is a lightweight daemon that connects to `sai-server` as a power controller/agent. Instead of managing physical power outlets or static builders, it coordinates and spawns **ephemeral Virtual Machines (VMs)** on demand. + +When `sai-virt` detects a pending job queue for a platform it supports, it spawns a transient instance of a VM template corresponding to that platform. Once the VM finishes the build or stays idle, it is destroyed, resetting the environment to a pristine state. + +--- + +## 1. Installation & Service Setup + +To run `sai-virt` as a persistent background daemon managed by systemd: + +1. Build `sai-virt` by compiling the project (ensure `LWS_WITH_CLIENT`, `LWS_WITH_STRUCT_JSON`, and `LWS_WITH_SECURE_STREAMS` are enabled in `libwebsockets`). +2. Copy the systemd service template to the system directory: + ```bash + sudo cp scripts/sai-virt.service /etc/systemd/system/ + ``` +3. Enable and start the service: + ```bash + sudo systemctl daemon-reload + sudo systemctl enable --now sai-virt + ``` + +--- + +## 2. Configuration (`/etc/sai/virt/conf`) + +`sai-virt` reads its configuration from `/etc/sai/virt/conf` (or custom path passed via `-c`). The config is a JSON file matching the schema below: + +```json +{ + "perms": "sai:nobody", + "home": "/home/sai", + "hostname": "virt-host-1", + "max_vms": 4, + + "servers": [ + { + "url": "wss://libwebsockets.org:4444/sai/builder" + } + ], + + "platforms": [ + { + "name": "windows-x86_64" + }, + { + "name": "mac-m1" + }, + { + "name": "linux-fedora-x86_64" + } + ] +} +``` + +### Configuration Parameters +* **perms**: The `user:group` that the daemon drops privileges to after binding ports. +* **home**: The home directory for the daemon process. +* **hostname**: Hostname reported to the `sai-server` (masquerading as the power controller node). +* **max_vms**: The maximum number of concurrent VM instances allowed to run on this host. +* **servers**: Array of `sai-server` WebSocket endpoints to connect to. +* **platforms**: Array of platform strings representing the VM environments this host is capable of instantiating. + +--- + +## 3. VM Creation & Registration + +To make virtual machines available to `sai-virt`: + +1. **Create a VM Template**: Using tools like `virt-install` or `virt-manager`, install your guest OS and configure it to run `sai-builder` automatically on boot (configured to connect to the local UDS/TCP ports, or directly to `sai-server`). +2. **Platform Mapping**: The VM's name or metadata in libvirt must associate it with the corresponding platform defined in `/etc/sai/virt/conf`. +3. **Pristine State**: When `sai-virt` receives a command to spin up a builder for a platform, it looks for the defined template (e.g. `template-linux-fedora-x86_64`), clones/instantiates it, and boots it. + +--- + +## 4. Multi-Use Read-Only OS & Dynamic Overlays + +In a scalable build cluster, maintaining a separate copy of the OS disk image for every parallel VM consumes significant storage and creates maintenance overhead. Instead, we use a single **Read-Only (RO) OS Base Image** shared across multiple running instances, with a **Dynamic VM-specific copy-on-write (CoW) overlay** that stores writes and is discarded when the VM stops. + +There are two primary methods to implement this in QEMU/libvirt: + +### Method A: Libvirt Native `<transient/>` Disks (Recommended) + +Libvirt natively supports transient disks for domains. When `<transient/>` is placed under a disk's XML specification, libvirt intercepts disk writes by creating a temporary copy-on-write overlay file overlaying the base image when the domain starts. When the VM is shut down or destroyed, libvirt automatically deletes the temporary overlay. + +#### QEMU XML Configuration: +```xml +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2' discard='unmap'/> + <!-- Point source to the shared read-only base OS image --> + <source file='/var/lib/libvirt/images/fedora-base.qcow2'/> + <target dev='vda' bus='virtio'/> + <!-- Instruct libvirt to treat this disk as ephemeral/transient --> + <transient/> +</disk> +``` + +#### How it works: +* Libvirt boots the VM using `/var/lib/libvirt/images/fedora-base.qcow2` as the backing store. +* An overlay file (e.g., `/var/lib/libvirt/images/fedora-base.qcow2.TRANSIENT`) is created on startup. +* Multiple VM instances can run concurrently using the same base file because the base image is opened in read-only mode by QEMU. +* Discard and deletion of the transient overlay are handled natively by libvirt upon domain destruction. + +--- + +### Method B: Manual `qemu-img` Backing Chains + +If your libvirt version or storage driver does not support the `<transient/>` tag natively, you can arrange for the overlay manually. + +#### 1. Create a VM-specific overlay file prior to booting: +Before starting a VM instance, run `qemu-img` to create a new QCOW2 overlay image using the read-only OS layer as the backing file: +```bash +qemu-img create -f qcow2 -F qcow2 -b /var/lib/libvirt/images/fedora-base.qcow2 /var/lib/libvirt/images/sai-vm-fedora-instance1.qcow2 +``` + +#### 2. QEMU XML Configuration: +In the domain XML for the ephemeral VM instance, define the disk source to point to the newly created overlay file: +```xml +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2' discard='unmap'/> + <!-- Point source to the instance-specific overlay --> + <source file='/var/lib/libvirt/images/sai-vm-fedora-instance1.qcow2'/> + <target dev='vda' bus='virtio'/> +</disk> +``` + +#### 3. Orchestration in `sai-virt`: +* On **Spawn**: `sai-virt` generates a temporary XML file, runs `qemu-img create` to generate the unique overlay, updates the `<source>` tag in the XML, and runs `virsh create <temp-xml>`. +* On **Destroy**: `sai-virt` runs `virsh destroy <vm-name>` and then deletes the instance-specific overlay file from `/var/lib/libvirt/images/`. diff --git a/etc-sai-EXAMPLE/virt/conf b/etc-sai-EXAMPLE/virt/conf new file mode 100644 index 0000000..7fe0033 --- /dev/null +++ b/etc-sai-EXAMPLE/virt/conf @@ -0,0 +1,24 @@ +{ + "perms": "sai:nobody", + "home": "/home/sai", + "hostname": "virt-host-1", + "max_vms": 4, + + "servers": [ + { + "url": "wss://libwebsockets.org:4444/sai/builder" + } + ], + + "platforms": [ + { + "name": "windows-x86_64" + }, + { + "name": "mac-m1" + }, + { + "name": "linux-fedora-x86_64" + } + ] +} diff --git a/scripts/sai-virt.service b/scripts/sai-virt.service new file mode 100644 index 0000000..cd70aff --- /dev/null +++ b/scripts/sai-virt.service @@ -0,0 +1,9 @@ +[Unit] +Description=Sai Virtualization Daemon +After=network-online.target ntp.service + +[Service] +ExecStart=/usr/local/bin/sai-virt + +[Install] +WantedBy=multi-user.target
Page fetched 0s ago, creation time: 2ms (vhost etag hits: 0%, cache hits: 0%)