db

package
v1.0.0-alpha.2 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const (
	AgentTypeFilesystem = config.AgentTypeFilesystem
	AgentTypeDatabase   = config.AgentTypeDatabase
	AgentTypeKubernetes = config.AgentTypeKubernetes
	JobTypeFilesystem   = config.AgentTypeFilesystem
	JobTypeDatabase     = config.AgentTypeDatabase
	JobTypeKubernetes   = config.AgentTypeKubernetes
	// JobTypePVE backs up a Proxmox VE host's configuration; it runs on the
	// filesystem agent installed on the node
	JobTypePVE = "pve"
	// JobTypeDocker backs up a Docker host (definitions, compose files, volumes); it
	// runs on the filesystem agent installed on the host
	JobTypeDocker = "docker"
	// JobTypeM365 backs up a Microsoft 365 tenant through Graph; it runs on any
	// filesystem agent with outbound HTTPS (no host capability involved)
	JobTypeM365 = "m365"
)

Agent / job types: each agent binary handles one kind of job

View Source
const (
	PxarFormatV1 = "v1" // single stream + catalog; browsable everywhere
	PxarFormatV2 = "v2" // split metadata/payload streams; PBS 3.2+
)

pxar archive formats a target accepts

View Source
const (
	EncryptionNone    = "none"
	EncryptionEncrypt = "encrypt"
)

Encryption modes of a target

Variables

View Source
var (
	ErrNotFound = errors.New("record not found")
)
View Source
var ErrTenantInUse = errors.New("tenant is referenced by backup jobs")

ErrTenantInUse is returned when a tenant still has jobs

Functions

func CleanDBEngines added in v0.11.3

func CleanDBEngines(in []string) []string

CleanDBEngines keeps the known engine names, canonical and without duplicates

func JobAllowedOnAgent added in v0.9.5

func JobAllowedOnAgent(jobType, agentType string) bool

JobAllowedOnAgent reports whether an agent of agentType may run a job of jobType. Job types normally match the agent type; the exceptions are database jobs on a kubernetes agent (dumped from a pod inside the cluster) or on a filesystem agent (the combined agent, when it reports database client tools), Proxmox VE / Docker host jobs, which run on the filesystem agent installed on the host, and Microsoft 365 jobs, which any filesystem agent runs.

func NormalizeAgentType added in v0.6.0

func NormalizeAgentType(t string) (string, bool)

NormalizeAgentType maps "" to filesystem and reports unknown values

func NormalizeJobType added in v0.9.5

func NormalizeJobType(t string) (string, bool)

NormalizeJobType maps "" to filesystem and accepts the job-only types pve, docker and m365

func SetScheduleLocation added in v0.7.2

func SetScheduleLocation(loc *time.Location)

SetScheduleLocation installs the timezone used for next-run display

func ValidateBackupPaths added in v0.6.0

func ValidateBackupPaths(paths []string) ([]string, error)

ValidateBackupPaths normalises a job's backup paths and rejects combinations that cannot form one archive: every path must be absolute, exact duplicates are dropped and no path may lie inside another (its data would be archived twice). Paths sharing a basename are fine; the agent names them after their full path in the archive. The rules are those of a Unix agent regardless of the host the server runs on, so the slash-only path package is used rather than path/filepath.

func ValidateBackupPathsFor added in v0.9.5

func ValidateBackupPathsFor(agentOS string, paths []string) ([]string, error)

ValidateBackupPathsFor validates paths with the rules of the agent's operating system ("windows" or anything else): the server runs on Linux but stores jobs for Windows agents, whose paths use drive letters and backslashes.

func ValidateCron added in v0.6.2

func ValidateCron(expr string) error

ValidateCron rejects schedule expressions the scheduler cannot run; empty = manual

func ValidateExcludePatterns added in v0.6.0

func ValidateExcludePatterns(patterns []string) error

ValidateExcludePatterns checks exclude patterns against the pxar pattern syntax (proxmox-backup-client --exclude); invalid patterns would otherwise fail the backup only at run time on the agent.

func ValidateLocalBackupPaths added in v0.9.6

func ValidateLocalBackupPaths(paths []string) ([]string, error)

ValidateLocalBackupPaths validates paths with the rules of the operating system the caller runs on; the agent uses it for the paths it is about to read.

Types

type APIKey

