k8sbackup

package
v0.14.4 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: AGPL-3.0 Imports: 9 Imported by: 0

Documentation

Overview

Package k8sbackup holds the Kubernetes backup job specification (backup_jobs.k8s_config), the discovery plan exchanged between server and agent, and the run manifest. It is shared by the server (validation), the workflow and the agent, so it stays free of client-go machinery beyond label-selector parsing.

Index

Constants

View Source
const (
	ResourcesArchiveName = "resources"
	VolumeArchiveName    = "pvc"
	ManifestBlobName     = "k8s-manifest"
	ManifestFileName     = "k8s-manifest.json"
)

Archive and blob names inside the PBS snapshots

View Source
const (
	VolumesAll     = "all"     // every PVC passing the filters
	VolumesLabeled = "labeled" // only PVCs matching volumes.label_selector
	VolumesNone    = "none"    // resources only
)

Volume selection modes

View Source
const (
	ModeSnapshot = "snapshot" // CSI VolumeSnapshot → clone → upload
	ModeLive     = "live"     // read-only mount of the live volume
	ModeSkipped  = "skipped"
)

Per-volume backup modes decided at discovery

View Source
const (
	MaxParallelism    = 8
	MaxVolumes        = 500
	MaxSnapshotWait   = 30 * time.Minute
	MaxVolumeTimeout  = 5 * time.Hour
	DefaultParallel   = 2
	DefaultSnapWait   = 10 * time.Minute
	DefaultVolTimeout = 2 * time.Hour
)

Limits

View Source
const ManifestSchemaVersion = 1

ManifestSchemaVersion is bumped on incompatible manifest changes

Variables

View Source
var DefaultExcludedNamespaces = []string{"kube-system", "kube-node-lease", "kube-public"}

DefaultExcludedNamespaces prefills the UI form (control-plane churn)

View Source
var ErrInvalidSpec = errors.New("invalid kubernetes job configuration")

ErrInvalidSpec wraps every validation failure

Functions

func IsVolumeGroup

func IsVolumeGroup(clusterBackupID, groupID string) bool

IsVolumeGroup reports whether a PBS group id belongs to this cluster's volumes

func VolumeGroupID

func VolumeGroupID(clusterBackupID, namespace, pvcName string) string

VolumeGroupID is the PBS backup group id for one PVC: <cluster group>-pvc-<ns>-<name>, sanitised and length-capped with a stable hash suffix when truncated.

func VolumeGroupPrefix

func VolumeGroupPrefix(clusterBackupID string) string

VolumeGroupPrefix is the prefix shared by every volume group of a cluster

Types

type Manifest

type Manifest struct {
	SchemaVersion int               `json:"schema_version"`
	Generator     ManifestGenerator `json:"generator"`
	Job           ManifestJob       `json:"job"`
	Snapshot      ManifestSnapshot  `json:"snapshot"`
	Kubernetes    ManifestCluster   `json:"kubernetes"`
	Spec          *Spec             `json:"spec"`
	Resources     ManifestResources `json:"resources"`
	Volumes       []VolumeResult    `json:"volumes"`
	Warnings      []string          `json:"warnings,omitempty"`
	Restore       ManifestRestore   `json:"restore"`
	// Partial marks a manifest the server assembled from the volume outcomes because
	// the run ended (resources step failed, cancelled) before the agent produced one:
	// only Job, Snapshot and Volumes are meaningful, and nothing was uploaded for it
	Partial bool `json:"partial,omitempty"`
}

Manifest is stored as blob k8s-manifest.blob on the resources snapshot and as a file inside the resources archive; it is the restore runbook's index.

func ParseManifest

func ParseManifest(data []byte) (*Manifest, error)

ParseManifest decodes a manifest

func (*Manifest) Marshal

func (m *Manifest) Marshal() ([]byte, error)

Marshal renders the manifest as indented JSON

type ManifestCluster

type ManifestCluster struct {
	ServerVersion string `json:"server_version,omitempty"`
	SnapshotCRD   bool   `json:"snapshot_crd"`
}

