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

stackbackup

package
v0.17.0-rc1 Latest Latest
Warning

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

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

Documentation

Overview

Package stackbackup implements `obol stack export` / `obol stack import`: a single archive capturing everything a running stack needs that is not regenerable from the obol binary — host config (helmfiles, values, sell offer descriptors, wallet metadata), agent data dirs (brains + remote-signer keystores), portable encrypted wallet backups, and the etcd-resident resources that drifted out of helmfile management (Agent CRs, ServiceOffers, LiteLLM/eRPC config mutations).

Design notes live in plans/stack-export-import.md. The archive is a plain tar.gz with manifest.json as its first entry:

manifest.json          archive + obol version, stack id, component notes
config/...             $OBOL_CONFIG_DIR minus kubeconfig* (defaults/ included,
                       with its manifest, so hand-edits survive a restore)
data/<namespace>/...   agent data dirs (hermes-*, agent-*; openclaw-* left over from <= v0.15)
wallets/...            walletbackup-format files (encrypted if passphrase)
cluster/...            stripped JSON dumps of CRs/ConfigMaps/Secrets

The archive contains keystore passwords and provider API keys in the same plaintext form they already have on the host's disk — callers must treat it as a secret. The wallets/ component is additionally encryptable so wallet keys stay portable on their own.

Index

Constants

View Source
const ManifestFileName = "manifest.json"

ManifestFileName is the archive's first entry.

View Source
const ManifestVersion = 1

ManifestVersion is the current archive format version. Import refuses archives with a different version.

Variables

This section is empty.

Functions

func Export

func Export(cfg *config.Config, opts ExportOptions, u *ui.UI) (string, error)

Export captures the stack into a tar.gz archive and returns its path. Safe with the cluster up (agent deployments are quiesced while their data dirs are copied — never copy a live SQLite state.db) and with the cluster down (host dirs are the source of truth; the cluster component is skipped).

func Import

func Import(cfg *config.Config, opts ImportOptions, u *ui.UI) error

Import restores an export archive and, unless --skip-cluster, finishes the job instead of printing homework:

  1. host state (config + agent data) is restored, and absolute paths baked into the archive's config (helmfiles, k3d.yaml) are rewritten to this host's config/data dirs;
  2. a cluster left over from a `stack init`/`stack up` that this --force import replaced is removed when it holds no agents or offers (it was created moments ago and would otherwise squat on the ingress ports);
  3. the restored stack is brought up via StackUp when its cluster isn't running;
  4. etcd-resident resources are applied and agent instances re-synced.

It never deletes a cluster that holds agents/offers, and never applies an archive into another stack's cluster.

func PromptExportBeforePurge

func PromptExportBeforePurge(cfg *config.Config, u *ui.UI, force bool) bool

PromptExportBeforePurge offers a full stack export before a destructive purge and returns true when one was written (callers can then skip narrower wallet-only prompts). Non-interactive shells get a warning but are never blocked.

Offered for BOTH purge modes: a plain purge keeps the data dir but deletes the config dir, which holds every agent's keystore password (values-remote-signer.yaml) — the surviving keystores can't be unlocked without it. Either mode deletes the cluster, and with it the sub-agent wallets that exist only as in-cluster Secrets.

func StripK8sJSON

func StripK8sJSON(data []byte) ([]byte, error)

StripK8sJSON removes server-managed fields (status, managedFields, resourceVersion, uid, ownerReferences, last-applied annotation, ...) from a kubectl JSON dump so it can be re-applied to a fresh cluster. Returns nil for an empty List.

func StripServerManagedMetadata added in v0.14.0

func StripServerManagedMetadata(obj map[string]any)

StripServerManagedMetadata strips server-managed fields from one decoded Kubernetes object (map from json.Unmarshal or yaml.Unmarshal) so it can be re-applied. Used by StripK8sJSON (export/import dumps) and by internal/agentcrd.ResumeAll (persisted Agent manifests on stack up).

Types

type Component

type Component struct {
	Name     string   `json:"name"`
	Included bool     `json:"included"`
	Notes    []string `json:"notes,omitempty"`
}

Component records what one export component captured (or why it was skipped) so import and humans can reason about archive contents.

type ExportOptions

type ExportOptions struct {
	Output      string
	Passphrase  string
	HasPassFlag bool
}

ExportOptions holds options for `obol stack export`.

type ImportOptions

type ImportOptions struct {
	Input       string
	Force       bool
	SkipCluster bool
	ClusterOnly bool
	SkipSync    bool
	// Passphrase decrypts the archive's wallets/ backups when a keystore
	// must be re-materialised from them. HasPassFlag means it was given
	// (even empty); otherwise a terminal is prompted when needed.
	Passphrase  string
	HasPassFlag bool
	// StackUp brings the restored stack's cluster up with the full
	// `obol stack up` path (state replay included). Injected by the CLI —
	// internal/stack imports this package. When nil, Import prints the
	// remaining steps instead.
	StackUp func() error
}

ImportOptions holds options for `obol stack import`.

type Manifest

type Manifest struct {
	Version     int         `json:"version"`
	ObolVersion string      `json:"obolVersion"`
	StackID     string      `json:"stackId,omitempty"`
	CreatedAt   string      `json:"createdAt"`
	ConfigDir   string      `json:"configDir"`
	DataDir     string      `json:"dataDir"`
	Components  []Component `json:"components"`
}

Manifest describes an export archive.

Jump to

Keyboard shortcuts

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