type APIKey struct {
	ID         uuid.UUID  `json:"id"`
	Name       string     `json:"name"`
	KeyHash    string     `json:"-"`
	CreatedBy  string     `json:"created_by"`
	CreatedAt  time.Time  `json:"created_at"`
	LastUsedAt *time.Time `json:"last_used_at"`
	ExpiresAt  *time.Time `json:"expires_at"`
	RevokedAt  *time.Time `json:"revoked_at"`
}

APIKey is an admin credential for fallbck-ctl and scripts. The raw key is never stored.

type Agent

type Agent struct {
	ID        uuid.UUID `json:"id" db:"id"`
	Hostname  string    `json:"hostname" db:"hostname"`
	IPAddress string    `json:"ip_address" db:"ip_address"`
	OS        string    `json:"os" db:"os"`
	Arch      string    `json:"arch" db:"arch"`
	Version   string    `json:"version" db:"version"`
	AgentType string    `json:"agent_type" db:"agent_type"`
	TaskQueue string    `json:"task_queue" db:"task_queue"`
	// DebugLogging raises the agent's log level to debug (applied via heartbeats)
	DebugLogging bool `json:"debug_logging" db:"debug_logging"`
	// AutoUpdate lets the agent update itself to the server's version (per-agent opt-in)
	AutoUpdate bool `json:"auto_update" db:"auto_update"`
	// SelfUpdate is reported by the agent when it can replace its own binary (Linux
	// package or manual install; not containers, not Windows)
	SelfUpdate bool `json:"self_update" db:"self_update"`
	// UpdateRequestedAt is set by "Update now" in the web UI; cleared when the agent
	// reports the server's version or an update error
	UpdateRequestedAt *time.Time `json:"update_requested_at,omitempty" db:"update_requested_at"`
	// UpdateError is the agent's last self-update failure (empty: none)
	UpdateError string `json:"update_error,omitempty" db:"update_error"`
	// PVEHost is reported by the agent when it runs on a Proxmox VE node
	PVEHost bool `json:"pve_host" db:"pve_host"`
	// DockerHost is reported by the agent when a Docker daemon answers on its host
	DockerHost bool `json:"docker_host" db:"docker_host"`
	// DBTools is reported by a filesystem agent that found database client tools
	// (pg_dump, mysqldump/mariadb-dump, mongodump) and can therefore run database jobs
	DBTools bool `json:"db_tools" db:"db_tools"`
	// DBEngines are the database engines the agent reported (see CanRunDBEngine)
	DBEngines []string `json:"db_engines" db:"db_engines"`
	// Inventory is the compact summary the agent attaches to a heartbeat every few
	// minutes (inventory.Summary); InventoryDetail the on-demand full inventory
	Inventory         json.RawMessage `json:"inventory,omitempty" db:"inventory"`
	InventoryAt       *time.Time      `json:"inventory_at,omitempty" db:"inventory_at"`
	InventoryDetail   json.RawMessage `json:"inventory_detail,omitempty" db:"inventory_detail"`
	InventoryDetailAt *time.Time      `json:"inventory_detail_at,omitempty" db:"inventory_detail_at"`
	Status            AgentStatus     `json:"status" db:"status"`
	LastSeenAt        *time.Time      `json:"last_seen_at" db:"last_seen_at"`
	CreatedAt         time.Time       `json:"created_at" db:"created_at"`
	UpdatedAt         time.Time       `json:"updated_at" db:"updated_at"`
}

Agent represents a registered backup agent host

func (*Agent) CanRunDBEngine added in v0.11.3

func (a *Agent) CanRunDBEngine(engine string) bool

CanRunDBEngine reports whether this agent can back up the engine. Filesystem agents go by the engines they report; one that only sent the older db_tools flag predates the mssql engine and is assumed to have the client tools of the other three. Kubernetes agents dump from a pod and the retired database agent predates mssql, so both handle everything except SQL Server.

func (*Agent) CanRunJob added in v0.10.1

func (a *Agent) CanRunJob(jobType string) bool

CanRunJob reports whether this agent may run a job of jobType, including the capability flags a filesystem agent reports (Proxmox VE node, Docker daemon, database client tools)

type AgentAuthState

type AgentAuthState struct {
	ID           uuid.UUID
	TaskQueue    string
	TokenVersion int
	Revoked      bool
}

