bundle

package module
v0.0.0-...-5cda00c Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package bundle is the charly plugin housing the `charly bundle …` deployment CLI. It is a dual-placement command plugin (F8) mirroring candy/plugin-vm: the SAME NewProvider()/NewMeta()/ CliMain compile INTO charly in-process when listed in compiled_plugins (the canonical placement, P13), or cmd/serve serves them OUT-OF-PROCESS when they are not. It provides ONE capability —

  • command:bundle — `charly bundle add / del / show / export / import / reset / path / status / from-box`, the deployment CLI. COMPILED-IN, it dispatches IN-PROC via Invoke(OpRun) (runBundleCommand → kong-parse the BundleCmd tree — command.go), so the handlers run in charly's OWN process and inherit charly's real stdio/TTY natively. `add`/`del` (walk.go, the K4-C WALK PORT) drive the WHOLE deploy-tree walk plugin-side: the config loader (the merged-tree read, LoadUnified-coupled) + the del RESOLUTION (del_resolve.go, K-wave 2 cone R2 bank C) run plugin-side; the registry-backed executor-chain derivation (deriveChildExecutorForPath) stays host-side behind three narrow seams — deploy-plugins-connect / resolve-target-add / deploy-node-del-dispatch — while the tree traversal AND the per-node compile (compilePlansForRequest, IN-PROC after K4-C shape-2 — no OpCompile round-trip) run plugin-side; ResolveTarget → the deploy target's Add/Del is the host tail of the resolve-target-add / deploy-node-del-dispatch seams. Sibling `peer:` member bring-up/tear-down calls sdk/deploykit.BringUpMembers/TearDownMembers directly (#55 W3 A4 — the former deploy-members-up/-down seams are deleted). `from-box` runs fully plugin-side since K-wave 2 cone R2 (runFromBoxPod reaches deploy:pod's OpConfigSetup by direct InvokeProvider; the "deploy-from-box" seam is deleted); the config-management leaves (show/export/import/reset/status) run plugin-side — reads via loaderkit.LoadHostBundleConfigViaExecutor, writes via deploykit.SaveBundleConfig directly (#55 K4 config-write seam-collapse). `path` resolves plugin-side via kit.DefaultDeployConfigPath (no seam).

A standalone Go module (its own go.mod) importing ONLY the sdk module, compiled into charly for the canonical placement. The capability is advertised in Describe (NewMeta); command:bundle's grammar is prescanned into the CLI from plugin.providers.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CliMain

func CliMain(_ []string) int

CliMain is the OUT-OF-PROCESS command entry — unreachable in the canonical compiled-in placement. command:bundle's handlers reach the host reverse channel (the deploy-add/del/from-box dispatch + the deploy-config seam), which is unavailable out-of-process, so this errors (like plugin-vm's CliMain).

func DeployFromBox

func DeployFromBox(ctx context.Context, exec *sdk.Executor, opts DeployFromBoxOpts) (string, error)

DeployFromBox performs the source-less deploy. Returns the absolute path to the Kustomize overlay directory produced (the argument to `kubectl apply -k`).

func GenerateK8sKustomize

func GenerateK8sKustomize(ctx context.Context, exec *sdk.Executor, opts K8sGenerateOpts) (string, error)

GenerateK8sKustomize dispatches to candy/plugin-kube's deploy:k8s OpEmit (materializeKustomize) via exec.InvokeProvider — the plugin-side replacement for the former core providerRegistry.ResolveDeploy("k8s") + InvokeWithExecutor registry dance. Returns the absolute path to the overlay that `kubectl apply -k` should target.

func NewMeta

func NewMeta() pb.PluginMetaServer

NewMeta advertises command:bundle. The served schema carries no #*Input def — a command's args are pass-through CLI tokens, not a structured plugin_input — so the capability has no InputDef. command:bundle is COMPILED-IN and dispatched IN-PROC via Invoke(OpRun) (runBundleCommand, command.go); its grammar is prescanned into the CLI from plugin.providers.

func NewProvider

func NewProvider() pb.ProviderServer

NewProvider returns the bundle provider (command:bundle Invoke surface).

func ValidateEgress

func ValidateEgress(kind, label string, data []byte) error

