backup

package
v0.11.2 Latest Latest
Warning

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

Go to latest
Published: Sep 14, 2026 License: MIT Imports: 55 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultMaxRestoreFileSetFiles int64 = maxFileSetFiles
	DefaultMaxRestoreFileSetBytes int64 = 10 << 30 // 10 GiB across selected sets.
)
View Source
const (
	ConfidenceExact     = "exact"
	ConfidenceStrong    = "strong"
	ConfidenceAmbiguous = "ambiguous"
	ConfidenceUnknown   = "unknown"
	ConfidenceLocked    = "locked"
)
View Source
const (
	ArtifactManifestSchemaVersion = 1
	ArtifactManifestSuffix        = ".dbterm.json"
	ArtifactVerificationPassed    = "passed"
	ArtifactVerificationBasic     = "basic-structural"
	EncryptionSchemeNone          = "none"
	EncryptionSchemeAgeX25519V1   = "age-x25519-v1"
	FileSetConsistencyBestEffort  = "best-effort"
	FileSetConsistencyOmitted     = "omitted"
)
View Source
const (
	DefaultFilenameTemplate = "{connection}_{engine}_{date}_{time}_{run}"
	DefaultTimeoutMinutes   = 30
)
View Source
const (
	RestoreModeMerge RestoreMode = "merge"
	RestoreModeClean RestoreMode = "clean"

	// Short aliases keep call sites readable while retaining the enum-style
	// names used by the other backup model types.
	RestoreMerge = RestoreModeMerge
	RestoreClean = RestoreModeClean
)
View Source
const (
	DBTermBundleSchemaVersion = 1
)
View Source
const (
	// DefaultMaxDecodedBytes limits each decoded wrapper layer. Inspection
	// materializes decoded layers on disk rather than retaining database dumps
	// in memory.
	DefaultMaxDecodedBytes int64 = 1 << 30 // 1 GiB

)
View Source
const RcloneDestinationPrefix = "rclone://"

Variables

View Source
var (
	ErrRemoteCopyRetentionDisabled = errors.New("automatic retention for remote copy destinations is disabled until the transport can prove contained create ownership and verify-before-delete semantics")
	ErrCopyRetentionPlanChanged    = errors.New("copy retention plan changed after preview; preview again before deleting anything")
)
View Source
var (
	ErrCopyJobBusy                  = errors.New("copy job is already running")
	ErrCopyJobLeaseLost             = errors.New("copy job lease was lost")
	ErrCopyJobTransferProofRequired = errors.New("copy job requires a successful real transfer before automatic enablement")
)
View Source
var (
	ErrCopyVolumeBusy      = errors.New("copy destination volume is already in use")
	ErrCopyVolumeLeaseLost = errors.New("copy destination volume lease was lost")
)
View Source
var (
	ErrJobBusy      = errors.New("backup job is already running")
	ErrJobLeaseLost = errors.New("backup job lease was lost")
)
View Source
var ErrRcloneBackupPublicationDisabled = errors.New("rclone backup publication is disabled: generic rclone finalization cannot guarantee atomic create-only publication; use an absolute local or mounted destination, then copy the completed artifact separately")

ErrRcloneBackupPublicationDisabled is returned for generation jobs that target a generic rclone remote. rclone's single-object move operation is not an atomic create-if-absent primitive across its provider ecosystem, so it cannot uphold dbterm's immutable publication contract under a race.

View Source
var ErrRcloneRetentionDisabled = errors.New("rclone backup retention is disabled: generic rclone cannot conditionally delete the exact remote object version that dbterm verified; use a backend-specific version-aware retention policy")

ErrRcloneRetentionDisabled prevents a check-then-delete race where a remote object could be replaced after verification but before generic rclone deletefile removes it. Safe remote retention needs a backend generation or ETag-aware conditional delete operation.

Functions

func AgentProcessRunning

func AgentProcessRunning() (bool, error)

AgentProcessRunning reports whether the default backup catalog's scheduler lock is currently held. The lock file itself is persistent; only the kernel lock is authoritative, so a crash cannot strand the agent in a running state.

func ApplyCopyRetention added in v0.11.0

func ApplyCopyRetention(ctx context.Context, store *Store, job CopyJob, now time.Time) ([]string, error)

ApplyCopyRetention deletes only complete, verified artifacts durably recorded for this exact copy job and still contained by its configured destination.

func ApplyCopyRetentionPlan added in v0.11.0

func ApplyCopyRetentionPlan(ctx context.Context, store *Store, job CopyJob, now time.Time, expected []CopyRetentionCandidate) ([]string, error)

ApplyCopyRetentionPlan applies only the exact immutable candidate set shown by PreviewCopyRetention. Any newly completed, pruned, moved, or changed ownership record invalidates the plan before the first deletion.

func ApplyCopyRetentionPlanWithVolume added in v0.11.0

func ApplyCopyRetentionPlanWithVolume(ctx context.Context, store *Store, job CopyJob, now time.Time, expected []CopyRetentionCandidate) (removed []string, warnings []string, returnErr error)

ApplyCopyRetentionPlanWithVolume holds the copy-job lease while it verifies that the plan still exactly matches the earlier preview and while it applies that plan. This prevents a concurrent manual or scheduled copy from changing the retention window between comparison and deletion.

func ApplyCopyRetentionWithVolume added in v0.11.0

func ApplyCopyRetentionWithVolume(ctx context.Context, store *Store, job CopyJob, now time.Time) ([]string, []string, error)

ApplyCopyRetentionWithVolume prevents a configured removable destination from being pruned through its bare mount-point directory. The exact volume is prepared, leased, and rechecked around the existing contained retention implementation.

func ApplyRetention

func ApplyRetention(ctx context.Context, store *Store, job Job, now time.Time) ([]string, error)

ApplyRetention removes only successful artifacts recorded for this job and still contained by its configured destination. The newest success is always retained, even when an age policy would otherwise remove it.

func CreateNativeBackup

func CreateNativeBackup(ctx context.Context, cfg *config.ConnectionConfig, outputPath string, options NativeOptions) (err error)

CreateNativeBackup is the low-level engine-native export primitive. It refuses to replace an existing destination; user-facing backups normally go through Runner so they also receive a checksum and completion manifest.

func DefaultStagingPath

func DefaultStagingPath() (string, error)

DefaultStagingPath returns the private state path used for raw native dumps. It does not create the staging directory or a backup artifact.

func DefaultStorePath

func DefaultStorePath() (string, error)

func EncodeArtifactManifest added in v0.11.0

func EncodeArtifactManifest(writer io.Writer, manifest ArtifactManifest) error

EncodeArtifactManifest writes one strict schema-v1 JSON document.

func ExecuteRestore

func ExecuteRestore(ctx context.Context, plan *RestorePlan, emit func(string)) error

func FormatByteSize

func FormatByteSize(size uint64) string

func GenerateAgeIdentity

func GenerateAgeIdentity(path string) (string, error)

