config

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package config defines the multirunner configuration schema and loader.

Index

Constants

View Source
const ExamplePoolYAML = `` /* 139-byte string literal not displayed */

ExamplePoolYAML is the smallest pool that validates. It is shown in the error a config without pools produces, where a short, paste-ready answer beats a tour of the schema.

Variables

This section is empty.

Functions

func EnsureStarterPool

func EnsureStarterPool(path, dockerHost, architecture string, osType ...string) (bool, error)

EnsureStarterPool appends a working first pool to a config that has none, and reports whether it added one. connect otherwise writes credentials only, which leaves a config that cannot run; a live pool means the next command does something, and its comments name the options so nothing has to be looked up.

dockerHost is the endpoint the caller discovered on this machine. It is passed in rather than probed here so this package keeps no opinion about daemons.

func FallbackDockerHost

func FallbackDockerHost() string

FallbackDockerHost is the endpoint written when nothing on this host answered a probe: the named pipe Docker Desktop and Podman expose on Windows, the daemon socket everywhere else. It is a placeholder to edit, not a claim - `multirunner doctor` reports whether it is reachable.

func PoolsYAML

func PoolsYAML(dockerHost, architecture string, daemonOS ...string) string

PoolsYAML is the pool connect writes into a config that has none. It is a live, valid pool rather than a commented template: a config that loads is a better starting point than one the reader has to assemble. dockerHost is the endpoint discovery actually found on this machine; an empty value falls back to the platform default for the reader to correct.

func WriteAppAuth

func WriteAppAuth(path string, scope Scope, owner, repo string, appID, installationID int64, keyPath string) error

WriteAppAuth updates (or creates) a config file's github + auth sections to use GitHub App credentials, preserving other content and comments. Any existing auth.pat is removed.

func WriteDeviceAuth

func WriteDeviceAuth(path string, scope Scope, owner, repo, clientID, tokenPath string) error

WriteDeviceAuth updates (or creates) a config file's github + auth sections to use GitHub App device-flow credentials: a client id and a token-store path. Any existing auth.pat and installation-App keys (app_id, installation_id, private_key_path) are removed, since a user access token supersedes them.

Types

type Auth

type Auth struct {
	PAT            string `yaml:"pat"`
	AppID          int64  `yaml:"app_id"`
	InstallationID int64  `yaml:"installation_id"`
	PrivateKeyPath string `yaml:"private_key_path"`
	// ClientID is the GitHub App client id for the device-flow user token; empty
	// means the shared App's default (ghapp.DefaultClientID). Not a secret.
	ClientID string `yaml:"client_id"`
	// TokenPath points at the JSON sidecar holding the device-flow user access
	// and refresh tokens. Tokens rotate on refresh, so they live here, never in
	// the YAML.
	TokenPath string `yaml:"token_path"`
}

Auth holds a PAT, GitHub App installation credentials, or a GitHub App device-flow user token. PAT takes precedence when set.

func (Auth) IsApp

func (a Auth) IsApp() bool

IsApp reports whether GitHub App installation auth is configured.

func (Auth) IsDeviceApp

func (a Auth) IsDeviceApp() bool

IsDeviceApp reports whether GitHub App device-flow (user token) auth is configured: no PAT, no installation App id, and a token store path.

type CPUCount

type CPUCount int64

CPUCount is an integer number of virtual CPUs.

func (*CPUCount) UnmarshalYAML

func (c *CPUCount) UnmarshalYAML(node *yaml.Node) error

UnmarshalYAML rejects fractional and string CPU values.

type Cache

type Cache struct {
	Enabled             bool   `yaml:"enabled"`
	Mode                string `yaml:"mode"` // local-server | off
	Storage             string `yaml:"storage"`
	Path                string `yaml:"path"`
	Listen              string `yaml:"listen"`
	AdvertiseURL        string `yaml:"advertise_url"` // URL of this cache as seen from inside runner containers
	ExternalURL         string `yaml:"external_url"`  // if set, use an already-running cache here instead of starting the embedded server
	AccessToken         string `yaml:"access_token"`  // optional shared path token for cache API URLs; generated when omitted
	SkipTokenValidation bool   `yaml:"skip_token_validation"`
	Upstream            string `yaml:"upstream"`
	// Housekeeping (garbage collection of stored entries):
	MaxAgeDays    int `yaml:"max_age_days"`    // evict entries unused this many days (0 => default; <0 => never)
	MaxSizeGB     int `yaml:"max_size_gb"`     // LRU-evict to keep total blob size under this cap (0 => unlimited)
	GCIntervalSec int `yaml:"gc_interval_sec"` // sweep cadence (0 => default 3600; <0 => disabled)
}

