housekeeping

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package housekeeping is the housekeeping service: the default cron triggers that keep a harness host's disk and state healthy. Each trigger is one operation of a Housekeeper, mounted with the cron service, and every operation obeys one ownership rule: it deletes only what the harness records as created by a session that has ended, plus the Docker classes the docker trigger names (exited runner containers, dangling images, the build cache) and the database dumps the backup trigger itself wrote beyond their derived retention. Paths are never matched by pattern; anything the harness cannot attribute to an ended session is reported as a finding with its size and survives. Volumes and running containers are never touched. Two triggers keep state rather than reclaim disk: database_backup dumps the database the host owns, and live_checkout fast-forwards the Workbench's widgets checkout, never resetting anything.

The service crosses no boundary itself: it reads through the file capability (the state directory and the process table), runs programs through the process capability and reaches the Docker Engine through the container capability. Every deletion is logged with its path, size and owning session before it happens and recorded afterwards as a typed Record through the sink the binary grants.

Index

Constants

View Source
const (
	// TriggerDiskFloor measures free disk every five minutes and, below the
	// derived floor, reclaims until it is above it.
	TriggerDiskFloor = "housekeeping.disk_floor"
	// TriggerSessions reclaims what ended sessions left, every 15 minutes.
	TriggerSessions = "housekeeping.sessions"
	// TriggerDocker removes the Docker leftovers it names, hourly.
	TriggerDocker = "housekeeping.docker"
	// TriggerSharedCache trims the shared Bazel disk cache daily at 04:30.
	TriggerSharedCache = "housekeeping.shared_cache"
	// TriggerDatabaseBackup dumps the database the host owns, hourly.
	TriggerDatabaseBackup = "housekeeping.database_backup"
	// TriggerLiveCheckout fast-forwards the live checkout every minute.
	TriggerLiveCheckout = "housekeeping.live_checkout"
	// ScheduleLocation is the time zone the triggers are declared in.
	ScheduleLocation = "America/Los_Angeles"
)

The default triggers, as csfcron declares them.

View Source
const (
	// RunnerContainerPrefix names the CI runner containers whose exited
	// leftovers are removed.
	RunnerContainerPrefix = "candace-docker-runner"
)

The Docker classes the docker trigger removes, and nothing else.

Variables

View Source
var (
	// ErrInvalidOption reports a nil option or a value the service cannot use.
	ErrInvalidOption = errors.New("housekeeping: invalid option")
	// ErrMissingCapability reports a housekeeper built without a required
	// capability.
	ErrMissingCapability = errors.New("housekeeping: a required capability is missing")
	// ErrUnknownTrigger reports a Run of a trigger this service does not
	// declare.
	ErrUnknownTrigger = errors.New("housekeeping: unknown trigger")
	// ErrBelowFloor reports a disk_floor occurrence that ended with free disk
	// still below the floor.
	ErrBelowFloor = errors.New("housekeeping: free disk is below the floor")
)

Functions

This section is empty.

Types

type Housekeeper

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

Housekeeper runs the housekeeping operations. It holds no state between occurrences: each one measures the host again.

func NewHousekeeper

func NewHousekeeper(options ...HousekeeperOption) (*Housekeeper, error)

NewHousekeeper validates the whole option set and returns the service. The state directory, session list, launcher, containers, process table and record sink are required.

func (*Housekeeper) DatabaseBackup added in v0.3.0

func (housekeeper *Housekeeper) DatabaseBackup(ctx context.Context, occurrence cronservice.Occurrence) error

DatabaseBackup dumps the database this host owns into <state>/backups with pg_dump, run inside its container, and then keeps only as many dumps as the derived retention allows, newest first. A host whose database is someone else's (no <state>/database.json) has nothing to back up.

func (*Housekeeper) DiskFloor

func (housekeeper *Housekeeper) DiskFloor(ctx context.Context, occurrence cronservice.Occurrence) error

DiskFloor measures free disk against the derived floor. Below it, it holds the harness's admission and runs the reclaim steps in order (the sessions, Docker, the shared cache), measuring again after each, until free disk is above the floor; it releases admission once it is.

func (*Housekeeper) Docker

func (housekeeper *Housekeeper) Docker(ctx context.Context, occurrence cronservice.Occurrence) error

Docker removes the exited CI runner containers, the dangling images and the unused build cache. It never removes a volume (the capability it is granted has no volume operation), a running container or an image a container uses.

func (*Housekeeper) LiveCheckout added in v0.3.0

func (housekeeper *Housekeeper) LiveCheckout(ctx context.Context, occurrence cronservice.Occurrence) error

LiveCheckout fast-forwards the checkout the Workbench installs widgets from to origin/main, so a merged widget appears with nobody pulling. It only ever fast-forwards: a checkout on another branch, one whose main has commits origin/main lacks, or one whose local changes the fast-forward would overwrite is left exactly as it is and recorded as a finding.

func (*Housekeeper) Run

func (housekeeper *Housekeeper) Run(ctx context.Context, trigger string) error

Run invokes one trigger's operation once, outside the scheduler, as a manual occurrence.

func (*Housekeeper) Sessions

func (housekeeper *Housekeeper) Sessions(ctx context.Context, occurrence cronservice.Occurrence) error

Sessions reclaims what each ended session left: its leftover processes, its worktree, its Bazel output base and the branch of its merged or closed pull request. Everything else in the state directory, and every entry of a granted scratch directory, is reported as a finding.

func (*Housekeeper) SharedCache

func (housekeeper *Housekeeper) SharedCache(ctx context.Context, occurrence cronservice.Occurrence) error