type ManifestGenerator

type ManifestGenerator struct {
	Agent   string `json:"agent"`
	Version string `json:"version"`
	Cluster string `json:"cluster"`
}

type ManifestJob

type ManifestJob struct {
	ID          string `json:"id"`
	Name        string `json:"name,omitempty"`
	RunID       string `json:"run_id,omitempty"`
	BackupRunID string `json:"backup_run_id"`
}

type ManifestResources

type ManifestResources struct {
	DumpedAt        time.Time      `json:"dumped_at"`
	Counts          map[string]int `json:"counts,omitempty"` // "apps/deployments" -> n
	Excluded        []string       `json:"excluded,omitempty"`
	FailedGroups    []string       `json:"failed_groups,omitempty"`
	SecretsIncluded bool           `json:"secrets_included"`
	Namespaces      []string       `json:"namespaces,omitempty"`
}

type ManifestRestore

type ManifestRestore struct {
	Summary  string   `json:"summary"`
	Commands []string `json:"commands"`
}

type ManifestSnapshot

type ManifestSnapshot struct {
	Type    string    `json:"type"`
	ID      string    `json:"id"`
	Time    time.Time `json:"time"`
	Archive string    `json:"archive"`
}

type NamespaceFilter

type NamespaceFilter struct {
	Include []string `json:"include,omitempty"`
	Exclude []string `json:"exclude,omitempty"`
}

NamespaceFilter selects namespaces with glob patterns (path.Match syntax); an empty include list means all namespaces.

func (NamespaceFilter) Matches

func (f NamespaceFilter) Matches(ns string) bool

Matches reports whether a namespace passes the filter

type Plan

type Plan struct {
	ClusterName    string       `json:"cluster_name"`
	ServerVersion  string       `json:"server_version,omitempty"`
	SnapshotCRD    bool         `json:"snapshot_crd"`
	AgentNamespace string       `json:"agent_namespace,omitempty"`
	Volumes        []VolumePlan `json:"volumes"`
	Warnings       []string     `json:"warnings,omitempty"`
}

Plan is the discovery result the workflow fans out over

type ResourceOptions

type ResourceOptions struct {
	// ExcludeExtra adds group/resource patterns to the built-in exclusion list
	// ("apps/deployments", "*/secrets", "cert-manager.io/*")
	ExcludeExtra []string `json:"exclude_extra,omitempty"`
	// IncludeSecrets defaults to true: a disaster-recovery backup without Secrets is
	// crippled; the UI carries the warning instead
	IncludeSecrets *bool `json:"include_secrets,omitempty"`
}

ResourceOptions configure the API resource dump

type Spec

type Spec struct {
	Namespaces    NamespaceFilter `json:"namespaces"`
	LabelSelector string          `json:"label_selector,omitempty"`
	Resources     ResourceOptions `json:"resources"`
	Volumes       VolumeOptions   `json:"volumes"`
}

Spec is the Kubernetes job configuration (backup_jobs.k8s_config)

func (*Spec) Clone

func (s *Spec) Clone() *Spec

Clone returns a deep copy

func (*Spec) IncludeSecrets

func (s *Spec) IncludeSecrets() bool

func (*Spec) Summary

func (s *Spec) Summary() string

Summary is a short human-readable description for the UI list

func (*Spec) Validate

func (s *Spec) Validate() error

Validate normalises the spec and rejects inconsistent settings; called at job create/update and defensively before a run.

func (*Spec) VolumeNamespaces

func (s *Spec) VolumeNamespaces() NamespaceFilter

VolumeNamespaces is the namespace filter that applies to volumes

type VolumeOptions