Cache configures the self-hosted cache server.

type Config

type Config struct {
	GitHub       GitHub       `yaml:"github"`
	Auth         Auth         `yaml:"auth"`
	Provisioning Provisioning `yaml:"provisioning"`
	Cache        Cache        `yaml:"cache"`
	GitCache     GitCache     `yaml:"git_cache"`
	Webhook      Webhook      `yaml:"webhook"`
	Metrics      Metrics      `yaml:"metrics"`
	Pools        []Pool       `yaml:"pools"`
	Log          Log          `yaml:"log"`
}

Config is the root configuration.

func Load

func Load(path string) (*Config, error)

Load reads and validates a YAML config file, applying defaults.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks required fields and cross-field consistency.

func (*Config) Warnings

func (c *Config) Warnings() []string

Warnings returns non-fatal configuration smells worth surfacing at startup. Unlike Validate (which rejects broken configs), these are settings that are silently ineffective — e.g. an image flavor on a QEMU pool, which boots a baked golden image and ignores image/image_tier entirely.

type ConnectHints

type ConnectHints struct {
	Provisioning  Provisioning
	WebhookListen string
	GitHubURL     string
	Pools         int
}

ConnectHints holds the fields `multirunner connect` reads from an existing config to shape the GitHub App manifest.

func ReadConnectHints

func ReadConnectHints(path string) (hints ConnectHints, ok bool)

ReadConnectHints reads provisioning and webhook.listen from an existing config without validating it. A missing or unparseable file yields the zero value and ok=false, so connect can fall back to safe defaults rather than failing.

type ContainerConfig

type ContainerConfig struct {
	CPUs         CPUCount  `yaml:"cpus"`
	MemoryMB     Mebibytes `yaml:"memory_mb"`
	MemorySwapMB Mebibytes `yaml:"memory_swap_mb"`
	DNS          []string  `yaml:"dns"`
}

ContainerConfig limits each container runner. MemorySwapMB is the total memory plus swap limit used by Docker, so setting it equal to MemoryMB disables swap. Zero values leave the backend defaults unchanged.

func (ContainerConfig) MemoryBytes

func (c ContainerConfig) MemoryBytes() int64

MemoryBytes returns the normalized container memory limit.

func (ContainerConfig) MemorySwapBytes

func (c ContainerConfig) MemorySwapBytes() int64

MemorySwapBytes returns the normalized total memory plus swap limit.

func (ContainerConfig) NanoCPUs

func (c ContainerConfig) NanoCPUs() int64

NanoCPUs returns the Linux Docker CPU quota representation.

type Containerd

type Containerd struct {
	Address   string `yaml:"address"`   // containerd pipe (default \\.\pipe\containerd-containerd)
	Nerdctl   string `yaml:"nerdctl"`   // path to nerdctl.exe ("" => from PATH)
	Namespace string `yaml:"namespace"` // containerd namespace (default "multirunner")
	Isolation string `yaml:"isolation"` // process | hyperv | auto (default)
}

Containerd configures the containerd/runhcs Windows-container backend. The runner is launched via nerdctl; isolation auto-detects (process on Server, hyperv on client) when left empty.

type Docker

type Docker struct {
	Host           string    `yaml:"host"`
	TLS            DockerTLS `yaml:"tls"`
	EnableDinD     bool      `yaml:"enable_dind"`
	ShareWorkspace bool      `yaml:"share_workspace"`
	Isolation      string    `yaml:"isolation"`    // process | hyperv | auto (default, windows)
	WindowsDinD    string    `yaml:"windows_dind"` // off | host-pipe | hyperv
}

Docker configures a pool's backend daemon.

type DockerTLS

type DockerTLS struct {
	CAFile   string `yaml:"ca"`
	CertFile string `yaml:"cert"`
	KeyFile  string `yaml:"key"`
}

DockerTLS configures mutual-TLS client authentication for a Docker endpoint.

type GitCache

