cli.administration.recover package

Submodules

cli.administration.recover.full module

‘full’ recovery: recover every backup-stored type against a target host.

Resolves a source to a local backup-root, then discovers the newest generation of each repo present under it and recovers each type in order (nfs -> volume -> secrets) against the target via the per-type Recoverers. The source is one of:

  • a local backup-root directory (used directly),

  • a remote [user@]host[:/path] (its backup tree is rsync-pulled first),

  • a LUKS device / image (recovered first via the device step, which restores the tree to its restore-root, then discovered under that root).

cli.administration.recover.full.plan(root: Path) → tuple[list[tuple[str, str]], list[str]]

(type, source) for each present repo, in order; volume per-volume.

The volume repo contributes a database step after its file steps: the dumps have to land once the volumes are back and while the consumers are still down, which is where the caller has them.

Returns:

The steps, and the repos whose manifest could not be read. A repo that cannot state its layout is skipped rather than guessed at, but it must not take the others with it: recovering two repos of three beats recovering none because one manifest is corrupt.

cli.administration.recover.full.run(source: str, target: str, *, preview: bool, service_backup: bool) → int

cli.administration.recover.paths module

Standard filesystem layout the recover console restores into.

Derived from the paths SPOT (utils.paths, backed by group_vars/all/05_paths.yml). This uniform layout is what lets a recovery target a host by name alone: every host restores into these same paths.

cli.administration.recover.paths.volume_from_source(source: str) → str

Docker volume name embedded in a snapshot path <generation>/<volume>/files.

cli.administration.recover.recoverers module

Recoverer classes: one per svc-bkp-* recovery type.

Each Recoverer parses and validates its own colon-encoded source and builds the role’s files/python/recover.py invocation. Colon segments are classified by shape: an ABSOLUTE path is the restore destination (replacing a –target flag); for device a RELATIVE segment is the on-device snapshot subpath and an all-digit YYYYMMDDHHMMSS segment is the generation to restore. No colon means the derived standard-layout target and the newest generation. The uniform console command <type> <source> <target> dispatches to one Recoverer via RECOVERERS.

class cli.administration.recover.recoverers.DatabaseRecoverer

Bases: Recoverer

args(source: str, target: str) → list[str]

recover.py positional/type args, parsed and validated from source.

target is the host to restore onto (localhost = local); a remote host makes the recover push over ssh (rsync target / docker host / secret paths gain the remote prefix).

name: str = 'database'
role: str = 'svc-bkp-volume-2-local'
summary: str = "Generation's sql dumps -> their databases (consumers must be down)"
class cli.administration.recover.recoverers.DeviceRecoverer

Bases: Recoverer

args(source: str, target: str) → list[str]

recover.py positional/type args, parsed and validated from source.

target is the host to restore onto (localhost = local); a remote host makes the recover push over ssh (rsync target / docker host / secret paths gain the remote prefix).

extra_flags(*, passphrase_stdin: bool) → list[str]
name: str = 'device'
no_backup_flag: bool = False
role: str = 'svc-bkp-local-2-device'
summary: str = 'Encrypted LUKS device -> local backup root'
class cli.administration.recover.recoverers.NfsRecoverer

Bases: Recoverer

args(source: str, target: str) → list[str]

recover.py positional/type args, parsed and validated from source.

target is the host to restore onto (localhost = local); a remote host makes the recover push over ssh (rsync target / docker host / secret paths gain the remote prefix).

name: str = 'nfs'
role: str = 'svc-bkp-nfs-2-local'
summary: str = 'Snapshot -> live NFS export subtree'
class cli.administration.recover.recoverers.Recoverer

Bases: ABC

One recovery type backed by a role’s files/python/recover.py.

abstractmethod args(source: str, target: str) → list[str]

recover.py positional/type args, parsed and validated from source.

target is the host to restore onto (localhost = local); a remote host makes the recover push over ssh (rsync target / docker host / secret paths gain the remote prefix).

command(source: str, *, service_backup: bool = True, passphrase_stdin: bool = False, target: str = 'localhost') → list[str]
extra_flags(*, passphrase_stdin: bool) → list[str]
name: str
no_backup_flag: bool = True
role: str
script() → str
summary: str
class cli.administration.recover.recoverers.SecretsRecoverer

Bases: Recoverer

args(source: str, target: str) → list[str]

recover.py positional/type args, parsed and validated from source.

target is the host to restore onto (localhost = local); a remote host makes the recover push over ssh (rsync target / docker host / secret paths gain the remote prefix).

name: str = 'secrets'
role: str = 'svc-bkp-secrets-2-local'
summary: str = "Snapshot -> host secret paths (secrets, CA, Let's Encrypt, ACME)"
class cli.administration.recover.recoverers.VolumeRecoverer

Bases: Recoverer

args(source: str, target: str) → list[str]

recover.py positional/type args, parsed and validated from source.

target is the host to restore onto (localhost = local); a remote host makes the recover push over ssh (rsync target / docker host / secret paths gain the remote prefix).

name: str = 'volume'
role: str = 'svc-bkp-volume-2-local'
summary: str = 'Snapshot -> docker volume (name from the source path)'
cli.administration.recover.recoverers.is_remote(source: str) → bool

A source not starting with / is a remote [user@]host:/path (rsync pulls it).

cli.administration.recover.recoverers.remote_target(target: str) → bool

A target other than localhost is a remote [user@]host reached over ssh.

cli.administration.recover.recoverers.split_target(source: str) → tuple[str, str | None]

Split <path>:<absolute-target> -> (path, target).

A remote source ([user@]host:/path) is returned as-is with the default target (its colon is the rsync host separator). Otherwise a colon suffix is a restore target only when absolute; a relative suffix is rejected here (device parses those itself).

cli.administration.recover.remote module

Remote device source: [user@]host:/device[:subpath][:gen][:/root].

A block device (remote path under /dev/) is recovered on the host over ssh (the host must carry the repo checkout), then the restored backup tree is rsync-pulled. An image file is rsync-pulled and recovered locally. Either way the result is a local backup root the caller then recovers from.

cli.administration.recover.remote.commands(source: str, *, service_backup: bool, passphrase_stdin: bool) → tuple[list[list[str]], str]

Steps that produce a local backup root from a remote device, and that root.

cli.administration.recover.remote.run(source: str, *, preview: bool, service_backup: bool, passphrase_stdin: bool) → tuple[int, str | None]

Execute (or preview) the remote-device steps; return (exit code, local root).

cli.administration.recover.remote.split_host(source: str) → tuple[str, str]

[user@]host:/device[:segments] -> (host, /device[:segments]).

Module contents

Uniform recover CLI around the svc-bkp-* recover.py scripts.