backend

package
v0.2.27 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CleanupOrphanedBuildxBuilders added in v0.2.23

func CleanupOrphanedBuildxBuilders(ctx context.Context, client DockerAPI, maxAge time.Duration, logger *slog.Logger) error

CleanupOrphanedBuildxBuilders removes buildx BuildKit builder containers (named buildx_buildkit_*) older than maxAge, along with their named `_state` volumes. Such builders are created by `docker buildx create` (e.g. via docker/setup-buildx-action); on a persistent host sharing one Docker daemon they accumulate when per-job cleanup never runs, each leaving behind a multi-GB state volume. maxAge is kept well above any realistic build so a sweep never disrupts an in-progress build. A no-op when maxAge <= 0.

func CleanupSharedDocker added in v0.2.18

func CleanupSharedDocker(ctx context.Context, client DockerAPI, removeVolume bool, logger *slog.Logger)

CleanupSharedDocker removes the shared Docker volume (if removeVolume is true) and prunes dangling images and build cache. It is safe to call once after all Docker-backed scale sets have finished shutting down; calling it concurrently or per-backend will race with container removal and other prune operations.

func CleanupSharedVolumeStale added in v0.2.20

func CleanupSharedVolumeStale(ctx context.Context, client DockerAPI, helperImage, mountPath string, ttl time.Duration, logger *slog.Logger) error

CleanupSharedVolumeStale runs an ephemeral helper container that mounts the shared volume at mountPath and deletes files whose mtime is older than ttl. Empty directories left behind are also pruned. The helper image must already be available locally; the runner image is reused so no additional pull is required. A no-op when ttl <= 0.

func FormatBytes

func FormatBytes(b uint64) string

FormatBytes formats a byte count into a human-readable string.

func PruneTartCache added in v0.2.22

func PruneTartCache(ctx context.Context, tartHome string, maxAge time.Duration, spaceBudgetGB int, logger *slog.Logger) error

PruneTartCache runs `tart prune --entries caches` against the given TART_HOME, trimming OCI/IPSW caches. Local VMs are never touched. Two criteria can apply: age (maxAge, via --older-than) reclaims layers left behind by image updates, and an optional size cap (spaceBudgetGB, via --space-budget) bounds the total. A no-op when both criteria are off (maxAge <= 0 and spaceBudgetGB <= 0).

tartHome may be empty, meaning use tart's default ($HOME/.tart). It is passed through TART_HOME so a single binary can prune multiple independent caches.

Types

type CommandRunner

type CommandRunner interface {
	Run(ctx context.Context, name string, args ...string) ([]byte, error)
	// RunStreaming executes a command with stdout/stderr piped to the terminal.
	// Used for long-running commands where progress output is important (e.g. tart pull).
	RunStreaming(ctx context.Context, name string, args ...string) error
}

CommandRunner abstracts shell command execution for testability.

type DockerAPI

type DockerAPI interface {
	ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)
	ContainerStart(ctx context.Context, containerID string, options container.StartOptions) error
	ContainerRemove(ctx context.Context, containerID string, options container.RemoveOptions) error
	ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
	ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error)
	BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error)
	VolumeRemove(ctx context.Context, volumeID string, force bool) error
	ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error)
	VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error)
}

DockerAPI abstracts the Docker client methods used by DockerBackend, enabling dependency injection and testing.

type DockerBackend

type DockerBackend struct {
	// contains filtered or unexported fields
}

DockerBackend runs GitHub Actions runners as Docker containers.

func NewDockerBackend

func NewDockerBackend(ss config.ScaleSetConfig, client DockerAPI, logger *slog.Logger) *DockerBackend

NewDockerBackend creates a DockerBackend from scale set config.

func (*DockerBackend) RemoveRunner

func (b *DockerBackend) RemoveRunner(ctx context.Context, resourceID string) error

RemoveRunner force-removes a Docker container by ID.

func (*DockerBackend) Shutdown

func (b *DockerBackend) Shutdown(_ context.Context)

Shutdown is a no-op for DockerBackend — shared Docker resources (volume, image/build caches) are cleaned up once at process exit via CleanupSharedDocker to avoid races when multiple scale sets share the same Docker client and volume.

func (*DockerBackend) StartRunner

func (b *DockerBackend) StartRunner(ctx context.Context, name string, jitConfig string) (string, error)

StartRunner creates and starts a new ephemeral Docker container runner.

type RunnerBackend

type RunnerBackend interface {
	// StartRunner creates and starts a new ephemeral runner with the given
	// name and JIT configuration. Returns a resource ID used for cleanup.
	StartRunner(ctx context.Context, name string, jitConfig string) (resourceID string, err error)

	// RemoveRunner stops and removes a runner by its resource ID.
	RemoveRunner(ctx context.Context, resourceID string) error

	// Shutdown performs backend-specific cleanup (prune images, remove volumes, etc.).
	Shutdown(ctx context.Context)
}

RunnerBackend abstracts runner lifecycle operations across different execution backends (Docker containers, Tart VMs, etc.).

type TartBackend

type TartBackend struct {
	// contains filtered or unexported fields
}

TartBackend runs GitHub Actions runners as ephemeral Tart macOS VMs.

Lifecycle per runner:

  1. tart clone <baseImage> <name> — APFS CoW clone (< 1 sec)
  2. tart set <name> --cpu/--memory — configure VM resources (if specified)
  3. Set deterministic MAC address — prevent DHCP lease exhaustion
  4. tart run <name> --no-graphics — boot VM in background goroutine
  5. tart exec <name> true — poll until Guest Agent is ready
  6. tart exec <name> ... run.sh — start runner with JIT config
  7. tart stop + tart delete on removal

When poolSize > 0, VMs are pre-booted and kept ready in a pool. StartRunner picks a warm VM from the pool (near-instant) instead of cold-starting one (~30s). The pool is refilled in the background.

func NewTartBackend

func NewTartBackend(ss config.ScaleSetConfig, logger *slog.Logger) *TartBackend

NewTartBackend creates a TartBackend from scale set config.

func (*TartBackend) EnsureImage

func (b *TartBackend) EnsureImage(ctx context.Context) error

EnsureImage checks if the base image exists locally, and pulls it if not.

func (*TartBackend) RemoveRunner

func (b *TartBackend) RemoveRunner(ctx context.Context, resourceID string) error

RemoveRunner stops and deletes a Tart VM, releasing its VM slot.

func (*TartBackend) Shutdown

func (b *TartBackend) Shutdown(ctx context.Context)

Shutdown stops the warm pool and cleans up any idle VMs.

func (*TartBackend) StartPool

func (b *TartBackend) StartPool(ctx context.Context)

StartPool begins pre-warming VMs in the background. Call this after EnsureImage and before the listener starts.

func (*TartBackend) StartRunner

func (b *TartBackend) StartRunner(ctx context.Context, name string, jitConfig string) (string, error)

StartRunner starts a GitHub Actions runner in a Tart VM. If a warm pool is available, picks a pre-booted VM (near-instant). Otherwise, cold-starts a new VM (~30s).

Jump to

Keyboard shortcuts

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