Help us shape the future of Go! Take the 2026 Go Developer Survey

deployplan

package
v0.9.0 Latest Latest
Warning

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

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

Documentation

Overview

Package deployplan decides what one pod has to do to reach a render: run runtime ops, write files only, or reload. It compares two renderplan.Plans and composes typed agent ops; it is pure data in, data out — no I/O, no controller imports and no HAProxy configuration parsing — so every rule is table tested and the playground runs the same code in a browser.

Index

Constants

View Source
const (
	// MaxChunks bounds execution batches within one agent transaction.
	MaxChunks = api.MaxOpBatches
	// MaxReasons caps the reason list, which ships in status and logs.
	MaxReasons = 32
)

Variables

This section is empty.

Functions

func ComposedOps

func ComposedOps() []string

ComposedOps returns the op kinds this controller composes — the set an agent is measured against before it is sent anything.

func Files

func Files(p *renderplan.Plan) []api.File

Files projects a plan's file set onto the wire type.

func InventoryOf

func InventoryOf(p *renderplan.Plan) api.Inventory

InventoryOf projects what a worker that reloaded this plan would report as loaded. It answers "what would this pod be", which is what an offline comparison of two renders — `haptic diff` between two configurations, the playground's verdict — has instead of a pod. A live diff always uses the inventory the pod itself reported: a file the render declares is not proof the worker loaded it.

Types

type Baseline

type Baseline struct {
	Applied      *renderplan.Plan // the plan the pod ACKed; nil means unknown
	AppliedIndex *Index           // Applied's index when the caller keeps one
	Running      *renderplan.Plan // what the worker runs; equals Applied without a pending reload
	WorkerOps    *renderplan.Plan // Running plus the in-place ops accepted since
	Inventory    api.Inventory    // maps, certs, CA and crt-list files the worker loaded
	Caps         Caps

	PendingServerDeletes  int
	PendingBackendDeletes int
	ReloadPending         bool
}

Baseline is what the controller knows about one pod, every field sourced from that pod's ACK or /v1/state.

type Caps

type Caps struct {
	DynamicServers  bool            // add server / del server
	DynamicBackends bool            // add backend / del backend, 3.4+
	ServerInitState bool            // add server ... init-state up, 3.1+
	AgentOps        map[string]bool // nil: the agent executes every kind
}

Caps is what one pod can do at runtime: what its HAProxy version accepts and which op kinds its agent executes.

func CapsFor

func CapsFor(haproxyVersion string, agentOps []string) Caps

CapsFor derives the capabilities of a pod running haproxyVersion whose agent reported agentOps. An unreadable version leaves every capability false, so a pod HAPTIC cannot identify reloads instead of receiving ops it may reject.

type Decision

type Decision struct {
	Verdict Verdict  `json:"verdict"`
	Ops     []api.Op `json:"ops,omitempty"`
	InPlace []api.Op `json:"in_place_ops,omitempty"` // executable while a reload is pending; empty otherwise
	// WorkerPlan is what the worker holds once InPlace ran; its ID is the
	// pod's next worker-ops baseline. Set exactly when InPlace is.
	WorkerPlan *renderplan.Plan `json:"-"`
	Chunks     int              `json:"chunks,omitempty"` // execution batches, >1 only past api.MaxOpsPerApply
	Reasons    []string         `json:"reasons,omitempty"`
	Files      []api.File       `json:"files"`
	Mode       string           `json:"mode"` // api.ModeAuto or api.ModeReload
}

Decision is the apply one pod gets. Ops is empty unless Verdict is runtime; Files is always the complete desired set. Reasons name every change that was not applied at runtime, whether it forced a reload or only a file write.

func Diff

func Diff(next *renderplan.Plan, base *Baseline) Decision

Diff decides what the pod described by base has to do to reach next.

func DiffIndexed

func DiffIndexed(next *renderplan.Plan, nextIndex *Index, base *Baseline) Decision

DiffIndexed is Diff with next's index already built; nil builds it here.

func (*Decision) Chunk

func (d *Decision) Chunk() [][]api.Op

Chunk bounds execution batches; all batches belong to one agent apply.

type Index

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

Index is what a diff looks up in a plan by name. A caller that holds a plan across deployments builds it once with IndexPlan; Diff builds its own for a plan that comes without one. It points into the plan, so it is only valid while the plan is left alone, which a shared or decoded plan is.

func IndexPlan

func IndexPlan(p *renderplan.Plan) *Index

IndexPlan indexes p; nil for a nil plan.

type Verdict

type Verdict string

Verdict is what an apply built from a Decision does to the pod.

const (
	VerdictRuntime  Verdict = "runtime"
	VerdictFileOnly Verdict = "file_only"
	VerdictReload   Verdict = "reload"
)

The three outcomes of a diff.

Jump to

Keyboard shortcuts

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