vm

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 15, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package vm manages virtual machines for cross-OS job execution.

ephemerd uses VMs in two scenarios:

  1. Linux VM (long-running): On Windows and macOS hosts, a lightweight Linux VM runs containerd for Linux jobs. Same OCI images as native Linux. - Windows: Hyper-V Gen 2 VM with direct kernel boot via HCS API - macOS: Virtualization.framework Linux VM

  2. macOS VM (per-job): On macOS hosts, ephemeral macOS VMs run macOS-native jobs (Xcode, Swift, etc.). Each job gets a clone-on-write copy of a base image that is destroyed after the job completes.

Platform-specific implementations are in *_darwin.go, *_windows.go, and *_linux.go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateEphemeralSSHKey

func GenerateEphemeralSSHKey() (ed25519.PrivateKey, string, error)

GenerateEphemeralSSHKey creates an in-memory ed25519 key pair for SSH access to macOS VMs. The private key is never written to disk — it lives only for the lifetime of this ephemerd process and rotates on restart. Returns the private key (as crypto.Signer) and the public key in authorized_keys format.

func WindowsPathToWSL

func WindowsPathToWSL(winPath string) (string, error)

WindowsPathToWSL converts a Windows absolute path to a WSL /mnt/ path. Example: C:\Users\luthe\repo → /mnt/c/Users/luthe/repo

Types

type LinuxVM

type LinuxVM interface {
	// Client returns a containerd client connected to containerd inside the VM.
	Client() *client.Client

	// DispatchAddr returns the address of the dispatch gRPC server running
	// inside the VM (e.g. "localhost:10001"). Empty if dispatch is unavailable.
	DispatchAddr() string

	// Stop gracefully shuts down the VM.
	Stop()
}

LinuxVM is a long-running Linux VM that hosts containerd for Linux jobs. Implemented per-platform: Virtualization.framework on macOS, Hyper-V on Windows.

func StartLinuxVM

func StartLinuxVM(_ LinuxVMConfig) (LinuxVM, error)

StartLinuxVM is not needed on Linux — containerd runs directly on the host.

type LinuxVMConfig

type LinuxVMConfig struct {
	// DataDir is the ephemerd data directory. VM assets live under <DataDir>/vm/linux/.
	DataDir string

	// CPUs is the number of virtual CPUs. Defaults to 2.
	CPUs uint

	// MemoryMB is the VM memory in megabytes. Defaults to 2048.
	MemoryMB uint64

	// DiskSizeGB is the VM root disk size in gigabytes (sparse). Defaults to 50.
	DiskSizeGB uint64

	// ContainerdPort is the port containerd listens on inside the VM. Defaults to 10000.
	ContainerdPort uint32

	// DindEnabled passes --dind to the VM's ephemerd serve, mounting a fake
	// Docker socket into each container.
	DindEnabled bool

	// DindAllowPrivileged forwards the host's dind.allow_privileged setting
	// to the in-VM ephemerd via the kernel cmdline. Kept as a fallback for
	// environments where the Plan9 host-config share fails to mount (e.g.
	// stripped kernel without 9p modules); the share normally supersedes
	// this by carrying the same value through the shared config.toml.
	DindAllowPrivileged bool

	// HostDataDir is the host's ephemerd data directory. When set,
	// <HostDataDir>/config.toml is appended into the runtime-generated
	// boot-initrd tail (next to ephemerd-linux) and staged at
	// /etc/ephemerd/config.toml inside the VM, so any host-side setting
	// takes effect on the next VM boot without per-setting kernel cmdline
	// plumbing. A missing config.toml is non-fatal (fresh installs run on
	// defaults). See docs/arch/host-config-initrd.md.
	HostDataDir string

	Log *slog.Logger
}

LinuxVMConfig configures the long-running Linux VM for Linux jobs on non-Linux hosts.

func (*LinuxVMConfig) SetDefaults

func (c *LinuxVMConfig) SetDefaults()

SetDefaults applies default values for unconfigured fields.

type MacOSInstallOptions

type MacOSInstallOptions struct {
	CustomDiskImage string
	TartImage       string
}