GenerateAgeIdentity creates a private age X25519 identity with no-clobber semantics. Jobs store only the returned public recipient.

func IsRemoteBackupDestination added in v0.6.2

func IsRemoteBackupDestination(value string) bool

IsRemoteBackupDestination reports whether value uses dbterm's first-class rclone destination syntax. Invalid rclone values still return true so callers never accidentally reinterpret them as local filesystem paths.

func JoinBackupDestination added in v0.6.2

func JoinBackupDestination(raw, filename string) (string, error)

JoinBackupDestination appends one artifact name without converting a legacy rclone URI into a local path. Generation policy is enforced by Job.Validate.

func NewID

func NewID(prefix string) (string, error)

func NormalizeBackupDestination added in v0.6.2

func NormalizeBackupDestination(raw string) (string, error)

NormalizeBackupDestination returns a stable local or legacy-rclone storage value. Job.Validate separately rejects rclone for new backup generation; parsing remains available for historical records and the future copy layer.

func RunAfterSuccessCopies added in v0.11.0

func RunAfterSuccessCopies(ctx context.Context, store *Store, backupJobID string, progress ProgressFunc) error

RunAfterSuccessCopies runs producer-owned copies bound to one successful backup stream. Errors are returned to the caller but never rewrite the already-durable backup run as failed.

func RunAgent

func RunAgent(ctx context.Context, store *Store, pollInterval time.Duration, emit func(string)) error

RunAgent executes scheduled jobs sequentially and relies on the durable store lease to prevent overlap with manual invocations or a second agent.

func RunDue

func RunDue(ctx context.Context, store *Store, owner string, now time.Time, emit func(string)) error

func RunDueCopies added in v0.11.0

func RunDueCopies(ctx context.Context, store *Store, owner string, now time.Time, emit func(string)) error

RunDueCopies drains timed copy jobs serially using the same agent owner.

func SendCopyRunNotification added in v0.11.0

func SendCopyRunNotification(ctx context.Context, job CopyJob, run CopyRun) (err error)

SendCopyRunNotification reports copy health without changing the validity of either the producer backup or a verified vault copy.

func SendRunNotification

func SendRunNotification(ctx context.Context, job Job, run Run) (err error)

SendRunNotification sends a terminal run result according to the job policy. It never includes SMTP credentials in the message and redacts them from all returned errors, including errors returned by the remote SMTP server.

func SetDBTermVersion added in v0.11.0

func SetDBTermVersion(version string)

SetDBTermVersion lets the main package report its linker-provided release version to backup manifests. Library callers safely fall back to build info.

func TestEmailNotification

func TestEmailNotification(ctx context.Context, notification EmailNotification) (err error)

TestEmailNotification validates and exercises the same SMTP/TLS/auth path as scheduled notifications, regardless of the saved delivery policy. It lets a client verify credentials and routing before depending on a future backup.

func VerifyAgeIdentityRecipient added in v0.11.0

func VerifyAgeIdentityRecipient(path, recipient string) error

VerifyAgeIdentityRecipient proves that the private identity file can decrypt bytes encrypted to recipient. It is intentionally separate from backup generation: unattended producer jobs need only the public recipient, while operators should keep and test the private identity on independent storage.

func VerifyCopyDestinationVolumeIdentity added in v0.11.0

func VerifyCopyDestinationVolumeIdentity(job CopyJob) error

VerifyCopyDestinationVolumeIdentity performs the read-only, positive volume identity check used by endpoint tests. It deliberately does not claim a lease, mount, unmount, sync, or power-manage a device; an actual copy run repeats this check while holding the durable destination-volume lease.

func VerifyDBTermBundleEnvelope added in v0.11.0

func VerifyDBTermBundleEnvelope(readerAt io.ReaderAt, size int64) error

VerifyDBTermBundleEnvelope validates the complete deterministic tar layout and every internal size/SHA-256 without extracting paths. The caller must separately authenticate or hash the outer artifact when that is required.

func VerifyDBTermBundleEnvelopeContext added in v0.11.0

func VerifyDBTermBundleEnvelopeContext(ctx context.Context, readerAt io.ReaderAt, size int64) error

VerifyDBTermBundleEnvelopeContext is the cancellation-aware form used by transfer paths that already own a job context.

Types

type AgentActivity

