Complete infrastructure platform CLI: - Container runtime (systemd-nspawn) - VoltVisor VMs (Neutron Stardust / QEMU) - Stellarium CAS (content-addressed storage) - ORAS Registry - GitOps integration - Landlock LSM security - Compose orchestration - Mesh networking Copyright (c) Armored Gates LLC. All rights reserved. Licensed under AGPSL v5.0
278 lines
10 KiB
Go
278 lines
10 KiB
Go
/*
|
|
Manifest v2 — Workload manifest format for the Volt hybrid platform.
|
|
|
|
Defines the data structures and TOML parser for Volt workload manifests.
|
|
A manifest describes everything needed to launch a workload: the execution
|
|
mode (container, hybrid-native, hybrid-kvm, hybrid-emulated), kernel config,
|
|
security policy, resource limits, networking, and storage layout.
|
|
|
|
The canonical serialization format is TOML. JSON round-tripping is supported
|
|
via struct tags for API use.
|
|
|
|
Copyright (c) Armored Gates LLC. All rights reserved.
|
|
*/
|
|
package manifest
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
// ── Execution Modes ──────────────────────────────────────────────────────────
|
|
|
|
// Mode selects the workload execution strategy.
|
|
type Mode string
|
|
|
|
const (
|
|
// ModeContainer runs a standard systemd-nspawn container with no custom
|
|
// kernel. Fastest to start, smallest footprint.
|
|
ModeContainer Mode = "container"
|
|
|
|
// ModeHybridNative runs a systemd-nspawn container in boot mode with the
|
|
// host kernel. Full namespace isolation with shared kernel. This is the
|
|
// primary Volt mode.
|
|
ModeHybridNative Mode = "hybrid-native"
|
|
|
|
// ModeHybridKVM runs the workload inside a lightweight KVM guest using a
|
|
// custom kernel. Strongest isolation boundary.
|
|
ModeHybridKVM Mode = "hybrid-kvm"
|
|
|
|
// ModeHybridEmulated runs the workload under user-mode emulation (e.g.
|
|
// proot or QEMU user-mode) for cross-architecture support.
|
|
ModeHybridEmulated Mode = "hybrid-emulated"
|
|
)
|
|
|
|
// ValidModes is the set of recognized execution modes.
|
|
var ValidModes = map[Mode]bool{
|
|
ModeContainer: true,
|
|
ModeHybridNative: true,
|
|
ModeHybridKVM: true,
|
|
ModeHybridEmulated: true,
|
|
}
|
|
|
|
// ── Landlock Profile Names ───────────────────────────────────────────────────
|
|
|
|
// LandlockProfile selects a pre-built Landlock policy or a custom path.
|
|
type LandlockProfile string
|
|
|
|
const (
|
|
LandlockStrict LandlockProfile = "strict"
|
|
LandlockDefault LandlockProfile = "default"
|
|
LandlockPermissive LandlockProfile = "permissive"
|
|
LandlockCustom LandlockProfile = "custom"
|
|
)
|
|
|
|
// ValidLandlockProfiles is the set of recognized Landlock profile names.
|
|
var ValidLandlockProfiles = map[LandlockProfile]bool{
|
|
LandlockStrict: true,
|
|
LandlockDefault: true,
|
|
LandlockPermissive: true,
|
|
LandlockCustom: true,
|
|
}
|
|
|
|
// ── Network Mode Names ───────────────────────────────────────────────────────
|
|
|
|
// NetworkMode selects the container network topology.
|
|
type NetworkMode string
|
|
|
|
const (
|
|
NetworkBridge NetworkMode = "bridge"
|
|
NetworkHost NetworkMode = "host"
|
|
NetworkNone NetworkMode = "none"
|
|
NetworkCustom NetworkMode = "custom"
|
|
)
|
|
|
|
// ValidNetworkModes is the set of recognized network modes.
|
|
var ValidNetworkModes = map[NetworkMode]bool{
|
|
NetworkBridge: true,
|
|
NetworkHost: true,
|
|
NetworkNone: true,
|
|
NetworkCustom: true,
|
|
}
|
|
|
|
// ── Writable Layer Mode ──────────────────────────────────────────────────────
|
|
|
|
// WritableLayerMode selects how the writable layer on top of the CAS rootfs
|
|
// is implemented.
|
|
type WritableLayerMode string
|
|
|
|
const (
|
|
WritableOverlay WritableLayerMode = "overlay"
|
|
WritableTmpfs WritableLayerMode = "tmpfs"
|
|
WritableNone WritableLayerMode = "none"
|
|
)
|
|
|
|
// ValidWritableLayerModes is the set of recognized writable layer modes.
|
|
var ValidWritableLayerModes = map[WritableLayerMode]bool{
|
|
WritableOverlay: true,
|
|
WritableTmpfs: true,
|
|
WritableNone: true,
|
|
}
|
|
|
|
// ── Manifest v2 ──────────────────────────────────────────────────────────────
|
|
|
|
// Manifest is the top-level workload manifest. Every field maps to a TOML
|
|
// section or key. The zero value is not valid — at minimum [workload].name
|
|
// and [workload].mode must be set.
|
|
type Manifest struct {
|
|
Workload WorkloadSection `toml:"workload" json:"workload"`
|
|
Kernel KernelSection `toml:"kernel" json:"kernel"`
|
|
Security SecuritySection `toml:"security" json:"security"`
|
|
Resources ResourceSection `toml:"resources" json:"resources"`
|
|
Network NetworkSection `toml:"network" json:"network"`
|
|
Storage StorageSection `toml:"storage" json:"storage"`
|
|
|
|
// Extends allows inheriting from a base manifest. The value is a path
|
|
// (relative to the current manifest) or a CAS reference.
|
|
Extends string `toml:"extends,omitempty" json:"extends,omitempty"`
|
|
|
|
// SourcePath records where this manifest was loaded from (not serialized
|
|
// to TOML). Empty for manifests built programmatically.
|
|
SourcePath string `toml:"-" json:"-"`
|
|
}
|
|
|
|
// WorkloadSection identifies the workload and its execution mode.
|
|
type WorkloadSection struct {
|
|
Name string `toml:"name" json:"name"`
|
|
Mode Mode `toml:"mode" json:"mode"`
|
|
Image string `toml:"image,omitempty" json:"image,omitempty"`
|
|
Description string `toml:"description,omitempty" json:"description,omitempty"`
|
|
}
|
|
|
|
// KernelSection configures the kernel for hybrid modes. Ignored in container
|
|
// mode.
|
|
type KernelSection struct {
|
|
Version string `toml:"version,omitempty" json:"version,omitempty"`
|
|
Path string `toml:"path,omitempty" json:"path,omitempty"`
|
|
Modules []string `toml:"modules,omitempty" json:"modules,omitempty"`
|
|
Cmdline string `toml:"cmdline,omitempty" json:"cmdline,omitempty"`
|
|
}
|
|
|
|
// SecuritySection configures the security policy.
|
|
type SecuritySection struct {
|
|
LandlockProfile string `toml:"landlock_profile,omitempty" json:"landlock_profile,omitempty"`
|
|
SeccompProfile string `toml:"seccomp_profile,omitempty" json:"seccomp_profile,omitempty"`
|
|
Capabilities []string `toml:"capabilities,omitempty" json:"capabilities,omitempty"`
|
|
ReadOnlyRootfs bool `toml:"read_only_rootfs,omitempty" json:"read_only_rootfs,omitempty"`
|
|
}
|
|
|
|
// ResourceSection configures cgroups v2 resource limits. All values use
|
|
// human-readable strings (e.g. "512M", "2G") that are parsed at validation
|
|
// time.
|
|
type ResourceSection struct {
|
|
MemoryLimit string `toml:"memory_limit,omitempty" json:"memory_limit,omitempty"`
|
|
MemorySoft string `toml:"memory_soft,omitempty" json:"memory_soft,omitempty"`
|
|
CPUWeight int `toml:"cpu_weight,omitempty" json:"cpu_weight,omitempty"`
|
|
CPUSet string `toml:"cpu_set,omitempty" json:"cpu_set,omitempty"`
|
|
IOWeight int `toml:"io_weight,omitempty" json:"io_weight,omitempty"`
|
|
PidsMax int `toml:"pids_max,omitempty" json:"pids_max,omitempty"`
|
|
}
|
|
|
|
// NetworkSection configures the container network.
|
|
type NetworkSection struct {
|
|
Mode NetworkMode `toml:"mode,omitempty" json:"mode,omitempty"`
|
|
Address string `toml:"address,omitempty" json:"address,omitempty"`
|
|
DNS []string `toml:"dns,omitempty" json:"dns,omitempty"`
|
|
Ports []string `toml:"ports,omitempty" json:"ports,omitempty"`
|
|
}
|
|
|
|
// StorageSection configures the rootfs and volumes.
|
|
type StorageSection struct {
|
|
Rootfs string `toml:"rootfs,omitempty" json:"rootfs,omitempty"`
|
|
Volumes []VolumeMount `toml:"volumes,omitempty" json:"volumes,omitempty"`
|
|
WritableLayer WritableLayerMode `toml:"writable_layer,omitempty" json:"writable_layer,omitempty"`
|
|
}
|
|
|
|
// VolumeMount describes a bind mount from host to container.
|
|
type VolumeMount struct {
|
|
Host string `toml:"host" json:"host"`
|
|
Container string `toml:"container" json:"container"`
|
|
ReadOnly bool `toml:"readonly,omitempty" json:"readonly,omitempty"`
|
|
}
|
|
|
|
// ── Parser ───────────────────────────────────────────────────────────────────
|
|
|
|
// LoadFile reads a TOML manifest from disk and returns the parsed Manifest.
|
|
// No validation or resolution is performed — call Validate() and Resolve()
|
|
// separately.
|
|
func LoadFile(path string) (*Manifest, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("read manifest: %w", err)
|
|
}
|
|
|
|
m, err := Parse(data)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parse %s: %w", path, err)
|
|
}
|
|
m.SourcePath = path
|
|
return m, nil
|
|
}
|
|
|
|
// Parse decodes a TOML document into a Manifest.
|
|
func Parse(data []byte) (*Manifest, error) {
|
|
var m Manifest
|
|
if err := toml.Unmarshal(data, &m); err != nil {
|
|
return nil, fmt.Errorf("toml decode: %w", err)
|
|
}
|
|
return &m, nil
|
|
}
|
|
|
|
// Encode serializes a Manifest to TOML bytes.
|
|
func Encode(m *Manifest) ([]byte, error) {
|
|
buf := new(tomlBuffer)
|
|
enc := toml.NewEncoder(buf)
|
|
if err := enc.Encode(m); err != nil {
|
|
return nil, fmt.Errorf("toml encode: %w", err)
|
|
}
|
|
return buf.Bytes(), nil
|
|
}
|
|
|
|
// tomlBuffer wraps a byte slice to satisfy io.Writer for the TOML encoder.
|
|
type tomlBuffer struct {
|
|
data []byte
|
|
}
|
|
|
|
func (b *tomlBuffer) Write(p []byte) (int, error) {
|
|
b.data = append(b.data, p...)
|
|
return len(p), nil
|
|
}
|
|
|
|
func (b *tomlBuffer) Bytes() []byte {
|
|
return b.data
|
|
}
|
|
|
|
// ── Convenience ──────────────────────────────────────────────────────────────
|
|
|
|
// IsHybrid returns true if the workload mode requires kernel isolation.
|
|
func (m *Manifest) IsHybrid() bool {
|
|
switch m.Workload.Mode {
|
|
case ModeHybridNative, ModeHybridKVM, ModeHybridEmulated:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// NeedsKernel returns true if the workload mode requires a kernel path.
|
|
func (m *Manifest) NeedsKernel() bool {
|
|
return m.Workload.Mode == ModeHybridNative || m.Workload.Mode == ModeHybridKVM
|
|
}
|
|
|
|
// HasCASRootfs returns true if the storage rootfs references the CAS store.
|
|
func (m *Manifest) HasCASRootfs() bool {
|
|
return len(m.Storage.Rootfs) > 6 && m.Storage.Rootfs[:6] == "cas://"
|
|
}
|
|
|
|
// CASDigest extracts the digest from a cas:// reference, e.g.
|
|
// "cas://sha256:abc123" → "sha256:abc123". Returns empty string if the
|
|
// rootfs is not a CAS reference.
|
|
func (m *Manifest) CASDigest() string {
|
|
if !m.HasCASRootfs() {
|
|
return ""
|
|
}
|
|
return m.Storage.Rootfs[6:]
|
|
}
|