Class: Hermetic::Backends::Firecracker
- Defined in:
- lib/hermetic/backends/firecracker.rb
Overview
Strongest self-host option: each run cold-boots a Firecracker microVM — its own guest kernel behind KVM (~125 ms boot). v1 ships the pure half (machine_config hash + jailer argv, unit-tested with zero infra) and a single-shot cold-boot path behind an injectable runner; real orchestration (jail materialization, vsock I/O, tap+nftables egress, warm pools) is deferred per spec §7, so the default runner refuses — actually booting is smoke-gated on a KVM host. trust :vm but co-located: off_host? is false. Pair with Hermetic::Remote to put the KVM host outside the app's trust domain.
Constant Summary collapse
- BOOT_ARGS =
"console=ttyS0 reboot=k panic=1 pci=off"- CONFIG_FILE =
jail-relative; jailer chroots firecracker
"vm-config.json"
Constants inherited from Base
Base::OFF_HOST_TRUST, Base::TIMEOUT_EXIT
Instance Attribute Summary collapse
-
#kernel ⇒ Object
readonly
Returns the value of attribute kernel.
-
#rootfs ⇒ Object
readonly
Returns the value of attribute rootfs.
Attributes inherited from Base
Instance Method Summary collapse
-
#initialize(kernel:, rootfs:, boot_args: BOOT_ARGS, firecracker_bin: "firecracker", jailer_bin: "jailer", uid: 65_534, gid: 65_534, chroot_base: "/srv/jailer", runner: nil, **opts) ⇒ Firecracker
constructor
A new instance of Firecracker.
-
#jailer_argv(id:) ⇒ Object
Pure: jailer chroots + re-namespaces firecracker and drops to an unprivileged uid/gid before the VMM runs.
-
#machine_config(request) ⇒ Object
Pure: the firecracker --config-file hash for one run.
Methods inherited from Base
#backend_name, #enabled?, #off_host?, #run
Methods included from SilasLedgerGuard
Constructor Details
#initialize(kernel:, rootfs:, boot_args: BOOT_ARGS, firecracker_bin: "firecracker", jailer_bin: "jailer", uid: 65_534, gid: 65_534, chroot_base: "/srv/jailer", runner: nil, **opts) ⇒ Firecracker
Returns a new instance of Firecracker.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/hermetic/backends/firecracker.rb', line 20 def initialize(kernel:, rootfs:, boot_args: BOOT_ARGS, firecracker_bin: "firecracker", jailer_bin: "jailer", uid: 65_534, gid: 65_534, chroot_base: "/srv/jailer", runner: nil, **opts) raise ConfigError, "kernel: (vmlinux path) is required for firecracker" if kernel.to_s.strip.empty? raise ConfigError, "rootfs: (ext4 image path) is required for firecracker" if rootfs.to_s.strip.empty? super(trust: :vm, **opts) @kernel = kernel @rootfs = rootfs @boot_args = boot_args @firecracker_bin = firecracker_bin @jailer_bin = jailer_bin @uid = uid @gid = gid @chroot_base = chroot_base @runner = runner end |
Instance Attribute Details
#kernel ⇒ Object (readonly)
Returns the value of attribute kernel.
18 19 20 |
# File 'lib/hermetic/backends/firecracker.rb', line 18 def kernel @kernel end |
#rootfs ⇒ Object (readonly)
Returns the value of attribute rootfs.
18 19 20 |
# File 'lib/hermetic/backends/firecracker.rb', line 18 def rootfs @rootfs end |
Instance Method Details
#jailer_argv(id:) ⇒ Object
Pure: jailer chroots + re-namespaces firecracker and drops to an unprivileged uid/gid before the VMM runs. Everything after "--" goes to firecracker itself; the config path is relative to the jail root.
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/hermetic/backends/firecracker.rb', line 68 def jailer_argv(id:) [ @jailer_bin, "--id", id, "--exec-file", @firecracker_bin, "--uid", @uid.to_s, "--gid", @gid.to_s, "--chroot-base-dir", @chroot_base, "--", "--no-api", "--config-file", CONFIG_FILE ] end |
#machine_config(request) ⇒ Object
Pure: the firecracker --config-file hash for one run. Rootfs is attached read-only (writable scratch is guest-init's job — same posture as docker --read-only + tmpfs); default-deny network attaches no NIC at all. pids has no seat in the VM config — it's enforced by guest init, deferred with the rest of orchestration.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/hermetic/backends/firecracker.rb', line 44 def machine_config(request) { "boot-source" => { "kernel_image_path" => @kernel, "boot_args" => @boot_args }, "drives" => [ { "drive_id" => "rootfs", "path_on_host" => @rootfs, "is_root_device" => true, "is_read_only" => true } ], "machine-config" => { "vcpu_count" => vcpu_count(request.limits.cpus), "mem_size_mib" => mem_size_mib(request.limits.memory), "smt" => false }, "network-interfaces" => request.network.firecracker_ifaces } end |