Volt CLI: source-available under AGPSL v5.0
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
This commit is contained in:
277
pkg/manifest/manifest.go
Normal file
277
pkg/manifest/manifest.go
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
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:]
|
||||
}
|
||||
Reference in New Issue
Block a user