AgentAuthState is the subset of agent state needed to validate an agent bearer token

type AgentCapabilities added in v0.10.1

type AgentCapabilities struct {
	PVEHost    bool
	DockerHost bool
	DBTools    bool
	DBEngines  []string
	// Version is the running binary's version (empty keeps the stored one)
	Version string
	// SelfUpdate / UpdateError: see Agent
	SelfUpdate  bool
	UpdateError string
	// Inventory is the summary attached to this heartbeat (nil: none this time)
	Inventory json.RawMessage
}

AgentCapabilities are the host facts a filesystem agent reports with every heartbeat

type AgentStatus

type AgentStatus string

AgentStatus represents the lifecycle state of an agent

const (
	AgentStatusOnline  AgentStatus = "online"
	AgentStatusOffline AgentStatus = "offline"
	AgentStatusBusy    AgentStatus = "busy"
	AgentStatusError   AgentStatus = "error"
)

type BackupJob

type BackupJob struct {
	ID           uuid.UUID `json:"id" db:"id"`
	Name         string    `json:"name" db:"name"`
	AgentID      uuid.UUID `json:"agent_id" db:"agent_id"`
	TargetID     uuid.UUID `json:"target_id" db:"target_id"`
	ScheduleCron string    `json:"schedule_cron" db:"schedule_cron"`
	BackupPaths  []string  `json:"backup_paths" db:"backup_paths"`
	ExcludePaths []string  `json:"exclude_paths" db:"exclude_paths"`
	Enabled      bool      `json:"enabled" db:"enabled"`
	// DirectPBS makes the agent talk to PBS itself (credentials handed out per run)
	// instead of through the server-side tunnel. Server-side setting only.
	DirectPBS bool `json:"direct_pbs" db:"direct_pbs"`
	// JobType is filesystem (BackupPaths) or database (DBConfig)
	JobType string `json:"job_type" db:"job_type"`
	// DBConfig is the database job specification; the password is stored but never
	// returned by the API (see Sanitize)
	DBConfig *dbbackup.Spec `json:"db_config,omitempty" db:"db_config"`
	// K8sConfig is the kubernetes job specification
	K8sConfig *k8sbackup.Spec `json:"k8s_config,omitempty" db:"k8s_config"`
	// PVEConfig is the Proxmox VE host job specification
	PVEConfig *pvebackup.Spec `json:"pve_config,omitempty" db:"pve_config"`
	// DockerConfig is the Docker host job specification
	DockerConfig *dockerbackup.Spec `json:"docker_config,omitempty" db:"docker_config"`
	// M365Config is the Microsoft 365 job specification (its TenantID is also the
	// m365_tenant_id column, so a tenant cannot be deleted while jobs use it)
	M365Config *m365.Spec `json:"m365_config,omitempty" db:"m365_config"`
	CreatedAt  time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt  time.Time  `json:"updated_at" db:"updated_at"`

	// Joined fields for display
	AgentName  string `json:"agent_name,omitempty"`
	TargetName string `json:"target_name,omitempty"`
	// LastRun is the job's newest run (filled by the Jobs page; nil = never ran)
	LastRun *JobLastRun `json:"last_run,omitempty" db:"-"`
}

BackupJob defines what, when, and where an agent backs up

func (*BackupJob) IsDatabase added in v0.6.0

func (j *BackupJob) IsDatabase() bool

IsDatabase reports whether the job is a database backup

func (*BackupJob) IsDocker added in v0.9.11

func (j *BackupJob) IsDocker() bool

IsDocker reports whether the job is a Docker host backup

func (*BackupJob) IsKubernetes added in v0.7.2

func (j *BackupJob) IsKubernetes() bool

IsKubernetes reports whether the job is a kubernetes backup

func (*BackupJob) IsM365 added in v0.14.0

func (j *BackupJob) IsM365() bool

IsM365 reports whether the job is a Microsoft 365 backup

func (*BackupJob) IsPVE added in v0.9.5

func (j *BackupJob) IsPVE() bool

IsPVE reports whether the job is a Proxmox VE host backup

func (*BackupJob) NextRunString added in v0.6.2

func (j *BackupJob) NextRunString() string

NextRunString reports when the schedule fires next, in the schedule timezone with its abbreviation; empty when the job is manual, disabled, or the expression does not parse.