SharedCache trims the shared Bazel disk cache to its derived size, oldest entries first.

func (*Housekeeper) Triggers

func (housekeeper *Housekeeper) Triggers() ([]cronservice.Option, error)

Triggers declares the default triggers for the cron service, in ScheduleLocation: live_checkout only with WithLiveCheckout.

type HousekeeperOption

type HousekeeperOption func(housekeeper *Housekeeper) error

HousekeeperOption configures a Housekeeper.

func WithAdmission

func WithAdmission(admission IAdmission) HousekeeperOption

WithAdmission grants the harness's admission, which disk_floor holds while free disk is below the floor.

func WithClock

func WithClock(source clock.IClock) HousekeeperOption

WithClock replaces the host's clock, which stamps every record.

func WithContainers

func WithContainers(containers IContainers) HousekeeperOption

WithContainers grants the container capability. Required.

func WithDryRun

func WithDryRun() HousekeeperOption

WithDryRun measures and records the plan without deleting anything or holding admission.

func WithLauncher

func WithLauncher(launcher proc.ILauncher) HousekeeperOption

WithLauncher grants the process capability. Required.

func WithLiveCheckout added in v0.3.0

func WithLiveCheckout(directory string) HousekeeperOption

WithLiveCheckout names a directory of the checkout live_checkout keeps fast-forwarded to origin/main; without it that trigger is not declared.

func WithLogger

func WithLogger(logger *slog.Logger) HousekeeperOption

WithLogger receives the line logged before every deletion.

func WithProcessTable

func WithProcessTable(processes IProcessTable) HousekeeperOption

WithProcessTable grants the process table. Required.

func WithRecordSink

func WithRecordSink(sink RecordSink) HousekeeperOption

WithRecordSink grants where records go. Required.

func WithSandboxImage

func WithSandboxImage(image string) HousekeeperOption

WithSandboxImage names the image the root-owned remainder of an output base is removed in, through a container that mounts only that path.

func WithScratch

func WithScratch(directory string, files iofs.IFiles) HousekeeperOption

WithScratch grants a scratch directory whose entries the sessions trigger reports, with their sizes, as findings. Nothing in it is ever deleted.

func WithSessions

func WithSessions(list SessionList) HousekeeperOption

WithSessions grants the harness's session list. Required.

func WithState

func WithState(directory string, files iofs.IFiles) HousekeeperOption

WithState grants the harness state directory: its absolute path, for the programs that measure and remove, and read access to it.

type IAdmission

type IAdmission interface {
	HoldAdmission(reason string)
	ReleaseAdmission()
}

IAdmission is the harness's session admission: held while free disk is below the floor, so no new session starts on a full disk.

type IContainers

IContainers is the part of the container capability housekeeping uses. It has no volume operation, so no trigger can remove a volume.

type IProcessTable

type IProcessTable interface {
	iofs.IFiles
	ReadLink(name string) (string, error)
}

IProcessTable is the host's process table, granted as /proc.

type Kind

type Kind string

Kind is what a deletion removed, or what a finding is about.

const (
	KindWorktree        Kind = "worktree"
	KindBazelOutputBase Kind = "bazel_output_base"
	KindBranch          Kind = "branch"
	KindProcess         Kind = "process"
	KindRunnerContainer Kind = "runner_container"
	KindDanglingImages  Kind = "dangling_images"
	KindBuildCache      Kind = "build_cache"
	KindSharedCache     Kind = "shared_cache_entries"
	KindBackup          Kind = "database_backup"
	// KindLiveCheckout is a live checkout that could not be fast-forwarded.
	KindLiveCheckout Kind = "live_checkout"
)

type Record

type Record struct {
	Time       time.Time  `json:"time"`
	Type       RecordType `json:"type"`
	Trigger    string     `json:"trigger"`
	Occurrence string     `json:"occurrence"`
	Kind       Kind       `json:"kind,omitempty"`
	What       string     `json:"what"`
	Session    string     `json:"owner_session,omitempty"`
	Bytes      uint64     `json:"bytes"`
	DryRun     bool       `json:"dry_run,omitempty"`
	Detail     string     `json:"detail,omitempty"`
}

Record is one typed receipt in the harness state directory: a deletion, a finding or a floor measurement, with the trigger and occurrence that wrote it.

type RecordSink

type RecordSink func(record Record) error

RecordSink receives every record an operation writes.

type RecordType

type RecordType string

RecordType says what a Record reports.

const (
	// RecordDeletion is one deletion, or in a dry run one planned deletion:
	// Bytes is what it freed.
	RecordDeletion RecordType = "deletion"
	// RecordFinding is something measured and left because the harness
	// cannot attribute it to an ended session: Bytes is what it holds.
	RecordFinding RecordType = "finding"
	// RecordFloor is a disk_floor measurement: Bytes is the free disk and
	// Detail the floor's derivation.
	RecordFloor RecordType = "floor"
	// RecordBackup is one database dump written: What is its path and Bytes
	// its size.
	RecordBackup RecordType = "backup"
	// RecordRetention is how many dumps are kept: Bytes is the count and
	// Detail its derivation.
	RecordRetention RecordType = "retention"
	// RecordFastForward is the live checkout moved to origin/main: Detail is
	// the old..new range.
	RecordFastForward RecordType = "fast_forward"
)

type SessionList

type SessionList func(ctx context.Context) (*harnessv1.ListAgentSessionsResponse, error)

SessionList reports the harness's sessions and the process they run in: the session service's List in the host, its client elsewhere.

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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