maintenance

package
v1.3.6 Latest Latest
Warning

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

Go to latest
Published: Sep 12, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package maintenance — daily Hasura metadata backup cron registration.

Installs a system-level timer that calls `nself backup hasura-metadata` at 02:00 UTC every day. Uses systemd (Linux) or launchd (macOS).

Index

Constants

View Source
const DefaultPressureThreshold = 75

DefaultPressureThreshold is the disk-used percentage at/above which idle-shared cache reclaims run regardless of runner busy state. A full disk fails every job on the box anyway, so waiting for idle past this point is strictly worse than reclaiming now.

75, not 85, because this number has to keep a DIFFERENT check satisfied: `nself doctor --deep` fails the host with "Disk free: /: N% free (<20%)" at 80% used. An escalation threshold above that lets the box settle in a band where cleanup is content but doctor is red — which is exactly what happened on nSelf staging on 2026-09-11, where the dogfood gate failed on disk while the daily cleanup timer reported nothing to do. Escalating at 75 keeps the box under doctor's limit with headroom for one large job's working set.

Keep this BELOW the doctor host-disk threshold. If that check's limit moves, move this with it.

Variables

This section is empty.

Functions

func InstallDailyTimer

func InstallDailyTimer() error

InstallDailyTimer installs a system-level timer that runs disk-cleanup every day at 03:00 local time. On Linux it writes systemd unit files; on macOS it writes a LaunchDaemon plist. Returns an error if the required privileges are not available.

func InstallHasuraMetadataCron added in v1.0.14

func InstallHasuraMetadataCron() error

InstallHasuraMetadataCron installs a daily cron that runs Hasura metadata backup at 02:00 UTC. On Linux it writes systemd unit files; on macOS it writes a LaunchDaemon plist.

func RemoveDailyTimer

func RemoveDailyTimer() error

RemoveDailyTimer uninstalls the daily timer installed by InstallDailyTimer.

func RemoveHasuraMetadataCron added in v1.0.14

func RemoveHasuraMetadataCron() error

RemoveHasuraMetadataCron removes the timer installed by InstallHasuraMetadataCron.

Types

type CleanupResult

type CleanupResult struct {
	Before DiskUsage
	After  DiskUsage

	// DryRun is true when this result came from a dry-run — Reclaimed lists what
	// WOULD have been removed and Bytes are estimates; nothing was actually deleted.
	DryRun bool

	// BytesReclaimed is the total size of everything actually removed (0 for a
	// dry-run's real disk impact, but Reclaimed still lists the would-be total).
	BytesReclaimed int64
	Reclaimed      []ReclaimEntry
	Skipped        []SkipEntry

	DockerPruneOut   string
	LogRotationOut   string
	JournalVacuumOut string

	Errors []error
}

CleanupResult summarises what disk-cleanup did.

func DiskCleanup

func DiskCleanup() CleanupResult

DiskCleanup runs the full cleanup with default options: not a dry run, the default pressure threshold, real runner discovery, and $HOME for caches.

func DiskCleanupDryRun added in v1.3.6

func DiskCleanupDryRun() CleanupResult

DiskCleanupDryRun runs the full cleanup in dry-run mode: nothing is removed, but the returned CleanupResult's Reclaimed/Skipped/BytesReclaimed report exactly what a real run would have done and why anything was left alone.

func DiskCleanupWithOptions added in v1.3.6

func DiskCleanupWithOptions(opts DiskCleanupOptions) CleanupResult

DiskCleanupWithOptions runs disk-cleanup with explicit options. It never aborts early — it collects all errors/skips and reports at the end, tier by tier:

  1. tierAlways — docker dangling image/build-cache/anonymous-volume prune, old compressed log rotation, journald vacuum. Runs unconditionally.
  2. tierIdlePerRunner — GitHub Actions runner job workspace directories under "<root>/_work", one runner root at a time. Only runs for a runner root that isRunnerBusy reports idle; a busy runner's workspace is always left alone, pressure or not, because deleting an in-progress job's own checkout breaks that job outright.
  3. tierIdleShared — regenerable package/module caches (go build cache excluded — see protectedCacheSubpaths). Prefers every runner being idle, but runs anyway once disk usage is at/above PressureThreshold.