func (*BackupJob) Sanitize added in v0.6.0

func (j *BackupJob) Sanitize() *BackupJob

Sanitize redacts the stored database password (HasPassword tells whether one exists)

func (*BackupJob) Summary added in v0.6.0

func (j *BackupJob) Summary() string

Summary describes what the job backs up (paths, database target or cluster scope)

type BackupRun

type BackupRun struct {
	ID            uuid.UUID  `json:"id" db:"id"`
	JobID         uuid.UUID  `json:"job_id" db:"job_id"`
	AgentID       uuid.UUID  `json:"agent_id" db:"agent_id"`
	TargetID      uuid.UUID  `json:"target_id" db:"target_id"`
	WorkflowID    string     `json:"workflow_id" db:"workflow_id"`
	RunID         string     `json:"run_id" db:"run_id"`
	Status        RunStatus  `json:"status" db:"status"`
	StartTime     *time.Time `json:"start_time" db:"start_time"`
	EndTime       *time.Time `json:"end_time" db:"end_time"`
	BytesScanned  int64      `json:"bytes_scanned" db:"bytes_scanned"`
	BytesUploaded int64      `json:"bytes_uploaded" db:"bytes_uploaded"`
	DedupRatio    float64    `json:"dedup_ratio" db:"dedup_ratio"`
	ChunkCount    int        `json:"chunk_count" db:"chunk_count"`
	ErrorMessage  string     `json:"error_message" db:"error_message"`
	PBSSnapshotID string     `json:"pbs_snapshot_id" db:"pbs_snapshot_id"`
	// LogTail is the agent's recent log output captured when the run failed
	LogTail string `json:"log_tail,omitempty" db:"log_tail"`
	// KeyFingerprint names the encryption key the snapshot was written with ("" = plaintext)
	KeyFingerprint string `json:"key_fingerprint,omitempty" db:"key_fingerprint"`
	// Details is a type-specific JSON blob (archives / databases / PVCs) for the run
	// detail page; carries a top-level "type" discriminator. Empty for older runs.
	Details json.RawMessage `json:"details,omitempty" db:"details"`
	// Progress is the live state of a running backup (phase + per-item statuses),
	// updated mid-run and polled by the detail page.
	Progress  json.RawMessage `json:"progress,omitempty" db:"progress"`
	CreatedAt time.Time       `json:"created_at" db:"created_at"`

	// Joined fields
	JobName   string `json:"job_name,omitempty"`
	AgentName string `json:"agent_name,omitempty"`
}

BackupRun records a single execution of a backup job

func (*BackupRun) DurationString added in v0.6.0

func (r *BackupRun) DurationString() string

DurationString renders how long the run took (or has been running); "-" before start

type BackupTarget

type BackupTarget struct {
	ID         uuid.UUID `json:"id" db:"id"`
	Name       string    `json:"name" db:"name"`
	TargetType string    `json:"target_type" db:"target_type"` // "pbs"
	Endpoint   string    `json:"endpoint" db:"endpoint"`
	Datastore  string    `json:"datastore" db:"datastore"`
	Namespace  string    `json:"namespace" db:"namespace"`
	// AuthToken is the PBS API token in clear in memory; the repository seals it with
	// the server master key on write and opens it on read (column auth_token_encrypted)
	AuthToken   string    `json:"-" db:"auth_token_encrypted"`
	Fingerprint string    `json:"fingerprint" db:"fingerprint"`
	TLSVerify   bool      `json:"tls_verify" db:"tls_verify"`
	PxarFormat  string    `json:"pxar_format" db:"pxar_format"`
	CreatedAt   time.Time `json:"created_at" db:"created_at"`
	UpdatedAt   time.Time `json:"updated_at" db:"updated_at"`

	// Client-side encryption: EncryptionNone or EncryptionEncrypt; the active key is
	// EncryptionKeyID (a target_keys row), MasterPublicKey an optional RSA public key
	// (PEM) every snapshot wraps the encryption key with, for recovery
	EncryptionMode  string     `json:"encryption_mode" db:"encryption_mode"`
	EncryptionKeyID *uuid.UUID `json:"encryption_key_id,omitempty" db:"encryption_key_id"`
	MasterPublicKey string     `json:"master_public_key,omitempty" db:"master_public_key"`
	// KeyFingerprint / KeyCreatedAt describe the active key (joined on read)
	KeyFingerprint string     `json:"key_fingerprint,omitempty" db:"-"`
	KeyCreatedAt   *time.Time `json:"key_created_at,omitempty" db:"-"`

	// HasToken reports whether an API token is stored (the token itself is never returned)
	HasToken bool `json:"has_token" db:"-"`
}

