controller

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Jun 12, 2026 License: Apache-2.0 Imports: 28 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultDaemonStopGracePeriod = 5 * time.Second

DefaultDaemonStopGracePeriod is the SIGTERM-to-SIGKILL grace window. Five seconds matches the issue's "wait up to ~5s" — long enough for a clean JSON-RPC drain on a quiescent daemon, short enough that a wedged daemon does not block uninstall noticeably.

Variables

This section is empty.

Functions

func SortDocumentsByKind

func SortDocumentsByKind(docs []parser.Document, reverse bool) []parser.Document

SortDocumentsByKind sorts documents by kind order. If reverse is true, sorts in reverse dependency order (Container → Cell → Stack → Space → Realm). If reverse is false, sorts in dependency order (Realm → Space → Stack → Cell → Container). Within the same kind, documents are sorted by their original index.

Types

type ApplyResult

type ApplyResult struct {
	Resources []ResourceResult
}

ApplyResult represents the result of applying a set of resources.

type BootstrapReport

type BootstrapReport struct {
	RunPath string

	KukeonCgroupExistsPre  bool
	KukeonCgroupExistsPost bool
	KukeonCgroupCreated    bool

	// CNI bootstrap details
	CniConfigDir           string
	CniCacheDir            string
	CniBinDir              string
	CniConfigDirExistsPre  bool
	CniCacheDirExistsPre   bool
	CniBinDirExistsPre     bool
	CniConfigDirCreated    bool
	CniCacheDirCreated     bool
	CniBinDirCreated       bool
	CniConfigDirExistsPost bool
	CniCacheDirExistsPost  bool
	CniBinDirExistsPost    bool

	// Default user hierarchy (realm=default, space=default, stack=default, no cell).
	DefaultRealm RealmSection
	DefaultSpace SpaceSection
	DefaultStack StackSection

	// System hierarchy (realm=kuke-system, space=kukeon, stack=kukeon, cell=kukeond).
	SystemRealm RealmSection
	SystemSpace SpaceSection
	SystemStack StackSection
	SystemCell  CellSection

	// KukeondImage is the resolved image reference provisioned for the kukeond
	// container inside the system cell.
	KukeondImage string
}

type BuildCachePurgeOutcome added in v0.6.0

type BuildCachePurgeOutcome struct {
	Namespace string
	Path      string
	Existed   bool
	Removed   bool
	Err       error
}

BuildCachePurgeOutcome reports the result of reclaiming one realm's per-namespace BuildKit state directory at <BuildCacheBaseDir>/<namespace> (issue #904). The reclaim only runs for realms whose containerd namespace was actually removed (NamespaceRemoved=true); a residual namespace's cache is intentionally left in place so a follow-up `kuke uninstall` still has the BuildKit metadata to drive its own teardown.

Existed is "did we find the per-namespace dir before removal" — the renderer's analog of the dirOutcome existed/removed pair used for the socket and run-path rows.

type CellSection

type CellSection struct {
	CellName                    string
	CellMetadataExistsPre       bool
	CellMetadataExistsPost      bool
	CellCreated                 bool
	CellCgroupExistsPre         bool
	CellCgroupExistsPost        bool
	CellCgroupCreated           bool
	CellRootContainerExistsPre  bool
	CellRootContainerExistsPost bool
	CellRootContainerCreated    bool
	CellStartedPre              bool
	CellStartedPost             bool
	CellStarted                 bool
	// CellRecreatedDueToImageDrift is true when bootstrapCell observed a
	// persisted cell whose root container image diverged from the desired
	// image and dropped into a stop+delete+recreate branch instead of the
	// idempotent EnsureCell+StartCell path. Issue #868: without this branch,
	// `kuke init --kukeond-image <new>` would silently keep starting the
	// stale container record left behind by a prior reset, and the running
	// daemon binary would never refresh across a `make dev-init` re-bootstrap.
	CellRecreatedDueToImageDrift bool
	// CellPriorImage carries the persisted root container image observed at
	// drift detection time, so the init report can render
	// "recreated (image drift: <old> → <new>)" instead of the misleading
	// "already existed" line on the recreate branch.
	CellPriorImage string
}

CellSection holds the bootstrap outcome for a single cell.

type ContainerCreationOutcome

type ContainerCreationOutcome struct {
	Name       string
	ExistsPre  bool
	ExistsPost bool
	Created    bool
}

type Controller

type Controller interface {
	Bootstrap() (BootstrapReport, error)
	CreateRealm(realm intmodel.Realm) (CreateRealmResult, error)
	CreateSpace(space intmodel.Space) (CreateSpaceResult, error)
	CreateStack(stack intmodel.Stack) (CreateStackResult, error)
	CreateCell(cell intmodel.Cell) (CreateCellResult, error)
	CreateSecret(secret intmodel.Secret) (CreateSecretResult, error)
	DeleteRealm(realm intmodel.Realm, force, cascade bool) (DeleteRealmResult, error)
	DeleteSpace(space intmodel.Space, force, cascade bool) (DeleteSpaceResult, error)
	DeleteStack(stack intmodel.Stack, force, cascade bool) (DeleteStackResult, error)
	DeleteCell(cell intmodel.Cell) (DeleteCellResult, error)
	GetRealm(realm intmodel.Realm) (GetRealmResult, error)
	ListRealms() ([]intmodel.Realm, error)
	GetSpace(space intmodel.Space) (GetSpaceResult, error)
	ListSpaces(realmName string) ([]intmodel.Space, error)
	GetStack(stack intmodel.Stack) (GetStackResult, error)
	ListStacks(realmName, spaceName string) ([]intmodel.Stack, error)
	GetCell(cell intmodel.Cell) (GetCellResult, error)
	ListCells(realmName, spaceName, stackName string) ([]intmodel.Cell, error)
	GetContainer(container intmodel.Container) (GetContainerResult, error)
	ListContainers(realmName, spaceName, stackName, cellName string) ([]intmodel.ContainerSpec, error)
	StartCell(cell intmodel.Cell) (StartCellResult, error)
	StopCell(cell intmodel.Cell) (StopCellResult, error)
	KillCell(cell intmodel.Cell) (KillCellResult, error)
	PurgeRealm(realm intmodel.Realm, force, cascade bool) (PurgeRealmResult, error)
	PurgeSpace(space intmodel.Space, force, cascade bool) (PurgeSpaceResult, error)
	PurgeStack(stack intmodel.Stack, force, cascade bool) (PurgeStackResult, error)
	PurgeCell(cell intmodel.Cell, force, cascade bool) (PurgeCellResult, error)
	RefreshAll() (RefreshResult, error)
	ReconcileCells() (ReconcileResult, error)
	Uninstall(opts UninstallOptions) (UninstallReport, error)
	Close() error
}