MacOSInstallOptions is the non-darwin stub. See macos_install_darwin.go.

type MacOSVM

type MacOSVM interface {
	// WriteJITConfig writes the encoded JIT runner config to the job's shared
	// directory so the guest can pick it up on boot via virtio-fs.
	WriteJITConfig(encodedJIT string) error

	// Start boots the VM from a clone-on-write copy of the base image.
	Start(ctx context.Context) error

	// WaitForRunner blocks until the GitHub runner inside the VM is reachable.
	// Checks for a .ready sentinel file on the virtio-fs share first, then
	// falls back to SSH port 22. Returns the VM's discovered IP address.
	WaitForRunner(ctx context.Context) (string, error)

	// RunnerAddress returns the VM's discovered IP address, or empty if not yet known.
	RunnerAddress() string

	// Wait blocks until the VM exits. Returns the exit code.
	Wait(ctx context.Context) (int, error)

	// Stop forcefully stops the VM and deletes the clone.
	Stop()
}

MacOSVM is an ephemeral macOS VM for a single job. Only available on macOS hosts via Virtualization.framework.

func NewMacOSVM

func NewMacOSVM(_ MacOSVMConfig, _ string) (MacOSVM, error)

NewMacOSVM is only available on macOS hosts.

type MacOSVMConfig

type MacOSVMConfig struct {
	// DataDir is the ephemerd data directory. VM assets live under <DataDir>/vm/macos/.
	DataDir string

	// DiskImage is the path to the installed macOS disk (produced from
	// an Apple IPSW via EnsureMacOSBaseImage). Each job gets an APFS
	// clone of this file. Not to be confused with the OCI base image
	// that jobs overlay onto the VM at runtime.
	DiskImage string

	// SSHSigner is the ephemeral SSH private key for guest access.
	// Generated fresh on each ephemerd startup — never persisted to disk.
	SSHSigner interface{} // crypto.Signer (ed25519.PrivateKey)

	// SSHPubKey is the authorized_keys-format public key to inject into
	// each job's virtio-fs share. The guest picks it up on boot.
	SSHPubKey string

	// CPUs per macOS VM. Defaults to 4.
	CPUs uint

	// MemoryMB per macOS VM. Defaults to 8192.
	MemoryMB uint64

	Log *slog.Logger
}

MacOSVMConfig configures per-job macOS VMs (macOS hosts only).

func (*MacOSVMConfig) SetDefaults

func (c *MacOSVMConfig) SetDefaults()

SetDefaults applies default values for unconfigured fields.

type MacOSVMDiskFiles

type MacOSVMDiskFiles struct {
	DataDir       string
	DiskImage     string
	AuxStorage    string
	MachineID     string
	HardwareModel string
}

MacOSVMDiskFiles is the non-darwin stub. See macos_install_darwin.go.

func EnsureMacOSVMDisk

func EnsureMacOSVMDisk(_ context.Context, _ string, _ MacOSInstallOptions, _ *slog.Logger) (*MacOSVMDiskFiles, error)

EnsureMacOSVMDisk is only implemented on darwin.

type RunDistro

type RunDistro struct {
	Name string
	// contains filtered or unexported fields
}

RunDistro tracks a single ephemerd-run WSL distro instance. Each concurrent "ephemerd run" gets its own distro with a unique name.

func NewRunDistro

func NewRunDistro(_ context.Context, _ RunDistroConfig) (*RunDistro, error)

NewRunDistro is only available on Windows.

func (*RunDistro) Destroy

func (d *RunDistro) Destroy()

Destroy is only available on Windows.

func (*RunDistro) Run

func (d *RunDistro) Run(_ context.Context, _ RunInWSLConfig) (int, error)

Run is only available on Windows.

type RunDistroConfig

type RunDistroConfig struct {
	DataDir string
	Log     *slog.Logger
}

RunDistroConfig configures the creation of a new RunDistro.

type RunInWSLConfig

type RunInWSLConfig struct {
	WorkflowPath string // absolute path to the workflow YAML
	JobFilter    string // optional --job filter
	RepoDir      string // absolute path to the repo root
}

RunInWSLConfig configures a single ephemerd run delegation to WSL.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL