Modules
Accrues consumption from a monotonically increasing cumulative counter, tolerating counter resets (the counter's source was destroyed and recreated, restarting from zero — e.g. a VM's cgroup across a restart).
First-order exponential moving average - a discrete low-pass filter (LPF) with an irregular-sampling-correct gain.
Turns a monotonically increasing byte counter (e.g. /proc/diskstats sectors
or /proc/net/dev bytes) into a per-second rate.
The one place every Hyper configuration value is read.
This node's resource budget. Each field reads from config.exs
(config :hyper, Hyper.Cfg.Budget, ..., typically set via the operator
override file /etc/hyper/config.exs), then the [budget] table in
/etc/hyper/config.toml, then its built-in default. Unit.* quantities may
be given as Elixir terms in config.exs or as strings ("4GiB", "1GiBps")
in TOML.
BEAM cluster (Distributed Erlang) topology for Hyper. Set it in config.exs
via config :hyper, Hyper.Cfg.Cluster, topologies: [...] using
libcluster topology syntax;
Hyper.Application forwards it straight to Cluster.Supervisor, which is what
Horde's members: :auto registries form over. config.exs-only because a
topology references strategy modules. The default — [] — is a single,
unclustered node.
The node's work directory and every directory derived from it.
Layer garbage collector tuning. Each field reads from config.exs
(config :hyper, Hyper.Cfg.Gc, ...), then the [img.gc] table, then its
default. Durations are Unit.Time — Elixir terms in config.exs, strings
("60s", "1h") in TOML.
gRPC server configuration, read from application env into a struct
This node's image storage configuration: the device-mapper geometry behind the read-only layer chain (dm-snapshot) and the per-VM writable layers (dm-thin).
Image-database (Ecto/Postgres) connection settings — database/username/
password/hostname. These are secrets, so they are read from config.exs
only (config :hyper, Hyper.Cfg.Img.Db, ...), never the shared config.toml.
Hyper.Img.Db.Repo.init/2 merges these over its compile-time defaults.
VM confinement settings from the [jails] table — config.toml-only because
the setuid helper enforces the same uid_gid_range it reads from this file.
Raised when a required config value is absent from every permitted source.
VM egress networking settings from the [network] table — config.toml-only
because the setuid helper reads the same uplink and clone_pool to build
each VM's netns, veth, and NAT rules.
OpenTelemetry exporter configuration. Resolved from config :hyper, Hyper.Cfg.Otel, proto:/endpoint:/headers: (config.exs), the [otel] toml
table, then the standard OTEL_EXPORTER_OTLP_ENDPOINT env var.
config/runtime.exs calls exporter_options/1 and feeds the result to
config :opentelemetry_exporter.
Paths to every external binary Hyper runs, read from the [tools] table.
Per-architecture guest-kernel image paths. Operators set amd64/aarch64
(mapped to :x86_64/:aarch64) in config :hyper, Hyper.Cfg.VmLinux, ... or
the [vmlinux] toml table. An unset architecture is simply absent from the map.
Owns this node's participation in the cluster-wide CRDTs: the VM routing
registry (Hyper.Cluster.Routing) and the budget telemetry registry
(Hyper.Cluster.Budget). One supervisor, one membership story, two
independent DeltaCRDTs.
Cluster-wide budget telemetry: one Hyper.Node.Budget.NodeState per node,
keyed {:node, node()}. A Horde.Registry (DeltaCRDT) with members: :auto.
Cluster-wide VM routing registry: maps {vm_id, component} -> pid so any node
can name a VM's processes (via/1) and find which machine runs a VM
(whereis/1). A Horde.Registry (DeltaCRDT) with members: :auto, so it
forms over the BEAM cluster libcluster builds.
Picks the node to run a VM on. The first pass reads the gossip-replicated
Hyper.Node.Budget.NodeStates (Hyper.Cluster.Budget.all_states/0), drops
nodes that cannot fit the spec, and ranks survivors by how many bytes of the
VM's image layers they already have mounted (colo(N, VM) = sum of |L| over
shared mounted layers). The result is an ordered candidate list; the chosen
node confirms authoritatively via Hyper.Node.Budget.admit/2 (see place/3).
Provides struct and type for a ArmRegisterModifier
Provides struct and type for a Balloon
Provides struct and type for a BalloonHintingStatus
Provides struct and type for a BalloonStartCmd
Provides struct and type for a BalloonStats
Provides struct and type for a BalloonStatsUpdate
Provides struct and type for a BalloonUpdate
Provides struct and type for a BootSource
Compile-time JSON codec injected into every generated schema via the
generator's schema_use option.
Provides struct and type for a CpuConfig
Provides struct and type for a CpuidLeafModifier
Provides struct and type for a CpuidRegisterModifier
Provides struct and type for a Drive
Provides struct and type for a EntropyDevice
Provides struct and type for a Error
Provides struct and type for a FirecrackerVersion
Provides struct and type for a FullVmConfiguration
Provides struct and type for a InstanceActionInfo
Provides struct and type for a InstanceInfo
Provides struct and type for a Logger
Provides struct and type for a MachineConfiguration
Provides struct and type for a MemoryBackend
Provides struct and type for a MemoryHotplugConfig
Provides struct and type for a MemoryHotplugSizeUpdate
Provides struct and type for a MemoryHotplugStatus
Provides struct and type for a Metrics
Provides struct and type for a MmdsConfig
Provides struct and type for a MsrModifier
Provides struct and type for a NetworkInterface
Provides struct and type for a NetworkOverride
Provides API endpoints related to operations
Provides struct and type for a PartialDrive
Provides struct and type for a PartialNetworkInterface
Provides struct and type for a PartialPmem
Provides struct and type for a Pmem
Provides struct and type for a RateLimiter
Provides struct and type for a SerialDevice
Provides struct and type for a SnapshotCreateParams
Provides struct and type for a SnapshotLoadParams
Provides struct and type for a TokenBucket
Provides struct and type for a VcpuFeatures
Provides struct and type for a Vm
Provides struct and type for a Vsock
Provides struct and type for a VsockOverride
Public gRPC interface to a Hyper cluster.
Translation between the gRPC wire types (Hyper.Grpc.V0.*) and Hyper's domain
types. Two entry points, each dispatching by pattern match on the value's type
The gRPC endpoint: logs each call and routes to Hyper.Grpc.Server.
gRPC handler for hyper.grpc.v0.Hyper. A thin translation layer: each RPC
maps its request to a domain value via Hyper.Grpc.Codec.from_grpc/1, calls
the existing Hyper BEAM API, and maps the result back with
Hyper.Grpc.Codec.to_grpc/1 (raising the GRPC.RPCError it returns on error).
A content-addressed image: an ordered stack of layers, and the entry point for putting one into the cluster.
An immutable, content-addressed leaf object stored on NFS - a base (P.img) or
a delta (L.img). The id is both primary key and identity, so inserts are
conflict-free: two nodes publishing the same bytes write the same row.
Cluster-singleton garbage collector that reconciles the blobs table against
the shared medium: a :present blob whose backing file is gone is a stale row
and is pruned. Runs continuously, one keyset page at a time.
The delete step of the layer GC, factored out of the Gc server so its
safety contracts are testable against a real database without the
cluster-singleton GenServer around them
Pure accounting core for the layer GC.
A derivation - e.g. P' = P + L. It is resolved at mount time into an
ordered set of blobs via its image_layers. "P'" is a node in the lineage
graph, never a stored file.
One rung of an image's assembly chain. position 0 is the base blob; ascending
positions are deltas applied on top (each a dm-snapshot COW store over the layer
below). Selecting all rows for an image ordered by position yields exactly the
ordered blob list and params needed to emit the dmsetup tables.
A single running VM's claim on an image (and transitively, every blob in that image's chain).
Global database of all known layers, and how they relate to each other.
Builds an ext4 rootfs from an OCI image and hands it to Hyper.Img.create/2.
Resolves and (when not operator-provided) installs the umoci binary that
Hyper.Img.OciLoader uses to flatten OCI image layers.
A content-addressed image layer.
One VM's metered compute over one wall-clock window: cpu_usec is CPU time
the VM actually executed between window_start and window_end, measured
from its cgroup's cpu.stat by Hyper.Node.FireVMM.Meter.
Per-machine supervisor. Exactly one Hyper.Node runs per BEAM node; it owns
every microVM scheduled onto this machine.
Public entry point for this node's resource budget. Thin facade over
Hyper.Node.Budget.Hard, the per-node accounting GenServer supervised by
Hyper.Node.Budget.Supervisor.
Owns this node's entry in Hyper.Cluster.Budget. Registers a fresh
Hyper.Node.Budget.NodeState on start and re-publishes it on demand
(publish/0, called on every allocation by Hyper.Node.Budget.Hard) and on a
periodic heartbeat (keeps drifting soft-load fresh and restores the
registration if the registry restarted).
Hard per-node resource accounting. One Hard runs per BEAM node (named
__MODULE__, started under Hyper.Node.Budget.Supervisor) and tracks how much
memory and disk the VMs scheduled onto this machine have reserved.
The per-node resource snapshot published into Hyper.Cluster.Budget and read by
Hyper.Cluster.Scheduler as the first pass of placement.
Soft per-node admission check. Where Hyper.Node.Budget.Hard tracks memory and
disk reserved from VM specs, Soft holds no state: it answers, from this node's
live resource monitors (Sys.Mon), whether the machine currently has the
instantaneous headroom to take on another VM.
Per-node supervisor for the budget subsystem. Runs once per BEAM node and owns both sides of the budget plus the cluster advertisement
Supervises a single Firecracker microVM, split into four independent children so no lifecycle invariant rides on the ordering of a flat child list
gRPC client to the in-guest agent, dialed through the per-VM relay UDS.
Per-VM gRPC relay: listens on a host Unix-domain socket and for each
inbound connection performs the Firecracker vsock CONNECT/OK handshake
via RelayDialer, then pipes bytes bidirectionally until either side
closes.
Connects to a Firecracker vsock Unix-domain socket and performs the host-initiated CONNECT/OK handshake, returning the open socket ready for use as a transparent byte pipe to the guest agent.
Resolves a Hyper.Vm.source() + instance type into a concrete, API-shaped
cold-boot spec the :configuring state issues: machine config (from the
instance type), a kernel boot source, and a root drive.
A resolved cold boot.
Places a VM's boot artifacts inside its jailer chroot and points the boot spec at them.
Per-microVM facade over the generated Firecracker API
(Hyper.Firecracker.Api.Operations). One GenServer per VM, registered
cluster-wide via Hyper.Cluster.Routing.via({vm_id, :client}). It serializes
every request through handle_call (Firecracker's API server is
single-threaded).
Start options for Hyper.Node.FireVMM.Client. Only :vm_id is required;
the socket path is derived from it unless :socket_path is given.
The lifecycle-coupled core of one microVM: the jailed firecracker daemon and
its controller, restarted as a pair. Isolated from the API client
(Hyper.Node.FireVMM.Client) so the only order-sensitive relationship in the
VM tree lives in this two-child supervisor.
The jailed firecracker OS process for one microVM, as a static child of
Hyper.Node.FireVMM.Core.
Resolves the path of the hyper-guest-agent static musl binary that the
:guest_agent_build Mix compiler builds into priv/guest-agent/ at compile
time. The agent ships inside the app (and its release) -- there is no separate
install step.
Builds the hyper-suidhelper jailer command for one VM.
Host pre-requisite checks for running the jailer. Each check returns
:ok | {:error, reason}; run/0 evaluates them in order and stops at the
first failure.
Per-VM compute meter: samples the VM's cgroup cpu.stat every second,
accrues the CPU time actually executed, and flushes one
Hyper.Metering.Usage window per minute — plus a final one at teardown.
The meter is the FireVMM supervisor's last child, so at shutdown it
stops first, taking its final reading before the Daemon removes the
cgroup.
Meter wiring: the VM, its cgroup leaf, and the usage sink.
The per-VM inner-world networking contract. Every VM's netns is identical —
tap0 at 172.30.0.1/30, guest at 172.30.0.2/30 — so a snapshot clone restores
a correct network with zero renumbering; host-side uniqueness is the helper's
job (see Hyper.SuidHelper.Network). This module owns the three values that
must agree between the guest kernel cmdline, the Firecracker NIC config, and
the helper: the guest MAC, the ip= autoconfig string, and the NIC spec.
Per-VM request: instance size + architecture, isolation ids, the kernel
image, optional boot args, and the per-VM Img.Mutable layer the VM boots
from. The root device is read from the mutable layer at configure time, so a
VM can only be booted from a mutable layer - never a bare Hyper.Img.
:gen_statem controller for one microVM. It drives the boot protocol against a
daemon whose lifecycle is owned by the supervisor (Hyper.Node.FireVMM.Core,
:one_for_all): the controller does not launch, monitor, or kill the daemon -
if firecracker dies, Core restarts the daemon and this controller together,
and init simply cold-boots again.
Poll the (already-launched) daemon's API socket, then advance to :configuring.
Stage the kernel + rootfs device into the jail chroot. Enter :running after.
The guest is live. Handles stop (-> :stopping).
Teardown was requested in-band.
The statically-embedded vmlinux release manifest.
One kernel build from the manifest.
Installs the guest-kernel (vmlinux) images for the current architecture into
Hyper.Cfg.Dirs.vmlinux_install_dir/0 (<work_dir>/redist/vmlinux).
Supervisor for this node's active images, and the entry point for image operations. Owns
The per-VM mutable rootfs. On start it activates (or reuses) the image's
read-only Img.Server, takes a reference on it, reads the composed device's
size, and asks the node ThinPool for a thin volume with that device as a
read-only external origin. blk_path/1 is the mutable host device the VM
boots from (staged into the jail by mknod from this path).
Materialize a running VM's disk divergence as a new immutable delta layer.
GenServer representing a single active image on this node.
Options for starting an image server.
The node's single dm-thin pool. On start it materialises two sparse backing
files in scratch_dir (metadata + data), attaches them as writable loop
devices, zeroes the metadata (so the kernel treats it as a fresh pool), and
creates the hyper-thinpool device-mapper pool.
Supervisor for this node's mounted layers. Owns a unique Registry
(layer_id -> Layer.Server) and a DynamicSupervisor that holds those
servers, so a layer can be mounted on demand and looked up by its id.
Repo for looking up layers in the shared layer directory. Currently backed by a flat file-directory.
GenServer responsible for managing a single mounted layer.
Per-node periodic, liveness-aware garbage collector for per-VM host resources
that an unclean BEAM death can strand: a firecracker cgroup leaf and a
hyper-rw-<id> dm volume whose owning processes' terminate/2 never ran and
whose vm_id never reboots (so Hyper.Node.Reclaim, which runs once at boot, and
the relaunch-time cleanup in the FireVMM path, never get a chance to clear it).
Pure reap-decision core for Hyper.Node.Reaper. No I/O. Every safety invariant
is a property of these functions: a live vm_id is never a candidate, only an
orphan seen on two consecutive ticks is reaped, and only hyper-rw-* dm names
yield candidates (so hyper-thinpool / hyper-img-* can never be reaped).
Boot-time reclamation of device-mapper and loop devices orphaned by an unclean
shutdown (SIGKILL or :erlang.halt, where the owning GenServers' terminate/2
never ran to tear them down).
Process running on the Hyper.Node responsible for creating and managing POSIX users.
Bump-pointer + freed-stack id pool. Only ids currently in flight are stored
Resolves the guest kernel (vmlinux) image for this node.
Interface to the setuid-root device helper (hyper-suidhelper), split by tool
Chunked ranged copy between block devices, via the setuid helper's
blockcopy tool — used to fill a fork delta layer's COW store with exactly
the divergent chunks.
Block-device queries, via the setuid helper's blockdev tool.
Privileged chroot/jail lifecycle, via the setuid helper's chroot-jail
subcommands (prepare / remove). These are built into the helper (no
external binary), so there is no separate test_system/0 -
Hyper.SuidHelper.test_system/0 already checks the helper itself is present.
device-mapper operations (snapshot / thin), via the setuid helper's dmsetup tool.
Loop-device operations, via the setuid helper's losetup tool.
Privileged per-VM egress networking via the setuid helper's network
subcommands. The helper derives every address, interface name, and netns path
from vm_id + the validated uid + the root-owned [network] config — the
node passes only those two untrusted values.
Extract a thin device's provisioned-range map from the pool's metadata, via
the setuid helper's thin-dump tool (thin-provisioning-tools). Only valid
while the pool's metadata snapshot is reserved — see
Hyper.Node.Img.ThinPool.mappings/1, the sole intended caller.
A microVM handle (its controller pid) and cluster-wide fork operations.
A microVM id and its generator.
Named instance types - fixed (vCPU, memory) sizes, like cloud instance classes.
Resource bundle for one instance type.
A request to create a VM: which image to boot, the instance size, the guest architecture, and optional kernel boot args.
Fetches a single raw file from a URL, verifies its SHA-256, and installs it at
a destination path. The raw-file analogue of Redist.Targz (used for
assets that ship as plain files rather than tarballs, e.g. vmlinux images).
Streaming SHA-256 of a file, returned as lowercase hex.
Fetches a gzipped tarball from a URL, verifies its SHA-256, and extracts it into a directory.
CPU architecture detection for the current machine.
cgroup introspection.
cgroup v2 (unified hierarchy) helpers.
Map which represents the possible configurations of a cgroup
Reads a cgroup v2 cpu.stat interface file — the cumulative CPU time the
cgroup's processes have actually executed since the cgroup was created.
Parsing of /etc/fstab-style entries.
A parsed /etc/fstab entry.
NSS (Name Service Switch) utilities - queries users and groups via getent.
The group database (getent group).
A parsed group entry.
The passwd database (getent passwd).
A parsed passwd entry.
Parses /proc/diskstats into per-device I/O counters.
One /proc/diskstats row: a block device and its cumulative read/written bytes.
Reads memory totals from /proc/meminfo.
A point-in-time /proc/meminfo reading. Every field maps to a line present
on all Linux kernels (MemTotal/MemFree/Buffers/Cached since 2.4,
MemAvailable since 3.14).
Reads the currently-mounted filesystems from /proc/mounts.
Parses /proc/net/dev into per-interface byte counters.
One /proc/net/dev row: an interface and its cumulative rx/tx bytes.
Reads kernel counters from /proc/stat.
Cumulative jiffies a CPU (the aggregate, or one core) has spent in each state
since boot: user nice system idle iowait irq softirq steal guest guest_nice.
A point-in-time /proc/stat reading.
Subuid and Subgid utilities
A subordinate id range - one /etc/subuid or /etc/subgid entry.
Supervises this node's real-time resource monitors and exposes their current
readings to the scheduler via readings/0.
Monitors instantaneous CPU utilization (the soft beta_vcpus signal).
Monitors instantaneous disk bandwidth (the soft beta_disk_bw signal).
Monitors instantaneous memory pressure.
Monitors instantaneous network bandwidth (the soft beta_net_bw signal).
A snapshot of every monitored soft metric at one instant. Each field is a
Sys.Mon.Server.Reading whose instant/smoothed carry that metric's domain
type - cpu a Float fraction, mem a Unit.Information, disk_bw/net_bw
a Unit.Bandwidth.
Behaviour for a single soft-metric probe.
Generic monitor process: drives a Sys.Mon.Sampler on a fixed period, folds
each reading through a Controls.Ewma low-pass filter, and answers value/1.
A monitor reading: the latest instantaneous and filtered values, each in the
sampler's domain type (a number or any Unit.Quantity).
POSIX filesystem helpers.
Temporary file/directory helpers.
A throughput, stored canonically in bytes per second. Build with bps/1 or the
binary-prefix constructors (kibps/1, mibps/1, gibps/1, tibps/1); read back
with as_bytes_per_sec/1. Arithmetic (+, -) and comparison
(<, >, <=, >=) come from Unit.Operators.
Operator overloading for Unit.Quantity types.
A one-dimensional physical quantity backed by a single canonical integer
(bytes, nanoseconds, bytes/sec, ...). Implementing this is all a unit type
needs to get +, -, and the ordering operators from Unit.Operators.
Mix Tasks
Downloads, verifies, and installs the pinned Firecracker release (v1.16.0) for the current CPU architecture.
Builds, stamps, and installs the Rust setuid helper.