type GitCache struct {
	Mode string `yaml:"mode"` // mirror | dotgit-cache | off
	Path string `yaml:"path"`
	// MaxAgeDays removes bare mirrors not used (cloned/fetched/bundled) within
	// this many days. 0 => use the default; negative => never prune.
	MaxAgeDays int `yaml:"max_age_days"`
}

GitCache configures the host-resident bare-mirror git cache.

  • mirror: bind-mount the bare mirror into the runner (Docker/containers).
  • dotgit-cache: serve the mirror as a git bundle over the cache server; a runner job-started hook seeds the workspace from it so checkout fetches only the delta. Works where mounts can't (the QEMU VM), riding the cache server.

func (GitCache) DotGit

func (g GitCache) DotGit() bool

DotGit reports whether the bundle-over-cache-server mode is selected.

func (GitCache) Enabled

func (g GitCache) Enabled() bool

Enabled reports whether any git mirror cache is active (both modes maintain a host bare mirror).

type GitHub

type GitHub struct {
	URL   string   `yaml:"url"`
	Scope Scope    `yaml:"scope"`
	Owner string   `yaml:"owner"`
	Repo  string   `yaml:"repo"`
	Repos []string `yaml:"repos"` // only for scope=repos: "repo" or "owner/repo"
}

GitHub identifies the target and scope.

func (GitHub) RepoTargets

func (gh GitHub) RepoTargets() []RepoRef

RepoTargets returns the concrete repositories available to repository-level diagnostics for both singular and plural repository scopes.

func (GitHub) ResolvedRepos

func (gh GitHub) ResolvedRepos() []RepoRef

ResolvedRepos returns each repos entry parsed into owner/repo pairs.

type Log

type Log struct {
	Level  string `yaml:"level"`
	Format string `yaml:"format"`
}

Log configures logging output.

type Mebibytes

type Mebibytes int64

Mebibytes is an integer memory quantity in 1,048,576-byte units.

func (*Mebibytes) UnmarshalYAML

func (m *Mebibytes) UnmarshalYAML(node *yaml.Node) error

UnmarshalYAML rejects fractional and string memory values.

type Metrics

type Metrics struct {
	Listen string `yaml:"listen"` // empty disables it
}

Metrics configures the Prometheus metrics + health endpoint.

type Pool

type Pool struct {
	Name                   string          `yaml:"name"`
	OS                     string          `yaml:"os"`      // linux | windows
	Backend                string          `yaml:"backend"` // docker (default) | containerd | qemu
	Size                   int             `yaml:"size"`
	ImageTier              string          `yaml:"image_tier"`
	Image                  string          `yaml:"image"`
	Container              ContainerConfig `yaml:"container"`
	QEMU                   QEMU            `yaml:"qemu"`
	Containerd             Containerd      `yaml:"containerd"`
	RunnerGroupID          int64           `yaml:"runner_group_id"`
	Labels                 []string        `yaml:"labels"`
	Repository             string          `yaml:"repository"`
	Workflows              []string        `yaml:"workflows"`
	WorkflowEvent          string          `yaml:"workflow_event"`
	WorkflowActor          string          `yaml:"workflow_actor"`
	WorkflowRef            string          `yaml:"workflow_ref"`
	WorkFolder             string          `yaml:"work_folder"`
	NamePrefix             string          `yaml:"name_prefix"`
	Docker                 Docker          `yaml:"docker"`
	ToolCache              ToolCache       `yaml:"tool_cache"`
	MaxConsecutiveFailures int             `yaml:"max_consecutive_failures"`
	// ScaleSet names the runner scale set that feeds this pool when
	// provisioning is "scaleset". Each pool needs its own, because a scale set
	// carries one set of labels and therefore one runner OS.
	ScaleSet string `yaml:"scale_set"`
	// RunnerGroup is the runner group the scale set is created in. Empty means
	// the default group.
	RunnerGroup string `yaml:"runner_group"`
}

Pool is one per-OS pool of ephemeral runner slots.

func (Pool) CanServeJob

func (p Pool) CanServeJob(target, workflow, event, actor, ref string) bool

CanServeJob applies the optional repository and workflow authorization tuple.

func (Pool) CanServeRepository

func (p Pool) CanServeRepository(target string) bool

CanServeRepository reports whether this pool may register a runner to target. An empty binding preserves the existing all-configured-repositories behavior.

