kubectl plugin (kubectl kopiur)¶
Kopiur ships a kubectl plugin that wraps the day-to-day operations, so you do not have to hand-write CR YAML for routine tasks. It suspends and resumes resources, inspects snapshots, triggers backups and restores, runs maintenance, browses snapshot contents and reads files out of them, and migrates from VolSync.
To see these commands in the context of a full install-to-restore journey, follow the Complete walkthrough.
The plugin is a single static binary, shipped as kopiur. kubectl discovers plugins by binary name: any executable called kubectl-kopiur on your PATH makes kubectl kopiur … work. krew creates that link for you, and Homebrew installs the standalone kopiur command instead. Having both installed never causes a collision.
The plugin talks to the cluster with the same configuration kubectl uses, so $KUBECONFIG, ~/.kube/config, or in-cluster credentials. It needs nothing besides API-server access.
Alpha, like the operator
The plugin tracks the v1alpha1 CRDs and is versioned with the operator. A plugin build talking to a much older or newer operator may not know fields the other side uses, so keep them on the same release.
The command map¶
| Command | What it does | Page |
|---|---|---|
snapshot now |
Run a SnapshotPolicy immediately (a manual Snapshot CR) |
Backups, restores & logs |
restore |
The Restore CRD's source × target matrix as one command line |
Backups, restores & logs |
logs |
Stream a Snapshot/Restore mover Job's logs | Backups, restores & logs |
snapshots list |
A richer kubectl get snapshots (origin, kopia id, size, filters) |
Inspecting & browsing |
ls / cat / download / browse |
Read snapshot contents without restoring | Inspecting & browsing |
session end |
End a warm browse session early | Inspecting & browsing |
status |
One-screen health overview | Operations |
doctor |
Diagnose an installation, exit 1 on failure | Operations |
maintenance run |
Trigger an out-of-band maintenance run | Operations |
suspend / resume |
Pause/unpause reconciliation declaratively | Operations |
migrate volsync |
Translate VolSync restic objects into kopiur manifests | Migrating from VolSync |
Install¶
Install with krew. The kopiur repository doubles as its own custom index, which is the plugins/ directory at the repo root. The plugin is not in the official krew-index yet; that submission waits until kopiur leaves heavy development.
$ kubectl krew index add kopiur https://github.com/home-operations/kopiur.git
$ kubectl krew install kopiur/kopiur
$ kubectl kopiur --version
kubectl krew upgrade picks up new releases after a kubectl krew update, which pulls the index.
Or install with Homebrew. The release workflow publishes a cask to home-operations/homebrew-tap from the same release assets, covering macOS and Linux on amd64 and arm64. Brew installs the standalone kopiur command rather than the kubectl-kopiur shim, so it coexists with a krew install of the same plugin:
brew upgrade picks up new releases.
Without krew or Homebrew, use the release assets. Every GitHub release attaches per-platform archives named kubectl-kopiur_<version>_<os>_<arch>.tar.gz, for linux and darwin on amd64 and arm64, and the Linux binaries are fully static musl builds. Each archive ships with a .sha256 checksum, an SBOM, and a keyless Cosign signature.
kubectl krew install --manifest-url https://raw.githubusercontent.com/home-operations/kopiur/main/plugins/kopiur.yaml also works, using the in-repo index copy, which always points at the latest release. Or put the archive's kopiur binary on your PATH, named kubectl-kopiur if you want kubectl discovery, or left as-is for the standalone command.
From source, with the repo checked out and mise installed:
Try it end-to-end¶
Stand up a small playground that the rest of the CLI pages build on, then prove the plugin can see it with doctor.
The playground is one apply-ready bundle, deploy/examples/tryit/cli-playground.yaml. It contains a media Namespace, a PVC seeded with a config/app.yaml file and a multi-MB blob, the backend Secret, an S3 Repository called nas, and a SnapshotPolicy plus SnapshotSchedule called nightly. It deliberately has no Snapshot, because the other CLI arcs create those.
This is the shared starting point. Every CLI page's "Try it end-to-end" assumes you have applied this bundle and that the repository is Ready.
1. Apply the playground. Fill in the AWS_* and KOPIA_PASSWORD REPLACE_ME values first, then apply and wait for the repository:
$ kubectl apply -f deploy/examples/tryit/cli-playground.yaml
$ kubectl -n media wait --for=condition=Ready repository/nas --timeout=2m
$ kubectl -n media wait --for=condition=complete job/seed-app-data --timeout=2m
2. Install the plugin with krew:
$ kubectl krew index add kopiur https://github.com/home-operations/kopiur.git
$ kubectl krew install kopiur/kopiur
$ kubectl kopiur --version
3. Prove the install with doctor (deep). It exits 0 when all nine checks pass:
$ kubectl kopiur doctor -n media
ok CRDs installed
ok controller running
ok webhook running
ok webhook admission (live dry-run probe)
ok repositories ready
ok credential secrets present
ok no blocked or stuck work
ok no recent failed snapshots/restores
ok recent warning events
9 check(s): 0 failed, 0 warning(s)
$ echo $?
0
A non-zero exit, plus a FAIL line with why: and fix:, means something needs attention. See doctor for the full check list and for how a restricted kubeconfig degrades to warnings.
From here, follow any CLI page's "Try it end-to-end" against this same media playground: take a backup and restore it, browse a snapshot's files, run day-2 operations, or migrate from VolSync.
Global flags¶
Every subcommand accepts the same connection and output flags kubectl uses:
| Flag | Meaning |
|---|---|
--kubeconfig PATH |
Use this kubeconfig instead of $KUBECONFIG / ~/.kube/config. |
--context NAME |
Use this kubeconfig context instead of the current one. |
-n, --namespace NS |
Operate in this namespace (default: the context's namespace). |
-A, --all-namespaces |
List across all namespaces (list commands). |
-o, --output FORMAT |
table (default), wide, yaml, json, or name. |
-v / -vv |
Debug / trace diagnostics on stderr (KOPIUR_LOG accepts a full filter). |
-o yaml and -o json always emit the exact Kubernetes objects, and a v1/List for list commands. The output is therefore ready to pipe into kubectl apply, jq or yq; the table is just one rendering of the same data.