type CreateCellResult

type CreateCellResult struct {
	Cell intmodel.Cell

	MetadataExistsPre       bool
	MetadataExistsPost      bool
	CgroupExistsPre         bool
	CgroupExistsPost        bool
	CgroupCreated           bool
	RootContainerExistsPre  bool
	RootContainerExistsPost bool
	RootContainerCreated    bool
	StartedPre              bool
	StartedPost             bool
	Started                 bool
	Created                 bool

	Containers []ContainerCreationOutcome
}

CreateCellResult reports reconciliation outcomes for a cell.

type CreateConfigResult added in v0.6.0

type CreateConfigResult struct {
	Config  intmodel.CellConfig
	Created bool
}

CreateConfigResult reports the outcome of an atomic create-only CellConfig write (issue #839). `Created` is true on success; the carrier always surfaces back the desired document so callers can echo the persisted name without re-issuing GetConfig.

type CreateRealmResult

type CreateRealmResult struct {
	Realm intmodel.Realm

	MetadataExistsPre             bool
	MetadataExistsPost            bool
	CgroupExistsPre               bool
	CgroupExistsPost              bool
	CgroupCreated                 bool
	ContainerdNamespaceExistsPre  bool
	ContainerdNamespaceExistsPost bool
	ContainerdNamespaceCreated    bool
	Created                       bool
}

CreateRealmResult reports the reconciliation outcomes for a realm.

type CreateSecretResult added in v0.6.0

type CreateSecretResult struct {
	Secret  intmodel.Secret
	Created bool
}

CreateSecretResult reports the outcome of a Secret write.

type CreateSpaceResult

type CreateSpaceResult struct {
	Space intmodel.Space

	MetadataExistsPre    bool
	MetadataExistsPost   bool
	CgroupExistsPre      bool
	CgroupExistsPost     bool
	CgroupCreated        bool
	CNINetworkExistsPre  bool
	CNINetworkExistsPost bool
	CNINetworkCreated    bool
	Created              bool
}

CreateSpaceResult reports reconciliation outcomes for a space.

type CreateStackResult

type CreateStackResult struct {
	Stack intmodel.Stack

	MetadataExistsPre  bool
	MetadataExistsPost bool
	CgroupExistsPre    bool
	CgroupExistsPost   bool
	CgroupCreated      bool
	Created            bool
}

CreateStackResult reports reconciliation outcomes for a stack.

type DaemonStopReport added in v0.3.0

type DaemonStopReport struct {
	PIDFilePresent bool
	PIDFile        string
	PID            int
	Signalled      bool
	ForceKilled    bool
}

DaemonStopReport summarizes the outcome of the daemon-stop step run at the top of Uninstall.

The fields cover the three observable states the operator cares about: (1) was a PID file present at all (PIDFilePresent), (2) was a signal actually delivered (Signalled — false when the PID was already dead by the time we read the file, or the file held garbage), and (3) did the daemon require SIGKILL (ForceKilled) — that is the operator-facing tell that the daemon ignored SIGTERM during the grace window.

type DaemonStopper added in v0.3.0

type DaemonStopper func(ctx context.Context, pidFile string, gracePeriod time.Duration) (DaemonStopReport, error)

DaemonStopper is the injection point for the daemon-stop step. The default implementation reads the PID file, sends SIGTERM, waits up to gracePeriod for the process to exit, then escalates to SIGKILL. Tests stub this to avoid touching real processes.

type DeleteBlueprintResult added in v0.6.0

type DeleteBlueprintResult struct {
	Blueprint intmodel.CellBlueprint
	Deleted   bool
}

DeleteBlueprintResult reports the outcome of removing a single CellBlueprint's daemon-stored document file.

type DeleteCellResult

type DeleteCellResult struct {
	Cell              intmodel.Cell
	ContainersDeleted bool
	CgroupDeleted     bool
	MetadataDeleted   bool
}

DeleteCellResult reports what was deleted during cell deletion.

type DeleteConfigResult added in v0.6.0

type DeleteConfigResult struct {
	Config       intmodel.CellConfig
	Deleted      bool
	BackRefCells []string
}

DeleteConfigResult reports the outcome of removing a single CellConfig's daemon-stored document file (issue #644). BackRefCells lists the scope paths of every live cell that still carries the kukeon.io/config back-reference label to this config. It is informational, never a refusal: deleting a Config does not delete the cell it materialized (that is `kuke delete cell`), so the CLI surfaces a one-line notice pointing the operator there.

type DeleteImageResult added in v0.3.0

type DeleteImageResult struct {
	Realm     string
	Namespace string
	Ref       string
}

DeleteImageResult reports the outcome of a `kuke image delete` removal.

type DeleteRealmResult

type DeleteRealmResult struct {
	Realm                      intmodel.Realm
	Deleted                    []string // Resources that were deleted (metadata, cgroup, namespace, cascaded resources)
	MetadataDeleted            bool
	CgroupDeleted              bool
	ContainerdNamespaceDeleted bool
}

DeleteRealmResult reports what was deleted during realm deletion.

type DeleteResult

type DeleteResult struct {
	Resources []ResourceDeleteResult
}

DeleteResult represents the result of deleting a set of resources.

type DeleteSecretResult added in v0.6.0

type DeleteSecretResult struct {
	Secret  intmodel.Secret
	Deleted bool
}

DeleteSecretResult reports the outcome of removing a single Secret's daemon-stored file.

type DeleteSpaceResult

type DeleteSpaceResult struct {
	SpaceName string
	RealmName string
	Space     intmodel.Space

	MetadataDeleted   bool
	CgroupDeleted     bool
	CNINetworkDeleted bool

	Deleted []string // Resources that were deleted (metadata, cgroup, network, cascaded resources)
}

DeleteSpaceResult reports what was deleted during space deletion.

type DeleteStackResult

type DeleteStackResult struct {
	StackName string
	RealmName string
	SpaceName string
	Stack     intmodel.Stack

	MetadataDeleted bool
	CgroupDeleted   bool

	Deleted []string // Resources that were deleted (metadata, cgroup, cascaded resources)
}

DeleteStackResult reports what was deleted during stack deletion.

type Exec

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

func NewControllerExec

func NewControllerExec(ctx context.Context, logger *slog.Logger, opts Options) *Exec

func NewControllerExecForTesting

func NewControllerExecForTesting(ctx context.Context, logger *slog.Logger, opts Options, r runner.Runner) *Exec

NewControllerExecForTesting creates a controller with a custom runner for testing. This function is exported for testing purposes only.

func (*Exec) ApplyDocuments

func (b *Exec) ApplyDocuments(docs []parser.Document, team string) (ApplyResult, error)

ApplyDocuments applies a set of resource documents in dependency order. Documents are sorted: Realm → Space → Stack → Cell → Container. Returns a summary of actions taken for each resource.

When team is non-empty (issue #1027 per-team prune apply), the daemon stamps `kukeon.io/team=<team>` on every applied CellBlueprint / CellConfig before persistence, and after the apply loop enumerates daemon-stored Blueprint / Config objects carrying the same team label, deleting those not in the applied set. The empty-string team preserves the historical no-stamp, no-prune behavior of `kuke apply -f`.

func (*Exec) Bootstrap

func (b *Exec) Bootstrap() (BootstrapReport, error)

func (*Exec) Close

func (b *Exec) Close() error

Close closes the controller and releases all resources, including the containerd connection.

func (*Exec) CreateCell

func (b *Exec) CreateCell(cell intmodel.Cell) (CreateCellResult, error)

CreateCell creates a new cell or ensures an existing cell's resources exist, then starts the cell's containers. See createCellInternal for the full contract.

func (*Exec) CreateConfig added in v0.6.0

func (b *Exec) CreateConfig(config intmodel.CellConfig) (CreateConfigResult, error)

CreateConfig persists a new CellConfig document under atomic create-only semantics — the same scope / blueprint / slot-fill validation as ApplyDocuments-driven create, but the runner write is gated on the file not existing (issue #839). The caller is `kuke create config`; the path returns errdefs.ErrConfigExists on collision, which the CLI surfaces as a hard error rather than the write-through overwrite ApplyDocuments would perform.

func (*Exec) CreateRealm

func (b *Exec) CreateRealm(realm intmodel.Realm) (CreateRealmResult, error)

CreateRealm creates a new realm or ensures an existing realm's resources exist. It returns a CreateRealmResult and an error. The CreateRealmResult reports the state of realm resources before and after the operation, indicating what was created vs what already existed. The error is returned if the realm name is required, the namespace is required, the realm cgroup does not exist, the containerd namespace does not exist, or the realm creation fails.

func (*Exec) CreateSecret added in v0.6.0

func (b *Exec) CreateSecret(secret intmodel.Secret) (CreateSecretResult, error)

CreateSecret persists a Secret's bytes to daemon storage via the runner's WriteSecret (write-through, create-or-overwrite). The data is provided at create time from CLI --from-literal or --from-file flags. The spec is never echoed back — the result carries only metadata (issue #619).

func (*Exec) CreateSpace

func (b *Exec) CreateSpace(space intmodel.Space) (CreateSpaceResult, error)

CreateSpace creates a new space or ensures an existing space's resources exist. It returns a CreateSpaceResult and an error. The CreateSpaceResult reports the state of space resources before and after the operation, indicating what was created vs what already existed. The error is returned if the space name is required, the realm name is required, the space cgroup does not exist, the cni network does not exist, or the space creation fails.

func (*Exec) CreateStack

func (b *Exec) CreateStack(stack intmodel.Stack) (CreateStackResult, error)

CreateStack creates a new stack or ensures an existing stack's resources exist. It returns a CreateStackResult and an error. The CreateStackResult reports the state of stack resources before and after the operation, indicating what was created vs what already existed. The error is returned if the stack name is required, the realm name is required, the space name is required, the stack cgroup does not exist, or the stack creation fails.

func (*Exec) DeleteBlueprint added in v0.6.0

func (b *Exec) DeleteBlueprint(blueprint intmodel.CellBlueprint) (DeleteBlueprintResult, error)

DeleteBlueprint removes a single named, scoped CellBlueprint's daemon-stored document. Returns a "not found" error when the blueprint does not exist, matching the DeleteSecret contract. There is no live-reference gate: cells materialized from a blueprint are independent copies (#620).

func (*Exec) DeleteCell

func (b *Exec) DeleteCell(cell intmodel.Cell) (DeleteCellResult, error)

DeleteCell deletes a cell. Always deletes all containers first.

func (*Exec) DeleteConfig added in v0.6.0

func (b *Exec) DeleteConfig(config intmodel.CellConfig) (DeleteConfigResult, error)

DeleteConfig removes a single named, scoped CellConfig's daemon-stored document. Returns a "not found" error when the config does not exist, matching the DeleteBlueprint contract.

Back-reference notice (issue #644 AC): deleting a Config does NOT delete the cell it materialized. Before unlinking, scan every persisted cell for the kukeon.io/config back-reference label pointing at this config and report the matches in the result so the CLI can emit a one-line notice pointing at `kuke delete cell <name>`. Unlike DeleteSecret's live-reference gate this is informational only — it never refuses the delete.

func (*Exec) DeleteDocuments

func (b *Exec) DeleteDocuments(docs []parser.Document, cascade, force bool) (DeleteResult, error)

DeleteDocuments deletes a set of resource documents in reverse dependency order. Documents are sorted: Container → Cell → Stack → Space → Realm. Returns a summary of actions taken for each resource.

func (*Exec) DeleteImage added in v0.3.0

func (b *Exec) DeleteImage(realm, ref string) (DeleteImageResult, error)

DeleteImage removes the named image ref from the realm's containerd namespace. errdefs.ErrImageNotFound is propagated unchanged so callers (CLI, RPC) can map it to a clean "image not found" message.

func (*Exec) DeleteRealm

func (b *Exec) DeleteRealm(realm intmodel.Realm, force, cascade bool) (DeleteRealmResult, error)

DeleteRealm deletes a realm. If cascade is true, deletes all spaces first. If force is true, skips validation of child resources.

func (*Exec) DeleteSecret added in v0.6.0

func (b *Exec) DeleteSecret(secret intmodel.Secret) (DeleteSecretResult, error)

DeleteSecret removes a single named, scoped Secret's daemon-stored file. Returns a "not found" error when the secret does not exist, matching the DeleteRealm contract.

Live-reference safety gate (issue #623, AC5): before unlinking, scan every persisted cell's container specs for a secretRef pointing at this secret. If any references it, refuse with ErrSecretInUse naming the referencing cells — deleting the bytes out from under a live container would break it on its next start. This mirrors the DeleteRealm dependency guard.

func (*Exec) DeleteSpace

func (b *Exec) DeleteSpace(space intmodel.Space, force, cascade bool) (DeleteSpaceResult, error)

DeleteSpace deletes a space. If cascade is true, deletes all stacks first. If force is true, skips validation of child resources.

func (*Exec) DeleteStack

func (b *Exec) DeleteStack(stack intmodel.Stack, force, cascade bool) (DeleteStackResult, error)

DeleteStack deletes a stack. If cascade is true, deletes all cells first. If force is true, skips validation of child resources.

func (*Exec) GetBlueprint added in v0.6.0

func (b *Exec) GetBlueprint(blueprint intmodel.CellBlueprint) (GetBlueprintResult, error)

GetBlueprint reads one named, scoped CellBlueprint's document. The scope coordinates are validated for completeness (a deeper coordinate requires every shallower one; a Blueprint may not be cell-scoped); realm and name are mandatory. Returns MetadataExists=false (no error) when the blueprint is absent, mirroring GetSecret's "report, don't error on not-found" shape.

func (*Exec) GetCell

func (b *Exec) GetCell(cell intmodel.Cell) (GetCellResult, error)

GetCell retrieves a single cell and reports its current state.

func (*Exec) GetConfig added in v0.6.0

func (b *Exec) GetConfig(config intmodel.CellConfig) (GetConfigResult, error)

GetConfig reads one named, scoped CellConfig's document. The scope coordinates are validated for completeness (a deeper coordinate requires every shallower one; a Config may not be cell-scoped); realm and name are mandatory. Returns MetadataExists=false (no error) when the config is absent, mirroring GetBlueprint's "report, don't error on not-found" shape.

func (*Exec) GetContainer

func (b *Exec) GetContainer(container intmodel.Container) (GetContainerResult, error)

GetContainer retrieves a single container and reports its current state.

func (*Exec) GetImage added in v0.3.0

func (b *Exec) GetImage(realm, ref string) (GetImageResult, error)

GetImage returns metadata for the named image ref in the realm's containerd namespace. errdefs.ErrImageNotFound is propagated unchanged so callers (CLI, RPC) can map it to a clean "image not found" message.

func (*Exec) GetRealm

func (b *Exec) GetRealm(realm intmodel.Realm) (GetRealmResult, error)

GetRealm retrieves a single realm and reports its current state.

func (*Exec) GetSecret added in v0.6.0

func (b *Exec) GetSecret(secret intmodel.Secret) (GetSecretResult, error)

GetSecret retrieves the metadata-only view of one named, scoped Secret. The scope coordinates are validated for completeness (a deeper coordinate requires every shallower one); realm and name are mandatory. Returns a result with MetadataExists=false (and no error) when the secret is absent, mirroring GetRealm's "report, don't error on not-found" shape.

func (*Exec) GetSpace

func (b *Exec) GetSpace(space intmodel.Space) (GetSpaceResult, error)

GetSpace retrieves a single space and reports its current state.

func (*Exec) GetStack

func (b *Exec) GetStack(stack intmodel.Stack) (GetStackResult, error)

GetStack retrieves a single stack and reports its current state.

func (*Exec) KillCell

func (b *Exec) KillCell(cell intmodel.Cell) (KillCellResult, error)

KillCell immediately force-kills all containers in a cell and updates the cell metadata state.

func (*Exec) ListBlueprints added in v0.6.0

func (b *Exec) ListBlueprints(realmName, spaceName, stackName string) ([]intmodel.CellBlueprint, error)

ListBlueprints lists the metadata of every CellBlueprint bound to the filter scope or any scope nested within it (issue #643). An empty realm lists across all realms; the filter coordinates must still be contiguous (no gap below a set level), and — a Blueprint never being cell-scoped — there is no cell coordinate.

func (*Exec) ListCells

func (b *Exec) ListCells(realmName, spaceName, stackName string) ([]intmodel.Cell, error)

ListCells lists all cells, optionally filtered by realm, space, and/or stack.

func (*Exec) ListConfigs added in v0.6.0

func (b *Exec) ListConfigs(realmName, spaceName, stackName string) ([]intmodel.CellConfig, error)

ListConfigs lists the metadata of every CellConfig bound to the filter scope or any scope nested within it (issue #644). An empty realm lists across all realms; the filter coordinates must still be contiguous (no gap below a set level), and — a Config never being cell-scoped — there is no cell coordinate.

func (*Exec) ListContainers

func (b *Exec) ListContainers(realmName, spaceName, stackName, cellName string) ([]intmodel.ContainerSpec, error)

ListContainers lists all containers, optionally filtered by realm, space, stack, and/or cell.

func (*Exec) ListImages added in v0.3.0

func (b *Exec) ListImages(realm string) (ListImagesResult, error)

ListImages enumerates images in the realm's containerd namespace. The realm is validated up-front so callers see ErrRealmNotFound before any containerd round-trip; the namespace mapping mirrors LoadImage.

func (*Exec) ListRealms

func (b *Exec) ListRealms() ([]intmodel.Realm, error)

ListRealms lists all realms.

func (*Exec) ListSecrets added in v0.6.0

func (b *Exec) ListSecrets(realmName, spaceName, stackName, cellName string) ([]intmodel.Secret, error)

ListSecrets lists the metadata of every Secret bound to the filter scope or any scope nested within it. An empty realm lists across all realms; the filter coordinates must still be contiguous (no gap below a set level).

func (*Exec) ListSpaces

func (b *Exec) ListSpaces(realmName string) ([]intmodel.Space, error)

ListSpaces lists all spaces, optionally filtered by realm.

func (*Exec) ListStacks

func (b *Exec) ListStacks(realmName, spaceName string) ([]intmodel.Stack, error)

ListStacks lists all stacks, optionally filtered by realm and/or space.

func (*Exec) LoadImage added in v0.3.0

func (b *Exec) LoadImage(realm string, reader io.Reader) (LoadImageResult, error)

LoadImage imports an OCI/docker image tarball into the realm's containerd namespace. The realm name is mapped to a containerd namespace via consts.RealmNamespace, the same source of truth used by `kuke init` and every other realm operation.

func (*Exec) MaterializeCell added in v0.6.0

func (b *Exec) MaterializeCell(cell intmodel.Cell) (CreateCellResult, error)

MaterializeCell creates a new cell record (or ensures an existing cell's resources exist) without starting any container tasks. The resulting cell is left in a stopped/created state; the operator runs `kuke start <name>` to start it. Used by the CLI's `kuke create cell --from-blueprint` and `--from-config` scaffolding modes (#818) — distinct from `kuke run -b` / `kuke run <cfg>` (materialise + start + attach) and (for Config-lineage cells) `kuke restart <name>` (reconcile + start on OutOfSync).

func (*Exec) ProvisionKukeondCell added in v0.6.0

func (b *Exec) ProvisionKukeondCell() (CellSection, error)

ProvisionKukeondCell creates the kukeond daemon cell using the same cell-creation path that `kuke init`'s Bootstrap exercises. Factored out so `kuke daemon recreate` cannot drift from `kuke init` on the kukeond provisioning logic — both verbs call this single helper.

func (*Exec) PruneImages added in v0.6.0

func (b *Exec) PruneImages(realm string) (PruneImagesResult, error)

PruneImages reclaims dangling image layers and the orphaned leases pinning them in the realm's containerd namespace. The realm is validated up-front so callers see ErrRealmNotFound before any containerd round-trip; the namespace mapping mirrors DeleteImage. Tagged images and the snapshots backing live cells are left untouched (see ctr.PruneImages).

func (*Exec) PurgeCell

func (b *Exec) PurgeCell(cell intmodel.Cell, force, cascade bool) (PurgeCellResult, error)

PurgeCell purges a cell with comprehensive cleanup. Always purges all containers first. If force is true, skips validation (currently unused but recorded for auditing).

func (*Exec) PurgeRealm

func (b *Exec) PurgeRealm(realm intmodel.Realm, force, cascade bool) (PurgeRealmResult, error)

PurgeRealm purges a realm with comprehensive cleanup. If cascade is true, purges all spaces first. If force is true, skips validation of child resources.

func (*Exec) PurgeSpace

func (b *Exec) PurgeSpace(space intmodel.Space, force, cascade bool) (PurgeSpaceResult, error)

PurgeSpace purges a space with comprehensive cleanup. If cascade is true, purges all stacks first. If force is true, skips validation of child resources.

func (*Exec) PurgeStack

func (b *Exec) PurgeStack(stack intmodel.Stack, force, cascade bool) (PurgeStackResult, error)

PurgeStack purges a stack with comprehensive cleanup. If cascade is true, purges all cells first. If force is true, skips validation of child resources.

func (*Exec) ReapplyAttachableSocketPerms added in v0.6.0

func (b *Exec) ReapplyAttachableSocketPerms(spec intmodel.ContainerSpec)

ReapplyAttachableSocketPerms heals a single attachable container's live tty control socket inode to the connect(2)-able mode/group on the attach path (#1169). AttachContainer calls it before handing back the socket path so a `kuke run` against an already-Ready cell — which short-circuits past StartCell and so past the #935 StartCell-skip heal — still corrects a wrong-mode (pre-sbsh#361 0o640) live socket in place, matching `kuke restart` without reintroducing the #630 start-on-running hazard. Best-effort and root-owned (the daemon runs as root); a chmod miss is logged by the runner and never surfaced, so a healthy socket is untouched.

func (*Exec) ReconcileCells added in v0.4.0

func (b *Exec) ReconcileCells() (ReconcileResult, error)

ReconcileCells walks every realm/space/stack and reconciles each cell's status against observed container state. Errors at any level are logged and recorded in Errors; the walk continues so a single bad cell does not silence the rest of the host.

func (*Exec) RefreshAll

func (b *Exec) RefreshAll() (RefreshResult, error)

RefreshAll refreshes all metadata entities by introspecting containerd and CNI.

func (*Exec) RunPath added in v0.2.0

func (b *Exec) RunPath() string

RunPath returns the configured kukeon run path. Surfaced for callers that need to derive host paths from the same root the controller writes to — notably the in-process AttachContainer endpoint, which resolves the SUN_PATH-safe per-container kuketty socket via fs.ContainerSocketSymlinkPath.

func (*Exec) StartCell

func (b *Exec) StartCell(cell intmodel.Cell) (StartCellResult, error)

StartCell starts all containers in a cell and updates the cell metadata state.

For a Config-lineage cell whose persisted Status.OutOfSync is true, StartCell first re-materialises the cell's spec from its lineage Config + Blueprint and rebuilds the containerd records, so `kuke stop` followed by `kuke start` produces the same end state as `kuke restart` on an OutOfSync cell — issue #983. The reapply is daemon-side so every client that issues StartCell (CLI, future API consumers) gets the reconcile-on-start behaviour.

func (*Exec) StopCell

func (b *Exec) StopCell(cell intmodel.Cell) (StopCellResult, error)

StopCell stops all containers in a cell and updates the cell metadata state.

func (*Exec) Uninstall added in v0.3.0

func (b *Exec) Uninstall(opts UninstallOptions) (UninstallReport, error)

Uninstall performs a comprehensive teardown of all kukeon runtime state. Steps (in order):

  1. Stop the kukeond daemon (SIGTERM, then SIGKILL after a short grace) when a PID file is present. Doing this before any per-realm purge prevents the live daemon from racing the in-process containerd cleanup and pinning containers in `kuke-system.kukeon.io` while we are trying to drain it.

  2. Purge every realm with --cascade --force (drains spaces/stacks/cells/ containers + tasks; the kukeond cell living inside `kuke-system` is killed and deleted as part of that cascade). Realms are enumerated by merging on-disk metadata with the set of containerd namespaces whose name carries the `.kukeon.io` suffix, so user-created realms whose metadata was wiped before `kuke uninstall` (the #193 partial-state path) still get their namespaces cleaned up. The two well-known realms (`default`, `kuke-system`) are kept as a safety floor so a containerd-list failure cannot strand them.

    For every realm whose containerd namespace was actually removed, also reclaim the matching per-namespace BuildKit cache directory at <BuildCacheBaseDir>/<namespace> (default consts.KukebuildBaseDir). The cache references containerd by snapshot ID and content digest; a surviving cache after a successful namespace drop strands the next `kuke build` with "parent snapshot does not exist" or "content digest ... not found" — issue #904.

  3. Release live kukeon-owned bind mounts under SocketDir, then RemoveAll on SocketDir (typically /run/kukeon). The unmount step is what makes a post-attach uninstall succeed: kuketty leaves a /run/kukeon/tty bind mount behind, and rmdir refuses to descend through it (the #434 regression). A plain umount is tried first, falling back to lazy MNT_DETACH so the parent dir can still be removed when the mount has stragglers holding it open.

  4. The same release + RemoveAll for the run path (typically /opt/kukeon).

  5. Remove the kukeon system user and group (no-op if absent).

  6. After the per-namespace cache sweep, try a plain rmdir on BuildCacheBaseDir — only succeeds when it is empty so a scoped uninstall (`--server-configuration` narrowing realm enumeration to one suffix) leaves cousin instances' caches under sibling subdirs intact.

Steps 2–4 are gated on every realm reporting NamespaceRemoved=true. When at least one realm fails to drop its containerd namespace, the report's CleanupSkipped flag is set and the filesystem + user/group teardown is left for a follow-up run — see issue #287 for the half-cleaned-host failure mode this prevents. The per-namespace BuildKit cache sweep (the cache reclaim half of step 1) is **not** gated on that flag: a namespace that was actually removed should have its cache reclaimed even when a sibling realm's purge failed.

Any step's error is recorded in the report. The first non-nil step error is returned so callers can surface "uninstall failed at step X" without dropping subsequent best-effort cleanup.

type GetBlueprintResult added in v0.6.0

type GetBlueprintResult struct {
	Blueprint      intmodel.CellBlueprint
	MetadataExists bool
}

GetBlueprintResult reports the full document view of a single `kind: CellBlueprint` (issue #620). Unlike a Secret, a blueprint carries no credential bytes — only template references — so the whole document is returned for `kuke run -b` to materialize.

type GetCellResult

type GetCellResult struct {
	Cell                intmodel.Cell
	MetadataExists      bool
	CgroupExists        bool
	RootContainerExists bool
	// RootContainerTaskRunning reports whether the cell's root container has a
	// live containerd task (status Running). RootContainerExists keys on the
	// containerd container *record*, which survives a host/daemon restart while
	// the backing task does not (#654, #683): a record-existence check passes
	// even when attaching would land on a dead socket. Callers gating an attach
	// must consult this task-liveness signal, not record existence.
	RootContainerTaskRunning bool
}

GetCellResult reports the current state of a cell.

type GetConfigResult added in v0.6.0

type GetConfigResult struct {
	Config         intmodel.CellConfig
	MetadataExists bool
}

GetConfigResult reports the full document view of a single `kind: CellConfig` (issue #644). Unlike a Secret, a Config carries no credential bytes — only a blueprint reference, scalar values, and repo/secret slot fills — so the whole document is returned for `kuke get config` to surface.

type GetContainerResult

type GetContainerResult struct {
	Container          intmodel.Container
	CellMetadataExists bool
	ContainerExists    bool
}

GetContainerResult reports the current state of a container.

type GetImageResult added in v0.3.0

type GetImageResult struct {
	Realm     string
	Namespace string
	Image     ImageInfo
}

GetImageResult reports the metadata of one named image in a realm.

type GetRealmResult

type GetRealmResult struct {
	Realm                     intmodel.Realm
	MetadataExists            bool
	CgroupExists              bool
	ContainerdNamespaceExists bool
}

GetRealmResult reports the current state of a realm.

type GetSecretResult added in v0.6.0

type GetSecretResult struct {
	Secret         intmodel.Secret
	MetadataExists bool
}

GetSecretResult reports the metadata-only view of a single `kind: Secret` (issue #622). The bytes are never carried — Secret.Spec is left zero so the never-round-tripped contract from #619 holds end to end.

type GetSpaceResult

type GetSpaceResult struct {
	Space            intmodel.Space
	MetadataExists   bool
	CgroupExists     bool
	CNINetworkExists bool
}

GetSpaceResult reports the current state of a space.

type GetStackResult

type GetStackResult struct {
	Stack          intmodel.Stack
	MetadataExists bool
	CgroupExists   bool
}

GetStackResult reports the current state of a stack.

type ImageInfo added in v0.3.0

type ImageInfo struct {
	Name      string
	Size      int64
	CreatedAt time.Time
	Digest    string
	MediaType string
	Labels    map[string]string
}

ImageInfo is the controller-layer view of a containerd image. The fields are a re-export of internal/ctr's ImageInfo so transports above the controller never need to import the ctr package.

type KillCellResult

type KillCellResult struct {
	Cell   intmodel.Cell
	Killed bool
}

KillCellResult reports the outcome of killing a cell.

type ListImagesResult added in v0.3.0

type ListImagesResult struct {
	Realm     string
	Namespace string
	Images    []ImageInfo
}

ListImagesResult reports the images present in a realm's containerd namespace.

type LoadImageResult added in v0.3.0

type LoadImageResult struct {
	Realm     string
	Namespace string
	Images    []string
}

LoadImageResult reports the outcome of a `kuke image load` import.

type MountReleaseAttempt added in v0.5.0

type MountReleaseAttempt struct {
	Target   string
	Released bool
	Err      error
}

MountReleaseAttempt records the outcome of trying to release a single mountpoint enumerated under a kukeon-owned directory at uninstall time.

Released is true when the mount no longer pins the host directory (either because the plain unmount succeeded or the lazy MNT_DETACH fallback did). Err is non-nil only on the residual-mount path: the plain unmount and the lazy detach both failed, so the operator must intervene by hand.

type MountReleaser added in v0.5.0

type MountReleaser func(root string) ([]MountReleaseAttempt, error)

MountReleaser releases live bind mounts under the given root directory so the subsequent rmdir of root succeeds. The production implementation reads /proc/self/mounts and calls syscall.Unmount; tests inject a stub.

The empty return slice means "no mounts under root" — distinct from an error, which signals the enumerator itself failed (e.g., /proc/self/mounts is unreadable).

type Options

type Options struct {
	RunPath          string
	ContainerdSocket string
	// KukeondImage is the container image for the kukeond system cell. If empty,
	// bootstrap will skip provisioning the system cell (but still provision the
	// system realm/space/stack).
	KukeondImage string
	// KukeondSocket is the unix socket path kukeond serves on. Used by bootstrap
	// to build the bind-mount for the system cell.
	KukeondSocket string
	// KukeondSocketGID, when non-zero, is passed to the kukeond cell as
	// --socket-gid <gid> so the daemon can chown its listener socket on every
	// restart. Set by `kuke init` to the kukeon group's numeric GID.
	KukeondSocketGID int
	// KukeondConfiguration, when set, is passed to the kukeond cell as
	// --configuration <path> and bind-mounted into the cell so the daemon
	// re-reads the same ServerConfiguration on every restart.
	KukeondConfiguration string
	// ForceRegenerateCNI forces bootstrap to rewrite space conflists even when
	// they already exist with the expected bridge name. Surfaces via
	// `kuke init --force-regenerate-cni`.
	ForceRegenerateCNI bool
	// DefaultMemoryLimitBytes, when > 0, is the daemon-wide fallback memory
	// limit (in bytes) applied to every admitted container whose
	// ContainerSpec.Resources.MemoryLimitBytes is unset or zero. Surfaces via
	// `kukeond serve --default-memory-limit-bytes`, KUKEOND_DEFAULT_MEMORY_LIMIT_BYTES,
	// or ServerConfiguration.Spec.DefaultMemoryLimitBytes. Closes the host-
	// wedge gap on no-swap + no-userspace-OOM hosts (issue #531). Zero (the
	// default) preserves the prior behavior — no fallback, the kernel sees
	// memory.max=max for any spec that did not declare a limit.
	DefaultMemoryLimitBytes int64
	// KukettyLogLevel is the daemon-wide default verbosity of the kuketty
	// wrapper's slog output, applied when a cell omits per-container
	// ContainerTty.LogLevel. Surfaces via `kukeond serve --kuketty-log-level`,
	// KUKEOND_KUKETTY_LOG_LEVEL, or ServerConfiguration.Spec.KukettyLogLevel.
	// Empty falls through to the hardcoded "info" default inside the renderer.
	// Issue #599.
	KukettyLogLevel string
	// DiskPressureWarnPercent, when > 0, is the data-volume usage percentage
	// above which the reconcile loop emits a rate-limited WARN naming the realm
	// and current usage (no deletion). Surfaces via
	// `kukeond serve --disk-pressure-warn-percent` / KUKEOND_DISK_PRESSURE_WARN_PCT.
	// Zero disables the warning. Issue #1035.
	DiskPressureWarnPercent int
	// DiskPressureBlockPercent, when > 0, is the data-volume usage percentage
	// at or above which CreateCell refuses to provision a new cell. Surfaces
	// via `kukeond serve --disk-pressure-block-percent` /
	// KUKEOND_DISK_PRESSURE_BLOCK_PCT. Zero disables the guard. Issue #1035.
	DiskPressureBlockPercent int
}

type PruneImagesResult added in v0.6.0

type PruneImagesResult struct {
	Realm          string
	Namespace      string
	LeasesDeleted  int
	LeasesRetained int
}

PruneImagesResult reports the outcome of a `kuke image prune`: the realm / namespace it ran against and the count of leases released vs. retained.

type PurgeCellResult

type PurgeCellResult struct {
	Cell              intmodel.Cell
	ContainersDeleted bool
	CgroupDeleted     bool
	MetadataDeleted   bool
	PurgeSucceeded    bool
	Force             bool
	Cascade           bool
	Deleted           []string // Resources that were deleted (standard cleanup)
	Purged            []string // Additional resources purged (CNI, orphaned containers, etc.)
}

PurgeCellResult reports what was purged during cell purging.

type PurgeRealmResult

type PurgeRealmResult struct {
	Realm            intmodel.Realm
	RealmDeleted     bool     // Whether realm deletion succeeded
	PurgeSucceeded   bool     // Whether comprehensive purge succeeded
	NamespaceRemoved bool     // Whether the containerd namespace was actually removed
	Force            bool     // Force flag that was used
	Cascade          bool     // Cascade flag that was used
	Deleted          []string // Resources that were deleted (standard cleanup)
	Purged           []string // Additional resources purged (CNI, orphaned containers, etc.)
}

PurgeRealmResult reports what was purged during realm purging.

type PurgeSpaceResult

type PurgeSpaceResult struct {
	Space intmodel.Space

	MetadataDeleted   bool
	CgroupDeleted     bool
	CNINetworkDeleted bool
	PurgeSucceeded    bool
	Force             bool
	Cascade           bool

	Deleted []string // Resources that were deleted (standard cleanup)
	Purged  []string // Additional resources purged (CNI, orphaned containers, etc.)
}

PurgeSpaceResult reports what was purged during space purging.

type PurgeStackResult

type PurgeStackResult struct {
	Stack   intmodel.Stack
	Deleted []string // Resources that were deleted (standard cleanup)
	Purged  []string // Additional resources purged (CNI, orphaned containers, etc.)
}

PurgeStackResult reports what was purged during stack purging.

type RealmPurgeOutcome added in v0.3.0

type RealmPurgeOutcome struct {
	Name             string
	Namespace        string
	Purged           bool
	NamespaceRemoved bool
	Err              error
}

RealmPurgeOutcome reports the result of purging a single realm.

Purged is the high-level "did the cleanup function complete without a fatal error" flag; NamespaceRemoved is the narrower "did the containerd namespace actually get removed" signal — the residual-namespace bug from issue #193 is the case where Purged was true but NamespaceRemoved was false, leaving the caller with a misleading "purged" report.

type RealmSection

type RealmSection struct {
	RealmName                          string
	RealmContainerdNamespace           string
	RealmMetadataExistsPre             bool
	RealmMetadataExistsPost            bool
	RealmContainerdNamespaceExistsPre  bool
	RealmContainerdNamespaceExistsPost bool
	RealmContainerdNamespaceCreated    bool
	RealmCreated                       bool
	RealmCgroupExistsPre               bool
	RealmCgroupExistsPost              bool
	RealmCgroupCreated                 bool
}

RealmSection holds the bootstrap outcome for a single realm.

type ReconcileResult added in v0.4.0

type ReconcileResult struct {
	CellsScanned int
	CellsUpdated int
	// CellsDeleted counts cells the reconciler removed during the pass
	// because Spec.AutoDelete=true and the root container's task had
	// exited. Tracked separately from CellsUpdated so callers can tell
	// "state flip persisted" apart from "cell is gone".
	CellsDeleted int
	CellsErrored int
	Errors       []string
}

ReconcileResult summarizes a single pass of the daemon's background cell-reconciliation loop. Counts are scoped to cells (v1 of #161 is cell-only); per-pass errors are collected so the loop can keep ticking.

type RefreshResult

type RefreshResult struct {
	RealmsFound       []string
	SpacesFound       []string
	StacksFound       []string
	CellsFound        []string
	ContainersFound   []string
	RealmsUpdated     []string
	SpacesUpdated     []string
	StacksUpdated     []string
	CellsUpdated      []string
	ContainersUpdated []string
	Errors            []string
}

RefreshResult contains the summary of the refresh operation.

type ResourceDeleteResult

type ResourceDeleteResult struct {
	Index    int
	Kind     string
	Name     string
	Action   string // "deleted", "not found", "failed"
	Error    error
	Cascaded []string // Child resources deleted (if cascade=true)
	Details  map[string]string
}

ResourceDeleteResult represents the result of deleting a single resource.

func (ResourceDeleteResult) MarshalJSON

func (r ResourceDeleteResult) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for ResourceDeleteResult.

func (ResourceDeleteResult) MarshalYAML

func (r ResourceDeleteResult) MarshalYAML() (interface{}, error)

MarshalYAML implements yaml.Marshaler for ResourceDeleteResult.

type ResourceResult

type ResourceResult struct {
	Index   int
	Kind    string
	Name    string
	Action  string // "created", "updated", "unchanged", "failed"
	Error   error
	Changes []string
	Details map[string]string
}

ResourceResult represents the result of applying a single resource.

func (ResourceResult) MarshalJSON

func (r ResourceResult) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for ResourceResult.

func (ResourceResult) MarshalYAML

func (r ResourceResult) MarshalYAML() (interface{}, error)

MarshalYAML implements yaml.Marshaler for ResourceResult.

type SpaceSection

type SpaceSection struct {
	SpaceName                 string
	SpaceCNINetworkName       string
	SpaceMetadataExistsPre    bool
	SpaceMetadataExistsPost   bool
	SpaceCNINetworkExistsPre  bool
	SpaceCNINetworkExistsPost bool
	SpaceCNINetworkCreated    bool
	SpaceCreated              bool
	SpaceCgroupExistsPre      bool
	SpaceCgroupExistsPost     bool
	SpaceCgroupCreated        bool
}

SpaceSection holds the bootstrap outcome for a single space.

type StackSection

type StackSection struct {
	StackName               string
	StackMetadataExistsPre  bool
	StackMetadataExistsPost bool
	StackCreated            bool
	StackCgroupExistsPre    bool
	StackCgroupExistsPost   bool
	StackCgroupCreated      bool
}

StackSection holds the bootstrap outcome for a single stack.

type StartCellResult

type StartCellResult struct {
	Cell    intmodel.Cell
	Started bool
}

StartCellResult reports the outcome of starting a cell.

type StopCellResult

type StopCellResult struct {
	Cell    intmodel.Cell
	Stopped bool
}

StopCellResult reports the outcome of stopping a cell.

type UninstallOptions added in v0.3.0

type UninstallOptions struct {
	// SocketDir is the parent directory of the kukeond unix socket
	// (typically /run/kukeon). Removed recursively when non-empty.
	SocketDir string
	// SystemUser/SystemGroup are the names of the kukeon system user and
	// group to remove. Defaults to "kukeon"/"kukeon" when empty.
	SystemUser  string
	SystemGroup string
	// SkipUserGroup skips userdel/groupdel. Set in tests where touching
	// the host's /etc/passwd is undesirable.
	SkipUserGroup bool
	// UserGroupRemover overrides the default userdel/groupdel routine.
	// Tests inject a stub; production callers leave it nil.
	UserGroupRemover UserGroupRemover
	// KukeondPIDFile points at the kukeond PID file. The daemon-stop step
	// signals the live daemon before any realm purge, so a fight between
	// the in-process PurgeRealm and the running daemon's containerd session
	// can never block the namespace delete with "namespace not empty".
	// Empty disables the daemon-stop step; absent file is a no-op (the
	// partial-uninstall path from #193).
	KukeondPIDFile string
	// DaemonStopper overrides the default PID-file-based stopper. Tests
	// inject a stub; production callers leave it nil.
	DaemonStopper DaemonStopper
	// DaemonStopGracePeriod is the SIGTERM→SIGKILL grace window. Zero uses
	// DefaultDaemonStopGracePeriod (5s).
	DaemonStopGracePeriod time.Duration
	// MountReleaser releases live bind mounts under SocketDir and RunPath
	// before the rmdir step. Production callers leave it nil (defaults to
	// reading /proc/self/mounts + syscall.Unmount); tests inject a stub so
	// they do not have to provision real mounts.
	MountReleaser MountReleaser
	// BuildCacheBaseDir overrides the directory under which `kukebuild`
	// keeps its per-namespace BuildKit state (issue #904). Empty falls
	// back to consts.KukebuildBaseDir; tests pin t.TempDir() so they do
	// not have to write under /var/lib.
	BuildCacheBaseDir string
}

UninstallOptions configures Uninstall.

type UninstallReport added in v0.3.0

type UninstallReport struct {
	Daemon          DaemonStopReport
	Realms          []RealmPurgeOutcome
	CleanupSkipped  bool
	SocketDir       string
	SocketDirExists bool
	SocketDirRemove bool
	// SocketDirMounts records every kukeon-owned bind mount found under
	// SocketDir at uninstall time and whether it was released. A non-empty
	// list with all entries Released=true is the success path: the rmdir
	// step that follows can now reach an empty directory. Any entry with
	// Err!=nil names a mountpoint the kernel refused to detach — surfacing
	// the busy target so the operator does not have to grep /proc/mounts to
	// find what blocked the teardown (the #434 regression).
	SocketDirMounts []MountReleaseAttempt
	RunPath         string
	RunPathExists   bool
	RunPathRemove   bool
	// RunPathMounts is the RunPath analogue of SocketDirMounts; the run
	// path is checked separately so a busy mount under /opt/kukeon does not
	// mask a busy mount under /run/kukeon (and vice versa).
	RunPathMounts []MountReleaseAttempt
	UserName      string
	UserExisted   bool
	UserRemoved   bool
	GroupName     string
	GroupExisted  bool
	GroupRemoved  bool
	// BuildCaches records the per-namespace BuildKit state directories the
	// uninstall pass reclaimed (issue #904). One entry per realm whose
	// containerd namespace was successfully removed; ordered to match
	// Realms. A realm whose namespace survived contributes no entry —
	// leaving its cache in place is intentional, see BuildCachePurgeOutcome.
	BuildCaches []BuildCachePurgeOutcome
	// BuildCacheBaseDir is the directory the renderer attempted to rmdir
	// after the per-namespace sweep. Empty when no BuildKit cache was
	// touched (no realm purged with NamespaceRemoved=true).
	BuildCacheBaseDir string
	// BuildCacheBaseExisted reports whether BuildCacheBaseDir existed at
	// the start of the rmdir step (after the per-namespace sweep). Lets the
	// renderer distinguish "absent" from "kept".
	BuildCacheBaseExisted bool
	// BuildCacheBaseRemoved reports whether BuildCacheBaseDir was rmdir'd.
	// Only true when the base directory was empty after the per-namespace
	// sweep — a scoped uninstall (`--server-configuration` narrowing the
	// realm set) leaves cousin-instance caches untouched and the base dir
	// stays. Plain `os.Remove`, not `RemoveAll`: stomping on another
	// instance's cache would be a regression of the scoping invariant.
	BuildCacheBaseRemoved bool
}

UninstallReport summarizes what Uninstall did.

CleanupSkipped is true when the filesystem + user/group teardown steps were skipped because at least one realm failed to drop its containerd namespace. Tearing out /opt/kukeon while a residual namespace is still pinning overlay mounts on disk left a half-cleaned host where the next `kuke init` had to coexist with stale containerd state — see issue #287.

type UserGroupRemovalReport added in v0.3.0

type UserGroupRemovalReport struct {
	UserExisted  bool
	UserRemoved  bool
	GroupExisted bool
	GroupRemoved bool
}

UserGroupRemovalReport mirrors the user/group fields on UninstallReport without forcing the implementation to know the report type's layout.

type UserGroupRemover added in v0.3.0

type UserGroupRemover func(ctx context.Context, user, group string) (UserGroupRemovalReport, error)

UserGroupRemover removes a system user and group from the host. The real implementation shells out to userdel/groupdel; tests inject a stub.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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