type AgentActivity struct {
	JobID        string    `json:"job_id"`
	JobName      string    `json:"job_name"`
	RunID        string    `json:"run_id"`
	Phase        string    `json:"phase"`
	Message      string    `json:"message"`
	CurrentBytes int64     `json:"current_bytes,omitempty"`
	TotalBytes   int64     `json:"total_bytes,omitempty"`
	StartedAt    time.Time `json:"started_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

type AgentStatus

type AgentStatus struct {
	Heartbeat time.Time      `json:"heartbeat"`
	PID       int            `json:"pid"`
	Healthy   bool           `json:"healthy"`
	Activity  *AgentActivity `json:"activity,omitempty"`
}

func AgentHealth

func AgentHealth(ctx context.Context, store *Store, now time.Time) (AgentStatus, error)

type Artifact

type Artifact struct {
	ID                string                   `json:"id,omitempty"`
	Path              string                   `json:"path"`
	Size              int64                    `json:"size"`
	SHA256            string                   `json:"sha256"`
	Format            string                   `json:"format"`
	Verified          bool                     `json:"verified"`
	VerificationLevel string                   `json:"verification_level,omitempty"`
	PublicationState  ArtifactPublicationState `json:"publication_state,omitempty"`
	CreatedAt         time.Time                `json:"created_at"`
	BackupName        string                   `json:"backup_name,omitempty"`
	ManifestPath      string                   `json:"manifest_path,omitempty"`
	ManifestSize      int64                    `json:"manifest_size,omitempty"`
	ManifestSHA256    string                   `json:"manifest_sha256,omitempty"`
	PrunedAt          time.Time                `json:"pruned_at,omitempty"`
	PruneReason       string                   `json:"prune_reason,omitempty"`
}

type ArtifactManifest added in v0.11.0

type ArtifactManifest struct {
	SchemaVersion     int               `json:"schema_version"`
	ArtifactID        string            `json:"artifact_id"`
	RunID             string            `json:"run_id"`
	JobID             string            `json:"job_id"`
	CreatedAt         time.Time         `json:"created_at"`
	ProducerID        string            `json:"producer_id"`
	DBTermVersion     string            `json:"dbterm_version"`
	Engine            config.DBType     `json:"engine"`
	Format            string            `json:"format"`
	Compression       Compression       `json:"compression"`
	Encryption        string            `json:"encryption"`
	Encrypted         bool              `json:"encrypted"`
	SizeBytes         int64             `json:"size_bytes"`
	SHA256            string            `json:"sha256"`
	Verification      string            `json:"verification"`
	VerificationLevel string            `json:"verification_level"`
	FileSets          []ManifestFileSet `json:"file_sets"`
	Warnings          []string          `json:"warnings"`
}

ArtifactManifest is the portable completion contract beside a verified artifact. It contains recovery metadata only: never connection details, credentials, private age identities, or the full public recipient.

func DecodeArtifactManifest added in v0.11.0

func DecodeArtifactManifest(reader io.Reader) (*ArtifactManifest, error)

DecodeArtifactManifest rejects unknown fields, trailing JSON values, and unsupported schema versions so a vault never guesses at publication data.

func ReadArtifactManifest added in v0.11.0

func ReadArtifactManifest(path string) (*ArtifactManifest, error)

ReadArtifactManifest reads a local sidecar without following a symlink.

func ReadArtifactManifestForArtifact added in v0.11.0

func ReadArtifactManifestForArtifact(artifactPath string) (*ArtifactManifest, bool, error)

ReadArtifactManifestForArtifact returns the sidecar only when it exists. Missing sidecars preserve inspection compatibility for legacy artifacts.

func (ArtifactManifest) Validate added in v0.11.0

func (manifest ArtifactManifest) Validate() error

type ArtifactPublicationState added in v0.11.0

type ArtifactPublicationState string
const (
	ArtifactPublicationComplete     ArtifactPublicationState = "complete"
	ArtifactPublicationArtifactOnly ArtifactPublicationState = "artifact-only"
	ArtifactPublicationUncertain    ArtifactPublicationState = "uncertain"
)

type BackupAttempt added in v0.11.2

type BackupAttempt struct {
	Number     int       `json:"number"`
	StartedAt  time.Time `json:"started_at"`
	FinishedAt time.Time `json:"finished_at"`
	Phase      string    `json:"phase"`
	Error      string    `json:"error,omitempty"`
}

BackupAttempt records generation attempts within one leased run. Older runs have no attempt details. Errors have already passed connection redaction.

type Compression

type Compression string
const (
	CompressionNone Compression = "none"
	CompressionGzip Compression = "gzip"
	CompressionZip  Compression = "zip"
	CompressionZstd Compression = "zstd"
)

type CopyArtifactFilter added in v0.11.0

type CopyArtifactFilter struct {
	ProducerID string   `json:"producer_id,omitempty"`
	JobID      string   `json:"job_id,omitempty"`
	Formats    []string `json:"formats,omitempty"`
}

type CopyArtifactResult added in v0.11.0

type CopyArtifactResult struct {
	ArtifactID       string                   `json:"artifact_id"`
	Source           string                   `json:"source"`
	Destination      string                   `json:"destination"`
	SourceCreatedAt  time.Time                `json:"source_created_at,omitempty"`
	SizeBytes        int64                    `json:"size_bytes"`
	SHA256           string                   `json:"sha256,omitempty"`
	Verification     CopyVerificationStrength `json:"verification"`
	VerifiedAt       time.Time                `json:"verified_at"`
	ManifestPath     string                   `json:"manifest_path,omitempty"`
	ManifestSize     int64                    `json:"manifest_size,omitempty"`
	ManifestSHA256   string                   `json:"manifest_sha256,omitempty"`
	PublicationState ArtifactPublicationState `json:"publication_state"`
	// AlreadyPresent records that this run reverified an immutable destination
	// artifact instead of transferring its bytes. The result can still be the
	// first durable ownership record when a catalog is rebuilt.
	AlreadyPresent bool      `json:"already_present,omitempty"`
	Reconciled     bool      `json:"reconciled,omitempty"`
	PrunedAt       time.Time `json:"pruned_at,omitempty"`
	PruneReason    string    `json:"prune_reason,omitempty"`
}

func SelectCopyArtifactForInspection added in v0.11.0

func SelectCopyArtifactForInspection(runs []CopyRun, requestedID string) (CopyArtifactResult, error)

SelectCopyArtifactForInspection returns one exact completed, unpruned copy record. With no requested ID it deterministically selects the newest source recovery point and refuses ambiguous catalog identities.

type CopyDestinationVolume added in v0.11.0

type CopyDestinationVolume struct {
	Mode                CopyVolumeMode `json:"mode"`
	MountPoint          string         `json:"mount_point"`
	SentinelFile        string         `json:"sentinel_file"`
	SentinelValue       string         `json:"sentinel_value"`
	FilesystemUUID      string         `json:"filesystem_uuid,omitempty"`
	ExpectedFilesystem  string         `json:"expected_filesystem,omitempty"`
	ExpectedVolumeLabel string         `json:"expected_volume_label,omitempty"`
	MountOptions        []string       `json:"mount_options,omitempty"`
	WarmupSeconds       int            `json:"warmup_seconds,omitempty"`
	CooldownSeconds     int            `json:"cooldown_seconds,omitempty"`
	Spindown            bool           `json:"spindown,omitempty"`
}

CopyDestinationVolume binds a local copy destination to a positive volume identity. SentinelValue is intentionally not secret; it should be a stable, unique token stored in SentinelFile at the root of the intended volume. This makes a missing mount fail closed instead of writing into an ordinary directory on the system disk.

type CopyEndpoint added in v0.11.0

type CopyEndpoint struct {
	Kind          CopyEndpointKind `json:"kind"`
	Location      string           `json:"location,omitempty"`
	CredentialRef string           `json:"credential_ref,omitempty"`
	PinnedHostKey string           `json:"pinned_host_key,omitempty"`
}

CopyEndpoint stores public routing data and references to separately managed credentials. Secret key or password material must never be embedded here. PinnedHostKey is required for SSH/SFTP so a later transfer implementation cannot silently fall back to trust-on-first-use or an insecure callback.

type CopyEndpointKind added in v0.11.0

type CopyEndpointKind string
const (
	CopyEndpointLocal  CopyEndpointKind = "local"
	CopyEndpointSSH    CopyEndpointKind = "ssh"
	CopyEndpointSFTP   CopyEndpointKind = "sftp"
	CopyEndpointRclone CopyEndpointKind = "rclone"
)

type CopyInspectionLocation added in v0.11.0

type CopyInspectionLocation string

CopyInspectionLocation selects which independently stored recovery point is materialized. A push normally inspects its destination; a pull can inspect either its local destination or the remote producer copy.

const (
	CopyInspectionSource      CopyInspectionLocation = "source"
	CopyInspectionDestination CopyInspectionLocation = "destination"
)

type CopyInspectionStageOptions added in v0.11.0

type CopyInspectionStageOptions struct {
	Location    CopyInspectionLocation
	StagingRoot string
}

CopyInspectionStageOptions controls private materialization. StagingRoot is primarily useful to applications that already own a private state root. When empty, dbterm's native private backup staging root is used.

type CopyJob added in v0.11.0

type CopyJob struct {
	ID                       string                   `json:"id"`
	Name                     string                   `json:"name"`
	Enabled                  bool                     `json:"enabled"`
	Mode                     CopyMode                 `json:"mode"`
	Source                   CopyEndpoint             `json:"source"`
	SourceBackupJobID        string                   `json:"source_backup_job_id,omitempty"`
	Destination              CopyEndpoint             `json:"destination"`
	DestinationVolume        *CopyDestinationVolume   `json:"destination_volume,omitempty"`
	ArtifactFilter           CopyArtifactFilter       `json:"artifact_filter,omitempty"`
	Trigger                  CopyTrigger              `json:"trigger"`
	Schedule                 Schedule                 `json:"schedule"`
	ExpectedFreshnessMinutes int                      `json:"expected_freshness_minutes,omitempty"`
	Verification             CopyVerificationStrength `json:"verification"`
	Retention                Retention                `json:"retention"`
	Notification             EmailNotification        `json:"notification,omitempty"`
	TimeoutMinutes           int                      `json:"timeout_minutes"`
	MaxAttempts              int                      `json:"max_attempts"`
	RetryInitialSeconds      int                      `json:"retry_initial_seconds"`
	RetryMaxSeconds          int                      `json:"retry_max_seconds"`
	TransferProofAt          time.Time                `json:"transfer_proof_at,omitempty"`
	TransferProofFingerprint string                   `json:"transfer_proof_fingerprint,omitempty"`
	CreatedAt                time.Time                `json:"created_at"`
	UpdatedAt                time.Time                `json:"updated_at"`
	LastRunAt                time.Time                `json:"last_run_at,omitempty"`
	NextRunAt                time.Time                `json:"next_run_at,omitempty"`
}

CopyJob is a durable transfer policy. SourceBackupJobID binds an after-success push to one local backup stream without conflating the backup and copy run histories.

func (*CopyJob) ApplyDefaults added in v0.11.0

func (job *CopyJob) ApplyDefaults(now time.Time) error

func (CopyJob) HasCurrentTransferProof added in v0.11.0

func (job CopyJob) HasCurrentTransferProof() bool

HasCurrentTransferProof reports whether a real completed transfer has been recorded for the job's current transport-critical configuration. A read-only endpoint test and an already-present or reconciled artifact never create this proof.

func (CopyJob) TransferConfigurationFingerprint added in v0.11.0

func (job CopyJob) TransferConfigurationFingerprint() (string, error)

TransferConfigurationFingerprint identifies only the settings that decide what bytes are read, where they are published, and how they are verified. Scheduling, retention, notification, retry, and display settings are intentionally excluded so operational edits do not invalidate a successful end-to-end transfer proof.

func (CopyJob) Validate added in v0.11.0

func (job CopyJob) Validate() error

type CopyLocalPublicationGuard added in v0.11.0

type CopyLocalPublicationGuard func(context.Context, string, CopyLocalPublicationPhase) error

type CopyLocalPublicationPhase added in v0.11.0

type CopyLocalPublicationPhase string

CopyLocalPublicationPhase identifies the local filesystem boundary being checked. A configured destination volume supplies the guard; transports call it after creating each private partial and immediately before each immutable final-name publication.

const (
	CopyLocalStageCreated          CopyLocalPublicationPhase = "stage-created"
	CopyLocalBeforeArtifactPublish CopyLocalPublicationPhase = "before-artifact-publish"
	CopyLocalBeforeManifestPublish CopyLocalPublicationPhase = "before-manifest-publish"
)

type CopyMode added in v0.11.0

type CopyMode string

CopyMode names the machine that owns a transfer. Push jobs run on the producer; pull jobs run on the vault. Backup generation remains a separate Job and Run lifecycle.

const (
	CopyModePush CopyMode = "push"
	CopyModePull CopyMode = "pull"
)

type CopyOutcome added in v0.11.0

type CopyOutcome struct {
	Discovered     int
	AlreadyPresent int
	BytesCopied    int64
	Artifacts      []CopyArtifactResult
	Warnings       []string
	NewestSourceAt time.Time
}

CopyOutcome is the transfer-only result. The durable CopyRun lifecycle is owned by the store/agent layer so a valid local backup never changes status merely because an independent copy fails.

type CopyRetentionCandidate added in v0.11.0

type CopyRetentionCandidate struct {
	RunID           string    `json:"run_id"`
	ArtifactID      string    `json:"artifact_id"`
	Path            string    `json:"path"`
	ManifestPath    string    `json:"manifest_path"`
	SizeBytes       int64     `json:"size_bytes"`
	SHA256          string    `json:"sha256"`
	ManifestSize    int64     `json:"manifest_size"`
	ManifestSHA256  string    `json:"manifest_sha256"`
	SourceCreatedAt time.Time `json:"source_created_at"`
}

func PreviewCopyRetention added in v0.11.0

func PreviewCopyRetention(ctx context.Context, store *Store, job CopyJob, now time.Time) ([]CopyRetentionCandidate, error)

PreviewCopyRetention returns the exact local artifacts selected by policy without deleting or changing catalog state. The newest verified recovery point is always retained.

func PreviewCopyRetentionWithVolume added in v0.11.0

func PreviewCopyRetentionWithVolume(ctx context.Context, store *Store, job CopyJob, now time.Time) ([]CopyRetentionCandidate, []string, error)

PreviewCopyRetentionWithVolume prepares and positively identifies a configured local destination volume while holding its durable lease. Release warnings are returned separately because a completed preview remains valid.

type CopyRun added in v0.11.0

type CopyRun struct {
	ID                    string                   `json:"id"`
	JobID                 string                   `json:"job_id"`
	Trigger               CopyTrigger              `json:"trigger"`
	Status                RunStatus                `json:"status"`
	StartedAt             time.Time                `json:"started_at"`
	FinishedAt            time.Time                `json:"finished_at,omitempty"`
	RequiredVerification  CopyVerificationStrength `json:"required_verification"`
	Discovered            int                      `json:"discovered,omitempty"`
	AlreadyPresent        int                      `json:"already_present,omitempty"`
	BytesCopied           int64                    `json:"bytes_copied,omitempty"`
	NewestSourceAt        time.Time                `json:"newest_source_at,omitempty"`
	Artifacts             []CopyArtifactResult     `json:"artifacts,omitempty"`
	Warnings              []string                 `json:"warnings,omitempty"`
	RetentionError        string                   `json:"retention_error,omitempty"`
	NotificationAttempted bool                     `json:"notification_attempted,omitempty"`
	NotificationSent      bool                     `json:"notification_sent,omitempty"`
	NotificationError     string                   `json:"notification_error,omitempty"`
	Error                 string                   `json:"error,omitempty"`
}

func RunCopyJobNow added in v0.11.0

func RunCopyJobNow(ctx context.Context, store *Store, idOrName string, emit func(string)) (CopyRun, error)

RunCopyJobNow claims and executes one copy job. Copy runs are durable and independent from backup-generation runs.

func RunCopyJobNowWithProgress added in v0.11.0

func RunCopyJobNowWithProgress(ctx context.Context, store *Store, idOrName string, progress ProgressFunc) (CopyRun, error)

type CopyRunner added in v0.11.0

type CopyRunner struct {
	Store                 *Store
	Now                   func() time.Time
	Progress              ProgressFunc
	LocalPublicationGuard CopyLocalPublicationGuard
}

CopyRunner moves already-published artifacts. It never creates a database dump and only discovers artifacts through strict portable sidecar manifests.

func (CopyRunner) Run added in v0.11.0

func (runner CopyRunner) Run(ctx context.Context, job CopyJob) (CopyOutcome, error)

type CopyTrigger added in v0.11.0

type CopyTrigger string
const (
	CopyTriggerManual       CopyTrigger = "manual"
	CopyTriggerAfterSuccess CopyTrigger = "after_success"
	CopyTriggerTimed        CopyTrigger = "timed"
)

type CopyVerificationStrength added in v0.11.0

type CopyVerificationStrength string

CopyVerificationStrength records what evidence a copy must produce. Values are deliberately ordered by verifyCopyStrengthRank, not lexically.

const (
	CopyVerificationSizeOnly     CopyVerificationStrength = "size-only"
	CopyVerificationSHA256       CopyVerificationStrength = "sha256"
	CopyVerificationSHA256Format CopyVerificationStrength = "sha256+format"
)

type CopyVolumeLease added in v0.11.0

type CopyVolumeLease struct {
	VolumeKey string
	Owner     string
	JobID     string
	RunID     string
	Until     time.Time
}

type CopyVolumeMode added in v0.11.0

type CopyVolumeMode string

CopyVolumeMode describes who owns the destination mount lifecycle. The two verify-only modes never mount or unmount anything. Managed Linux volumes are the sole mode permitted to invoke mount-management commands.

const (
	CopyVolumeAlreadyMounted          CopyVolumeMode = "already_mounted"
	CopyVolumeOSManaged               CopyVolumeMode = "os_managed"
	CopyVolumeManagedLinuxBlockDevice CopyVolumeMode = "managed_linux_block_device"
)

type DBTermBundleDatabase added in v0.11.0

type DBTermBundleDatabase struct {
	Engine    config.DBType `json:"engine"`
	Format    string        `json:"format"`
	Path      string        `json:"path"`
	SizeBytes int64         `json:"size_bytes"`
	SHA256    string        `json:"sha256"`
}

type DBTermBundleFile added in v0.11.0

type DBTermBundleFile struct {
	Path      string `json:"path"`
	SizeBytes int64  `json:"size_bytes"`
	SHA256    string `json:"sha256"`
}

type DBTermBundleFileSet added in v0.11.0

type DBTermBundleFileSet struct {
	Label     string             `json:"label"`
	Required  bool               `json:"required"`
	FileCount int64              `json:"file_count"`
	SizeBytes int64              `json:"size_bytes"`
	Files     []DBTermBundleFile `json:"files"`
}

type DBTermBundleManifest added in v0.11.0

type DBTermBundleManifest struct {
	SchemaVersion int                   `json:"schema_version"`
	Database      DBTermBundleDatabase  `json:"database"`
	FileSets      []DBTermBundleFileSet `json:"file_sets"`
}

DBTermBundleManifest is the self-contained recovery index inside a dbterm bundle. It intentionally excludes configured absolute source roots.

func DecodeDBTermBundleManifest added in v0.11.0

func DecodeDBTermBundleManifest(reader io.Reader) (*DBTermBundleManifest, error)

func (DBTermBundleManifest) Validate added in v0.11.0

func (manifest DBTermBundleManifest) Validate() error

type DiskUsage

type DiskUsage struct {
	Path           string
	Volume         string
	CapacityBytes  uint64
	FreeBytes      uint64
	AvailableBytes uint64
}

func DestinationDiskUsage

func DestinationDiskUsage(path string) (DiskUsage, error)

DestinationDiskUsage reports capacity for the filesystem that will contain path. The destination itself need not exist yet; its nearest existing parent is used for the operating-system query.

type EmailNotification

type EmailNotification struct {
	Policy     NotificationPolicy `json:"policy"`
	SMTPHost   string             `json:"smtp_host,omitempty"`
	SMTPPort   int                `json:"smtp_port,omitempty"`
	TLSMode    SMTPTLSMode        `json:"tls_mode,omitempty"`
	Recipients []string           `json:"recipients,omitempty"`
	Username   string             `json:"username,omitempty"`
	Password   string             `json:"password,omitempty"`
	From       string             `json:"from,omitempty"`
}

EmailNotification is stored in the private backup catalog as part of the job JSON. Password is necessarily plaintext so the unattended OS service can authenticate; the SQLite catalog and its parent state directory are protected with 0600/0700 permissions and must be treated as secrets.

func (EmailNotification) ShouldNotify

func (notification EmailNotification) ShouldNotify(status RunStatus) bool

func (EmailNotification) ShouldNotifyCopyRun added in v0.11.0

func (notification EmailNotification) ShouldNotifyCopyRun(run CopyRun) bool

func (EmailNotification) ShouldNotifyRun added in v0.11.0

func (notification EmailNotification) ShouldNotifyRun(run Run) bool

func (EmailNotification) Validate

func (notification EmailNotification) Validate() error

type Encryption

type Encryption string
const (
	EncryptionNone Encryption = "none"
	EncryptionAge  Encryption = "age"
)

type FileSet added in v0.11.0

type FileSet struct {
	Label    string   `json:"label"`
	Root     string   `json:"root"`
	Include  []string `json:"include,omitempty"`
	Exclude  []string `json:"exclude,omitempty"`
	Required bool     `json:"required"`
}

FileSet describes application files that must travel with a database recovery point. Root is machine-local configuration and is never written to a portable artifact manifest. Include and Exclude use slash-separated globs; ** is supported only as a complete path segment.

type Format

type Format string
const (
	FormatPostgresCustom Format = "postgres_custom"
	FormatPostgresTar    Format = "postgres_tar"
	FormatPostgresSQL    Format = "postgres_sql"
	FormatMySQLSQL       Format = "mysql_sql"
	FormatSQLiteDatabase Format = "sqlite_database"
	FormatSQLiteSQL      Format = "sqlite_sql"
	FormatGenericSQL     Format = "generic_sql"
	FormatDBTermBundle   Format = "dbterm_bundle"
	FormatUnknown        Format = "unknown"
)

type InspectOptions

type InspectOptions struct {
	AgeIdentityPath string
	MaxDecodedBytes int64
}

type Inspection

type Inspection struct {
	Path           string
	Size           int64
	SHA256         string
	Manifest       *ArtifactManifest
	Wrappers       []Wrapper
	Format         Format
	DatabaseFormat Format
	Engine         config.DBType
	Confidence     string
	Evidence       []string
	Warnings       []string
	Locked         bool
	RequiredTools  []string
	FileSets       []ManifestFileSet
}

func Inspect

func Inspect(ctx context.Context, path string, opts InspectOptions) (*Inspection, error)

Inspect identifies a database backup from its bytes, independently of its filename. The SHA-256 digest and Size always describe the original outer artifact, while Wrappers is ordered outermost first.

type Job

type Job struct {
	ID                  string            `json:"id"`
	Name                string            `json:"name"`
	ConnectionID        string            `json:"connection_id"`
	Enabled             bool              `json:"enabled"`
	Destination         string            `json:"destination"`
	FilenameTemplate    string            `json:"filename_template"`
	Compression         Compression       `json:"compression"`
	CompressionLevel    int               `json:"compression_level"`
	Encryption          Encryption        `json:"encryption"`
	AgeRecipient        string            `json:"age_recipient,omitempty"`
	FileSets            []FileSet         `json:"file_sets,omitempty"`
	Schedule            Schedule          `json:"schedule"`
	Retention           Retention         `json:"retention"`
	Notification        EmailNotification `json:"notification,omitempty"`
	TimeoutMinutes      int               `json:"timeout_minutes"`
	MaxAttempts         int               `json:"max_attempts,omitempty"`
	RetryInitialSeconds int               `json:"retry_initial_seconds,omitempty"`
	RetryMaxSeconds     int               `json:"retry_max_seconds,omitempty"`
	CreatedAt           time.Time         `json:"created_at"`
	UpdatedAt           time.Time         `json:"updated_at"`
	LastRunAt           time.Time         `json:"last_run_at,omitempty"`
	NextRunAt           time.Time         `json:"next_run_at,omitempty"`
}

Job is a durable backup policy. It references a saved connection by its stable ID so renaming or reordering dashboard entries cannot redirect it.

func (*Job) ApplyDefaults

func (j *Job) ApplyDefaults(now time.Time) error

func (Job) Validate

func (j Job) Validate() error

type ManifestFileSet added in v0.11.0

type ManifestFileSet struct {
	Label        string   `json:"label"`
	FileCount    int64    `json:"file_count"`
	SizeBytes    int64    `json:"size_bytes"`
	Consistency  string   `json:"consistency"`
	ChangedFiles []string `json:"changed_files"`
	Warnings     []string `json:"warnings"`
}

ManifestFileSet describes one portable application-file capture. A best-effort capture is copied from a live folder with change detection; it does not claim application, filesystem-snapshot, or cross-file atomicity. Database-only backups deliberately publish an empty list rather than null.

type NativeOptions

type NativeOptions struct {
	PostgresCompression int
	Progress            ProgressFunc
	// contains filtered or unexported fields
}

type NativePlan

type NativePlan struct {
	Format      string
	FormatLabel string
	ToolLabel   string
	Extension   string
}

func PlanFor

func PlanFor(cfg *config.ConnectionConfig) (NativePlan, error)

type NotificationPolicy

type NotificationPolicy string
const (
	NotificationNever   NotificationPolicy = "never"
	NotificationFailure NotificationPolicy = "failure"
	NotificationSuccess NotificationPolicy = "success"
	NotificationBoth    NotificationPolicy = "both"
)

type ProgressEvent

type ProgressEvent struct {
	Phase        string
	Message      string
	CurrentBytes int64
	TotalBytes   int64
	Elapsed      time.Duration
}

ProgressEvent describes a bounded, low-overhead backup status update. A zero TotalBytes means that the native database tool cannot report its final size in advance; CurrentBytes still reflects the staging file observed on disk.

type ProgressFunc

type ProgressFunc func(ProgressEvent)

type RcloneSourceMeasurement added in v0.11.0

type RcloneSourceMeasurement struct {
	ListDuration       time.Duration `json:"list_duration"`
	Objects            int           `json:"objects"`
	CompletedManifests int           `json:"completed_manifests"`
}

func MeasureRcloneSource added in v0.11.0

func MeasureRcloneSource(ctx context.Context, endpoint CopyEndpoint) (RcloneSourceMeasurement, error)

MeasureRcloneSource performs a read-only capability and latency check. It intentionally uses no copy, move, delete, or cleanup command.

type RestoreFileSetPlan added in v0.11.0

type RestoreFileSetPlan struct {
	Label     string
	Root      string
	FileCount int64
	SizeBytes int64
}

RestoreFileSetPlan is the immutable, normalized file publication contract shown during restore review.

type RestoreFileSetTarget added in v0.11.0

type RestoreFileSetTarget struct {
	Label string
	Root  string
}

RestoreFileSetTarget maps one named bundle file set to a new, explicitly selected root. Bundles intentionally do not carry their original absolute roots, so restore can never silently write back to a production path.

type RestoreMode

type RestoreMode string

type RestoreOptions

type RestoreOptions struct {
	Mode              RestoreMode
	StopOnError       bool
	SingleTransaction bool
	AgeIdentityPath   string
	// MaxDecodedBytes limits each decoded wrapper layer. Zero uses
	// DefaultMaxDecodedBytes.
	MaxDecodedBytes int64
	// FileSetTargets opts individual bundle file sets into restore. An empty
	// slice deliberately means database-only restore. Source roots are never
	// stored in a bundle, so every selected set requires an explicit new root.
	FileSetTargets []RestoreFileSetTarget
	// OverwriteFileSetFiles permits atomic replacement of existing regular
	// files. Symbolic links, reparse points, and non-regular files are always
	// refused. The zero value is no-clobber.
	OverwriteFileSetFiles bool
	// MaxFileSetFiles and MaxFileSetBytes limit the selected file-set payload.
	// Zero uses the conservative package defaults.
	MaxFileSetFiles int64
	MaxFileSetBytes int64
}

type RestorePlan

type RestorePlan struct {
	Inspection       *Inspection
	Target           config.ConnectionConfig
	Options          RestoreOptions
	IncludedFileSets []ManifestFileSet
	FileSetTargets   []RestoreFileSetPlan
	Warnings         []string
}

func BuildRestorePlan

func BuildRestorePlan(inspection *Inspection, target *config.ConnectionConfig, options RestoreOptions) (*RestorePlan, error)

BuildRestorePlan performs every check that does not require opening the artifact or connecting to the target. ExecuteRestore repeats this validation so a caller cannot bypass it by mutating or hand-building a plan.

type Retention

type Retention struct {
	KeepLast      int   `json:"keep_last"`
	MaxAgeDays    int   `json:"max_age_days"`
	MaxTotalBytes int64 `json:"max_total_bytes,omitempty"`
}

type Run

type Run struct {
	ID                    string          `json:"id"`
	JobID                 string          `json:"job_id"`
	Trigger               Trigger         `json:"trigger"`
	Status                RunStatus       `json:"status"`
	StartedAt             time.Time       `json:"started_at"`
	FinishedAt            time.Time       `json:"finished_at,omitempty"`
	Artifact              Artifact        `json:"artifact,omitempty"`
	Error                 string          `json:"error,omitempty"`
	Attempts              []BackupAttempt `json:"attempts,omitempty"`
	RetentionError        string          `json:"retention_error,omitempty"`
	NotificationAttempted bool            `json:"notification_attempted,omitempty"`
	NotificationSent      bool            `json:"notification_sent,omitempty"`
	NotificationError     string          `json:"notification_error,omitempty"`
}

func RunJobNow

func RunJobNow(ctx context.Context, store *Store, idOrName string, emit func(string)) (Run, error)

func RunJobNowWithProgress

func RunJobNowWithProgress(ctx context.Context, store *Store, idOrName string, progress ProgressFunc) (Run, error)

RunJobNowWithProgress runs a claimed job and reports structured progress for clients that want byte counts and elapsed time instead of formatted lines.

type RunStatus

type RunStatus string
const (
	RunRunning   RunStatus = "running"
	RunSucceeded RunStatus = "succeeded"
	RunFailed    RunStatus = "failed"
	RunCanceled  RunStatus = "canceled"
)

type Runner

type Runner struct {
	Now           func() time.Time
	Progress      ProgressFunc
	ProducerID    string
	DBTermVersion string
	// OutputFilename is an optional exact basename for an on-demand backup.
	// Durable jobs normally leave this empty and use FilenameTemplate.
	OutputFilename string
}

func (Runner) Run

func (r Runner) Run(ctx context.Context, job Job, cfg *config.ConnectionConfig, runID string) (artifact Artifact, err error)

type SFTPTransportMeasurement added in v0.11.0

type SFTPTransportMeasurement struct {
	EndpointKind       CopyEndpointKind
	HostKeyFingerprint string
	ConnectDuration    time.Duration
	ListDuration       time.Duration
	Entries            int
	Readable           bool
	CreateOnlyPublish  bool
	StableStorageSync  bool
}

SFTPTransportMeasurement is a read-only endpoint test. It deliberately does not upload and remove a probe object: some SFTP servers cannot make that capability test race-free, and copy jobs must never depend on broad cleanup.

func MeasureSFTPTransport added in v0.11.0

func MeasureSFTPTransport(ctx context.Context, endpoint CopyEndpoint) (SFTPTransportMeasurement, error)

MeasureSFTPTransport verifies the pinned host key, authenticates only with the endpoint's dedicated identity file, starts the SFTP subsystem, and lists the configured root. It performs no remote writes.

type SMTPTLSMode

type SMTPTLSMode string
const (
	SMTPTLSStartTLS SMTPTLSMode = "starttls"
	SMTPTLSImplicit SMTPTLSMode = "implicit"
	SMTPTLSNone     SMTPTLSMode = "none"
)

type Schedule

type Schedule struct {
	Kind            ScheduleKind `json:"kind"`
	EveryMinutes    int          `json:"every_minutes,omitempty"`
	TimeOfDay       string       `json:"time_of_day,omitempty"`
	TimesOfDay      []string     `json:"times_of_day,omitempty"`
	Weekdays        []int        `json:"weekdays,omitempty"`
	Timezone        string       `json:"timezone,omitempty"`
	RunMissedOnWake bool         `json:"run_missed_on_wake"`
}

func (Schedule) AdvancePast

func (s Schedule) AdvancePast(scheduled, now time.Time) (time.Time, bool, error)

AdvancePast returns the first scheduled occurrence strictly after now while preserving the original cadence for interval schedules. It is used when a sleeping agent intentionally skips an overdue run.

func (Schedule) Next

func (s Schedule) Next(after time.Time) (time.Time, bool, error)

func (Schedule) Validate

func (s Schedule) Validate() error

func (Schedule) WallClockTimes added in v0.11.0

func (s Schedule) WallClockTimes() ([]string, error)

WallClockTimes returns the effective daily/weekly wall-clock times in canonical HH:MM order. The plural field is authoritative when present; TimeOfDay remains a backward-compatible fallback for existing catalogs.

type ScheduleKind

type ScheduleKind string
const (
	ScheduleManual   ScheduleKind = "manual"
	ScheduleInterval ScheduleKind = "interval"
	ScheduleDaily    ScheduleKind = "daily"
	ScheduleWeekly   ScheduleKind = "weekly"
)

type StagedCopyArtifact added in v0.11.0

type StagedCopyArtifact struct {
	Path         string
	ManifestPath string
	Origin       string
	Manifest     ArtifactManifest
	// contains filtered or unexported fields
}

StagedCopyArtifact is an independently verified, local view of one durable copy result. Call Cleanup when inspection or restore preview is complete. Path has its completion sidecar beside it, so it can be passed directly to Inspect and the existing guarded restore flow.

func StageCopyArtifactForInspection added in v0.11.0

func StageCopyArtifactForInspection(ctx context.Context, job CopyJob, result CopyArtifactResult, options CopyInspectionStageOptions) (_ *StagedCopyArtifact, err error)

StageCopyArtifactForInspection materializes one completed CopyArtifactResult into private local storage. It re-reads the sidecar as the publication signal, binds it to the catalog identity, streams the exact artifact bytes, verifies SHA-256 and the lightweight format envelope, and checks the source did not change during transfer.

func StageCopyArtifactForInspectionWithVolume added in v0.11.0

func StageCopyArtifactForInspectionWithVolume(ctx context.Context, store *Store, job CopyJob, result CopyArtifactResult, options CopyInspectionStageOptions) (*StagedCopyArtifact, []string, error)

StageCopyArtifactForInspectionWithVolume safely stages a destination copy from a configured local volume. The volume may be released after staging because StagedCopyArtifact owns independently verified bytes in private local storage. Source inspection does not touch the destination volume.

func (*StagedCopyArtifact) Cleanup added in v0.11.0

func (staged *StagedCopyArtifact) Cleanup() error

Cleanup removes only the two files and exact private directory created by StageCopyArtifactForInspection. Unexpected entries or directory replacement are preserved for review rather than recursively removed.

func (*StagedCopyArtifact) Close added in v0.11.0

func (staged *StagedCopyArtifact) Close() error

Close is an io.Closer-style alias for Cleanup, allowing callers to simply defer staged.Close() around an inspect or restore preview.

func (*StagedCopyArtifact) Inspect added in v0.11.0

func (staged *StagedCopyArtifact) Inspect(ctx context.Context, options InspectOptions) (*Inspection, error)

Inspect enters the ordinary byte-based inspection flow after remote or copied storage has been staged and verified.

type Store

type Store struct {
	// contains filtered or unexported fields
}

func OpenDefaultStore

func OpenDefaultStore() (*Store, error)

func OpenStore

func OpenStore(path string) (*Store, error)

func (*Store) ClaimCopyJob added in v0.11.0

func (store *Store) ClaimCopyJob(ctx context.Context, idOrName, owner string, now time.Time) (CopyJob, error)

func (*Store) ClaimCopyVolumeLease added in v0.11.0

func (store *Store) ClaimCopyVolumeLease(ctx context.Context, volumeKey, owner, jobID, runID string, now, until time.Time) (CopyVolumeLease, error)

func (*Store) ClaimDueCopyJobs added in v0.11.0

func (store *Store) ClaimDueCopyJobs(ctx context.Context, now time.Time, owner string, limit int) ([]CopyJob, error)

func (*Store) ClaimDueJobs

func (s *Store) ClaimDueJobs(ctx context.Context, now time.Time, owner string, limit int) ([]Job, error)

func (*Store) ClaimJob

func (s *Store) ClaimJob(ctx context.Context, idOrName, owner string, now time.Time) (Job, error)

func (*Store) Close

func (s *Store) Close() error

func (*Store) DeleteCopyJob added in v0.11.0

func (store *Store) DeleteCopyJob(ctx context.Context, idOrName string) error

func (*Store) DeleteJob

func (s *Store) DeleteJob(ctx context.Context, id string) error

func (*Store) FinishCopyRun added in v0.11.0

func (store *Store) FinishCopyRun(ctx context.Context, run *CopyRun, leaseOwner string) error

func (*Store) FinishRun

func (s *Store) FinishRun(ctx context.Context, run *Run, leaseOwner string) error

func (*Store) GetCopyJob added in v0.11.0

func (store *Store) GetCopyJob(ctx context.Context, idOrName string) (CopyJob, error)

func (*Store) GetCopyRun added in v0.11.0

func (store *Store) GetCopyRun(ctx context.Context, runID string) (CopyRun, error)

func (*Store) GetJob

func (s *Store) GetJob(ctx context.Context, idOrName string) (Job, error)

func (*Store) GetMeta

func (s *Store) GetMeta(ctx context.Context, key string) (string, bool, error)

func (*Store) LatestCopyRun added in v0.11.0

func (store *Store) LatestCopyRun(ctx context.Context, jobID string) (CopyRun, bool, error)

func (*Store) LatestRun

func (s *Store) LatestRun(ctx context.Context, jobID string) (Run, bool, error)

func (*Store) ListCopyArtifactsForInspection added in v0.11.0

func (store *Store) ListCopyArtifactsForInspection(ctx context.Context, jobID string) ([]CopyArtifactResult, error)

ListCopyArtifactsForInspection returns every active recovery point owned by one copy job. Unlike the run-history view, this read is deliberately unbounded: an older retained artifact must remain selectable even when more than the UI history limit of runs have been recorded.

func (*Store) ListCopyJobs added in v0.11.0

func (store *Store) ListCopyJobs(ctx context.Context) ([]CopyJob, error)

func (*Store) ListCopyRuns added in v0.11.0

func (store *Store) ListCopyRuns(ctx context.Context, jobID string, limit int) ([]CopyRun, error)

func (*Store) ListEnabledAfterSuccessCopyJobs added in v0.11.0

func (store *Store) ListEnabledAfterSuccessCopyJobs(ctx context.Context, backupJobID string) ([]CopyJob, error)

ListEnabledAfterSuccessCopyJobs returns the locally owned push policies that should be considered after one backup job has durably completed. The caller must still acquire each copy-job lease before starting a run.

func (*Store) ListJobs

func (s *Store) ListJobs(ctx context.Context) ([]Job, error)

func (*Store) ListLatestVerifiedUnprunedRuns added in v0.11.0

func (s *Store) ListLatestVerifiedUnprunedRuns(ctx context.Context) ([]Run, error)

ListLatestVerifiedUnprunedRuns returns at most one retained recovery point per job without applying the bounded activity-history limit. UI protection summaries must not forget an inactive job merely because other jobs produced more recent run rows.

func (*Store) ListRuns

func (s *Store) ListRuns(ctx context.Context, jobID string, limit int) ([]Run, error)

func (*Store) MarkArtifactPruned

func (s *Store) MarkArtifactPruned(ctx context.Context, runID, reason string, at time.Time) error

func (*Store) MarkCopyArtifactPruned added in v0.11.0

func (store *Store) MarkCopyArtifactPruned(ctx context.Context, runID, artifactID, destination, reason string, at time.Time) error

func (*Store) ReconcileStaleCopyRuns added in v0.11.0

func (store *Store) ReconcileStaleCopyRuns(ctx context.Context, now time.Time) (int, error)

func (*Store) ReconcileStaleRuns

func (s *Store) ReconcileStaleRuns(ctx context.Context, now time.Time) (int, error)

ReconcileStaleRuns closes history entries abandoned by a crashed process. A running entry is stale only when its job no longer has an unexpired lease; the conditional update repeats that check inside the transaction so an actively leased run is never rewritten.

func (*Store) ReleaseCopyJob added in v0.11.0

func (store *Store) ReleaseCopyJob(ctx context.Context, jobID, leaseOwner string) error

func (*Store) ReleaseCopyVolumeLease added in v0.11.0

func (store *Store) ReleaseCopyVolumeLease(ctx context.Context, lease CopyVolumeLease) error

func (*Store) ReleaseJob

func (s *Store) ReleaseJob(ctx context.Context, jobID, leaseOwner string) error

func (*Store) RenewCopyJobLease added in v0.11.0

func (store *Store) RenewCopyJobLease(ctx context.Context, jobID, leaseOwner string, now, leaseUntil time.Time) error

RenewCopyJobLease extends an existing live lease only for its current owner. It never revives an expired lease: once expiry permits another process to claim the job, the former owner must not continue into retention or other post-processing that assumes exclusive ownership.

func (*Store) RenewCopyVolumeLease added in v0.11.0

func (store *Store) RenewCopyVolumeLease(ctx context.Context, lease *CopyVolumeLease, now, until time.Time) error

func (*Store) RenewJobLease added in v0.11.0

func (s *Store) RenewJobLease(ctx context.Context, jobID, leaseOwner string, now, leaseUntil time.Time) error

RenewJobLease extends only the current owner's still-live lease. It never revives an expired lease because another process may already be entitled to claim the job and begin a new backup.

func (*Store) SetCopyJobEnabled added in v0.11.0

func (store *Store) SetCopyJobEnabled(ctx context.Context, idOrName string, enabled bool) error

func (*Store) SetJobEnabled

func (s *Store) SetJobEnabled(ctx context.Context, id string, enabled bool) error

func (*Store) SetMeta

func (s *Store) SetMeta(ctx context.Context, key, value string) error

func (*Store) StartCopyRun added in v0.11.0

func (store *Store) StartCopyRun(ctx context.Context, jobID string, trigger CopyTrigger, now time.Time) (CopyRun, error)

func (*Store) StartRun

func (s *Store) StartRun(ctx context.Context, jobID string, trigger Trigger, now time.Time) (Run, error)

func (*Store) UpsertCopyJob added in v0.11.0

func (store *Store) UpsertCopyJob(ctx context.Context, job *CopyJob) error

func (*Store) UpsertJob

func (s *Store) UpsertJob(ctx context.Context, job *Job) error

type Trigger

type Trigger string
const (
	TriggerManual    Trigger = "manual"
	TriggerScheduled Trigger = "scheduled"
)

type Wrapper

type Wrapper string
const (
	WrapperGzip Wrapper = "gzip"
	WrapperZstd Wrapper = "zstd"
	WrapperZip  Wrapper = "zip"
	WrapperAge  Wrapper = "age"
)

Jump to

Keyboard shortcuts

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