Skip to content

Backups, restores & logs

Trigger a backup right now, drive the Restore CRD’s full source-by-target matrix from one command line, and follow the mover’s logs, all without writing CR YAML. All global flags apply.

Run a SnapshotPolicy immediately. The plugin creates a manual Snapshot object, which is the same thing a SnapshotSchedule does on a cron slot, labeled origin: manual.

With --wait it follows the run to its terminal phase. On Succeeded it exits 0 and prints a one-line stats summary. On Failed it exits 1 and prints the failure class, a tail of kopia’s stderr, and the log tail on stderr. Unchanged, meaning nothing had changed so kopia created no new snapshot, also exits 0, with a line saying so instead of the stats. It is a successful run, not a failure.

Terminal window
$ kubectl kopiur snapshot now --policy nightly -n media --tag reason=pre-upgrade --wait
snapshot.kopiur.home-operations.com/nightly-manual-20260611030012 created
snapshot nightly-manual-20260611030012 succeeded: kopia id a1b2c3d4e5f6, 5.0 GiB, took 300s
Flag Effect
--policy NAME The SnapshotPolicy (recipe) to run. Checked up front, so a typo fails fast with a fix hint.
--name NAME Name the Snapshot (default <policy>-manual-<timestamp>).
--tag KEY=VALUE kopia snapshot tag; repeatable.
--deletion-policy delete|retain|orphan What happens to the kopia snapshot when the CR is deleted.
--pin Exempt this snapshot from GFS retention until unpinned.
--backoff-limit N / --active-deadline-seconds SECS Mover Job retry budget / wall-clock cap.
--wait Watch until Succeeded (exit 0) or Failed (exit 1).
--logs Stream the mover’s logs while waiting (implies --wait).
--timeout DURATION Give up waiting after e.g. 90s, 30m, 1h (default 30m). Timing out stops the waiting, not the run.

Without --wait the command returns as soon as the object is admitted. -o yaml and -o json then print the created object, and -o name prints just its name.

The Restore CRD’s three sources and three targets as one command line. Exactly one source and exactly one target are required. The plugin enforces that when it parses your flags, and the webhook enforces it again at admission.

Source Meaning
--from-snapshot NAME [--snapshot-namespace NS] An explicit Snapshot CR (scheduled, manual, or discovered).
--from-policy NAME [--policy-namespace NS] [--as-of RFC3339] [--offset N] Resolve via the SnapshotPolicy’s identity. Works with no Snapshot CR present (the GitOps deploy-or-restore pattern).
--identity USER@HOST[:PATH] [--snapshot-id ID] [--as-of] [--offset] A raw kopia identity, for foreign writers or snapshots aged out of the catalog. Requires --repository.
Target Meaning
--to-pvc NAME Write into an existing PVC.
--create-pvc NAME --size 10Gi [--storage-class X] [--access-mode RWO]… The operator creates the PVC. --size is required, because kopiur never guesses a capacity.
--populator Passive mode: the restore is claimed later by a PVC’s dataSourceRef.
Terminal window
$ kubectl kopiur restore --from-policy nightly --create-pvc data-restored --size 10Gi -n media --wait
restore.kopiur.home-operations.com/restore-nightly-20260611120001 created
restore restore-nightly-20260611120001 completed: kopia id a1b2c3d4e5f6, 5.0 GiB / 1000 files into pvc/data-restored

Every spec.options and spec.policy knob has a flag: --enable-file-deletion for an exact-mirror restore, since the default is additive, plus --ignore-permission-errors true|false, --write-files-atomically true|false, --on-missing-snapshot fail|continue and --wait-timeout 5m. --backoff-limit and --active-deadline-seconds configure the mover Job.

--credential-projection copies the repository’s credential Secret into the restore’s namespace. It needs the owning ClusterRepository’s credentialProjection.allowed gate; see Movers → credential projection.

--wait, --logs and --timeout behave exactly as they do in snapshot now: Completed exits 0 with a summary, and Failed exits 1 with the failure block.

Stream the mover Job’s logs for a Snapshot or Restore, without chasing Job and pod names yourself:

Terminal window
$ kubectl kopiur logs snapshot nightly-manual-20260611030012 -n media -f

You name the kind explicitly, as logs snapshot … or logs restore …, because the two kinds may share names. -f/--follow, --tail N and --previous behave like kubectl logs, and for a retried Job the newest pod is selected.

When the Job and its pods are already garbage-collected, the plugin prints the tail the operator recorded in status.logTail, plus the structured failure block, and says that is what it is doing. It never presents rotated logs as complete.

Take a backup and restore it into a fresh PVC, end to end, with two commands.

1. Back up now and wait for it to finish:

Terminal window
$ kubectl kopiur snapshot now --policy nightly -n media --wait
snapshot.kopiur.home-operations.com/nightly-manual-20260611030012 created
snapshot nightly-manual-20260611030012 succeeded: kopia id a1b2c3d4e5f6, 5.0 GiB, took 12s

The succeeded: line, with exit 0, is the proof. It carries the kopia id, the size, and the duration of the run.

2. Restore that snapshot into a brand-new PVC the operator creates for you:

Terminal window
$ kubectl kopiur restore --from-snapshot nightly-manual-20260611030012 \
--create-pvc data-restored --size 10Gi -n media --wait
restore.kopiur.home-operations.com/restore-nightly-manual-20260611030012 created
restore restore-nightly-manual-20260611030012 completed: kopia id a1b2c3d4e5f6, 5.0 GiB / 2 files into pvc/data-restored

The completed: line, with exit 0, reports the bytes and file count written into pvc/data-restored.

3. Confirm the restored PVC is real (deep). It exists and is Bound:

Terminal window
$ kubectl -n media get pvc data-restored
NAME STATUS VOLUME CAPACITY ACCESS MODES AGE
data-restored Bound pvc-9f3a… 10Gi RWO 30s

Mount it in a throwaway pod and diff it against the source if you want the full round-trip proof.