BackupTarget represents a remote backup repository such as Proxmox Backup Server

func (*BackupTarget) Encrypted added in v0.13.0

func (t *BackupTarget) Encrypted() bool

Encrypted reports whether runs to this target encrypt client-side

func (*BackupTarget) Sanitize added in v0.6.0

func (t *BackupTarget) Sanitize() *BackupTarget

Sanitize fills derived, API-safe fields

type DB

type DB struct {
	Pool *pgxpool.Pool
	// Sealer protects stored secrets (target API tokens, encryption keys) at rest.
	// nil (tests) stores them in clear.
	Sealer *secrets.Sealer
}

DB wraps the pgx connection pool and exposes repository operations

func New

func New(ctx context.Context, cfg config.DatabaseConfig) (*DB, error)

New creates a new database connection pool and applies migrations if enabled

func (*DB) BindTokenAgent added in v0.11.0

func (d *DB) BindTokenAgent(ctx context.Context, tokenID, agentID uuid.UUID) error

BindTokenAgent records the agent that enrolled with the token

func (*DB) BumpAgentTokenVersion

func (d *DB) BumpAgentTokenVersion(ctx context.Context, id uuid.UUID) (int, error)

BumpAgentTokenVersion invalidates every previously issued token for the agent and returns the new version that must be embedded in freshly issued tokens.

func (*DB) ClearAgentUpdateRequest added in v0.14.3

func (d *DB) ClearAgentUpdateRequest(ctx context.Context, id uuid.UUID) error

ClearAgentUpdateRequest drops a pending request (the agent reached the version)

func (*DB) CloneTarget added in v0.11.0

func (d *DB) CloneTarget(ctx context.Context, sourceID uuid.UUID, name, namespace, pxarFormat string) (*BackupTarget, error)

CloneTarget creates a new target from an existing one: same PBS endpoint, datastore, API token (the sealed column is copied as is), fingerprint, TLS setting, master public key and (unless overridden) pxar format, with a new name and namespace. The encryption key is not copied: the clone starts unencrypted and gets its own key when encryption is enabled on it (import the exported file to share one).

func (*DB) Close

func (d *DB) Close()

Close closes the underlying pool

func (*DB) CountRunsWithKey added in v0.13.0

func (d *DB) CountRunsWithKey(ctx context.Context, fingerprint string) (int, error)

CountRunsWithKey counts runs whose snapshot was written with the key

func (*DB) CreateAPIKey

func (d *DB) CreateAPIKey(ctx context.Context, key *APIKey) error

func (*DB) CreateAgent

func (d *DB) CreateAgent(ctx context.Context, agent *Agent) error

func (*DB) CreateEnrollmentToken

func (d *DB) CreateEnrollmentToken(ctx context.Context, token *EnrollmentToken) error

func (*DB) CreateJob

func (d *DB) CreateJob(ctx context.Context, job *BackupJob) error

func (*DB) CreateRun

func (d *DB) CreateRun(ctx context.Context, run *BackupRun) error

func (*DB) CreateTarget

func (d *DB) CreateTarget(ctx context.Context, target *BackupTarget) error

func (*DB) CreateTargetKey added in v0.13.0

func (d *DB) CreateTargetKey(ctx context.Context, k *TargetKey) error

CreateTargetKey stores a key (sealed) for a target

func (*DB) CreateTenant added in v0.14.0

func (d *DB) CreateTenant(ctx context.Context, t *m365.Tenant) error

CreateTenant stores a tenant; the secret and private key are sealed

func (*DB) DeleteAgent

func (d *DB) DeleteAgent(ctx context.Context, id uuid.UUID) error

func (*DB) DeleteEnrollmentToken added in v0.6.0

func (d *DB) DeleteEnrollmentToken(ctx context.Context, id uuid.UUID) error

DeleteEnrollmentToken invalidates a token immediately (enrollment looks tokens up by hash, so a deleted row can never be consumed again)