ValidateEgress validates already-serialized YAML or JSON bytes against the egress kind's schema before they are written. JSON is a YAML subset, so one ingest path covers both.

func ValidateEgressValue

func ValidateEgressValue(kind, label string, v any) error

ValidateEgressValue validates an in-memory Go value (a manifest map[string]any, a record struct) by marshalling it to JSON and validating as bytes — faithful for the data values egress gates (k8s manifests, ledger records).

Types

type BundleAddCmd

type BundleAddCmd struct {
	Name string `arg:"" help:"Deploy name ('host' for local system; any other string is a container deploy name)"`
	Ref  string `arg:"" optional:"" help:"Box or candy reference (local name, ./path.yml, or github.com/org/repo[/box/<n>|/candy/<n>][@ref])"`

	// Candy overlays (repeatable).
	AddCandy []string `name:"add-candy" help:"Extra candy to apply on top of the base image (repeatable)"`

	// Plan-level flags.
	Tag      string `name:"tag" help:"Image CalVer tag (empty = newest local CalVer resolved via the ai.opencharly.version OCI label)"`
	DryRun   bool   `name:"dry-run" help:"Print the plan without executing"`
	NodeOnly bool   `` /* 147-byte string literal not displayed */
	Format   string `name:"format" default:"table" enum:"table,json" help:"Output format for --dry-run"`
	Pull     bool   `name:"pull" help:"Force re-fetch of remote refs / image pull"`
	Verify   bool   `name:"verify" help:"Re-run candy tests: on the host after install"`

	// Host-only gates.
	WithServices     bool   `name:"with-services" help:"Install systemd services (host target only)"`
	AllowRepoChanges bool   `name:"allow-repo-changes" help:"Allow repo config mutations (host target only)"`
	AllowRootTasks   bool   `name:"allow-root-tasks" help:"Allow arbitrary root cmd: tasks (host target only)"`
	SkipIncompatible bool   `name:"skip-incompatible" help:"Skip candies without host-matching format (host target only)"`
	BuilderImage     string `name:"builder-image" help:"Override the compile builder image"`
	DevLocalPkg      bool   `` /* 340-byte string literal not displayed */
	AssumeYes        bool   `name:"assume-yes" short:"y" help:"Assume yes; implies all allow-* gates plus skip sudo preflight"`

	// Disposable + lifecycle classification (see /charly-internals:disposable).
	Disposable bool   `` /* 131-byte string literal not displayed */
	Lifecycle  string `` /* 147-byte string literal not displayed */
	// contains filtered or unexported fields
}

BundleAddCmd is the `charly bundle add <name> [<ref>]` grammar; it forwards to the deploy-add host-build seam, which runs the core add orchestration VERBATIM.

func (*BundleAddCmd) Run

func (c *BundleAddCmd) Run() error

Run executes `charly bundle add` (plugin-side walk; the deploy-add host-build seam it used to forward the WHOLE Run() to is retired).

type BundleCmd

type BundleCmd struct {
	Add BundleAddCmd `cmd:"" help:"Apply a deploy: 'host' targets the local system; any other name targets a container"`
	Del BundleDelCmd `cmd:"" help:"Tear down a deploy by name"`

	FromImage BundleFromBoxCmd `` /* 149-byte string literal not displayed */

	Export BundleExportCmd `cmd:"" help:"Export effective config as charly.yml"`
	Import BundleImportCmd `cmd:"" help:"Import charly.yml file(s) into config"`
	Path   BundlePathCmd   `cmd:"" help:"Print charly.yml file path"`
	Reset  BundleResetCmd  `cmd:"" help:"Remove charly.yml overrides"`
	Show   BundleShowCmd   `cmd:"" help:"Show current charly.yml overrides"`
	Status BundleStatusCmd `cmd:"" help:"Show sync status between charly.yml and quadlet files"`
}

BundleCmd is the `charly bundle …` command group — the CLI grammar the compiled-in command:bundle plugin contributes to charly's Kong tree (dispatched in-proc via Invoke(OpRun) → dispatchBundleCLI).

type BundleDelCmd

