Cerbero.Snapshot (cerbero v0.1.0)

Copy Markdown View Source

The snapshot artifact: decode, verify, canonically re-encode.

The checksum detects corruption and hand-edits — anyone who can commit can regenerate it; it is not tamper-proofing. Tamper-proofing is the optional Ed25519 signature (Cerbero.Snapshot.Signature): when .cerbero.exs pins snapshot_verify_keys, a snapshot must carry a valid signature from one of those keys to load.

Summary

Functions

Refuses engine versions below the supported floors.

Stamp-and-write for callers holding a raw (or deliberately mutated) map: always re-stamps, so the file's checksum matches its content. Callers that already stamped — and possibly signed over that checksum — use write_stamped!/2 to skip the redundant re-encode.

Encode an already-stamped (and possibly signed) map to disk verbatim — no re-stamp. stamp/1 is one full canonical encode (for the checksum); write!/2 on a stamped map would repeat it just to recompute the same checksum. Refuses an unstamped map loudly rather than writing a file load/2 would reject as missing its checksum.

Types

t()

@type t() :: %Cerbero.Snapshot{
  applied_migrations: term(),
  cerbero_version: term(),
  collected_at: term(),
  database: term(),
  engine: term(),
  format_version: term(),
  precision: term(),
  standby: term(),
  stats_provenance: term(),
  stats_reset: term(),
  tables: term()
}

Functions

check_engine_floor(engine, version_num)

@spec check_engine_floor(:postgres | :cockroachdb, integer()) ::
  :ok | {:error, {:unsupported_engine, String.t()}}

Refuses engine versions below the supported floors.

compute_checksum(map)

@spec compute_checksum(map()) :: String.t()

decode(raw)

@spec decode(map()) ::
  {:ok,
   %Cerbero.Snapshot{
     applied_migrations: term(),
     cerbero_version: term(),
     collected_at: term(),
     database: term(),
     engine: term(),
     format_version: term(),
     precision: term(),
     standby: term(),
     stats_provenance: term(),
     stats_reset: term(),
     tables: term()
   }}
  | {:error, term()}

format_version()

load(path, opts \\ [])

@spec load(
  Path.t(),
  keyword()
) ::
  {:ok,
   %Cerbero.Snapshot{
     applied_migrations: term(),
     cerbero_version: term(),
     collected_at: term(),
     database: term(),
     engine: term(),
     format_version: term(),
     precision: term(),
     standby: term(),
     stats_provenance: term(),
     stats_reset: term(),
     tables: term()
   }}
  | {:error, term()}

stamp(map)

@spec stamp(map()) :: map()

write!(map, path)

@spec write!(map(), Path.t()) :: :ok

Stamp-and-write for callers holding a raw (or deliberately mutated) map: always re-stamps, so the file's checksum matches its content. Callers that already stamped — and possibly signed over that checksum — use write_stamped!/2 to skip the redundant re-encode.

write_stamped!(map, path)

@spec write_stamped!(map(), Path.t()) :: :ok

Encode an already-stamped (and possibly signed) map to disk verbatim — no re-stamp. stamp/1 is one full canonical encode (for the checksum); write!/2 on a stamped map would repeat it just to recompute the same checksum. Refuses an unstamped map loudly rather than writing a file load/2 would reject as missing its checksum.