func (*DB) DeleteJob

func (d *DB) DeleteJob(ctx context.Context, id uuid.UUID) error

func (*DB) DeleteTarget

func (d *DB) DeleteTarget(ctx context.Context, id uuid.UUID) error

func (*DB) DeleteTenant added in v0.14.0

func (d *DB) DeleteTenant(ctx context.Context, id uuid.UUID) error

DeleteTenant removes a tenant that no job references (ErrTenantInUse otherwise)

func (*DB) GetAPIKeyByHash

func (d *DB) GetAPIKeyByHash(ctx context.Context, hash string) (*APIKey, error)

func (*DB) GetAgentAuthState

func (d *DB) GetAgentAuthState(ctx context.Context, id uuid.UUID) (*AgentAuthState, error)

GetAgentAuthState returns the token version and revocation state of an agent. Returns ErrNotFound if the agent does not exist (e.g. it was deleted).

func (*DB) GetAgentByID

func (d *DB) GetAgentByID(ctx context.Context, id uuid.UUID) (*Agent, error)

func (*DB) GetEnrollmentToken added in v0.11.0

func (d *DB) GetEnrollmentToken(ctx context.Context, id uuid.UUID) (*EnrollmentToken, error)

GetEnrollmentToken loads one token (with the hostname of the agent that used it)

func (*DB) GetJobByID

func (d *DB) GetJobByID(ctx context.Context, id uuid.UUID) (*BackupJob, error)

func (*DB) GetRunByID added in v0.3.1

func (d *DB) GetRunByID(ctx context.Context, id uuid.UUID) (*BackupRun, error)

GetRunByID returns a single run

func (*DB) GetRunByWorkflowID added in v0.3.1

func (d *DB) GetRunByWorkflowID(ctx context.Context, workflowID string) (*BackupRun, error)

GetRunByWorkflowID returns the run record created for a Temporal workflow execution

func (*DB) GetTargetByID

func (d *DB) GetTargetByID(ctx context.Context, id uuid.UUID) (*BackupTarget, error)

func (*DB) GetTargetKey added in v0.13.0

func (d *DB) GetTargetKey(ctx context.Context, id uuid.UUID) (*TargetKey, error)

GetTargetKey loads one key with its material

func (*DB) GetTenantByID added in v0.14.0

func (d *DB) GetTenantByID(ctx context.Context, id uuid.UUID) (*m365.Tenant, error)

GetTenantByID returns the tenant with its credentials opened

func (*DB) LatestRunByJob added in v0.11.2

func (d *DB) LatestRunByJob(ctx context.Context) (map[uuid.UUID]*JobLastRun, error)

LatestRunByJob returns the newest run of every job that has one

func (*DB) ListAPIKeys

func (d *DB) ListAPIKeys(ctx context.Context) ([]*APIKey, error)

func (*DB) ListAgents

func (d *DB) ListAgents(ctx context.Context) ([]*Agent, error)

func (*DB) ListEnrollmentTokens

func (d *DB) ListEnrollmentTokens(ctx context.Context) ([]*EnrollmentToken, error)

func (*DB) ListJobs

func (d *DB) ListJobs(ctx context.Context) ([]*BackupJob, error)

func (*DB) ListRuns

func (d *DB) ListRuns(ctx context.Context, limit int) ([]*BackupRun, error)

func (*DB) ListRunsByAgent added in v0.12.0

func (d *DB) ListRunsByAgent(ctx context.Context, agentID uuid.UUID, limit int) ([]*BackupRun, error)

ListRunsByAgent is ListRuns restricted to one agent (the agent status page)

func (*DB) ListTargetKeys added in v0.13.0

func (d *DB) ListTargetKeys(ctx context.Context, targetID uuid.UUID) ([]*TargetKey, error)

ListTargetKeys lists a target's keys (newest first) without their material

func (*DB) ListTargets

func (d *DB) ListTargets(ctx context.Context) ([]*BackupTarget, error)

func (*DB) ListTenants added in v0.14.0

func (d *DB) ListTenants(ctx context.Context) ([]*m365.Tenant, error)

ListTenants returns every tenant ordered by name

func (*DB) MarkRunStarted added in v0.3.1

func (d *DB) MarkRunStarted(ctx context.Context, id uuid.UUID, temporalRunID string, startedAt time.Time) error

