Documentation
¶
Overview ¶
Package pod defines the in-VM PodSpec — what the guest init is told to run. The on-the-wire form is weft-proto's guestv1.PodSpec; this Go type mirrors it so init code stays decoupled from the proto regeneration cycle.
One PodSpec drives one micro-VM. A pod with a single Container is the mono-container case ; multiple Containers share the pod's network + IPC namespaces (the "infra"/pause container pattern).
Index ¶
Constants ¶
const BackendCubeFS = "cubefs"
BackendCubeFS is the platform's RWX share backend — CubeFS, a CNCF distributed POSIX + S3 filesystem. The Backend field is kept so other backends can return without reshaping the event-bus contract.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Container ¶
type Container struct {
ID string `json:"id"`
RootfsTag string `json:"rootfs_tag"` // matches a Share.Tag (virtio-fs) OR a local dir under /run/weft/rootfs/<id>
Command []string `json:"command,omitempty"` // overrides image entrypoint
Args []string `json:"args,omitempty"`
Env map[string]string `json:"env,omitempty"`
Workdir string `json:"workdir,omitempty"`
User string `json:"user,omitempty"` // "uid:gid" or username
Restart RestartPolicy `json:"restart,omitempty"`
Mounts []Mount `json:"mounts,omitempty"`
Resources Resources `json:"resources,omitempty"`
Privileged bool `json:"privileged,omitempty"`
}
Container is one OCI container in the pod.
type CubeFSMount ¶
type CubeFSMount struct {
// Volume is the CubeFS volume name (the platform "share" maps 1:1 to
// a CubeFS volume).
Volume string `json:"volume"`
// Masters are the CubeFS master node addresses ("host:port"), reached
// over the wg0 overlay.
Masters []string `json:"masters"`
// Owner is the volume owner CubeFS authorizes against.
Owner string `json:"owner"`
// AccessKey / SecretKey authenticate to CubeFS (the volume's keypair).
AccessKey string `json:"access_key,omitempty"`
SecretKey string `json:"secret_key,omitempty"`
// SubDir optionally mounts only a subtree of the volume.
SubDir string `json:"subdir,omitempty"`
}
CubeFSMount is the connection detail for a CubeFS volume — what the in-guest CubeFS client (cfs-client) needs to attach the volume.
type Firewall ¶
type Firewall struct {
Rules []FirewallRule `json:"rules"`
}
Firewall is the per-VM desired stateful filter ruleset. weft publishes this whole-state on the event bus (subject "weft.firewall.<vm-uuid>") whenever the effective rules for the VM change (Security-Group rules edited, group attached/detached, network defaults changed). The agent inside the microVM atomically reconciles its nftables table against the new state — replace-set, idempotent, missed-message-self-heals — same model pkg/mesh / pkg/mounts use for their concerns.
The set is pre-resolved by the publisher: every Security-Group rule that references another group by UUID is expanded into one or more FirewallRule entries with concrete RemoteCIDR values. The guest never sees group references and never has to query the control plane.
func LoadFirewall ¶
LoadFirewall reads a standalone firewall ruleset from path. Returns (nil, nil) if the file does not exist — boot without a pre-staged ruleset is legal; the agent will receive the first state via NATS.
type FirewallRule ¶
type FirewallRule struct {
// Direction is "ingress" (traffic into the VM) or "egress" (traffic
// out of the VM). Empty is rejected by Validate.
Direction string `json:"direction"`
// Protocol is "tcp", "udp", "icmp" (any code/type), or "" meaning any
// L4 protocol. PortMin/PortMax are ignored when Protocol is "" or
// "icmp".
Protocol string `json:"protocol,omitempty"`
// PortMin / PortMax describe an inclusive destination port range
// (for ingress) or source port range (for egress). 0 = unset; if
// set, PortMin must be ≤ PortMax. A single port is encoded as
// PortMin == PortMax.
PortMin uint16 `json:"port_min,omitempty"`
PortMax uint16 `json:"port_max,omitempty"`
// RemoteCIDR is the peer subnet matched on the rule. Empty means
// any. Validated as a parseable CIDR by Validate.
RemoteCIDR string `json:"remote_cidr,omitempty"`
}
FirewallRule mirrors weft-proto's SecurityRule but with remote_group_uuid already dereferenced to a CIDR (or empty = any). Stateful: the reconciler installs the rule on the matching hook (ingress/egress) with conntrack established/related already accepted at the top of the chain.
func (FirewallRule) Validate ¶
func (r FirewallRule) Validate() error
Validate checks a single rule. Pulled out so the host-side publisher can validate one rule at a time when expanding remote_group_uuid.
type FirewallStatus ¶
type FirewallStatus struct {
// Overall is "Healthy" when the reconciler successfully read
// the kernel table on the last poll, "Degraded" when the
// nftables read errored. Defined as a string so the UI can
// render unknown future states without code churn.
Overall string `json:"Overall"`
// TableInstalled is true when the "weft-fw" table is present
// in the kernel ; false when no ruleset has been applied yet
// (fresh boot before the first publish lands) or it was
// flushed externally.
TableInstalled bool `json:"TableInstalled"`
// RulesInstalled is the total number of nftables rules across
// the input + output chains, including the unconditional
// ct/lo accepts the reconciler always installs. The UI
// subtracts those defaults to show the tenant-visible count.
RulesInstalled int `json:"RulesInstalled"`
// LastError carries the most recent read error message ;
// empty on success. Surfaced so an operator can tell
// "reconciler crashed" from "no policy yet" without ssh-ing
// into the guest.
LastError string `json:"LastError,omitempty"`
// PublishedAtUnix is the wall-clock time of this status
// message (set by the emitter, not by the reconciler).
PublishedAtUnix int64 `json:"PublishedAtUnix"`
}
FirewallStatus is the per-VM live state weft-microvm-agent publishes on "weft.firewall.<vm-uuid>.status" so the control plane (and the UI) can show whether the firewall reconciler is healthy and what's installed right now.
Reverse direction of the firewall config subject : weft-network (or weft) PUBLISHES the desired ruleset on the per-VM "weft.firewall.<vm-uuid>" subject ; the agent PUBLISHES this status back on a sibling subject. Same Subscriber+ApplyFunc / emitter pair that weft-router uses for its BGP state.
type MountAction ¶
type MountAction string
MountAction distinguishes a mount request from an unmount on the event bus. The zero value ("") means mount, so a boot-time Spec.ShareMounts entry needs no explicit action.
const ( MountActionMount MountAction = "" // also "mount" MountActionUnmount MountAction = "unmount" )
type Network ¶
type Network struct {
Interface string `json:"interface,omitempty"` // default "eth0"
Address string `json:"address,omitempty"` // CIDR, e.g. "10.0.2.15/24"
Gateway string `json:"gateway,omitempty"`
DNS []string `json:"dns,omitempty"`
Hostname string `json:"hostname,omitempty"`
}
Network is the pod-level network config. The init brings up eth0 before any container starts ; containers join the pod netns.
type RestartPolicy ¶
type RestartPolicy string
const ( RestartNever RestartPolicy = "" RestartOnFailure RestartPolicy = "on-failure" RestartAlways RestartPolicy = "always" )
type Share ¶
type Share struct {
}
Share is a host-mounted filesystem exposed to the guest (typically virtio-fs). One share usually carries the OCI rootfs of one container.
type ShareMount ¶
type ShareMount struct {
// targets the same mount deterministically.
ID string `json:"id"`
Action MountAction `json:"action,omitempty"`
Backend string `json:"backend,omitempty"`
// "/run/weft/shares/team-data". Bind-mount it into containers via
// Container.Mounts to expose it to a workload.
MountPoint string `json:"mount_point"`
Readonly bool `json:"readonly,omitempty"`
// is CubeFS / empty).
CubeFS *CubeFSMount `json:"cubefs,omitempty"`
}
ShareMount is one multi-attach POSIX share mounted inside the guest. It serves two roles, mirroring how pod.WireGuard is both a Spec field and the mesh update message:
- boot-time: an entry in Spec.ShareMounts the agent mounts at startup;
- dynamic: the JSON payload an operator (e.g. a teacher) publishes on the event bus to mount/unmount a share on a running VM — which the control plane fans out to a whole group of student VMs.
State is pushed whole and applied idempotently (replace-by-ID), so a missed message self-heals on the next publish — same model as the mesh.
func LoadShareMounts ¶
func LoadShareMounts(path string) ([]ShareMount, error)
LoadShareMounts reads a standalone list of share mounts (JSON array) from path — the file the host drops into the config share for boot-time mounts. A missing file is not an error (returns nil, nil).
func (*ShareMount) EffectiveBackend ¶
func (m *ShareMount) EffectiveBackend() string
EffectiveBackend reports the backend, applying the CubeFS default.
func (*ShareMount) Validate ¶
func (m *ShareMount) Validate() error
Validate checks the fields the action+backend need. Unmount only needs ID + MountPoint ; a CubeFS mount needs the volume connection set.
type Spec ¶
type Spec struct {
PodID string `json:"pod_id"`
Containers []Container `json:"containers"`
Network *Network `json:"network,omitempty"`
WireGuard *WireGuard `json:"wireguard,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
}
Spec is the full pod description handed to weft-init.
type WGPeer ¶
type WGPeer struct {
PublicKey string `json:"public_key"` // base64, 32 bytes
Endpoint string `json:"endpoint,omitempty"` // underlay "host:port"
AllowedIPs []string `json:"allowed_ips"` // overlay CIDRs routed to this peer
PersistentKeepalive uint16 `json:"persistent_keepalive,omitempty"` // seconds; 0 = disabled
}
WGPeer is one authorized WireGuard peer on the overlay.
type WireGuard ¶
type WireGuard struct {
Interface string `json:"interface,omitempty"` // default "wg0"
PrivateKey string `json:"private_key"` // base64, 32 bytes
ListenPort uint16 `json:"listen_port,omitempty"` // UDP underlay port; 0 = ephemeral
Address string `json:"address"` // overlay CIDR, e.g. "10.9.0.1/24"
Peers []WGPeer `json:"peers,omitempty"`
}
WireGuard configures an optional kernel WireGuard interface the init brings up after eth0 — the encrypted overlay a micro-VM uses to reach other VMs, or to be reached by an operator CLI. Keys are base64-encoded 32-byte Curve25519 values, matching `wg`'s textual form.
func LoadWireGuard ¶
LoadWireGuard reads a standalone WireGuard overlay config (the same shape as Spec.WireGuard) from path. This is how the host delivers a per-VM overlay without owning the whole pod spec: weft drops wireguard.json into the config share alongside pod.json, and weft-init applies it when the pod spec itself carries no WireGuard block.
A missing file is not an error — it just means no overlay was provisioned (returns nil, nil).