diff

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 29, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package diff computes and renders the diff between a work-dir's rendered manifests and the corresponding ConfigHub Units. Used by `installer plan` (read-only) and `installer update` (executes the plan).

The Package label written by upload (Package=<pkg.Name>) is what scopes ownership: a Space may contain Units owned by other tools or other packages (or added by the operator before cloning the Space), and we must never delete those.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Print

func Print(w io.Writer, p Plan)

Print renders a Plan in the terraform-style format documented in docs/lifecycle.md. Writes to w.

Empty plan emits a single line ("No changes."). Plans with content emit a totals header, then per-Space sections, then a per-Space Images: footer.

Types

type ApplyOptions

type ApplyOptions struct {
	// Yes skips per-delete interactive confirmation. Required when
	// stdin is not a TTY and the plan contains deletes.
	Yes bool
	// ChangeSetSlug is the slug used when opening a per-Space
	// ChangeSet for updates. Defaults to
	// changeset.DefaultSlug(time.Now()) when empty.
	ChangeSetSlug string
	// ChangeSetDescription is the human-readable description on the
	// opened ChangeSet. Defaults to a generic "installer update" line
	// when empty.
	ChangeSetDescription string
	// Targets maps a Space slug to the target ref forwarded to
	// `cub unit create --target` for adds in that Space. The ref is the
	// explicit --target (slug, space/slug, or UUID) when the operator
	// passed one, otherwise the Space's recorded TargetID annotation
	// (resolved by the CLI before Apply runs). A missing or empty entry
	// means no target binding.
	Targets map[string]string
	// Annotations and Labels are the operator's --unit-annotation /
	// --unit-label values, forwarded to `cub unit create` for adds. They
	// are NOT applied to existing Units on update — that would clobber
	// user post-install metadata edits, which Principle 1
	// (read-only-to-installer for post-install state in ConfigHub) does
	// not allow. (The PackageVersion annotation is the one exception —
	// see updateUnit — because it tracks which package version last
	// touched each Unit, which the installer owns.)
	Annotations []string
	Labels      []string
	// Stdout/Stderr override the I/O streams; nil uses os.Stdout/Stderr.
	// Tests pass buffers to capture output.
	Stdout io.Writer
	Stderr io.Writer
	// PostSpaceHook runs after each Space's Unit + link changes. The
	// CLI passes a hook that refreshes the installer-record Unit so
	// the cub-side spec stays in sync with local. Nil = no-op.
	PostSpaceHook PackageRefresher
}

ApplyOptions tunes Apply's behavior. Zero value is the safe default (interactive confirmation for deletes; no extra Unit flags).

type ApplyResult

type ApplyResult struct {
	Created          int
	Updated          int
	Deleted          int
	ChangeSetsOpened []ChangeSetRef
}

ApplyResult reports what Apply did, suitable for the CLI's final summary line. ChangeSetsOpened lists every (space, slug) ChangeSet the operator can revert via `cub unit update --restore Before:ChangeSet:<slug>`.

func Apply

func Apply(ctx context.Context, plan Plan, opts ApplyOptions) (ApplyResult, error)

Apply executes the plan inside a per-Space ChangeSet (for updates only — adds and deletes are not ChangeSet-revertable). Empty plan is a no-op.

type ChangeSetRef

type ChangeSetRef struct {
	Space        string
	Slug         string
	Component    string
	UpdatedSlugs []string
}

ChangeSetRef names one opened ChangeSet so the caller can render the revert command. UpdatedSlugs is the exact set of Units that were modified inside this ChangeSet — used to scope the revert.

type PackageRefresher

type PackageRefresher func(ctx context.Context, sp SpacePlan) error

PackageRefresher is the hook Apply calls after each Space's Unit changes (and link reconcile) to give the caller a chance to refresh per-package state in ConfigHub — notably the installer-record Unit whose body must stay in sync with the local spec/. Returning an error fails Apply.

type Plan

type Plan struct {
	Spaces []SpacePlan
}

Plan is the diff between a work-dir's rendered output and the live ConfigHub state, broken down per Space.

func Compute

func Compute(ctx context.Context, packages []upload.Package) (Plan, error)

Compute walks the discovered packages and produces a Plan by querying ConfigHub for the current Unit set under the Package label, then running a dry-run merge-external-source per intersecting slug. ConfigHub state is the single source of truth — local-only state (e.g., a stale prior render) is not considered.

func (Plan) Counts

func (p Plan) Counts() (adds, updates, deletes int)

Counts returns the totals across all Spaces in the plan.

func (Plan) HasChanges

func (p Plan) HasChanges() bool

HasChanges reports whether the plan would create, update, or delete anything. Used by callers to short-circuit "no changes" UX.

type SlugDiff

type SlugDiff struct {
	Slug string
	// Path is the rendered manifest file. Set for Adds and Updates;
	// empty for Deletes. For AppConfig updates this is unused — the
	// raw env content is staged from AppCfg.Content at apply time.
	Path string
	// DiffText is the cub -o mutations human-readable diff for this
	// slug, ANSI-stripped. Set only for Updates.
	DiffText string
	// AppCfg is non-nil for the AppConfig Unit of an AppConfig
	// manifest (the carrier ConfigMap that upload split into AppConfig
	// + placeholder + renderer Target). Apply uses it to stage raw env
	// content for the merge-external-source update. Nil for regular
	// Kubernetes manifests.
	AppCfg *upload.AppConfigManifest
}

SlugDiff is one entry in Adds/Updates/Deletes.

type SpacePlan

type SpacePlan struct {
	// Package is the source-package name (the value of the Package
	// label).
	Package string
	// PackageVersion is informational; rendered alongside Package.
	PackageVersion string
	// SpaceSlug is the ConfigHub Space slug.
	SpaceSlug string
	// Adds are slugs that exist in the rendered output but not in
	// ConfigHub. Path points to the rendered manifest file.
	Adds []SlugDiff
	// Updates are slugs that exist in both, with cub's dry-run
	// reporting non-empty mutations. DiffText is the cub -o mutations
	// output (ANSI-stripped).
	Updates []SlugDiff
	// Deletes are slugs that exist in ConfigHub (under the Package
	// label) but not in the rendered output. The installer-record Unit
	// is excluded.
	Deletes []SlugDiff
	// Images is the post-render image set for the footer; one entry per
	// container per workload found in rendered output.
	Images []WorkloadImage
}

SpacePlan is the slice of a Plan that lives in one ConfigHub Space.

type WorkloadImage

type WorkloadImage struct {
	Kind      string // Deployment, StatefulSet, DaemonSet, Job, CronJob, Pod, ReplicaSet
	Name      string // metadata.name
	Container string // .name from the container spec
	Image     string // .image
	// Init reports whether this entry came from initContainers.
	Init bool
}

WorkloadImage is one container's image inside a rendered manifest. Used by the per-Space `Images:` footer in plan output. Generated from local files (not from ConfigHub) so the footer reflects what the next apply would land, regardless of current ConfigHub state.

func ExtractImages

func ExtractImages(dir string) ([]WorkloadImage, error)

ExtractImages walks every .yaml / .yml file in dir (one level deep), parses each as a Kubernetes resource, and returns one WorkloadImage per container in every workload kind. Output is sorted by (kind, name, container, init) so the printer is deterministic.

Unknown kinds are silently skipped; YAML parse errors on a single file return an error (the renderer should produce well-formed YAML).

Jump to

Keyboard shortcuts

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