func (Pool) DockerSocketPath

func (p Pool) DockerSocketPath() string

DockerSocketPath is the in-container docker socket path for DinD.

func (Pool) ImageRef

func (p Pool) ImageRef() string

ImageRef resolves the container image for a pool, in priority order:

  • an explicit image: wins outright;
  • tier "" / "minimal" -> the published :latest base image;
  • a known published flavor -> the published :<flavor> tag;
  • any other tier -> a local multirunner/runner-<os>-<tier>:dev build.

func (Pool) SharedWorkspacePath

func (p Pool) SharedWorkspacePath() string

SharedWorkspacePath is the runner work directory as seen by both the runner container and its Docker daemon.

func (Pool) ToolCachePath

func (p Pool) ToolCachePath() string

ToolCachePath is the hostedtoolcache directory for the pool's OS.

type Provisioning

type Provisioning string

Provisioning selects how runner slots are triggered.

const (
	ProvisioningPool      Provisioning = "pool"
	ProvisioningAutoscale Provisioning = "autoscale"
	ProvisioningWebhook   Provisioning = "webhook" // alias for autoscale (kept for compatibility)
	// ProvisioningScaleset lets GitHub drive capacity through a runner scale
	// set. Unlike pool and autoscale, the decision is not made here: a
	// long-poll session reports the desired runner count, which is the same
	// mechanism actions-runner-controller uses.
	ProvisioningScaleset Provisioning = "scaleset"
)

func (Provisioning) IsAutoscale

func (p Provisioning) IsAutoscale() bool

IsAutoscale reports whether the provisioning mode scales on demand.

func (Provisioning) IsScaleset

func (p Provisioning) IsScaleset() bool

IsScaleset reports whether GitHub drives capacity through a scale set.

type QEMU

type QEMU struct {
	Golden  string `yaml:"golden"`   // path to the golden qcow2 (built by `multirunner bake`)
	WorkDir string `yaml:"work_dir"` // where per-job overlays/ISOs are written
	MemMB   int    `yaml:"mem_mb"`
	CPUs    int    `yaml:"cpus"`
	Accel   string `yaml:"accel"` // "" = auto (hardware acceleration on x86-64; TCG on ARM)
	// Housekeeping (golden eval license + rebuilds):
	BakeISO       string   `yaml:"bake_iso"`        // Windows ISO for rebuilds (enables auto-rebuild)
	BakeISOSHA256 string   `yaml:"bake_iso_sha256"` // optional expected SHA256 of bake_iso
	RunnerVersion string   `yaml:"runner_version"`  // runner version to bake
	RunnerSHA256  string   `yaml:"runner_sha256"`   // required with a non-default runner_version
	Licensed      bool     `yaml:"licensed"`        // real key/KMS -> skip eval housekeeping
	Tools         []string `yaml:"tools"`           // golden selectors: dotnet[:major] | node[:major] | go | buildtools[:line]
}

QEMU configures the x86-64 Windows VM backend.

type RepoRef

type RepoRef struct {
	Owner string
	Repo  string
}

RepoRef is a resolved owner/repo pair from the repos list.

func ParseRepoRef

func ParseRepoRef(entry, defaultOwner string) RepoRef

ParseRepoRef splits a repos entry into owner and repo. If the entry contains a slash, it is treated as "owner/repo". Otherwise the default owner is used.

type Scope

type Scope string

Scope is the GitHub level a runner registers against.

const (
	ScopeRepo       Scope = "repo"
	ScopeRepos      Scope = "repos"
	ScopeOrg        Scope = "org"
	ScopeEnterprise Scope = "enterprise"
)

type ToolCache

type ToolCache struct {
	Mode     string `yaml:"mode"` // shared-volume | off
	Volume   string `yaml:"volume"`
	ReadOnly bool   `yaml:"readonly"`
}

ToolCache configures hostedtoolcache sharing.

type Webhook

type Webhook struct {
	Listen          string `yaml:"listen"`
	Path            string `yaml:"path"`
	Secret          string `yaml:"secret"`
	PollIntervalSec int    `yaml:"poll_interval_sec"` // 0 = default 300s; <0 disables polling
}

Webhook configures the workflow_job webhook receiver (provisioning: webhook).

Jump to

Keyboard shortcuts

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