stacksync

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 14, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package stacksync plans stacks from their opt-in git source and, only when the stack opts in, hands a changed plan to the stack apply path. It never writes back to git and never approves its own revision.

Index

Constants

View Source
const (
	EventPending = "stacks.sync_pending"
	EventFailed  = "stacks.sync_failed"
)

Event types the syncer emits.

View Source
const (
	TriggerQueued    = "queued"
	TriggerCoalesced = "coalesced"
)

Trigger outcomes: queued started a run, coalesced folded into the pending one.

Variables

This section is empty.

Functions

This section is empty.

Types

type Apply

type Apply func(ctx context.Context, rec store.StackSyncRecord, files []File, commit string) (ApplyOutcome, error)

Apply hands the documents of commit to the stack apply path. It answers the revision made, or PendingApproval when the stack needs a human approval.

type ApplyOutcome

type ApplyOutcome struct {
	Revision        int
	PendingApproval bool
}

ApplyOutcome is what one sync apply produced.

type CodedError

type CodedError struct {
	Code string
	Msg  string
	// Detail is a file:line at most, never a value from the repository.
	Detail string
}

CodedError carries a stable code; its message never holds repository content.

func (*CodedError) Error

func (e *CodedError) Error() string

type Emit

type Emit func(ctx context.Context, typ string, rec store.StackSyncRecord, st store.StackSyncStatus)

Emit sends one event; status carries codes and counts only.

type Fetch

type Fetch func(ctx context.Context, rec store.StackSyncRecord) (dir, commit string, cleanup func(), err error)

Fetch checks out the configured branch and returns its commit; cleanup removes the tree.

type File

type File struct {
	Name    string
	Content string
}

File is one document read from the checkout; Name is relative to the sync path.

func ReadTree

func ReadTree(root, rel string, lim Limits) ([]File, error)

ReadTree reads the documents under rel without following any symlink. A symlink anywhere on the path or under it refuses the whole sync.

type Limits

type Limits struct {
	Tick         time.Duration
	MinInterval  time.Duration
	FetchTimeout time.Duration
	MaxRepoBytes int64
	MaxFileBytes int64
	MaxFiles     int
	// MinFreeBytes refuses a fetch while the free disk is below it; 0 skips the probe.
	MinFreeBytes int64
}

Limits are read from runtime settings on every tick.

func DefaultLimits

func DefaultLimits() Limits

DefaultLimits mirror the registered setting defaults for callers without settings.

type Plan

type Plan func(ctx context.Context, rec store.StackSyncRecord, files []File) (iac.Plan, error)

Plan diffs the stack's documents against live state; it must not write.

type Store

type Store interface {
	ListEnabledStackSyncs(ctx context.Context) ([]store.StackSyncRecord, error)
	SetStackSyncStatus(ctx context.Context, stackID string, st store.StackSyncStatus) error
}

Store is the slice of the store the syncer needs.

type Syncer

type Syncer struct {
	Store Store
	Fetch Fetch
	Plan  Plan
	Emit  Emit
	// Apply is nil on a plan only control plane; a stack must also set apply.
	Apply Apply
	// FreeBytes probes the disk a fetch writes to; an error refuses the fetch.
	FreeBytes func(ctx context.Context) (int64, error)
	Limits    func(ctx context.Context) Limits
	Logger    *slog.Logger
	Now       func() time.Time
	// contains filtered or unexported fields
}

Syncer runs the loop only while at least one stack has sync enabled.

func (*Syncer) Busy

func (s *Syncer) Busy(stackID string) bool

Busy reports whether a triggered run of the stack is going or pending.

func (*Syncer) Kick

func (s *Syncer) Kick()

Kick starts the loop when it is not running; a no-op before Start.

func (*Syncer) Running

func (s *Syncer) Running() bool

Running reports whether the loop goroutine is alive.

func (*Syncer) Start

func (s *Syncer) Start(ctx context.Context)

Start records the lifetime context and starts the loop if any stack syncs.

func (*Syncer) SyncOne

SyncOne fetches, reads and plans one stack, stores the status and emits pending once per new commit and failed once per new code.

func (*Syncer) Trigger

func (s *Syncer) Trigger(rec store.StackSyncRecord, apply bool) string

Trigger syncs rec in the background and returns at once. apply false plans only; true applies when the stack itself sets apply. Triggers that arrive while a run is going collapse into one pending run, so a burst costs two.

Jump to

Keyboard shortcuts

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