Documentation
¶
Index ¶
- Constants
- type BlueprintCellSpec
- type BlueprintContainer
- type BlueprintSecretSlot
- type CellBindingRef
- type CellBlueprintDoc
- type CellBlueprintMetadata
- type CellBlueprintParameter
- type CellBlueprintSpec
- type CellConfigBlueprintRef
- type CellConfigDoc
- type CellConfigMetadata
- type CellConfigRepoFill
- type CellConfigSecretFill
- type CellConfigSpec
- type CellDoc
- type CellMetadata
- type CellNetworkStatus
- type CellProfileParameterdeprecated
- type CellProvenance
- type CellSpec
- type CellState
- type CellStatus
- type CellTty
- type ClientConfigurationDoc
- type ClientConfigurationMetadata
- type ClientConfigurationSpec
- type ContainerCapabilities
- type ContainerDoc
- type ContainerGit
- type ContainerMetadata
- type ContainerRepo
- type ContainerResources
- type ContainerSecret
- type ContainerSecretRef
- type ContainerSpec
- type ContainerState
- type ContainerStatus
- type ContainerTmpfsMount
- type ContainerTty
- type EgressAllowRule
- type EgressDefault
- type EgressPolicy
- type GitIdentity
- type Kind
- type RealmDoc
- type RealmMetadata
- type RealmSpec
- type RealmState
- type RealmStatus
- type RegistryCredentials
- type RepoStatus
- type SecretDoc
- type SecretMetadata
- type SecretSpec
- type ServerConfigurationDoc
- type ServerConfigurationMetadata
- type ServerConfigurationSpec
- type SpaceContainerDefaults
- type SpaceDefaults
- type SpaceDoc
- type SpaceMetadata
- type SpaceNetwork
- type SpaceSpec
- type SpaceState
- type SpaceStatus
- type StackDoc
- type StackMetadata
- type StackSpec
- type StackState
- type StackStatus
- type StageStatus
- type TtyStage
- type Version
- type VolumeKind
- type VolumeMount
Constants ¶
const ( BindingKindConfig = "config" BindingKindBlueprint = "blueprint" )
Binding-kind discriminants for CellProvenance.BindingKind. A cell is materialized either from a Config (`kuke run <config>`) or directly from a Blueprint (`kuke run -b`); the kind tells P4 which binding channel to re-resolve against.
const ( // BlueprintSecretModeEnv injects the resolved secret as an environment // variable named EnvName. The default when Mode is empty. BlueprintSecretModeEnv = "env" // BlueprintSecretModeFile stages the resolved secret as a read-only file // mount at MountPath. BlueprintSecretModeFile = "file" )
Secret-slot modes.
const ( StatePendingStr = "Pending" StateReadyStr = "Ready" StateStoppedStr = "Stopped" StatePausedStr = "Paused" StatePausingStr = "Pausing" StateFailedStr = "Failed" StateUnknownStr = "Unknown" StateCreatingStr = "Creating" StateDeletingStr = "Deleting" // StateNotCreatedStr is the display label for a container with no // containerd record at all (see ContainerStateNotCreated). StateNotCreatedStr = "NotCreated" // StateExitedStr is the display label for a clean self-exit terminal — a // cell whose workloads all exited 0, or a container task that exited 0 // (see CellStateExited / ContainerStateExited, #1267). StateExitedStr = "Exited" // StateErrorStr is the display label for a workload-crash terminal — a // cell with a non-zero workload exit, or a container task that exited // non-zero (see CellStateError / ContainerStateError, #1267). Distinct // from StateFailedStr, which is reserved for kukeon's own bring-up faults. StateErrorStr = "Error" )
Common printable state strings.
const ( // RunOnStart forwards the stage to sbsh's Stages.OnInit (in-shell, every // boot). The default when RunOn is empty. RunOnStart = "start" // RunOnCreate routes the stage into kuketty's pre-Serve executor: it runs // to completion before the workload starts and is never handed to sbsh. RunOnCreate = "create" )
TtyStage.RunOn values. Empty deserializes as RunOnStart.
const ( // GitSignCommits enables commit signing (commit.gpgsign=true). GitSignCommits = "commits" // GitSignTags enables tag signing (tag.gpgsign=true). GitSignTags = "tags" )
GitSignTarget enumerates the artefacts ContainerGit.Sign can enable signing for. An entry maps to the matching git config key (commit.gpgsign / tag.gpgsign) in the expanded GIT_CONFIG_* block.
const ( // LabelTeam scopes an applied CellBlueprint / CellConfig to a project // (issue #1027). `kuke team init` (#796) stamps it on every object it // applies for one project so a repeat init can prune the team's prior // objects that the new roster no longer declares — converging the // project's slice without touching other teams' objects. LabelTeam = "kukeon.io/team" )
Label keys with reserved kukeon.io semantics. Other label keys on a resource's metadata.labels are user-controlled and carry no daemon meaning.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BlueprintCellSpec ¶ added in v0.6.0
type BlueprintCellSpec struct {
Tty *CellTty `json:"tty,omitempty" yaml:"tty,omitempty"`
Containers []BlueprintContainer `json:"containers" yaml:"containers"`
AutoDelete bool `json:"autoDelete,omitempty" yaml:"autoDelete,omitempty"`
NestedCgroupRuntime bool `json:"nestedCgroupRuntime,omitempty" yaml:"nestedCgroupRuntime,omitempty"`
}
BlueprintCellSpec is the cell template body of a CellBlueprint. It mirrors the runtime CellSpec's user-authorable surface but is a deliberately decoupled type: its containers carry structural slot declarations (BlueprintContainer.Secrets) whose shape differs from the runtime ContainerSpec, and it omits the daemon-stamped identity fields (id, realmId, spaceId, stackId) that materialization fills from the blueprint's metadata and the generated cell name. Materialization (internal/cellblueprint) maps it to a CellSpec.
type BlueprintContainer ¶ added in v0.6.0
type BlueprintContainer struct {
ID string `json:"id" yaml:"id"`
Root bool `json:"root,omitempty" yaml:"root,omitempty"`
Image string `json:"image" yaml:"image"`
Command string `json:"command,omitempty" yaml:"command,omitempty"`
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
WorkingDir string `json:"workingDir,omitempty" yaml:"workingDir,omitempty"`
Env []string `json:"env,omitempty" yaml:"env,omitempty"`
Ports []string `json:"ports,omitempty" yaml:"ports,omitempty"`
Volumes []VolumeMount `json:"volumes,omitempty" yaml:"volumes,omitempty"`
Networks []string `json:"networks,omitempty" yaml:"networks,omitempty"`
NetworksAliases []string `json:"networksAliases,omitempty" yaml:"networksAliases,omitempty"`
Privileged bool `json:"privileged,omitempty" yaml:"privileged,omitempty"`
HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"`
HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"`
HostCgroup bool `json:"hostCgroup,omitempty" yaml:"hostCgroup,omitempty"`
User string `json:"user,omitempty" yaml:"user,omitempty"`
ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty" yaml:"readOnlyRootFilesystem,omitempty"`
Capabilities *ContainerCapabilities `json:"capabilities,omitempty" yaml:"capabilities,omitempty"`
SecurityOpts []string `json:"securityOpts,omitempty" yaml:"securityOpts,omitempty"`
// Devices grants per-host-device passthrough (short form, e.g. "/dev/kvm")
// — the least-privilege alternative to Privileged. Mirrors
// ContainerSpec.Devices; see that field for semantics. Issue #1252.
Devices []string `json:"devices,omitempty" yaml:"devices,omitempty"`
Tmpfs []ContainerTmpfsMount `json:"tmpfs,omitempty" yaml:"tmpfs,omitempty"`
Resources *ContainerResources `json:"resources,omitempty" yaml:"resources,omitempty"`
Repos []ContainerRepo `json:"repos,omitempty" yaml:"repos,omitempty"`
Git *ContainerGit `json:"git,omitempty" yaml:"git,omitempty"`
RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"`
Attachable bool `json:"attachable,omitempty" yaml:"attachable,omitempty"`
Tty *ContainerTty `json:"tty,omitempty" yaml:"tty,omitempty"`
Secrets []BlueprintSecretSlot `json:"secrets,omitempty" yaml:"secrets,omitempty"`
}
BlueprintContainer is one container in a blueprint's cell template. It carries the user-authorable subset of ContainerSpec verbatim (so a blueprint can express the same workload a hand-written Cell can), plus two structural slot channels:
- Repos reuses the runtime ContainerRepo shape, but unlike `kuke apply`'s Cell/Container path the url is *not* required at apply time: a repo with no url is a structural slot a CellConfig fills (#624). A repo whose url is supplied inline (directly or via a `${PARAM}`) runs as-is under `kuke run -b`.
- Secrets is a slot-only channel (BlueprintSecretSlot): the blueprint declares the consumption side (env vs file, the env var / mount path); the source side (which kind: Secret provides the bytes) is filled by a CellConfig (#624). Because the source is never part of a blueprint, a blueprint that declares secret slots cannot be run inline with `-b` — it requires `kuke run -c` (#625).
Daemon-stamped / runtime-resolved fields (containerdId, realmId, spaceId, stackId, cellId, kukeonGroupGID) are intentionally absent: materialization and the runner fill them.
type BlueprintSecretSlot ¶ added in v0.6.0
type BlueprintSecretSlot struct {
// Name is the slot's identity, unique within the container. A CellConfig
// fills the slot by this name (#624). Required.
Name string `json:"name" yaml:"name"`
// Mode selects how the resolved secret is injected: "env" (default) sets
// an environment variable named EnvName; "file" stages a read-only file
// mount at MountPath.
Mode string `json:"mode,omitempty" yaml:"mode,omitempty"`
// EnvName is the environment variable name for Mode "env". Required when
// Mode is "env".
EnvName string `json:"envName,omitempty" yaml:"envName,omitempty"`
// MountPath is the absolute in-container path for Mode "file". Required
// when Mode is "file".
MountPath string `json:"mountPath,omitempty" yaml:"mountPath,omitempty"`
// Required gates whether a CellConfig must fill this slot.
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
}
BlueprintSecretSlot is a structural secret slot declared on a blueprint container. It is the consumption side of the two-channel interface (#423): the blueprint owns where the secret lands inside the container (env var or file mount), and a CellConfig owns the source side (which kind: Secret provides the bytes, #624). Name is the slot identity a CellConfig matches against; it is independent of the env var name so a Config can fill the same slot regardless of how the container consumes it.
type CellBindingRef ¶ added in v0.6.0
type CellBindingRef struct {
Name string `json:"name" yaml:"name"`
Realm string `json:"realm" yaml:"realm"`
Space string `json:"space,omitempty" yaml:"space,omitempty"`
Stack string `json:"stack,omitempty" yaml:"stack,omitempty"`
}
CellBindingRef is a scoped reference to the Config or Blueprint a cell was materialized from. The scope coordinates follow the same realm/space/stack contract every scoped kind uses (realm always set; a deeper coordinate requires every shallower one). Issue #1021.
type CellBlueprintDoc ¶ added in v0.6.0
type CellBlueprintDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata CellBlueprintMetadata `json:"metadata" yaml:"metadata"`
Spec CellBlueprintSpec `json:"spec" yaml:"spec"`
}
CellBlueprintDoc is a daemon-stored, scopable parametrized cell template (kind: CellBlueprint, issue #620, phase 4a-i of #423). The client-side CellProfile kind that originally co-existed with it was removed in #626 — `kuke apply` is now the single entry point and `kuke run -b` / `kuke run -c` are the run-time consumers.
A Blueprint declares two fill channels (see #423 "L1↔L2 interface"):
- Scalar parameters — `${KEY}` substitution using the CellBlueprintParameter shape. Filled inline by `kuke run -b --param K=V`.
- Structural slots — named repo/secret slots on each container that a CellConfig fills with structured values (repo URLs, secret sources). This kind ships the slot *declarations* only; the Config-side fill machinery lands in #624.
type CellBlueprintMetadata ¶ added in v0.6.0
type CellBlueprintMetadata struct {
// Name is the blueprint's name, unique within its scope.
Name string `json:"name" yaml:"name"`
// Realm is the always-required top-level scope coordinate.
Realm string `json:"realm" yaml:"realm"`
// Space, when set, scopes the blueprint to a space within Realm.
Space string `json:"space,omitempty" yaml:"space,omitempty"`
// Stack, when set, scopes the blueprint to a stack within Space.
Stack string `json:"stack,omitempty" yaml:"stack,omitempty"`
// Labels are copied onto every cell materialized from this blueprint, in
// addition to the kukeon.io/blueprint back-reference label.
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
}
CellBlueprintMetadata identifies a Blueprint by name and the scope it is bound to. Unlike a Secret, a Blueprint is scopable at realm, space, or stack only — never cell: a template scoped to a single cell is nonsensical (#423). The scope is the deepest non-empty coordinate; a deeper coordinate requires every shallower one (a stack-scoped Blueprint must also name its space and realm). Realm is always required.
type CellBlueprintParameter ¶ added in v0.6.0
type CellBlueprintParameter struct {
Name string `json:"name" yaml:"name"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Default *string `json:"default,omitempty" yaml:"default,omitempty"`
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
}
CellBlueprintParameter declares one `${KEY}` substitution variable used by a CellBlueprint's body. Default is a pointer so YAML/JSON can distinguish "no default" (nil) from an explicit empty default (""). The substitution engine treats them differently: a missing default falls through to the env-var lookup, while an explicit empty default short-circuits there.
type CellBlueprintSpec ¶ added in v0.6.0
type CellBlueprintSpec struct {
Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
Parameters []CellBlueprintParameter `json:"parameters,omitempty" yaml:"parameters,omitempty"`
Cell BlueprintCellSpec `json:"cell" yaml:"cell"`
}
CellBlueprintSpec carries the scalar parameter declarations plus the cell template body. Prefix overrides the cell-name prefix used when generating the `<prefix>-<6hex>` name on each `kuke run -b`; when unset it defaults to metadata.name. Every run produces a fresh hex-suffixed cell — the "Blueprint = always fresh" invariant.
type CellConfigBlueprintRef ¶ added in v0.6.0
type CellConfigBlueprintRef struct {
// Name is the referenced CellBlueprint's name within its scope. Required.
Name string `json:"name" yaml:"name"`
// Realm is the always-required top-level scope coordinate of the blueprint.
Realm string `json:"realm" yaml:"realm"`
// Space, when set, scopes the reference to a space within Realm.
Space string `json:"space,omitempty" yaml:"space,omitempty"`
// Stack, when set, scopes the reference to a stack within Space.
Stack string `json:"stack,omitempty" yaml:"stack,omitempty"`
}
CellConfigBlueprintRef references a CellBlueprint by name and scope. Name and Realm are required; Space/Stack are optional and follow the blueprint scope-coordinate contract (a deeper coordinate requires every shallower one). The reference may cross scopes — a Config in one realm may instantiate a Blueprint owned by another (e.g. a `default`-realm Config referencing a `kuke-system`-scoped template), the same cross-scope freedom a secretRef has.
type CellConfigDoc ¶ added in v0.6.0
type CellConfigDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata CellConfigMetadata `json:"metadata" yaml:"metadata"`
Spec CellConfigSpec `json:"spec" yaml:"spec"`
}
CellConfigDoc is the top-level document for a daemon-stored cell *identity* (kind: CellConfig, issue #624, phase 4b-i of #423). Where a CellBlueprint is the parametrized template (the "what"), a CellConfig binds that template to a concrete instance (the "which one"): it references a Blueprint by name+scope, supplies the scalar `values` and the structural repo/secret slot fills, and owns the deterministic name of the at-most-one live cell it materializes.
This kind ships the schema, daemon storage, `kuke apply`, slot-fill validation against the referenced Blueprint, and the stable-name + back-ref identity primitives. The runtime state machine that drives materialise/attach/start/refuse — and the `kuke run -c` verb it serves — lands in #625; a Config carries no Status because it has no runtime here.
type CellConfigMetadata ¶ added in v0.6.0
type CellConfigMetadata struct {
// Name is the config's name, unique within its scope. A Config is a 1:N
// binding (epic:cell-identity #1020): it may stamp many cells, each owning
// its own identity on the CellDoc. When Spec.Prefix is unset, Name is also
// the default cell-name prefix the unified generator uses (see
// internal/cellconfig.Prefix).
Name string `json:"name" yaml:"name"`
// Realm is the always-required top-level scope coordinate.
Realm string `json:"realm" yaml:"realm"`
// Space, when set, scopes the config to a space within Realm.
Space string `json:"space,omitempty" yaml:"space,omitempty"`
// Stack, when set, scopes the config to a stack within Space.
Stack string `json:"stack,omitempty" yaml:"stack,omitempty"`
// Labels are copied onto the cell materialized from this config, in
// addition to the kukeon.io/config back-reference label.
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
// Annotations carry non-identifying metadata about the config. Unlike
// Labels they are not copied onto the materialized cell.
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
}
CellConfigMetadata identifies a Config by name and the scope it is bound to. Like a CellBlueprint (and unlike a Secret) a Config is scopable at realm, space, or stack only — never cell: a Config materializes a cell, so scoping it to a single cell is nonsensical. The scope is the deepest non-empty coordinate; a deeper coordinate requires every shallower one. Realm is always required. Labels are copied onto the materialized cell in addition to the kukeon.io/config back-reference label.
type CellConfigRepoFill ¶ added in v0.6.0
type CellConfigRepoFill struct {
// URL is the clone URL filling the slot. Required.
URL string `json:"url" yaml:"url"`
// Branch is the branch to check out. Empty clones the remote's default.
// Mutually exclusive with Ref.
Branch string `json:"branch,omitempty" yaml:"branch,omitempty"`
// Ref is an immutable pin (tag or full commit SHA) — see
// ContainerRepo.Ref. Mutually exclusive with Branch.
Ref string `json:"ref,omitempty" yaml:"ref,omitempty"`
}
CellConfigRepoFill fills a structural repo slot the referenced blueprint declared (a BlueprintContainer repo with no inline url). It supplies the clone source the blueprint deliberately left open. URL is required.
type CellConfigSecretFill ¶ added in v0.6.0
type CellConfigSecretFill struct {
// SecretRef points at the kind: Secret that provides the slot's bytes.
// Required.
SecretRef *ContainerSecretRef `json:"secretRef,omitempty" yaml:"secretRef,omitempty"`
}
CellConfigSecretFill fills a structural secret slot the referenced blueprint declared (a BlueprintSecretSlot). The blueprint owns the consumption side (env var or file mount); this supplies the source side — which kind: Secret provides the bytes. SecretRef is required.
type CellConfigSpec ¶ added in v0.6.0
type CellConfigSpec struct {
// Prefix overrides the cell-name prefix used when the unified generator
// derives a `<prefix>-<6hex>` name for a cell materialized from this Config
// with no explicit name (epic:cell-identity #1022); when unset it defaults
// to metadata.name. Mirrors CellBlueprintSpec.Prefix — a Config is a 1:N
// binding, so each `create cell --from-config` (no name) stamps a fresh
// hex-suffixed cell.
Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
// Blueprint references the CellBlueprint this config instantiates.
Blueprint CellConfigBlueprintRef `json:"blueprint" yaml:"blueprint"`
// Values fill the referenced blueprint's `${KEY}` scalar parameters. Stored
// verbatim here; resolution happens at run time (#625).
Values map[string]string `json:"values,omitempty" yaml:"values,omitempty"`
// Repos fills the blueprint's structural repo slots, keyed by slot name.
Repos map[string]CellConfigRepoFill `json:"repos,omitempty" yaml:"repos,omitempty"`
// Secrets fills the blueprint's structural secret slots, keyed by slot name.
Secrets map[string]CellConfigSecretFill `json:"secrets,omitempty" yaml:"secrets,omitempty"`
}
CellConfigSpec binds a referenced Blueprint to a concrete instance: the scalar `values` filled into the blueprint's `${KEY}` parameters, and the structural repo/secret slot fills keyed by the blueprint's slot names. Values are stored verbatim and resolved at run time (#625); the repo/secret maps are validated against the referenced blueprint's declared slots at apply time.
type CellDoc ¶
type CellDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata CellMetadata `json:"metadata" yaml:"metadata"`
Spec CellSpec `json:"spec" yaml:"spec"`
Status CellStatus `json:"status" yaml:"status"`
}
func NewCellDoc ¶
NewCellDoc creates a CellDoc ensuring all nested structs are initialized.
type CellMetadata ¶
type CellMetadata struct {
Name string `json:"name" yaml:"name"`
Labels map[string]string `json:"labels" yaml:"labels"`
// Annotations carry non-identifying metadata about the cell. Unlike
// Labels, no reconcile or selector path keys off them, and DiffCell
// deliberately does not compare them — a clone's
// `kukeon.io/source-cell: <src>` provenance annotation must never trip a
// false OutOfSync (epic:cell-identity #1073). Mirrors the Annotations map
// CellConfig/CellBlueprint already carry.
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
// Generation is a monotonic counter bumped by a writer on each
// spec-changing update. Defaults to zero; phase 3 wires the writers to
// populate it. See ObservedGeneration on the status.
Generation int64 `json:"generation,omitempty" yaml:"generation,omitempty"`
}
type CellNetworkStatus ¶ added in v0.3.0
type CellNetworkStatus struct {
BridgeName string `json:"bridgeName,omitempty" yaml:"bridgeName,omitempty"`
}
CellNetworkStatus exposes the host-side bridge a cell is attached to. Populated by the runner during cell provisioning so describe/get -o yaml surfaces the iface name without recomputing the hash. Always emitted in the canonical k-{8hex} form (see cni.SafeBridgeName).
type CellProfileParameter
deprecated
added in
v0.4.0
type CellProfileParameter = CellBlueprintParameter
CellProfileParameter is the pre-#986 name for CellBlueprintParameter, kept as a deprecated alias for one release so sibling projects (sbsh, sbcrew, …) can rename on their own cadence. The on-wire YAML/JSON shape is unchanged.
Deprecated: use CellBlueprintParameter. Scheduled for removal in v0.7.0.
type CellProvenance ¶ added in v0.6.0
type CellProvenance struct {
// BindingKind is "config" or "blueprint" (see BindingKind* constants).
BindingKind string `json:"bindingKind" yaml:"bindingKind"`
// BindingRef is the scoped name of the Config or Blueprint this cell was
// materialized from — the lineage back-reference P4 re-resolves against.
BindingRef CellBindingRef `json:"bindingRef" yaml:"bindingRef"`
// Params are the scalar values resolved into the binding at
// materialization time (a Config's spec.values, or a Blueprint's
// resolved --param map). Persisted verbatim so re-resolution does not
// depend on re-reading transient CLI state.
Params map[string]string `json:"params,omitempty" yaml:"params,omitempty"`
// EnvOverrides are the `--env KEY=VALUE` entries supplied at run time.
// Mirrors the values RuntimeEnv carries transiently, but persisted here
// so a later re-resolution sees the same overrides the operator chose.
EnvOverrides []string `json:"envOverrides,omitempty" yaml:"envOverrides,omitempty"`
}
CellProvenance is the typed record of the inputs a cell was materialized from. See CellSpec.Provenance for the lifecycle contract. Issue #1021.
func CloneCellProvenance ¶ added in v0.6.0
func CloneCellProvenance(in *CellProvenance) *CellProvenance
CloneCellProvenance deep-copies a *CellProvenance so mutations on a materialized cell (or a converted copy) cannot leak back into a shared source. Returns nil for a nil input. Issue #1021.
type CellSpec ¶
type CellSpec struct {
ID string `json:"id" yaml:"id"`
RealmID string `json:"realmId" yaml:"realmId"`
SpaceID string `json:"spaceId" yaml:"spaceId"`
StackID string `json:"stackId" yaml:"stackId"`
RootContainerID string `json:"rootContainerId,omitempty" yaml:"rootContainerId,omitempty"`
Tty *CellTty `json:"tty,omitempty" yaml:"tty,omitempty"`
Containers []ContainerSpec `json:"containers" yaml:"containers"`
// AutoDelete asks kukeond to delete this cell best-effort after its root
// container's task exits (any rc). Set by `kuke run --rm`. Cleanup is
// scoped to the cell only — never cascades to stack/space/realm.
// Cleanup is driven by kukeond's reconcile loop: the next pass that
// observes the root task as Stopped/Failed runs KillCell+DeleteCell on
// the cell. Latency is bounded by the reconcile interval, and the
// trigger survives daemon restarts (no per-cell goroutine needs to be
// re-installed on startup).
AutoDelete bool `json:"autoDelete,omitempty" yaml:"autoDelete,omitempty"`
// NestedCgroupRuntime opts the cell into delegating the full
// host-available cgroup-v2 controller set on its cgroup.subtree_control,
// rather than the kukeon resource subset (cpu/memory/io/pids). This is
// the knob a cell that hosts a nested cgroup runtime — an inner
// containerd, runc, or systemd that places its own children in
// sub-cgroups under the cell — needs so the inner runtime can in turn
// delegate any controller it wants to its workloads. Default false
// keeps the existing cell-as-leaf semantics (issue #312) untouched.
NestedCgroupRuntime bool `json:"nestedCgroupRuntime,omitempty" yaml:"nestedCgroupRuntime,omitempty"`
// RuntimeEnv carries CLI-injected env entries (KUKE_RUN's --env
// KEY=VALUE) for the cell's attachable container, merged into the
// container's OCI process env at cell start time. Entries collide-and-
// replace against spec.containers[<attachable>].env (--env wins on
// matching KEY). Set by `kuke run --env` from the CLI; never authored
// in a YAML manifest, never read back off a daemon RPC response.
//
// Transport-only field with two boundary contracts:
//
// 1. The `yaml:"-"` tag keeps it out of any YAML-author surface.
// 2. JSON-RPC carries it CLI → daemon (where the daemon's StartCell /
// CreateCell handler copies it onto the internalCell before the
// runner uses it for OCI build). The daemon → CLI direction in
// apischeme.BuildCellExternalFromInternal deliberately drops it,
// which simultaneously keeps metadata.json clean (the same builder
// produces the disk-write doc) and keeps the divergent-spec check
// on a subsequent `kuke run <config>` from tripping on the prior
// --env injection. Each invocation re-supplies its own RuntimeEnv.
//
// Issue #834.
RuntimeEnv []string `json:"runtimeEnv,omitempty" yaml:"-"`
// Provenance records the materialization inputs this cell was stamped
// from — the binding it was instantiated against (a Blueprint or a
// Config), the scoped reference to that binding, and the scalar params /
// env overrides supplied at materialization time. It is the persisted
// record P4 re-runs to recompute the would-be desired spec for the
// OutOfSync diff, and the binding reference P2's name generator reads for
// the cell-name prefix (epic:cell-identity, umbrella #1020).
//
// Unlike RuntimeEnv (transport-only, yaml:"-"), Provenance IS persisted:
// it carries no yaml:"-" so it survives both the JSON metadata.json write
// and a `kuke get cell -o yaml` round-trip. It is identity/lineage data,
// not a runtime spec field, so DiffCell deliberately does not compare it
// (a provenance-only difference must never report a cell OutOfSync). A
// hand-built cell that was never materialized from a binding carries a
// nil Provenance. Issue #1021.
Provenance *CellProvenance `json:"provenance,omitempty" yaml:"provenance,omitempty"`
// IgnoreDiskPressure bypasses kukeond's data-volume disk-pressure guard for
// this cell's creation (issue #1035). Set by `kuke create cell` /
// `kuke run --ignore-disk-pressure`. Transport-only with the same two
// boundary contracts as RuntimeEnv: the `yaml:"-"` tag keeps it out of any
// YAML-author surface, and JSON-RPC carries it CLI → daemon where the
// CreateCell guard reads it. The daemon → CLI direction in
// apischeme.BuildCellExternalFromInternal deliberately drops it so the
// per-invocation override never persists into the stored cell spec; each
// `kuke create`/`kuke run` re-supplies its own.
IgnoreDiskPressure bool `json:"ignoreDiskPressure,omitempty" yaml:"-"`
}
type CellState ¶
type CellState int
const ( CellStatePending CellState = iota CellStateReady CellStateStopped CellStateFailed CellStateUnknown // CellStateExited is the clean self-exit terminal: every workload in the // cell exited 0 of its own accord (#1267). Distinct from CellStateStopped // (operator `kuke stop`/`kill`) and from CellStateError (a workload // crashed). Appended last to keep the ordinals in lockstep with the // internal modelhub.CellState enum, which scheme.go converts by direct // int cast. CellStateExited // CellStateError is the workload-crash terminal: at least one workload // exited non-zero (#1267). Inherits CellStateFailed's sticky / no-auto- // delete behavior, but reserves CellStateFailed for kukeon's own bring-up // failures. Appended last (after CellStateExited) for the same ordinal- // lockstep reason. CellStateError )
func (CellState) MarshalJSON ¶ added in v0.5.0
func (CellState) MarshalYAML ¶ added in v0.5.0
func (*CellState) UnmarshalJSON ¶ added in v0.5.0
type CellStatus ¶
type CellStatus struct {
State CellState `json:"state" yaml:"state"`
CgroupPath string `json:"cgroupPath" yaml:"cgroupPath"`
// SubtreeControllers is the cgroup-v2 controller set actually
// delegated on this cell's own cgroup.subtree_control after the
// host-root filter (issue #328). For NestedCgroupRuntime cells this
// is the full host-available set; for ordinary cells it's the
// kukeon resource subset (cpu/memory/io/pids).
SubtreeControllers []string `json:"subtreeControllers,omitempty" yaml:"subtreeControllers,omitempty"`
Network CellNetworkStatus `json:"network,omitempty" yaml:"network,omitempty"`
Containers []ContainerStatus `json:"containers" yaml:"containers"`
// ReadyObserved is the persisted form of the one-way latch the
// reconciler uses to gate Spec.AutoDelete cleanup. Once a cell has
// been observed Ready it stays true across daemon restarts so that
// cleanup of a `kuke run --rm` cell that was already Ready at
// shutdown still fires on the next tick after restart.
ReadyObserved bool `json:"readyObserved,omitempty" yaml:"readyObserved,omitempty"`
// Lifecycle and runtime-health fields — see RealmStatus for the
// per-field contract; the semantics carry across all four kinds.
CreatedAt time.Time `json:"createdAt,omitempty" yaml:"createdAt,omitempty"`
UpdatedAt time.Time `json:"updatedAt,omitempty" yaml:"updatedAt,omitempty"`
ReadyAt time.Time `json:"readyAt,omitempty" yaml:"readyAt,omitempty"`
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
CgroupReady bool `json:"cgroupReady,omitempty" yaml:"cgroupReady,omitempty"`
// ObservedGeneration is the Metadata.Generation the reconciler last
// acted on. Defaults to zero; phase 3 wires the reconciler to compare
// it against Generation to skip stale work.
ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"`
// OutOfSync is true when the daemon's reconciler detects that this
// cell's live spec has diverged from what its lineage Config would
// materialize (issue #820, foundation phase of #819's umbrella). Only
// set on cells carrying the kukeon.io/config lineage label; cells
// without that label leave it false. OutOfSyncReason carries a short
// human-readable summary when true. OutOfSyncError carries a distinct
// failure surface when the reconciler could not compute divergence at
// all (referenced Blueprint missing, materialization error) — when
// non-empty, OutOfSync stays false because divergence is undecidable.
OutOfSync bool `json:"outOfSync,omitempty" yaml:"outOfSync,omitempty"`
OutOfSyncReason string `json:"outOfSyncReason,omitempty" yaml:"outOfSyncReason,omitempty"`
OutOfSyncError string `json:"outOfSyncError,omitempty" yaml:"outOfSyncError,omitempty"`
}
type CellTty ¶ added in v0.3.0
type CellTty struct {
// Default names the attachable container the post-start attach
// (`kuke run`'s default mode) selects when no --container flag is
// given. Must reference an existing container in this cell whose
// Attachable=true (or be empty).
Default string `json:"default,omitempty" yaml:"default,omitempty"`
}
CellTty is cell-level tty/attach config. Kept intentionally minimal: only fields the container or container-level tty cannot express belong here.
type ClientConfigurationDoc ¶ added in v0.3.0
type ClientConfigurationDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata ClientConfigurationMetadata `json:"metadata" yaml:"metadata"`
Spec ClientConfigurationSpec `json:"spec" yaml:"spec"`
}
ClientConfigurationDoc is the kuke-side configuration document. It is loaded by the `kuke` cobra root via `kuke --configuration <path>` (default `~/.kuke/kuke.yaml`) and seeds defaults for client-only settings such as the daemon endpoint and the default output format. It is not a server-side resource: `kuke apply` rejects it.
type ClientConfigurationMetadata ¶ added in v0.3.0
type ClientConfigurationSpec ¶ added in v0.3.0
type ClientConfigurationSpec struct {
// Host is the kukeond endpoint kuke dials by default
// (`unix:///run/kukeon/kukeond.sock` or `ssh://user@host`).
Host string `json:"host,omitempty" yaml:"host,omitempty"`
// RunPath is the kukeon runtime root used by `--no-daemon` operations
// that read /opt/kukeon directly instead of going through kukeond.
RunPath string `json:"runPath,omitempty" yaml:"runPath,omitempty"`
// ContainerdSocket is the containerd unix socket `--no-daemon`
// operations connect to.
ContainerdSocket string `json:"containerdSocket,omitempty" yaml:"containerdSocket,omitempty"`
// LogLevel is the client log level when `--verbose` is on
// (debug, info, warn, error).
LogLevel string `json:"logLevel,omitempty" yaml:"logLevel,omitempty"`
// ContainerdNamespaceSuffix is the suffix appended to every realm name
// to form its containerd namespace. Realm "default" + suffix
// "kukeon.io" -> namespace "default.kukeon.io". `--no-daemon` workload
// paths run the controller in-process and read this field to address
// the correct kukeon instance's containerd namespaces — the parallel
// of ServerConfiguration.spec.containerdNamespaceSuffix on the daemon
// side. Default: kukeon.io.
ContainerdNamespaceSuffix string `json:"containerdNamespaceSuffix,omitempty" yaml:"containerdNamespaceSuffix,omitempty"`
// CgroupRoot is the cgroup root under which all realms / spaces /
// stacks / cells live (e.g. /kukeon-dev for a parallel dev instance on
// the same host). `--no-daemon` workload paths consult this field for
// the in-process cgroup hierarchy; the parallel of
// ServerConfiguration.spec.cgroupRoot on the daemon side.
// Default: /kukeon.
CgroupRoot string `json:"cgroupRoot,omitempty" yaml:"cgroupRoot,omitempty"`
// PodSubnetCIDR is the parent block the per-space CNI subnet allocator
// subdivides into /24 chunks. `--no-daemon` workload paths that create
// spaces in-process read this field so a parallel or nested kukeon
// instance never lands on another instance's subnet; the parallel of
// ServerConfiguration.spec.podSubnetCIDR on the daemon side (issue
// #1079). Default: 10.88.0.0/16.
PodSubnetCIDR string `json:"podSubnetCIDR,omitempty" yaml:"podSubnetCIDR,omitempty"`
}
ClientConfigurationSpec carries kuke-only settings. Each field is optional: an absent or empty value falls back to the client's hardcoded default. Explicit command-line flags (`--host`, `--log-level`, …) and matching env vars (`KUKEON_HOST`, `KUKEON_LOG_LEVEL`, …) still take precedence over values loaded from this document.
type ContainerCapabilities ¶ added in v0.2.0
type ContainerCapabilities struct {
Drop []string `json:"drop,omitempty" yaml:"drop,omitempty"`
Add []string `json:"add,omitempty" yaml:"add,omitempty"`
}
ContainerCapabilities groups Linux capability deltas applied to the container process relative to the image default set.
type ContainerDoc ¶
type ContainerDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata ContainerMetadata `json:"metadata" yaml:"metadata"`
Spec ContainerSpec `json:"spec" yaml:"spec"`
Status ContainerStatus `json:"status" yaml:"status"`
}
func NewContainerDoc ¶
func NewContainerDoc(from *ContainerDoc) *ContainerDoc
NewContainerDoc creates a ContainerDoc ensuring all nested structs are initialized.
type ContainerGit ¶ added in v0.6.0
type ContainerGit struct {
// Author sets git's author identity (GIT_AUTHOR_NAME / GIT_AUTHOR_EMAIL).
// Both name and email are required when present.
Author *GitIdentity `json:"author,omitempty" yaml:"author,omitempty"`
// Committer sets git's committer identity (GIT_COMMITTER_NAME /
// GIT_COMMITTER_EMAIL). Both name and email are required when present.
Committer *GitIdentity `json:"committer,omitempty" yaml:"committer,omitempty"`
// SigningKey is the absolute in-container path to the signing key
// (user.signingkey). kukeon signs with SSH keys, so a non-empty
// SigningKey also renders gpg.format=ssh. Per-container — root-cell vs
// non-root-cell key paths stay local to the container, not globalised.
SigningKey string `json:"signingKey,omitempty" yaml:"signingKey,omitempty"`
// Sign enables signing for the listed artefacts: "commits"
// (commit.gpgsign=true) and/or "tags" (tag.gpgsign=true). Requires
// SigningKey to be set.
Sign []string `json:"sign,omitempty" yaml:"sign,omitempty"`
// AllowedSigners is the absolute in-container path to git's SSH
// allowed-signers file (gpg.ssh.allowedSignersFile), used to verify
// signatures. Optional; rendered only when set. Team blueprint templates
// set this today, so the field exists for the env block to be a strict
// superset of what those templates render.
AllowedSigners string `json:"allowedSigners,omitempty" yaml:"allowedSigners,omitempty"`
}
ContainerGit is declarative sugar over the GIT_AUTHOR_* / GIT_COMMITTER_* / GIT_CONFIG_* env-var protocol git reads natively. The container runtime expands it into that env block before container start. Author/Committer render the GIT_AUTHOR_*/GIT_COMMITTER_* identity vars; SigningKey, Sign, and AllowedSigners render the GIT_CONFIG_* signing pairs (user.signingkey, gpg.format=ssh, commit.gpgsign, tag.gpgsign, gpg.ssh.allowedSignersFile) with GIT_CONFIG_COUNT tracking the live pair count. Issue #618.
type ContainerMetadata ¶
type ContainerRepo ¶ added in v0.6.0
type ContainerRepo struct {
// Name is the operator-facing identifier for the repo, echoed back in
// per-repo status. Required.
Name string `json:"name" yaml:"name"`
// Target is the absolute in-container path the repo is cloned into.
// Required.
Target string `json:"target" yaml:"target"`
// Branch is the branch to check out (moving target). Empty clones the
// remote's default branch. Mutually exclusive with Ref.
Branch string `json:"branch,omitempty" yaml:"branch,omitempty"`
// Ref is an immutable pin — a tag name or full commit SHA. When set,
// kuketty checks out a detached HEAD at the resolved ref and skips the
// fast-forward step on subsequent restarts, so an in-place restart of
// an already-cloned cell stays idempotent instead of failing on
// `git pull` against a detached HEAD. Mutually exclusive with Branch.
Ref string `json:"ref,omitempty" yaml:"ref,omitempty"`
// URL is the clone URL. In phases 1–3 it is supplied via scalar
// ${PARAM} substitution; phase 4 (#423) enables structural slot fill
// from a CellConfig. Required.
URL string `json:"url" yaml:"url"`
// Required gates failure handling. When true, a clone/fetch failure
// makes kuketty exit non-zero before sbsh starts, so the daemon
// observes the container task as Failed. When false (the default) the
// failure is logged but the container proceeds.
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
}
ContainerRepo declares a git repository the container depends on. kuketty clones (or fetches) it into Target before the workload starts, replacing the hand-rolled `if [ ! -d $DIR/.git ]; then git clone …; fi` blocks that team blueprint templates duplicate in onInit scripts today. The clone state becomes daemon-observable via ContainerStatus.Repos (reported over RPC in phase 1b, #642) rather than buried in attach stderr. Issue #617, phase 1a of #423.
type ContainerResources ¶ added in v0.2.0
type ContainerResources struct {
MemoryLimitBytes *int64 `json:"memoryLimitBytes,omitempty" yaml:"memoryLimitBytes,omitempty"`
PidsLimit *int64 `json:"pidsLimit,omitempty" yaml:"pidsLimit,omitempty"`
}
ContainerResources exposes the cgroup v2 knobs the orchestrator supports for per-container resource limits.
type ContainerSecret ¶ added in v0.2.0
type ContainerSecret struct {
Name string `json:"name" yaml:"name"`
FromFile string `json:"fromFile,omitempty" yaml:"fromFile,omitempty"`
FromEnv string `json:"fromEnv,omitempty" yaml:"fromEnv,omitempty"`
SecretRef *ContainerSecretRef `json:"secretRef,omitempty" yaml:"secretRef,omitempty"`
MountPath string `json:"mountPath,omitempty" yaml:"mountPath,omitempty"`
}
ContainerSecret references a credential that the daemon resolves at apply time and injects into the container — either as an environment variable (default) or as a read-only file when MountPath is set. Only the reference is persisted; the resolved value is never written to status, metadata, or logs.
Exactly one source must be set: FromFile (host-path reference), FromEnv (daemon-host env var), or SecretRef (a daemon-managed kind: Secret resolved from its scope's storage tree, issue #623). The env-vs-file dispatch is the same for all three: empty MountPath injects an env var, a set MountPath stages a read-only file mount.
type ContainerSecretRef ¶ added in v0.6.0
type ContainerSecretRef struct {
// Name is the referenced Secret's name within its scope. Required.
Name string `json:"name" yaml:"name"`
// Realm is the always-required top-level scope coordinate.
Realm string `json:"realm" yaml:"realm"`
// Space, when set, scopes the reference to a space within Realm.
Space string `json:"space,omitempty" yaml:"space,omitempty"`
// Stack, when set, scopes the reference to a stack within Space.
Stack string `json:"stack,omitempty" yaml:"stack,omitempty"`
// Cell, when set, scopes the reference to a cell within Stack.
Cell string `json:"cell,omitempty" yaml:"cell,omitempty"`
}
ContainerSecretRef points at a daemon-managed kind: Secret (issue #619) by name and scope. The scope follows the same coordinate contract as SecretMetadata: Realm is always required and a deeper coordinate may only be set when every shallower one is (a cell-scoped reference must also name its stack, space, and realm). The reference resolves to the same on-disk path the Secret's bytes were written to, so a container in one realm may reference a Secret owned by another (e.g. a workload in `default` reading a `kuke-system`-scoped token). Issue #623.
type ContainerSpec ¶
type ContainerSpec struct {
ID string `json:"id" yaml:"id"`
ContainerdID string `json:"containerdId,omitempty" yaml:"containerdId,omitempty"`
RealmID string `json:"realmId" yaml:"realmId"`
SpaceID string `json:"spaceId" yaml:"spaceId"`
StackID string `json:"stackId" yaml:"stackId"`
CellID string `json:"cellId" yaml:"cellId"`
Root bool `json:"root,omitempty" yaml:"root,omitempty"`
Image string `json:"image" yaml:"image"`
Command string `json:"command" yaml:"command"`
Args []string `json:"args" yaml:"args"`
// WorkingDir sets the cwd of the spawned container process — OCI
// process.cwd, Docker WORKDIR, K8s Container.workingDir. Empty falls
// back to the image's WORKDIR (no behavior change for existing specs).
WorkingDir string `json:"workingDir,omitempty" yaml:"workingDir,omitempty"`
Env []string `json:"env" yaml:"env"`
Ports []string `json:"ports" yaml:"ports"`
Volumes []VolumeMount `json:"volumes" yaml:"volumes"`
Networks []string `json:"networks" yaml:"networks"`
NetworksAliases []string `json:"networksAliases" yaml:"networksAliases"`
Privileged bool `json:"privileged" yaml:"privileged"`
// HostNetwork opts the container into the host's network namespace.
// When true, the runner omits the network LinuxNamespace from the OCI
// spec (containerd's WithHostNamespace) and does not invoke CNI attach,
// since a host-netns container has no per-container veth to wire up.
// Used by the kukeond bootstrap so daemon-installed bridges, veths, and
// iptables rules land in host scope where kubelet-style CNI plumbing
// belongs. Default false — no behavior change for existing specs.
HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"`
// HostPID opts the container into the host's PID namespace. When true,
// the runner omits the PID LinuxNamespace from the OCI spec so /proc
// inside the container reflects host PIDs. Used by the kukeond bootstrap
// so the CNI bridge plugin running inside the daemon can resolve the
// host PIDs containerd returns from task.Pid() — without this, attaching
// user cells to a network fails with `Statfs /proc/<host-pid>/ns/net:
// no such file or directory`. Default false — no behavior change for
// existing specs.
HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"`
// HostCgroup, when true, opts the container into its parent's cgroup
// namespace. Default false unshares the cgroup-ns: the container sees
// its own cgroup as / and any nested runtime (containerd, runc,
// dockerd, kuke init) writes its cgroup tree under the cell — which
// is the property that lets a nested kuke init complete the runc
// task-create step that otherwise trips the "cgroup not empty"
// precheck.
//
// Set true only for kukeond-style cells that need to write cgroups
// *outside* their own subtree to manage user workloads. For ordinary
// workload containers, leave false.
//
// Translates to omitting the LinuxNamespace{Type: cgroup} entry from
// the OCI spec when true; appending it when false.
HostCgroup bool `json:"hostCgroup,omitempty" yaml:"hostCgroup,omitempty"`
User string `json:"user,omitempty" yaml:"user,omitempty"`
ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty" yaml:"readOnlyRootFilesystem,omitempty"`
Capabilities *ContainerCapabilities `json:"capabilities,omitempty" yaml:"capabilities,omitempty"`
SecurityOpts []string `json:"securityOpts,omitempty" yaml:"securityOpts,omitempty"`
// Devices grants the container access to individual host device nodes —
// the least-privilege alternative to Privileged (which exposes every host
// device). Each entry is a host device path (short form, e.g. "/dev/kvm");
// the node is replicated into the container at the same path with default
// "rwm" cgroup access. The host node is stat'd at container *create* time
// (type/major/minor snapshot) and materialises as a Linux.Devices entry
// plus a matching Linux.Resources.Devices allow rule — the same pair
// Docker's --device emits. A device that appears on the host after the cell
// is created needs a cell recreate to be picked up; a missing host node
// fails container create with a clear error. Issue #1252.
Devices []string `json:"devices,omitempty" yaml:"devices,omitempty"`
Tmpfs []ContainerTmpfsMount `json:"tmpfs,omitempty" yaml:"tmpfs,omitempty"`
Resources *ContainerResources `json:"resources,omitempty" yaml:"resources,omitempty"`
Secrets []ContainerSecret `json:"secrets,omitempty" yaml:"secrets,omitempty"`
// Repos declares git repositories the container depends on. The kuketty
// wrapper clones (or fetches) each one in a pre-Serve step using the
// container's own git identity (~/.ssh, ~/.gitconfig, GIT_SSH_COMMAND),
// so the daemon never touches user-owned SSH keys. kuketty reads them
// straight from this ContainerDoc.Spec (it owns the spec→TerminalSpec
// build since issue #641) — there is no sidecar doc. Has no effect unless
// Attachable=true (kuketty owns the resolution step). Per-repo outcome
// surfaces in ContainerStatus.Repos over RPC in phase 1b (#642). Issue
// #617, phase 1a of #423.
Repos []ContainerRepo `json:"repos,omitempty" yaml:"repos,omitempty"`
// Git declares the container's git identity and signing config as
// declarative sugar over the GIT_AUTHOR_* / GIT_COMMITTER_* / GIT_CONFIG_*
// environment-variable protocol git reads natively. The container runtime
// expands it into that env-var block before container start (merged with
// any explicit env: entries, which win on key collision), so cell
// templates carry a four-line git: block instead of the hand-rolled
// ~13-line GIT_* env duplication. The signingKey path stays per-container
// (root-cell vs non-root-cell key paths are not globalised). Issue #618,
// phase 2 of #423.
Git *ContainerGit `json:"git,omitempty" yaml:"git,omitempty"`
CNIConfigPath string `json:"cniConfigPath,omitempty" yaml:"cniConfigPath,omitempty"`
RestartPolicy string `json:"restartPolicy" yaml:"restartPolicy"`
// Attachable opts the container into kuketty-wrapper injection. When
// true, the daemon rewrites process.args to a single element
// [/.kukeon/bin/kuketty] — no CLI flags, every runtime input flows
// through the bind-mounted metadata file — bind-mounts the kuketty
// binary read-only at /.kukeon/bin/kuketty, bind-mounts a per-container
// tty directory at /run/kukeon/tty (kuketty owns the attach socket
// inside it; capture and log files land in later phases), and
// bind-mounts the per-container metadata file read-only at
// /.kukeon/kuketty/metadata.json (carries this ContainerDoc with the
// resolved workload argv baked into Spec.Command / Spec.Args, from which
// kuketty builds the sbsh TerminalSpec it serves — issue #641). The
// host-visible peer of the tty directory lives in the per-container
// metadata dir and its `socket` entry is what `kuke attach` connects
// to. Default false — no behavior change for existing specs.
Attachable bool `json:"attachable,omitempty" yaml:"attachable,omitempty"`
// Tty configures shell-UX (prompt, init scripts) for the kuketty
// wrapper when Attachable=true. The container model already owns
// command, args, workingDir, and env, so Tty intentionally only adds
// layers the container model can't express. Setting any tty field with
// Attachable=false is a validation error.
Tty *ContainerTty `json:"tty,omitempty" yaml:"tty,omitempty"`
// KukeonGroupGID is a daemon-stamped transport field, not user-authored
// config. It carries the resolved kukeon-group GID into the ContainerDoc
// the daemon mounts at /.kukeon/kuketty/metadata.json so kuketty can apply
// the kukeon-group ownership (socket / capture / log GID + mode) the daemon
// used to fold into the rendered TerminalSpec — a value not knowable from
// inside the container. Zero means no kukeon group is configured (kuketty
// then leaves OS-default permissions on the inodes it creates, matching the
// no-group fallback). Always zero on the persisted ContainerDoc and on
// `kuke get` output (omitempty): the daemon populates it only on the
// kuketty-mounted doc, and the read path never round-trips it back into the
// internal model. Issue #641.
KukeonGroupGID int `json:"kukeonGroupGID,omitempty" yaml:"kukeonGroupGID,omitempty"`
}
type ContainerState ¶
type ContainerState int
const ( ContainerStatePending ContainerState = iota ContainerStateReady ContainerStateStopped ContainerStatePaused ContainerStatePausing ContainerStateFailed ContainerStateUnknown // ContainerStateNotCreated marks a container with no containerd record at // all — distinct from Stopped (a record that exists but whose task is // gone). Appended last to keep the ordinals in lockstep with the internal // modelhub.ContainerState enum, which scheme.go converts by direct int cast. ContainerStateNotCreated // ContainerStateExited is a containerd-stopped task that exited 0 — a // clean completion (#1267). Mirrors the cell-level CellStateExited split: // ContainerStateStopped no longer conflates a clean exit with a crash. // Appended last to keep the ordinals in lockstep with the internal enum. ContainerStateExited // ContainerStateError is a containerd-stopped task that exited non-zero — // a workload crash (#1267). Distinct from ContainerStateFailed, which // stays reserved for kukeon's own container bring-up failures. Appended // last (after ContainerStateExited) for the same ordinal-lockstep reason. ContainerStateError )
func (ContainerState) MarshalJSON ¶ added in v0.5.0
func (s ContainerState) MarshalJSON() ([]byte, error)
func (ContainerState) MarshalYAML ¶ added in v0.5.0
func (s ContainerState) MarshalYAML() (interface{}, error)
func (*ContainerState) String ¶
func (c *ContainerState) String() string
func (*ContainerState) UnmarshalJSON ¶ added in v0.5.0
func (s *ContainerState) UnmarshalJSON(data []byte) error
func (*ContainerState) UnmarshalYAML ¶ added in v0.5.0
func (s *ContainerState) UnmarshalYAML(node *yaml.Node) error
type ContainerStatus ¶
type ContainerStatus struct {
Name string `json:"name" yaml:"name"`
ID string `json:"id" yaml:"id"`
State ContainerState `json:"state" yaml:"state"`
// CreatedAt is the wall-clock time of the first time the controller
// observed this container in cell.Spec.Containers. Stamped on the
// first populateCellContainerStatuses pass and preserved across
// reconciliations (mirrors realm/space/stack/cell.Status.CreatedAt).
// Sources the AGE column on `kuke get container`. Issue #605.
CreatedAt time.Time `json:"createdAt,omitempty" yaml:"createdAt,omitempty"`
RestartCount int `json:"restartCount" yaml:"restartCount"`
RestartTime time.Time `json:"restartTime" yaml:"restartTime"`
StartTime time.Time `json:"startTime" yaml:"startTime"`
FinishTime time.Time `json:"finishTime" yaml:"finishTime"`
ExitCode int `json:"exitCode" yaml:"exitCode"`
ExitSignal string `json:"exitSignal" yaml:"exitSignal"`
// Repos reports the per-repo outcome of kuketty's pre-Serve clone/fetch
// step for an Attachable container's Spec.Repos. Empty for containers
// with no repos[] or that have not yet been provisioned. Populated over
// the GetSetupStatus RPC in phase 1b (#642); phase 1a lands the schema
// only. Issue #617.
Repos []RepoStatus `json:"repos,omitempty" yaml:"repos,omitempty"`
// Stages reports the per-stage outcome of kuketty's pre-Serve execution of
// the container's runOn: create TtyStages, in declaration order. Empty for
// containers with no create stages or that have not yet been provisioned.
// Populated over the GetSetupStatus RPC in phase B (#689); this phase (#635)
// lands the schema only. Issue #635.
Stages []StageStatus `json:"stages,omitempty" yaml:"stages,omitempty"`
}
type ContainerTmpfsMount ¶ added in v0.2.0
type ContainerTmpfsMount struct {
Path string `json:"path" yaml:"path"`
SizeBytes int64 `json:"sizeBytes,omitempty" yaml:"sizeBytes,omitempty"`
Options []string `json:"options,omitempty" yaml:"options,omitempty"`
}
ContainerTmpfsMount declares a tmpfs mount inside the container.
type ContainerTty ¶ added in v0.3.0
type ContainerTty struct {
// Prompt is the literal prompt expression sbsh stamps onto
// TerminalSpec.Prompt and flips SetPrompt on for. Empty leaves
// SetPrompt off (sbsh's wrapper skips PS1 injection).
Prompt string `json:"prompt,omitempty" yaml:"prompt,omitempty"`
// OnInit are scripts run once when the wrapped shell starts, in
// order. Forwarded to TerminalSpec.Stages.OnInit via sbsh's
// WithOnInit; an empty slice leaves Stages.OnInit zero.
OnInit []TtyStage `json:"onInit,omitempty" yaml:"onInit,omitempty"`
// LogFile is an optional operator override for the in-container path
// the kuketty wrapper writes its slog output to. Empty (the default)
// makes the daemon stamp ctr.AttachableKukettyLogPath
// (/run/kukeon/tty/kuketty.log inside the bind mount — peer to the
// capture file), which is always present after first attach. Set this
// to a different in-container path when the cell needs the log to
// land somewhere else (custom bind mount, fixed external mount). Mode
// and GID are not user-configurable — the daemon applies its
// AttachableLogFileMode and the kukeon-group GID, gated on the
// kukeon group being configured (matches socket/capture treatment).
// Issue #599.
LogFile string `json:"logFile,omitempty" yaml:"logFile,omitempty"`
// LogLevel controls the verbosity of the kuketty wrapper's own slog
// output. Accepted values: "debug", "info", "warn", "error". Empty
// falls through to the daemon-wide kuketty.logLevel set on
// ServerConfigurationSpec, which itself defaults to "info". The path
// the log lands at is daemon-controlled (peer to capture inside the
// per-container tty directory — see ctr.AttachableKukettyLogPath and
// fs.ContainerKukettyLogPath); operators only pick the verbosity.
// Validation rejects unknown values at apply time rather than
// silently coercing. Issue #599.
LogLevel string `json:"logLevel,omitempty" yaml:"logLevel,omitempty"`
}
ContainerTty carries per-attach shell-UX config that the daemon threads into kuketty on first attach. Has no effect unless Attachable=true.
All fields are stamped directly onto the rendered sbsh TerminalSpec via sbsh's inline builder lane (sbsh v0.11.2+, kukeon #494). The pre-#494 Profile / ProfilesDir fields that pointed at on-disk TerminalProfile YAML have been removed; cell YAML that still carries those keys is silently ignored by the default YAML decoder.
func (*ContainerTty) IsEmpty ¶ added in v0.3.0
func (t *ContainerTty) IsEmpty() bool
IsEmpty reports whether the tty block carries no user-supplied config — i.e. equivalent to omitting the block entirely. Used by validation to distinguish "explicitly empty" from "any field set".
type EgressAllowRule ¶ added in v0.2.0
type EgressAllowRule struct {
Host string `json:"host,omitempty" yaml:"host,omitempty"`
CIDR string `json:"cidr,omitempty" yaml:"cidr,omitempty"`
Ports []int `json:"ports,omitempty" yaml:"ports,omitempty"`
}
EgressAllowRule describes a single permitted destination. Exactly one of Host or CIDR must be set. Ports, when non-empty, constrains to those TCP destination ports; empty Ports means "any port on this destination".
Host entries are resolved to IPs by the daemon at apply time; the resulting iptables rules reflect the IPs known at that moment. See the Space manifest docs for the TTL caveat.
type EgressDefault ¶ added in v0.2.0
type EgressDefault string
EgressDefault is the fallthrough action when no allowlist rule matches.
const ( EgressDefaultAllow EgressDefault = "allow" EgressDefaultDeny EgressDefault = "deny" )
type EgressPolicy ¶ added in v0.2.0
type EgressPolicy struct {
Default EgressDefault `json:"default" yaml:"default"`
Allow []EgressAllowRule `json:"allow,omitempty" yaml:"allow,omitempty"`
}
EgressPolicy constrains outbound traffic leaving the space bridge toward the host or external networks. When nil, traffic is unconstrained (current behavior). An explicit Default=allow with no Allow rules also matches current behavior.
type GitIdentity ¶ added in v0.6.0
type GitIdentity struct {
Name string `json:"name" yaml:"name"`
Email string `json:"email" yaml:"email"`
}
GitIdentity is a name/email pair for a git author or committer identity.
type Kind ¶
type Kind string
const ( // KindCell identifies cell documents. KindCell Kind = "Cell" // KindContainer identifies container documents. KindContainer Kind = "Container" // KindRealm identifies realm documents. KindRealm Kind = "Realm" // KindSpace identifies space documents. KindSpace Kind = "Space" // KindStack identifies stack documents. KindStack Kind = "Stack" // KindSecret identifies named, scoped, daemon-managed credential // documents (issue #619). `kuke apply` writes the secret bytes to a // root-owned file under the scope's metadata tree; phase 3a ships no // `get`/`delete`/referencing surface (tracked in #622 and #623). KindSecret Kind = "Secret" // KindCellBlueprint identifies daemon-stored, scopable parametrized cell // templates (issue #620, phase 4a-i of #423). `kuke apply` writes the // blueprint to a root-owned, world-readable file under the scope's // metadata tree; `kuke run -b` resolves it from daemon storage and // materializes a fresh `<prefix>-<6hex>` cell. The get/delete verbs // (#643), CellConfig (#624), and `kuke run -c` (#625) build on this // foundation. The legacy client-side CellProfile kind (`kuke run -p`) // that originally co-existed was removed in #626 — Blueprint + Config are // the only template path now. KindCellBlueprint Kind = "CellBlueprint" // KindCellConfig identifies a daemon-stored cell identity that binds a // CellBlueprint to a concrete instance (issue #624, phase 4b-i of #423). A // CellConfig references a Blueprint by name+scope, supplies the scalar // values and the structural repo/secret slot fills, and owns the // deterministic name of the at-most-one live cell it materializes. // `kuke apply` writes it to a root-owned, world-readable file under the // scope's metadata tree; the `kuke run -c` verb + identity state machine // that runs it land in #625, and the get/delete verbs in #644. KindCellConfig Kind = "CellConfig" // KindServerConfiguration identifies the kukeond daemon's configuration // document loaded via `kukeond --configuration` (and consumed by // `kuke init --server-configuration`). Not a server-side resource — // `kuke apply` rejects it. KindServerConfiguration Kind = "ServerConfiguration" // KindClientConfiguration identifies the kuke client's configuration // document loaded via `kuke --configuration` (default // `~/.kuke/kuke.yaml`). Not a server-side resource — `kuke apply` // rejects it. KindClientConfiguration Kind = "ClientConfiguration" )
Kinds.
type RealmDoc ¶
type RealmDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata RealmMetadata `json:"metadata" yaml:"metadata"`
Spec RealmSpec `json:"spec" yaml:"spec"`
Status RealmStatus `json:"status" yaml:"status"`
}
type RealmMetadata ¶
type RealmMetadata struct {
Name string `json:"name" yaml:"name"`
Labels map[string]string `json:"labels" yaml:"labels"`
// Generation is a monotonic counter bumped by a writer on each
// spec-changing update. Defaults to zero; phase 3 (issue #596 follow-up)
// wires the writers to populate it. See ObservedGeneration on the status.
Generation int64 `json:"generation,omitempty" yaml:"generation,omitempty"`
}
type RealmSpec ¶
type RealmSpec struct {
Namespace string `json:"namespace" yaml:"namespace"`
RegistryCredentials []RegistryCredentials `json:"registryCredentials,omitempty" yaml:"registryCredentials,omitempty"`
}
type RealmState ¶
type RealmState int
const ( RealmStatePending RealmState = iota RealmStateCreating RealmStateReady RealmStateDeleting RealmStateFailed RealmStateUnknown )
func (RealmState) MarshalJSON ¶ added in v0.5.0
func (s RealmState) MarshalJSON() ([]byte, error)
func (RealmState) MarshalYAML ¶ added in v0.5.0
func (s RealmState) MarshalYAML() (interface{}, error)
func (*RealmState) String ¶
func (r *RealmState) String() string
func (*RealmState) UnmarshalJSON ¶ added in v0.5.0
func (s *RealmState) UnmarshalJSON(data []byte) error
func (*RealmState) UnmarshalYAML ¶ added in v0.5.0
func (s *RealmState) UnmarshalYAML(node *yaml.Node) error
type RealmStatus ¶
type RealmStatus struct {
State RealmState `json:"state" yaml:"state"`
CgroupPath string `json:"cgroupPath,omitempty" yaml:"cgroupPath,omitempty"`
// SubtreeControllers is the cgroup-v2 controller set actually
// delegated on this realm's own cgroup.subtree_control after the
// host-root filter (issue #328).
SubtreeControllers []string `json:"subtreeControllers,omitempty" yaml:"subtreeControllers,omitempty"`
// CreatedAt is the wall-clock time of the first persist for this
// realm. Bumped only when zero so the value never moves once set.
CreatedAt time.Time `json:"createdAt,omitempty" yaml:"createdAt,omitempty"`
// UpdatedAt is the wall-clock time of the most recent persist.
UpdatedAt time.Time `json:"updatedAt,omitempty" yaml:"updatedAt,omitempty"`
// ReadyAt is the wall-clock time of the first State==Ready persist.
// Set-once: never overwritten by subsequent Ready transitions or
// state flaps, so it serves as an immutable "first reached Ready"
// marker.
ReadyAt time.Time `json:"readyAt,omitempty" yaml:"readyAt,omitempty"`
// Reason is a short reason code summarizing why State is in its
// current value. Empty when no reason has been recorded.
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
// Message is the human-readable detail backing Reason; especially
// valuable on State==Failed where it captures the immediate cause.
Message string `json:"message,omitempty" yaml:"message,omitempty"`
// CgroupReady reports whether CgroupPath actually exists on the
// host filesystem as of the last status write. The CgroupPath
// field records the intent (the path where the cgroup should
// live); this re-verifies presence so callers can distinguish
// "configured" from "still mounted".
CgroupReady bool `json:"cgroupReady,omitempty" yaml:"cgroupReady,omitempty"`
// ContainerdNamespaceReady reports whether the containerd
// namespace recorded in Spec.Namespace was actually present as of
// the last status write. Like CgroupReady, this separates intent
// from observation.
ContainerdNamespaceReady bool `json:"containerdNamespaceReady,omitempty" yaml:"containerdNamespaceReady,omitempty"`
// ObservedGeneration is the Metadata.Generation the reconciler last
// acted on. Defaults to zero; phase 3 wires the reconciler to compare
// it against Generation to skip stale work.
ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"`
}
type RegistryCredentials ¶
type RegistryCredentials struct {
// Username is the registry username.
Username string `json:"username" yaml:"username"`
// Password is the registry password or token.
Password string `json:"password" yaml:"password"`
// ServerAddress is the registry server address (e.g., "docker.io", "registry.example.com").
// If empty, credentials apply to the registry extracted from the image reference.
ServerAddress string `json:"serverAddress,omitempty" yaml:"serverAddress,omitempty"`
}
RegistryCredentials contains authentication information for a container registry.
type RepoStatus ¶ added in v0.6.0
type RepoStatus struct {
Name string `json:"name" yaml:"name"`
Target string `json:"target" yaml:"target"`
// State is one of "cloned", "fetched", or "failed".
State string `json:"state" yaml:"state"`
// Commit is the resolved HEAD commit (full SHA) on success.
Commit string `json:"commit,omitempty" yaml:"commit,omitempty"`
// Error is the failure detail when State == "failed".
Error string `json:"error,omitempty" yaml:"error,omitempty"`
}
RepoStatus is the resolved state of a single ContainerRepo after kuketty's pre-Serve step. Populated in phase 1b (#642). Issue #617.
type SecretDoc ¶ added in v0.6.0
type SecretDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata SecretMetadata `json:"metadata" yaml:"metadata"`
Spec SecretSpec `json:"spec" yaml:"spec"`
}
SecretDoc is the top-level document for a named, scoped, daemon-managed credential (kind: Secret, issue #619). Unlike the realm/space/stack/cell hierarchy resources it carries no Status: a Secret has no runtime — its bytes are written once to a daemon-owned file under the scope's metadata tree and are never round-tripped back into any output, log, or audit trail. Phase 3a ships only the schema + storage primitive + `kuke apply`; the `kuke get`/`kuke delete` verbs (#622) and the `ContainerSecret.secretRef` source (#623) build on this foundation.
type SecretMetadata ¶ added in v0.6.0
type SecretMetadata struct {
// Name is the secret's name, unique within its scope.
Name string `json:"name" yaml:"name"`
// Realm is the always-required top-level scope coordinate.
Realm string `json:"realm" yaml:"realm"`
// Space, when set, scopes the secret to a space within Realm.
Space string `json:"space,omitempty" yaml:"space,omitempty"`
// Stack, when set, scopes the secret to a stack within Space.
Stack string `json:"stack,omitempty" yaml:"stack,omitempty"`
// Cell, when set, scopes the secret to a cell within Stack.
Cell string `json:"cell,omitempty" yaml:"cell,omitempty"`
}
SecretMetadata identifies a Secret by name and the scope it is bound to. The scope is the deepest non-empty coordinate: a Secret with only Realm set is realm-scoped; one with Realm+Space+Stack set is stack-scoped; and so on. A deeper coordinate requires every shallower one (a Cell-scoped Secret must also name its Stack, Space, and Realm) — apply rejects a gap. Scope coordinates live on the metadata (not the spec) so the Secret's full identity is its scope plus its name.
type SecretSpec ¶ added in v0.6.0
type SecretSpec struct {
// Data is the raw secret material supplied at apply time.
Data string `json:"data,omitempty" yaml:"data,omitempty"`
}
SecretSpec carries the secret material supplied at apply time. Data is write-only from the operator's perspective: it is persisted to the daemon-managed file and never echoed back. The omitempty tag keeps a zero value out of any incidental serialization, but the value itself is never serialized into a result or status by design.
type ServerConfigurationDoc ¶ added in v0.3.0
type ServerConfigurationDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata ServerConfigurationMetadata `json:"metadata" yaml:"metadata"`
Spec ServerConfigurationSpec `json:"spec" yaml:"spec"`
}
ServerConfigurationDoc is the kukeond-side configuration document. It is loaded by the kukeond daemon (via `kukeond --configuration <path>`) and by `kuke init --server-configuration <path>` when bootstrapping the daemon. It is not a server-side resource: `kuke apply` rejects it.
type ServerConfigurationMetadata ¶ added in v0.3.0
type ServerConfigurationSpec ¶ added in v0.3.0
type ServerConfigurationSpec struct {
// Socket is the unix socket path the daemon listens on.
Socket string `json:"socket,omitempty" yaml:"socket,omitempty"`
// SocketGID is the numeric group ID the daemon chowns its listener
// socket to (mode 0o660 with group). Zero means root-only access.
SocketGID int `json:"socketGID,omitempty" yaml:"socketGID,omitempty"`
// RunPath is the kukeon runtime root (e.g. /opt/kukeon).
RunPath string `json:"runPath,omitempty" yaml:"runPath,omitempty"`
// ContainerdSocket is the path to the containerd unix socket the
// daemon connects to.
ContainerdSocket string `json:"containerdSocket,omitempty" yaml:"containerdSocket,omitempty"`
// LogLevel is the daemon log level (debug, info, warn, error).
LogLevel string `json:"logLevel,omitempty" yaml:"logLevel,omitempty"`
// KukettyLogLevel is the daemon-wide default verbosity of the kuketty
// wrapper's own slog output, applied to every Attachable container
// whose cell schema does not pin a per-container ContainerTty.LogLevel.
// Accepted values: "debug", "info", "warn", "error"; empty is treated
// as "info" by the daemon. Lets operators flip every attachable cell
// on the host to "debug" without editing each cell YAML. Issue #599.
KukettyLogLevel string `json:"kukettyLogLevel,omitempty" yaml:"kukettyLogLevel,omitempty"`
// ReconcileInterval is the period of the daemon's background cell
// reconciliation loop, expressed as a Go time.Duration string (e.g.
// "30s", "1m"). Empty falls back to the in-binary default. A zero or
// negative duration disables the loop.
ReconcileInterval string `json:"reconcileInterval,omitempty" yaml:"reconcileInterval,omitempty"`
// KukeondImage is the container image `kuke init` provisions for the
// kukeond system cell. Read by `kuke init` only; the daemon ignores it.
KukeondImage string `json:"kukeondImage,omitempty" yaml:"kukeondImage,omitempty"`
// ContainerdNamespaceSuffix is the suffix appended to every realm name
// to form its containerd namespace. Realm "default" + suffix
// "kukeon.io" -> namespace "default.kukeon.io". Lets two kukeon
// instances coexist on the same host under disjoint namespaces.
// Default: kukeon.io.
ContainerdNamespaceSuffix string `json:"containerdNamespaceSuffix,omitempty" yaml:"containerdNamespaceSuffix,omitempty"`
// CgroupRoot is the cgroup root under which all realms / spaces /
// stacks / cells live (e.g. /kukeon-dev for a parallel dev instance on
// the same host). Default: /kukeon.
CgroupRoot string `json:"cgroupRoot,omitempty" yaml:"cgroupRoot,omitempty"`
// PodSubnetCIDR is the parent block the per-space CNI subnet allocator
// subdivides into /24 chunks. Set it to a non-overlapping block (e.g.
// 10.89.0.0/16) when running a parallel or nested kukeon instance so its
// allocator never lands on another instance's subnet — in particular a
// nested `make dev-init` must avoid the parent host's 10.88.0.0/16 + .1
// gateway, which is the dev-root cell's own default gateway (issue
// #1079). Default: 10.88.0.0/16.
PodSubnetCIDR string `json:"podSubnetCIDR,omitempty" yaml:"podSubnetCIDR,omitempty"`
// DefaultMemoryLimitBytes is the daemon-wide fallback memory limit
// applied to every admitted container whose
// ContainerSpec.Resources.MemoryLimitBytes is unset or zero. Closes the
// host-wedge gap on no-swap, no-userspace-OOM hosts where an unbounded
// container can consume enough RAM to evict the daemon and journald.
// Zero (the default) preserves the prior behavior — no fallback.
// Operators should set this on hosts without swap and without
// systemd-oomd / earlyoom. An explicit per-container limit always wins.
// Issue #531. Default: 0.
DefaultMemoryLimitBytes int64 `json:"defaultMemoryLimitBytes,omitempty" yaml:"defaultMemoryLimitBytes,omitempty"`
}
ServerConfigurationSpec carries kukeond-only settings. Each field is optional: an absent or empty value falls back to the daemon's hardcoded default. Explicit command-line flags (`--socket`, `--run-path`, …) still take precedence over values loaded from this document.
type SpaceContainerDefaults ¶ added in v0.2.0
type SpaceContainerDefaults struct {
User string `json:"user,omitempty" yaml:"user,omitempty"`
ReadOnlyRootFilesystem *bool `json:"readOnlyRootFilesystem,omitempty" yaml:"readOnlyRootFilesystem,omitempty"`
Capabilities *ContainerCapabilities `json:"capabilities,omitempty" yaml:"capabilities,omitempty"`
SecurityOpts []string `json:"securityOpts,omitempty" yaml:"securityOpts,omitempty"`
Tmpfs []ContainerTmpfsMount `json:"tmpfs,omitempty" yaml:"tmpfs,omitempty"`
Resources *ContainerResources `json:"resources,omitempty" yaml:"resources,omitempty"`
}
SpaceContainerDefaults mirrors the isolation-related fields on ContainerSpec. Each field is applied to a Container only when the Container leaves it empty. Inheritance is shallow: a Container that sets Capabilities replaces the Space default outright — Drop and Add slices are not merged.
ReadOnlyRootFilesystem is a *bool so the default can distinguish "not set" from an explicit "false"; Container.Spec.ReadOnlyRootFilesystem is still a plain bool, so a Container cannot opt out of a Space default that enables it.
type SpaceDefaults ¶ added in v0.2.0
type SpaceDefaults struct {
Container *SpaceContainerDefaults `json:"container,omitempty" yaml:"container,omitempty"`
}
SpaceDefaults declares default values that Kukeon inherits into resources created inside the Space unless the resource's own spec overrides the field. It exists so the isolation envelope can be declared once on the Space and reused by every Container that lives in it.
type SpaceDoc ¶
type SpaceDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata SpaceMetadata `json:"metadata" yaml:"metadata"`
Spec SpaceSpec `json:"spec" yaml:"spec"`
Status SpaceStatus `json:"status" yaml:"status"`
}
type SpaceMetadata ¶
type SpaceMetadata struct {
Name string `json:"name" yaml:"name"`
Labels map[string]string `json:"labels" yaml:"labels"`
// Generation is a monotonic counter bumped by a writer on each
// spec-changing update. Defaults to zero; phase 3 wires the writers to
// populate it. See ObservedGeneration on the status.
Generation int64 `json:"generation,omitempty" yaml:"generation,omitempty"`
}
type SpaceNetwork ¶ added in v0.2.0
type SpaceNetwork struct {
Egress *EgressPolicy `json:"egress,omitempty" yaml:"egress,omitempty"`
}
SpaceNetwork groups network-scoped policy applied to the space bridge.
type SpaceSpec ¶
type SpaceSpec struct {
RealmID string `json:"realmId" yaml:"realmId"`
CNIConfigPath string `json:"cniConfigPath,omitempty" yaml:"cniConfigPath,omitempty"`
Network *SpaceNetwork `json:"network,omitempty" yaml:"network,omitempty"`
Defaults *SpaceDefaults `json:"defaults,omitempty" yaml:"defaults,omitempty"`
}
type SpaceState ¶
type SpaceState int
const ( SpaceStatePending SpaceState = iota SpaceStateReady SpaceStateFailed SpaceStateUnknown )
func (SpaceState) MarshalJSON ¶ added in v0.5.0
func (s SpaceState) MarshalJSON() ([]byte, error)
func (SpaceState) MarshalYAML ¶ added in v0.5.0
func (s SpaceState) MarshalYAML() (interface{}, error)
func (*SpaceState) String ¶
func (s *SpaceState) String() string
func (*SpaceState) UnmarshalJSON ¶ added in v0.5.0
func (s *SpaceState) UnmarshalJSON(data []byte) error
func (*SpaceState) UnmarshalYAML ¶ added in v0.5.0
func (s *SpaceState) UnmarshalYAML(node *yaml.Node) error
type SpaceStatus ¶
type SpaceStatus struct {
State SpaceState `json:"state" yaml:"state"`
CgroupPath string `json:"cgroupPath,omitempty" yaml:"cgroupPath,omitempty"`
// SubtreeControllers is the cgroup-v2 controller set actually
// delegated on this space's own cgroup.subtree_control after the
// host-root filter (issue #328).
SubtreeControllers []string `json:"subtreeControllers,omitempty" yaml:"subtreeControllers,omitempty"`
// Lifecycle and runtime-health fields — see RealmStatus for the
// per-field contract; the semantics carry across all four kinds.
CreatedAt time.Time `json:"createdAt,omitempty" yaml:"createdAt,omitempty"`
UpdatedAt time.Time `json:"updatedAt,omitempty" yaml:"updatedAt,omitempty"`
ReadyAt time.Time `json:"readyAt,omitempty" yaml:"readyAt,omitempty"`
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
CgroupReady bool `json:"cgroupReady,omitempty" yaml:"cgroupReady,omitempty"`
// ObservedGeneration is the Metadata.Generation the reconciler last
// acted on. Defaults to zero; phase 3 wires the reconciler to compare
// it against Generation to skip stale work.
ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"`
}
type StackDoc ¶
type StackDoc struct {
APIVersion Version `json:"apiVersion" yaml:"apiVersion"`
Kind Kind `json:"kind" yaml:"kind"`
Metadata StackMetadata `json:"metadata" yaml:"metadata"`
Spec StackSpec `json:"spec" yaml:"spec"`
Status StackStatus `json:"status" yaml:"status"`
}
type StackMetadata ¶
type StackMetadata struct {
Name string `json:"name" yaml:"name"`
Labels map[string]string `json:"labels" yaml:"labels"`
// Generation is a monotonic counter bumped by a writer on each
// spec-changing update. Defaults to zero; phase 3 wires the writers to
// populate it. See ObservedGeneration on the status.
Generation int64 `json:"generation,omitempty" yaml:"generation,omitempty"`
}
type StackState ¶
type StackState int
const ( StackStatePending StackState = iota StackStateReady StackStateFailed StackStateUnknown )
func (StackState) MarshalJSON ¶ added in v0.5.0
func (s StackState) MarshalJSON() ([]byte, error)
func (StackState) MarshalYAML ¶ added in v0.5.0
func (s StackState) MarshalYAML() (interface{}, error)
func (*StackState) String ¶
func (s *StackState) String() string
func (*StackState) UnmarshalJSON ¶ added in v0.5.0
func (s *StackState) UnmarshalJSON(data []byte) error
func (*StackState) UnmarshalYAML ¶ added in v0.5.0
func (s *StackState) UnmarshalYAML(node *yaml.Node) error
type StackStatus ¶
type StackStatus struct {
State StackState `json:"state" yaml:"state"`
CgroupPath string `json:"cgroupPath" yaml:"cgroupPath"`
// SubtreeControllers is the cgroup-v2 controller set actually
// delegated on this stack's own cgroup.subtree_control after the
// host-root filter (issue #328).
SubtreeControllers []string `json:"subtreeControllers,omitempty" yaml:"subtreeControllers,omitempty"`
// Lifecycle and runtime-health fields — see RealmStatus for the
// per-field contract; the semantics carry across all four kinds.
CreatedAt time.Time `json:"createdAt,omitempty" yaml:"createdAt,omitempty"`
UpdatedAt time.Time `json:"updatedAt,omitempty" yaml:"updatedAt,omitempty"`
ReadyAt time.Time `json:"readyAt,omitempty" yaml:"readyAt,omitempty"`
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
CgroupReady bool `json:"cgroupReady,omitempty" yaml:"cgroupReady,omitempty"`
// ObservedGeneration is the Metadata.Generation the reconciler last
// acted on. Defaults to zero; phase 3 wires the reconciler to compare
// it against Generation to skip stale work.
ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"`
}
type StageStatus ¶ added in v0.6.0
type StageStatus struct {
// Index is the 0-based position of the stage within the container's full
// Tty.OnInit list (not its position among create stages alone), in
// declaration order.
Index int `json:"index" yaml:"index"`
// State is the resolved outcome ("done" or "failed"); the daemon-side
// populator (phase B, #689) sets it from the wire payload.
State string `json:"state" yaml:"state"`
// Error is the failure detail when State reports a failure.
Error string `json:"error,omitempty" yaml:"error,omitempty"`
// Hash is the content hash of the stage at record time — the run-once
// "done" key. The daemon stamps it from the live spec and the controller
// preserves a done entry across stop/start only when its Hash still
// matches the current spec's stage Hash at the same Index, so an edited
// stage (new content) drops its prior done record on the next populate.
// Phase C1 (#690).
Hash string `json:"hash,omitempty" yaml:"hash,omitempty"`
}
StageStatus is the resolved state of a single runOn: create TtyStage after kuketty's pre-Serve execution. Populated in phase B (#689). Phase C1 (#690) adds the durable Hash key + merge that carries done records across stop/start; phase C2 (#737) lands the render-time gate that consumes them. Issue #635.
type TtyStage ¶ added in v0.3.0
type TtyStage struct {
Script string `json:"script,omitempty" yaml:"script,omitempty"`
// RunOn controls when the stage runs. Empty or "start" (RunOnStart) keeps
// today's behavior: the script is forwarded to sbsh's Stages.OnInit and
// runs in the wrapped shell on every boot. "create" (RunOnCreate) routes
// the script into kuketty's pre-Serve executor, where it runs to completion
// as a separate step instead of being handed to sbsh — the foundation for
// run-once-per-cell-instance setup (the run-once render gate itself lands
// in phase C, #690; this phase adds the field + routing + executor). Any
// other value is rejected at apply time by validateContainerTty. Issue #635.
RunOn string `json:"runOn,omitempty" yaml:"runOn,omitempty"`
}
TtyStage is a single onInit script entry. Wrapped in a struct rather than a bare string so future stage knobs (timeout, etc.) can land without breaking the YAML shape.
type Version ¶
type Version string
const ( // APIVersionV1Beta1 is the canonical API version for this package. APIVersionV1Beta1 Version = "v1beta1" )
type VolumeKind ¶ added in v0.4.0
type VolumeKind string
VolumeKind discriminates between the supported VolumeMount kinds. Mirrors intmodel.VolumeKind. An empty value deserializes as VolumeKindBind so YAML authored before the discriminator existed keeps its bind semantics.
const ( // VolumeKindBind is a host bind mount. Source and Target are required. VolumeKindBind VolumeKind = "bind" // VolumeKindTmpfs is an in-memory tmpfs mount. Only Target is required; // Source must be empty. SizeBytes and Mode tune the standard tmpfs // size= and mode= options when non-zero. VolumeKindTmpfs VolumeKind = "tmpfs" )
type VolumeMount ¶ added in v0.2.0
type VolumeMount struct {
Kind VolumeKind `json:"kind,omitempty" yaml:"kind,omitempty"`
Source string `json:"source,omitempty" yaml:"source,omitempty"`
Target string `json:"target" yaml:"target"`
ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"`
SizeBytes int64 `json:"sizeBytes,omitempty" yaml:"sizeBytes,omitempty"`
Mode uint32 `json:"mode,omitempty" yaml:"mode,omitempty"`
}
VolumeMount is a mount entry attached to a container. The Kind discriminator selects the OCI mount type the runtime emits: bind (host path → container path) or tmpfs (in-memory directory). Empty Kind means bind for back-compat with YAML authored before the discriminator existed.