runner

package
v1.0.7 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package-level error helpers for runner. These classify ECS RunTask errors into "transient capacity" (worth backing off and retrying) vs everything else (config, IAM, quota -- surface unchanged).

Package runner provides ECS task management for GitHub Actions runners. It defines a TaskRunner interface for testability and an ECS implementation that creates, stops, and lists runner tasks.

Index

Constants

This section is empty.

Variables

View Source
var ErrTransientCapacity = errors.New("ecs: transient capacity unavailable")

ErrTransientCapacity wraps RunTask failures attributed to ECS capacity exhaustion or upstream throttling. Callers detect it with errors.Is and engage a backoff before the next attempt.

Functions

This section is empty.

Types

type ECSClient

type ECSClient interface {
	RunTask(ctx context.Context, input *ecs.RunTaskInput, opts ...func(*ecs.Options)) (*ecs.RunTaskOutput, error)
	StopTask(ctx context.Context, input *ecs.StopTaskInput, opts ...func(*ecs.Options)) (*ecs.StopTaskOutput, error)
	ListTasks(ctx context.Context, input *ecs.ListTasksInput, opts ...func(*ecs.Options)) (*ecs.ListTasksOutput, error)
	DescribeTasks(ctx context.Context, input *ecs.DescribeTasksInput, opts ...func(*ecs.Options)) (*ecs.DescribeTasksOutput, error)
}

ECSClient is the subset of the ECS API that the runner package needs.

type ECSRunner

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

ECSRunner manages ECS tasks for GitHub Actions runners.

func NewECSRunner

func NewECSRunner(client ECSClient, cluster string, logger *slog.Logger) *ECSRunner

NewECSRunner creates a new ECSRunner.

func (*ECSRunner) RunTask

func (r *ECSRunner) RunTask(ctx context.Context, input RunTaskInput) (string, error)

RunTask creates a new ECS task for a GitHub Actions runner. It sets the ACTIONS_RUNNER_INPUT_JITCONFIG environment variable so the runner binary can authenticate without a separate registration step.

func (*ECSRunner) StopTask

func (r *ECSRunner) StopTask(ctx context.Context, taskARN, reason string) error

StopTask stops an ECS task with a reason.

type Reaper

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

Reaper periodically checks for stale runner tasks and stops them. It handles two cases:

  • Tasks stuck in PENDING state beyond the pending timeout
  • Tasks running longer than the configured max runtime

func NewReaper

func NewReaper(
	client ECSClient,
	ssClient ScaleSetClient,
	cluster, scaleSetName string,
	maxRuntime, pendingTimeout time.Duration,
	state *State,
	logger *slog.Logger,
) *Reaper

NewReaper creates a new Reaper.

func (*Reaper) Run

func (r *Reaper) Run(ctx context.Context, interval time.Duration)

Run starts the reaper loop, sweeping on the given interval until the context is cancelled.

func (*Reaper) Sweep

func (r *Reaper) Sweep(ctx context.Context) (int, error)

Sweep checks all tasks for this scale set and stops stale ones. Returns the number of tasks stopped.

type RunTaskInput

type RunTaskInput struct {
	TaskDefinition   string
	JITConfigEncoded string
	RunnerName       string
	ScaleSetName     string
	Subnets          []string
	SecurityGroups   []string
	CapacityProvider string
	LaunchType       ecsTypes.LaunchType
}

RunTaskInput holds the parameters for creating a new runner ECS task.

type ScaleSetClient added in v1.0.7

type ScaleSetClient interface {
	GetRunnerByName(ctx context.Context, name string) (*scaleset.RunnerReference, error)
	RemoveRunner(ctx context.Context, runnerID int64) error
}

ScaleSetClient is the subset of the scaleset API the Reaper uses to deregister GitHub runner registrations when the ECS task they back has stopped. It is a local copy of the interface shape used by internal/scaler, duplicated to avoid an import cycle.

type State

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

State tracks runner tasks and their lifecycle (idle -> busy -> done). It is safe for concurrent use.

func NewState

func NewState() *State

NewState creates a new empty State.

func (*State) AddIdle

func (s *State) AddIdle(name, taskARN string)

AddIdle registers a new runner as idle.

func (*State) Count

func (s *State) Count() int

Count returns the total number of tracked runners (idle + busy).

func (*State) IdleCount

func (s *State) IdleCount() int

IdleCount returns the number of idle runners.

func (*State) IsDeregistered added in v1.0.7

func (s *State) IsDeregistered(name string) bool

IsDeregistered reports whether name was recently marked deregistered. It prunes expired entries as a side effect.

func (*State) MarkBusy

func (s *State) MarkBusy(name string)

MarkBusy transitions a runner from idle to busy.

func (*State) MarkDeregistered added in v1.0.7

func (s *State) MarkDeregistered(name string)

MarkDeregistered records that name has been successfully deregistered on the GitHub side. Subsequent IsDeregistered calls return true until the entry expires after deregisteredTTL.

func (*State) MarkDone

func (s *State) MarkDone(name string) string

MarkDone removes a runner from tracking entirely, returning its task ARN. Returns empty string if the runner is unknown.

Jump to

Keyboard shortcuts

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