type BundleDelCmd struct {
	Name string `arg:"" help:"Deploy name (literal 'host' or a container deploy name)"`

	AssumeYes       bool `name:"assume-yes" short:"y" help:"Skip confirmation prompts"`
	KeepRepoChanges bool `name:"keep-repo-changes" help:"Don't revert repo config even at zero refcount"`
	KeepServices    bool `name:"keep-services" help:"Don't disable systemd units (just stop tracking)"`
	KeepImage       bool `name:"keep-image" help:"Don't remove the synthesized overlay image (container target only)"`
	DryRun          bool `name:"dry-run" help:"Print the teardown plan without executing"`
}

BundleDelCmd is the `charly bundle del <name>` grammar; Run() (walk.go) drives the deploy-del-resolve / deploy-node-del-dispatch seams plus a direct deploykit.TearDownMembers call (#55 W3 A4 — the former deploy-members-down HostBuild seam is deleted). The AssumeYes field renders as `--assume-yes`, stated by an explicit `name:` tag rather than left to Kong's derivation from the field, with `-y` as the short form — the exact contract spec.BundleDelArgv relies on.

func (*BundleDelCmd) Run

func (c *BundleDelCmd) Run() error

Run executes `charly bundle del` (plugin-side; the deploy-del host-build seam it used to forward the WHOLE Run() to is retired). The ledger lock spans resolve → members-down → node-del-dispatch — kit.AcquireLedgerLock is a pure sdk/kit filesystem primitive, so acquiring it plugin-side (the compiled-in placement shares charly's own process/filesystem) reproduces the SAME lock scope the OLD in-core Run() held.

type BundleExportCmd

type BundleExportCmd struct {
	Boxes  []string `arg:"" optional:"" help:"Boxes to export (default: all with overrides)"`
	Output string   `short:"o" help:"Write to file instead of stdout"`
	All    bool     `help:"Export all enabled boxes with all runtime fields"`
}

BundleExportCmd is the `charly bundle export [boxes…]` grammar (K4-C: runs plugin-side; --all reaches the project via the established InvokeProvider("build","project") seam).

func (*BundleExportCmd) Run

func (c *BundleExportCmd) Run() error

type BundleFromBoxCmd

type BundleFromBoxCmd struct {
	Ref       string   `arg:"" help:"Full image ref (local or registry), e.g. ghcr.io/opencharly/selkies-kde-nvidia:latest"`
	Name      string   `arg:"" optional:"" help:"Deploy name (default: the image-ref basename without tag)"`
	Instance  string   `short:"i" name:"instance" help:"Instance name"`
	Env       []string `short:"e" name:"env" sep:"none" help:"Set container env var (KEY=VALUE)"`
	Port      []string `short:"p" help:"Remap host port (newHost:containerPort)"`
	Cluster   string   `name:"cluster" help:"Target a K8s cluster profile instead of a local pod (emits Kustomize via the K8s from-box path)"`
	Namespace string   `name:"namespace" help:"K8s namespace override (--cluster only)"`
}

BundleFromBoxCmd is the `charly bundle from-box <ref> [name]` grammar. The pod path (default) runs ENTIRELY plugin-side (from_box_pod.go — a source-less deploy from an image's baked OCI labels, reaching deploy:pod's OpConfigSetup directly, no HostBuild round-trip); the --cluster path (Cone A shape 3) is handled plugin-side too — see deploy_from_box.go — reaching the k8s cluster lookup + the deploy:k8s substrate directly.

func (*BundleFromBoxCmd) Run

func (c *BundleFromBoxCmd) Run() error

type BundleImportCmd

type BundleImportCmd struct {
	Files   []string `arg:"" help:"Deploy YAML files to import (merged left-to-right)"`
	Replace bool     `help:"Replace entire charly.yml instead of merging with existing"`
	Box     string   `name:"box" help:"Import only this box's config"`
}

BundleImportCmd is the `charly bundle import <files…>` grammar (K4-C: runs plugin-side; the SAVE step writes plugin-side too — deploykit.SaveBundleConfig, #55 K4 config-write seam-collapse).

func (*BundleImportCmd) Run

func (c *BundleImportCmd) Run() error

type BundlePathCmd

type BundlePathCmd struct{}

BundlePathCmd is the `charly bundle path` grammar. It resolves the per-host deploy-overlay path entirely plugin-side (kit.DefaultDeployConfigPath — the SAME resolver core's DeployConfigPath aliases, R3), so it needs no host seam.

func (*BundlePathCmd) Run

func (c *BundlePathCmd) Run() error

type BundleResetCmd

type BundleResetCmd struct {
	Box      string `arg:"" optional:"" help:"Box to reset (omit to clear all)"`
	Instance string `short:"i" name:"instance" help:"Instance name"`
}

BundleResetCmd is the `charly bundle reset [box]` grammar (K4-C: runs plugin-side; the SAVE step writes plugin-side too — deploykit.SaveBundleConfig, #55 K4 config-write seam-collapse).

func (*BundleResetCmd) Run

func (c *BundleResetCmd) Run() error

type BundleShowCmd

type BundleShowCmd struct {
	Box      string `arg:"" optional:"" help:"Show overrides for a specific box"`
	Instance string `short:"i" name:"instance" help:"Instance name"`
}

BundleShowCmd is the `charly bundle show [box]` grammar (K4-C: runs entirely plugin-side — deploykit.LoadBundleConfig/DeployKey are already sdk-portable, no seam needed).

func (*BundleShowCmd) Run

func (c *BundleShowCmd) Run() error

type BundleStatusCmd

type BundleStatusCmd struct{}

BundleStatusCmd is the `charly bundle status` grammar (K4-C: runs entirely plugin-side).

func (*BundleStatusCmd) Run

func (c *BundleStatusCmd) Run() error

type DeployFromBoxOpts

type DeployFromBoxOpts struct {
	Engine         string // "podman" | "docker" (auto-detected if empty)
	ImageRef       string // fully-qualified registry/name:tag
	DeploymentName string // optional override; defaults to the basename of ImageRef without tag
	Instance       string // optional "image/instance" suffix
	ClusterName    string // cluster profile name
	Namespace      string // optional override of the cluster's default namespace
	DeployOverlay  *spec.Deploy
	OutputDir      string // defaults to <cwd>/.opencharly/k8s
	ProjectDir     string // for the self-loaded kind:k8s cluster lookup (resolveK8sSpec)
}

DeployFromBoxOpts carries the source-less-deploy inputs.

type DeployRef

type DeployRef struct {
	Raw    string          // original input
	Kind   RefKind         // box or candy
	Source RefSource       // local-name | local-path | remote
	Name   string          // resolved short name (ripgrep, fedora-coder, …)
	Path   string          // absolute path (local-path only; unset for local-name)
	Remote *spec.ParsedRef // populated for remote refs
}

DeployRef is a parsed `<box-or-candy-ref>`. The plugin resolver populates Raw/Kind/Source/Name (and Remote for a remote ref) — the compile is off the envelope, so no host-side Path load is needed (the host resolver's Path field is deliberately unused here).

type K8sGenerateOpts

type K8sGenerateOpts struct {
	DeploymentName string // the deployment's base name
	Instance       string // "" for the bare overlay; non-empty for image/instance
	ImageRef       string // fully qualified image ref (registry/name:tag)
	Deploy         spec.Deploy
	Capabilities   *spec.BoxMetadata
	Cluster        *spec.ResolvedK8s
	OutputDir      string // usually <projectDir>/.opencharly/k8s
}

K8sGenerateOpts carries the inputs a Kustomize emit needs.

type RefKind

type RefKind string

RefKind classifies a DeployRef.

const (
	RefKindBox   RefKind = "box"
	RefKindCandy RefKind = "candy"
)

type RefSource

type RefSource string

RefSource classifies where the ref's content lives.

const (
	RefSourceLocalName RefSource = "local-name"
	RefSourceLocalPath RefSource = "local-path"
	RefSourceRemote    RefSource = "remote"
)

Directories

Path Synopsis
cmd
serve command
Command serve is the OUT-OF-PROCESS entrypoint for the bundle command plugin: dual-mode sdk.Main (serve OR CLI).
Command serve is the OUT-OF-PROCESS entrypoint for the bundle command plugin: dual-mode sdk.Main (serve OR CLI).

Jump to

Keyboard shortcuts

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