protectedRunnerSubdirs and protectedCacheSubpaths are excluded at every tier, unconditionally — see their doc comments in runner_posix.go for the incidents that made them hard exclusions rather than a "prefer not to" default.

type DiskCleanupOptions added in v1.3.6

type DiskCleanupOptions struct {
	// DryRun reports what would be removed and the space it would free, without
	// removing anything.
	DryRun bool
	// PressureThreshold is the disk-used percentage at/above which idle-shared
	// reclaims run even while a runner is busy. Zero means DefaultPressureThreshold.
	PressureThreshold int
	// Home overrides the home directory used to locate caches. Defaults to $HOME
	// (falling back to os.UserHomeDir()). Tests inject this to point at a fixture
	// tree instead of the real user's home.
	Home string
	// RunnerRoots overrides runner discovery. Tests inject this to point at fixture
	// runner trees instead of discovering real installs via systemd/globs.
	RunnerRoots []RunnerRoot
	// SharedCacheRoots overrides the absolute (non-home-relative) cache locations
	// considered for reclaim (default: sharedCacheRoots, e.g. "/opt/pnpm-store").
	// Tests set this to an empty (non-nil) slice to guarantee nothing outside a
	// fixture tree is ever touched; nil means "use the default list".
	SharedCacheRoots []string
	// UsageOverride, when non-nil, is used instead of calling GetDiskUsage() for the
	// "before" reading that pressure-escalation compares against threshold. Tests use
	// this for deterministic threshold behavior instead of depending on the test
	// machine's real, unpredictable disk usage.
	UsageOverride *DiskUsage
}

DiskCleanupOptions configures a DiskCleanup run.

type DiskUsage

type DiskUsage struct {
	// UsedPercent is the percentage of the disk that is in use (0-100).
	UsedPercent int
	// TotalGB is the total disk capacity in gigabytes.
	TotalGB float64
	// UsedGB is the used disk space in gigabytes.
	UsedGB float64
	// FreeGB is the free disk space in gigabytes.
	FreeGB float64
}

DiskUsage holds before/after disk utilisation for a cleanup run.

func GetDiskUsage

func GetDiskUsage() (DiskUsage, error)

GetDiskUsage returns current disk utilisation for the root filesystem ("/").

type HasuraMetadataCronStatus added in v1.0.14

type HasuraMetadataCronStatus struct {
	Enabled  bool
	Platform string
	Detail   string
}

HasuraMetadataCronStatus reports the state of the Hasura metadata backup timer.

func GetHasuraMetadataCronStatus added in v1.0.14

func GetHasuraMetadataCronStatus() HasuraMetadataCronStatus

GetHasuraMetadataCronStatus returns the current status of the Hasura metadata backup timer.

type ReclaimEntry added in v1.3.6

type ReclaimEntry struct {
	Path  string
	Bytes int64
	Tier  reclaimTier
}

ReclaimEntry records one thing DiskCleanup removed (or, in dry-run mode, would remove).

type RunnerRoot added in v1.3.6

type RunnerRoot struct {
	// Name is the systemd unit name when discovered via systemd, or the directory
	// basename when discovered via the fallback glob list.
	Name string
	// Path is the runner's install directory (what the runner config calls "work
	// folder parent" — it contains _work, _diag, bin, etc.).
	Path string
}

RunnerRoot describes one discovered GitHub Actions self-hosted runner install.

type ScheduleStatus

type ScheduleStatus struct {
	Enabled  bool
	Platform string
	Detail   string
}

ScheduleStatus reports the current state of the daily timer.

func GetScheduleStatus

func GetScheduleStatus() ScheduleStatus

GetScheduleStatus returns the current status of the daily cleanup timer.

type SkipEntry added in v1.3.6

type SkipEntry struct {
	Path   string
	Reason string
}

SkipEntry records one thing DiskCleanup deliberately left alone, and why. This is what makes a `disk-cleanup` timer run diagnosable after the fact — "ran and found nothing to do" and "refused to touch anything because everything was busy" used to be indistinguishable in the log.

Jump to

Keyboard shortcuts

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