Documentation
¶
Overview ¶
Package pipeline orchestrates a backup run: WORM check -> enumerate -> per repo (clone --mirror, bundle, checksum, immutable upload) -> signed run-manifest. A repo failure makes the run fail and the manifest records it.
Index ¶
Constants ¶
const ( StatusSuccess = "success" StatusFailed = "failed" StatusSkipped = "skipped" // nothing to write; see RepoEntry.Reason for which case // The reasons a repository is skipped. Both mean "nothing was written and nothing was // lost", which is why neither fails the run, but they are different facts and an operator // reading a manifest is entitled to know which one applies. ReasonResume = "already backed up for this date" ReasonEmpty = "repository has no commits" )
Status values used in the manifest.
const ManifestSchema = "gitdr.manifest/v2"
ManifestSchema is the versioned identifier of the run-manifest contract. The manifest schema and the --output json shape are a STABLE PUBLIC CONTRACT: changing them requires a version bump and a note in SPEC.md.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ArtifactInfo ¶
type ArtifactInfo struct {
Kind string `json:"kind"` // bundle | meta | sha256
Key string `json:"key"`
Size int64 `json:"size"`
SHA256 string `json:"sha256"`
RetainUntil time.Time `json:"retainUntil"`
}
ArtifactInfo is one stored object with its integrity data.
type BackupDeps ¶
type BackupDeps struct {
Config *config.Config
Source source.Source
Dest dest.Destination
Git *gitexec.Git
SigningKey ed25519.PrivateKey
EncryptionKey []byte // optional client-side envelope key; nil = off
ToolVersion string
Logger *slog.Logger
Now func() time.Time
RequireWORM bool // --require-worm / worm.require: fail closed if not immutable
}
BackupDeps are the inputs to a backup run.
type BackupResult ¶
BackupResult carries the run-manifest and where it was stored. It is returned even when the run fails, so callers can surface the recorded failure.
func Backup ¶
func Backup(ctx context.Context, d BackupDeps) (*BackupResult, error)
Backup runs one backup. It returns a non-nil error on any failure (fail-closed); a BackupResult may still be returned to report what happened.
type DestInfo ¶
type DestInfo struct {
Type string `json:"type"`
Bucket string `json:"bucket"`
WormMode string `json:"wormMode,omitempty"` // configured retention mode
WormImmutable bool `json:"wormImmutable"` // WORM check confirmed immutable
WormDetails string `json:"wormDetails,omitempty"` // observed immutability detail
}
DestInfo identifies where the data went and the immutability observed at write time. wormImmutable records whether the WORM check confirmed the destination immutable, the signed, tamper-evident answer to "was this backup on WORM storage?" (v2).
type Manifest ¶
type Manifest struct {
Schema string `json:"schema"`
RunID string `json:"runId"`
Tool ToolInfo `json:"tool"`
Source SourceInfo `json:"source"`
Destination DestInfo `json:"destination"`
StartedAt time.Time `json:"startedAt"`
FinishedAt time.Time `json:"finishedAt"`
Status string `json:"status"` // success | failed
Repos []RepoEntry `json:"repos"`
}
Manifest is the signed record of one backup run.
type RepoEntry ¶
type RepoEntry struct {
Slug string `json:"slug"`
Status string `json:"status"` // success | failed | skipped
Error string `json:"error,omitempty"`
// Why a repository was skipped, in plain words. Additive to the manifest schema rather
// than a new status value, because a consumer switching on `status` would break on an
// unknown one and there is more than one reason to skip.
Reason string `json:"reason,omitempty"`
Artifacts []ArtifactInfo `json:"artifacts,omitempty"`
}
RepoEntry is the per-repository outcome.
type RestoreDeps ¶
type RestoreDeps struct {
Dest dest.Destination
Git *gitexec.Git
EncryptionKey []byte // optional; must match the backup's key
// PublicKey is optional. When set, restore locates the signed run-manifest for the
// requested date, verifies its signature, and checks every artifact it downloads
// against the checksums the manifest records. The unsigned .sha256 sidecar catches
// corruption but not tampering; the manifest catches both. Without a key restore
// keeps the sidecar-only check and says so in RestoreResult.Verification.
PublicKey ed25519.PublicKey
Logger *slog.Logger
}
RestoreDeps are the inputs to a restore.
type RestoreRequest ¶
type RestoreRequest struct {
Host string // e.g. github.com
Owner string
Name string
Date string // YYYY-MM-DD
OutDir string
}
RestoreRequest selects which dated bundle to restore and where to put it.
type RestoreResult ¶
type RestoreResult struct {
BundleKey string `json:"bundleKey"`
SHA256 string `json:"sha256"`
OutDir string `json:"outDir"`
Verified bool `json:"verified"`
// Verification says in plain words which integrity checks this restore ran, so a
// restore that was not checked against the signed manifest announces itself
// instead of looking identical to one that was. Deliberately kept out of the JSON:
// the --output json shape is a versioned public contract (SPEC §11), and widening
// it is its own change, made on purpose, not as a side effect of a read-side fix.
Verification string `json:"-"`
}
RestoreResult reports what was restored.
func Restore ¶
func Restore(ctx context.Context, d RestoreDeps, req RestoreRequest) (*RestoreResult, error)
Restore fetches a bundle, verifies its checksum against the stored sidecar (and, when a public key is configured, against the signed run-manifest), checks the bundle, and clones it into OutDir. Read-only against the destination.
type SourceInfo ¶
SourceInfo identifies where the data came from.
type VerifyDeps ¶
VerifyDeps are the inputs to a verify.
type VerifyResult ¶
type VerifyResult struct {
ManifestKey string `json:"manifestKey"`
SignatureValid bool `json:"signatureValid"`
ArtifactsChecked int `json:"artifactsChecked"`
ArtifactsOK int `json:"artifactsOk"`
Failures []string `json:"failures,omitempty"`
}
VerifyResult reports signature and per-artifact checksum results.
func Verify ¶
func Verify(ctx context.Context, d VerifyDeps, manifestKey string) (*VerifyResult, error)
Verify checks the manifest's Ed25519 signature, then re-reads every referenced artifact and recomputes its SHA-256 against the manifest. Read-only.