MarkRunStarted moves a pending run to running once the workflow has prepared the session

func (*DB) MergeAgents added in v0.10.1

func (d *DB) MergeAgents(ctx context.Context, from, into uuid.UUID) (int64, int64, error)

MergeAgents moves every job and run of the agent from onto the agent into and deletes from, in one transaction. Deleting an agent cascades to its jobs and runs, so the move must come first. It returns the number of jobs and runs moved.

func (*DB) Migrate

func (d *DB) Migrate(ctx context.Context) error

Migrate applies all pending schema migrations to PostgreSQL. Each migration runs in its own transaction and is recorded in schema_migrations so it is applied exactly once.

func (*DB) RequestAgentUpdate added in v0.14.3

func (d *DB) RequestAgentUpdate(ctx context.Context, id uuid.UUID) error

RequestAgentUpdate asks the agent to update on its next heartbeat (the web UI's "Update now"); a previous error is cleared so the retry starts clean

func (*DB) RetireTargetKey added in v0.13.0

func (d *DB) RetireTargetKey(ctx context.Context, id uuid.UUID) error

RetireTargetKey marks a key as no longer used for new snapshots

func (*DB) RevokeAPIKey

func (d *DB) RevokeAPIKey(ctx context.Context, id uuid.UUID) error

func (*DB) RevokeAgent

func (d *DB) RevokeAgent(ctx context.Context, id uuid.UUID) error

RevokeAgent marks the agent as revoked; its tokens stop validating immediately

func (*DB) SealLegacySecrets added in v0.13.0

func (d *DB) SealLegacySecrets(ctx context.Context) (int, error)

SealLegacySecrets rewrites secrets stored in clear before the master key existed. It returns how many rows were sealed. Safe to run at every start.

func (*DB) SetAgentAutoUpdate added in v0.14.3

func (d *DB) SetAgentAutoUpdate(ctx context.Context, id uuid.UUID, enabled bool) error

SetAgentAutoUpdate flips the per-agent auto-update opt-in

func (*DB) SetAgentDebugLogging added in v0.6.2

func (d *DB) SetAgentDebugLogging(ctx context.Context, id uuid.UUID, enabled bool) error

SetAgentDebugLogging flips the per-agent debug toggle (delivered on the next heartbeat)

func (*DB) SetAgentInventoryDetail added in v0.12.0

func (d *DB) SetAgentInventoryDetail(ctx context.Context, id uuid.UUID, detail []byte) error

SetAgentInventoryDetail stores the on-demand full inventory

func (*DB) SetRunItems added in v0.9.0

func (d *DB) SetRunItems(ctx context.Context, runID uuid.UUID, updatedAt string, items map[string][]byte) error

SetRunItems merges per-item statuses into an active run's progress. Each item is written at progress.items.<key> so concurrent per-item updates never clobber.

func (*DB) SetRunPhase added in v0.9.0

func (d *DB) SetRunPhase(ctx context.Context, runID uuid.UUID, phase, updatedAt string) error

SetRunPhase records the current phase of an active run (jsonb_set: no read-modify-write)

func (*DB) SetRunStatus added in v0.3.1

func (d *DB) SetRunStatus(ctx context.Context, id uuid.UUID, status RunStatus, message string, endTime *time.Time) error

SetRunStatus updates the status (and optionally end time / message) of a run

func (*DB) SetTargetEncryption added in v0.13.0

func (d *DB) SetTargetEncryption(ctx context.Context, targetID uuid.UUID, mode string, keyID *uuid.UUID) error

SetTargetEncryption switches a target's mode and active key in one statement; keyID nil clears the active key (mode none keeps the keys for old snapshots)

func (*DB) TouchAPIKey

func (d *DB) TouchAPIKey(ctx context.Context, id uuid.UUID) error

TouchAPIKey records the last use of a key (best-effort, called on successful auth)

func (*DB) UpdateAgentHeartbeat

func (d *DB) UpdateAgentHeartbeat(ctx context.Context, id uuid.UUID, status AgentStatus, caps AgentCapabilities) (HeartbeatState, error)

UpdateAgentHeartbeat records the heartbeat (status, capabilities, version) and returns what the response needs. An update error from the agent consumes a pending "update now" request so a failed manual update is not retried every heartbeat.

func (*DB) UpdateJob added in v0.6.0

func (d *DB) UpdateJob(ctx context.Context, job *BackupJob) error

UpdateJob replaces the editable fields of a job

func (*DB) UpdateRun

func (d *DB) UpdateRun(ctx context.Context, run *BackupRun) error

func (*DB) UpdateTarget added in v0.9.0

func (d *DB) UpdateTarget(ctx context.Context, target *BackupTarget) error

UpdateTarget replaces a target's editable fields (name, endpoint, datastore, namespace, token, fingerprint, TLS, format, master public key); the encryption mode and key change only through SetTargetEncryption. The caller supplies the final values, including AuthToken (kept unchanged by loading the existing row first when the operator leaves the token field blank).

func (*DB) UpdateTenant added in v0.14.0

func (d *DB) UpdateTenant(ctx context.Context, t *m365.Tenant) error

UpdateTenant replaces every editable field (the caller keeps the stored credential when the request carries none)

func (*DB) UpsertAgent

func (d *DB) UpsertAgent(ctx context.Context, agent *Agent) error

func (*DB) ValidateAndConsumeToken

func (d *DB) ValidateAndConsumeToken(ctx context.Context, tokenHash string) (*EnrollmentToken, error)

type EnrollmentToken

type EnrollmentToken struct {
	ID        uuid.UUID `json:"id" db:"id"`
	TokenHash string    `json:"-" db:"token_hash"`
	Name      string    `json:"name" db:"name"`
	MaxUses   int       `json:"max_uses" db:"max_uses"`
	UsesCount int       `json:"uses_count" db:"uses_count"`
	ExpiresAt time.Time `json:"expires_at" db:"expires_at"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
	// AgentID is the agent that last enrolled with this token (onboarding waits for it)
	AgentID *uuid.UUID `json:"agent_id,omitempty" db:"agent_id"`
	// AgentHostname is joined for display; empty when no agent used the token
	AgentHostname string `json:"agent_hostname,omitempty" db:"-"`
}

EnrollmentToken represents a one-time or multi-use token for agent onboarding

func (*EnrollmentToken) Status added in v0.6.0

func (t *EnrollmentToken) Status() string

Status describes whether the token can still be used

type HeartbeatState added in v0.14.3

type HeartbeatState struct {
	DebugLogging    bool
	AutoUpdate      bool
	UpdateRequested bool
	OS, Arch        string
}

HeartbeatState is what the heartbeat response needs from the agent row

type JobLastRun added in v0.11.2

type JobLastRun struct {
	RunID  uuid.UUID `json:"run_id"`
	Status RunStatus `json:"status"`
	At     time.Time `json:"at"`
}

JobLastRun is the newest run of a job, for list views

type Migration

type Migration struct {
	Version int
	Name    string
	SQL     string
}

Migration is a single embedded SQL migration file

func LoadMigrations

func LoadMigrations() ([]Migration, error)

LoadMigrations returns the embedded migrations ordered by version. Files are named NNN_description.sql; the numeric prefix is the version.

type RunStatus

type RunStatus string

RunStatus represents the state of a backup run

const (
	RunStatusPending   RunStatus = "pending"
	RunStatusRunning   RunStatus = "running"
	RunStatusCompleted RunStatus = "completed"
	RunStatusFailed    RunStatus = "failed"
	// RunStatusCancelling: cancellation requested, waiting for the agent to stop
	RunStatusCancelling RunStatus = "cancelling"
	RunStatusCancelled  RunStatus = "cancelled"
)

func (RunStatus) IsActive added in v0.3.1

func (s RunStatus) IsActive() bool

IsActive reports whether a run can still be cancelled

type TargetKey added in v0.13.0

type TargetKey struct {
	ID          uuid.UUID  `json:"id"`
	TargetID    uuid.UUID  `json:"target_id"`
	Key         [32]byte   `json:"-"`
	Fingerprint string     `json:"fingerprint"`
	CreatedAt   time.Time  `json:"created_at"`
	RetiredAt   *time.Time `json:"retired_at,omitempty"`
	CreatedBy   string     `json:"created_by,omitempty"`
}

TargetKey is one encryption key of a target. Key is in clear in memory only; the repository seals it with the server master key (column key_sealed). A retired key is kept because the snapshots written with it still need it.

Jump to

Keyboard shortcuts

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