type VolumeOptions struct {
	Mode          string `json:"mode,omitempty"` // all | labeled | none
	LabelSelector string `json:"label_selector,omitempty"`
	// SkipLabelSelector excludes PVCs whose labels match it (e.g. fallbck.io/skip-backup=true),
	// on top of the built-in fallbck.io/skip annotation; applied after LabelSelector
	SkipLabelSelector string `json:"skip_label_selector,omitempty"`
	// Namespaces overrides the top-level namespace filter for volumes (nil = inherit)
	Namespaces            *NamespaceFilter `json:"namespaces,omitempty"`
	StorageClasses        []string         `json:"storage_classes,omitempty"`
	ExcludeStorageClasses []string         `json:"exclude_storage_classes,omitempty"`
	// SnapshotClassOverrides maps a StorageClass to the VolumeSnapshotClass to use
	SnapshotClassOverrides map[string]string `json:"snapshot_class_overrides,omitempty"`
	// AllowLiveFallback (default true) backs up volumes without snapshot support by
	// mounting them read-only (rsync-grade consistency)
	AllowLiveFallback *bool `json:"allow_live_fallback,omitempty"`
	// ContinueOnError (default true) records failed volumes and completes the run
	ContinueOnError *bool `json:"continue_on_error,omitempty"`
	// Parallelism bounds concurrent volume uploads (worker pods), 1..8, default 2
	Parallelism int `json:"parallelism,omitempty"`
	// SnapshotTimeout waits for a VolumeSnapshot to become ready (default 10m, max 30m)
	SnapshotTimeout string `json:"snapshot_timeout,omitempty"`
	// VolumeTimeout bounds one volume's snapshot+upload (default 2h, max 5h)
	VolumeTimeout string `json:"volume_timeout,omitempty"`
}

VolumeOptions configure PVC backups

func (*VolumeOptions) EffAllowLiveFallback

func (v *VolumeOptions) EffAllowLiveFallback() bool

func (*VolumeOptions) EffContinueOnError

func (v *VolumeOptions) EffContinueOnError() bool

func (*VolumeOptions) EffParallelism

func (v *VolumeOptions) EffParallelism() int

func (*VolumeOptions) EffSnapshotTimeout

func (v *VolumeOptions) EffSnapshotTimeout() time.Duration

func (*VolumeOptions) EffVolumeTimeout

func (v *VolumeOptions) EffVolumeTimeout() time.Duration

type VolumePlan

type VolumePlan struct {
	Namespace     string `json:"namespace"`
	PVCName       string `json:"pvc"`
	PVName        string `json:"pv,omitempty"`
	StorageClass  string `json:"storage_class,omitempty"`
	Provisioner   string `json:"provisioner,omitempty"`
	VolumeMode    string `json:"volume_mode,omitempty"`
	CapacityBytes int64  `json:"capacity_bytes,omitempty"`
	// Mode: snapshot | live | skipped
	Mode          string `json:"mode"`
	SnapshotClass string `json:"snapshot_class,omitempty"`
	// GroupID is the PBS backup group this volume uploads into
	GroupID    string `json:"group_id"`
	SkipReason string `json:"skip_reason,omitempty"`
}

VolumePlan is one PVC the run intends to back up (produced by discovery)

type VolumeResult

type VolumeResult struct {
	Namespace string `json:"namespace"`
	PVCName   string `json:"pvc"`
	GroupID   string `json:"group_id"`
	// Mode actually used (snapshot may fall back to live)
	Mode string `json:"mode"`
	// Consistency: csi-snapshot | crash-consistent-live
	Consistency string `json:"consistency,omitempty"`
	// Status: completed | failed | skipped | cancelled
	Status        string  `json:"status"`
	SnapshotID    string  `json:"snapshot_id,omitempty"`
	BytesScanned  int64   `json:"bytes_scanned"`
	BytesUploaded int64   `json:"bytes_uploaded"`
	ChunkCount    int     `json:"chunk_count"`
	DedupRatio    float64 `json:"dedup_ratio,omitempty"`
	DurationMS    int64   `json:"duration_ms,omitempty"`
	Error         string  `json:"error,omitempty"`
}

VolumeResult is the outcome of one volume backup

Jump to

Keyboard shortcuts

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