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

stackbackup

package
v0.17.0 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 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
	// SkipWallets restores without re-materialising keystores from the
	// archive's wallets/ backups (and without checking they decrypt).
	SkipWallets 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