pub struct KopiaClient { /* private fields */ }Expand description
A kopia client backed by the real kopia binary via tokio::process.
Construction is pure — building a client never spawns a process. Only the
async methods invoke kopia. The builder defaults the binary to kopia
(resolved via PATH); inject a path for tests or non-standard images:
use std::path::PathBuf;
use kopiur_kopia::KopiaClient;
let client = KopiaClient::builder().build();
assert_eq!(client.binary(), &PathBuf::from("kopia"));
let custom = KopiaClient::builder()
.binary("/usr/local/bin/kopia")
.env("KOPIA_PASSWORD", "s3cr3t")
.build();
assert_eq!(custom.binary(), &PathBuf::from("/usr/local/bin/kopia"));Implementations§
Source§impl KopiaClient
impl KopiaClient
Sourcepub fn builder() -> KopiaClientBuilder
pub fn builder() -> KopiaClientBuilder
Start building a client.
Sourcepub fn common_env(&self) -> &BTreeMap<String, String>
pub fn common_env(&self) -> &BTreeMap<String, String>
The environment applied to every invocation (useful for tests asserting that the cache/log/config dirs were injected).
Sourcepub fn common_args(&self) -> &[String]
pub fn common_args(&self) -> &[String]
The global args appended after the subcommand on every invocation
(useful for tests asserting e.g. --no-auto-maintenance is always
present).
Sourcepub fn default_timeout(&self) -> Option<Duration>
pub fn default_timeout(&self) -> Option<Duration>
The timeout applied to every invocation when set (useful for tests asserting a caller time-bounds its subprocesses).
Sourcepub async fn repository_connect(
&self,
spec: &ConnectSpec,
cache: CacheTuning,
) -> Result<(), KopiaError>
pub async fn repository_connect( &self, spec: &ConnectSpec, cache: CacheTuning, ) -> Result<(), KopiaError>
Connect to an existing repository (kopia repository connect <backend>).
cache sizes this connection’s local kopia cache; pass
CacheTuning::default to leave kopia’s defaults.
Sourcepub async fn repository_connect_readonly(
&self,
spec: &ConnectSpec,
cache: CacheTuning,
) -> Result<(), KopiaError>
pub async fn repository_connect_readonly( &self, spec: &ConnectSpec, cache: CacheTuning, ) -> Result<(), KopiaError>
Connect to an existing repository read-only (kopia repository connect <backend> --readonly). The read-only bit persists in kopia’s
client config, so every subsequent invocation on this connection is
structurally unable to mutate the repository — the connect mode for
browse sessions. Every other mover flow stays on the read-write
Self::repository_connect.
Sourcepub async fn repository_create(
&self,
spec: &ConnectSpec,
cache: CacheTuning,
create_opts: &CreateOptions,
) -> Result<(), KopiaError>
pub async fn repository_create( &self, spec: &ConnectSpec, cache: CacheTuning, create_opts: &CreateOptions, ) -> Result<(), KopiaError>
Create a new repository (kopia repository create <backend>). cache sizes
the creating connection’s local cache; pass CacheTuning::default to leave
kopia’s defaults. create_opts carries the create-time-fixed knobs
(encryption/splitter/hash algorithms, ECC) baked into the repository format.
Sourcepub async fn repository_throttle_set(
&self,
throttle: &ThrottleArgs,
) -> Result<(), KopiaError>
pub async fn repository_throttle_set( &self, throttle: &ThrottleArgs, ) -> Result<(), KopiaError>
Set the repository’s throttling limits (kopia repository throttle set).
Caps upload/download bytes-per-sec and read/list/upload ops-per-sec so a run
doesn’t saturate a link or hammer an object store (ADR-0005 §13(e)). A no-op
(skips the call) when nothing is set.
Sourcepub async fn repository_set_parameters(
&self,
params: &SetParametersArgs,
) -> Result<(), KopiaError>
pub async fn repository_set_parameters( &self, params: &SetParametersArgs, ) -> Result<(), KopiaError>
Rewrite mutable repository parameters on the CONNECTED repository
(kopia repository set-parameters [flags]), issue #258. No-op when nothing is set.
Two properties the caller must respect:
- Never on a read-only connection. kopia hard-errors (
unable to write blobcfg blob: PutBlob() failed for "kopia.blobcfg": storage is read-only), so amode: ReadOnlyrepository must not reach here. - This invalidates every other client’s cached format blob. kopia says so itself
(“you must disconnect and re-connect all other Kopia clients”) and drops the local
kopia.repository/kopia.blobcfgcache. Other clients re-read withinformatBlobCacheDuration(15m) on their own, but this is why the caller applies only on observed drift rather than unconditionally.
Needs no maintenance ownership/lease.
Sourcepub async fn repository_sync_to(
&self,
destination: &ConnectSpec,
opts: &SyncToOptions,
) -> Result<(), KopiaError>
pub async fn repository_sync_to( &self, destination: &ConnectSpec, opts: &SyncToOptions, ) -> Result<(), KopiaError>
Mirror the connected repository’s blobs to a destination backend
(kopia repository sync-to <destination> [flags]), ADR-0005 §13(d) / issue
#216. The caller must already be connected to the source repository;
this copies its blobs to destination. The destination’s backend args are
built by ConnectSpec::backend_args (the same builder connect/create use),
so a new backend variant is wired through automatically. opts carries the
tuning knobs (parallelism, --delete, the must-exist/times/update
tri-states, throughput caps) — see SyncToOptions. Destination
credentials are supplied via the environment, never on argv, exactly like
connect/create. Success is exit code 0.
Sourcepub async fn repository_sync_to_with_env(
&self,
destination: &ConnectSpec,
opts: &SyncToOptions,
dest_env: &BTreeMap<String, Option<String>>,
) -> Result<(), KopiaError>
pub async fn repository_sync_to_with_env( &self, destination: &ConnectSpec, opts: &SyncToOptions, dest_env: &BTreeMap<String, Option<String>>, ) -> Result<(), KopiaError>
Self::repository_sync_to with a per-invocation environment overlay
applied to the sync-to subprocess only. The replication mover uses this to
give the destination backend its own credentials: it maps each of the
destination backend’s env-delivered credential vars (AWS_*, AZURE_*, …)
from the KOPIUR_DEST_-prefixed copy in its environment, and unsets any that
the destination doesn’t provide so a source credential cannot leak. The
source repository is read from the persisted connection config (kopia bakes
the source storage credentials in at repository connect), so overlaying the
plain credential names here cannot disturb the source read. Some(v) sets a
var, None removes it. Credentials travel via env, never argv.
Sourcepub async fn snapshot_create(
&self,
source_path: &str,
tags: &BTreeMap<String, String>,
override_source: Option<&str>,
) -> Result<SnapshotCreateResult, KopiaError>
pub async fn snapshot_create( &self, source_path: &str, tags: &BTreeMap<String, String>, override_source: Option<&str>, ) -> Result<SnapshotCreateResult, KopiaError>
Create a snapshot of source_path with the given tags
(key:value) and kopia’s own defaults for snapshot create’s tuning
knobs. Returns the parsed create result.
override_source, when set, is passed to kopia as --override-source
(format username@hostname:path). This is how Kopiur records snapshots
under the operator-resolved identity (ADR §4.2 / anchoring principle 9)
rather than the mover pod’s ambient user@host. Without it kopia would
attribute the snapshot to the pod, breaking the identity model that the
whole catalog/retention/restore machinery keys on.
Sourcepub async fn snapshot_create_with(
&self,
source_path: &str,
tags: &BTreeMap<String, String>,
override_source: Option<&str>,
opts: &SnapshotCreateOptions,
) -> Result<SnapshotCreateResult, KopiaError>
pub async fn snapshot_create_with( &self, source_path: &str, tags: &BTreeMap<String, String>, override_source: Option<&str>, opts: &SnapshotCreateOptions, ) -> Result<SnapshotCreateResult, KopiaError>
Create a snapshot honoring the operator’s SnapshotCreateOptions
(failFast, uploadLimitMb, description — M4 flag sweep, issue #216).
Same identity/tags contract as Self::snapshot_create, which now
delegates here with an all-default opts (byte-for-byte the same argv
as before this option struct existed).
Sourcepub async fn snapshot_list(
&self,
filter: Option<&SnapshotSource>,
) -> Result<Vec<SnapshotListEntry>, KopiaError>
pub async fn snapshot_list( &self, filter: Option<&SnapshotSource>, ) -> Result<Vec<SnapshotListEntry>, KopiaError>
List snapshots, optionally filtered by source identity. With no filter this lists all snapshots in the repository.
Sourcepub async fn snapshot_delete(&self, id: &str) -> Result<(), KopiaError>
pub async fn snapshot_delete(&self, id: &str) -> Result<(), KopiaError>
Delete a single snapshot by manifest id. kopia’s snapshot delete
requires --delete to actually remove (otherwise it dry-runs) and does
not support --json; success is signaled by exit code 0.
IDEMPOTENT: an already-absent snapshot (no snapshots matched <id> on
stderr) is success — that IS the goal state. kopia dedups
identical-content snapshot manifests, so several Snapshot CRs can
legitimately pin the SAME kopia id; when GFS retention prunes more than
one of them, the first finalizer’s delete removes the manifest and the
rest would otherwise fail terminally, wedging their CRs in Deleting
forever (caught by the retention e2e under suite load).
Sourcepub async fn snapshot_restore(
&self,
id: &str,
target_dir: &str,
) -> Result<(), KopiaError>
pub async fn snapshot_restore( &self, id: &str, target_dir: &str, ) -> Result<(), KopiaError>
Restore a snapshot’s contents to a target directory with kopia’s default
options. kopia’s snapshot restore does not emit JSON; success is exit
code 0.
Sourcepub async fn snapshot_restore_with(
&self,
id: &str,
target_dir: &str,
opts: &RestoreOptions,
) -> Result<(), KopiaError>
pub async fn snapshot_restore_with( &self, id: &str, target_dir: &str, opts: &RestoreOptions, ) -> Result<(), KopiaError>
Restore a snapshot honoring the operator’s RestoreOptions
(enableFileDeletion, ignorePermissionErrors, writeFilesAtomically,
…). Success is exit code 0.
Sourcepub async fn snapshot_verify(
&self,
opts: &VerifyOptions,
) -> Result<(), KopiaError>
pub async fn snapshot_verify( &self, opts: &VerifyOptions, ) -> Result<(), KopiaError>
Verify repository/snapshot integrity (kopia snapshot verify). Success is
exit code 0; a verification failure surfaces as a non-zero exit.
Sourcepub async fn snapshot_estimate(
&self,
source_path: &str,
) -> Result<(), KopiaError>
pub async fn snapshot_estimate( &self, source_path: &str, ) -> Result<(), KopiaError>
Estimate the size/scope of snapshotting source_path
(kopia snapshot estimate). Best-effort; success is exit code 0.
Sourcepub async fn snapshot_pin(&self, id: &str, pin: &str) -> Result<(), KopiaError>
pub async fn snapshot_pin(&self, id: &str, pin: &str) -> Result<(), KopiaError>
Add a pin to a snapshot so maintenance/expiration never deletes it
(kopia snapshot pin <id> --add <pin>). Used to protect snapshots whose
Snapshot carries deletionPolicy: Retain.
Sourcepub async fn snapshot_unpin(
&self,
id: &str,
pin: &str,
) -> Result<(), KopiaError>
pub async fn snapshot_unpin( &self, id: &str, pin: &str, ) -> Result<(), KopiaError>
Remove a pin from a snapshot (kopia snapshot pin <id> --remove <pin>).
Sourcepub async fn snapshot_expire(&self, delete: bool) -> Result<(), KopiaError>
pub async fn snapshot_expire(&self, delete: bool) -> Result<(), KopiaError>
Expire snapshots per the repository’s policy
(kopia snapshot expire --all). When delete is false this is a dry-run
(kopia requires --delete to actually remove). Success is exit code 0.
Sourcepub async fn repository_validate_provider(&self) -> Result<(), KopiaError>
pub async fn repository_validate_provider(&self) -> Result<(), KopiaError>
Validate that the connected storage provider behaves correctly
(kopia repository validate-provider). A good Repository-readiness
preflight for object-store backends. Success is exit code 0.
Sourcepub async fn policy_set(
&self,
target: &str,
policy: &PolicyArgs,
) -> Result<(), KopiaError>
pub async fn policy_set( &self, target: &str, policy: &PolicyArgs, ) -> Result<(), KopiaError>
Apply a policy to target (an identity string, a path, or --global)
via kopia policy set. The operator calls this before the first snapshot
so SnapshotPolicy.spec.policy (compression/splitter/ignore) is honored.
Sourcepub async fn policy_show(&self, target: &str) -> Result<Value, KopiaError>
pub async fn policy_show(&self, target: &str) -> Result<Value, KopiaError>
Show the effective policy for target (kopia policy show <target> --json), parsed as a generic JSON value.
Sourcepub async fn repository_status(&self) -> Result<RepositoryStatus, KopiaError>
pub async fn repository_status(&self) -> Result<RepositoryStatus, KopiaError>
Get repository status (kopia repository status --json).
This spawns kopia, so the example is no_run (it would need a real
binary + connected repository):
use kopiur_kopia::KopiaClient;
let client = KopiaClient::builder()
.env("KOPIA_PASSWORD", "s3cr3t")
.build();
let status = client.repository_status().await?;
println!("repository unique id: {}", status.unique_id_hex);Sourcepub async fn maintenance_info(&self) -> Result<MaintenanceInfo, KopiaError>
pub async fn maintenance_info(&self) -> Result<MaintenanceInfo, KopiaError>
Get maintenance info (kopia maintenance info --json).
Sourcepub async fn index_blob_count(&self) -> Result<i64, KopiaError>
pub async fn index_blob_count(&self) -> Result<i64, KopiaError>
Count the repository’s content-index blobs (kopia index list --json,
array length). kopia’s index is compacted by periodic maintenance; when
maintenance stops (e.g. a stale lease owner), this grows unbounded and
kopia eventually warns “Found too many index blobs (N), ensure periodic
repository maintenance”. The operator surfaces a Kubernetes Warning when
this crosses a configurable threshold. Cheap — lists index-blob metadata
only, no content read. Verified against kopia 0.23 (index list --[no-]json).
Sourcepub async fn maintenance_set_owner_me(&self) -> Result<(), KopiaError>
pub async fn maintenance_set_owner_me(&self) -> Result<(), KopiaError>
Claim the repository’s maintenance ownership for the currently connected
identity (kopia maintenance set --owner me). kopia ties “who may run
maintenance” to the connected user@hostname and rejects a maintenance run
from anyone but the designated owner (“maintenance must be run by designated
user: …”). A repo bootstrapped by the controller in-process is owned by the
controller’s identity, so a mover Job (a different pod) MUST claim ownership
before it can run maintenance. Idempotent; no JSON, success is exit 0.
Sourcepub async fn maintenance_set_owner(&self, owner: &str) -> Result<(), KopiaError>
pub async fn maintenance_set_owner(&self, owner: &str) -> Result<(), KopiaError>
Set the repository’s maintenance owner to an EXPLICIT user@hostname
(kopia maintenance set --owner <owner>). Used by the bootstrap mover
right after repository create to stamp the stable, lease-derived
owner (kopiur_api::maintenance::kopia_owner_for_lease) instead of the
creating pod’s ephemeral identity — without this, every later
maintenance mover sees a foreign owner and takeoverPolicy: Never
yields forever. Verified against kopia 0.23 maintenance set --help
(--owner=OWNER Set maintenance owner user@hostname).
Sourcepub async fn repository_set_client_identity(
&self,
username: &str,
hostname: &str,
) -> Result<(), KopiaError>
pub async fn repository_set_client_identity( &self, username: &str, hostname: &str, ) -> Result<(), KopiaError>
Switch the CONNECTED client identity (kopia repository set-client --username … --hostname …). The maintenance mover assumes the stable
lease-derived identity this way (kopia 0.23 has no identity override on
repository connect; the OS user@pod-hostname is ephemeral), so
maintenance set --owner me records a stable string and the
designated-user check passes on every later run. Verified against
kopia 0.23 repository set-client --help.
Sourcepub async fn maintenance_run(
&self,
mode: MaintenanceMode,
) -> Result<(), KopiaError>
pub async fn maintenance_run( &self, mode: MaintenanceMode, ) -> Result<(), KopiaError>
Run a maintenance pass. kopia’s maintenance run does not emit JSON;
success is exit code 0. The caller must already be the designated
maintenance owner (see maintenance_set_owner_me).
Sourcepub async fn run_raw_streaming(
&self,
args: &[String],
sink: &mut (dyn AsyncWrite + Unpin + Send),
) -> Result<u64, KopiaError>
pub async fn run_raw_streaming( &self, args: &[String], sink: &mut (dyn AsyncWrite + Unpin + Send), ) -> Result<u64, KopiaError>
Run kopia with args and stream stdout byte-for-byte into sink
(no line splitting, no UTF-8 assumption), returning the byte count on a
zero exit. This is the file-content path for kopia show <file-oid>
(the browse data-plane’s cat/download), where stdout is the raw
object bytes — buffering it whole or splitting it into lines would
corrupt/clamp arbitrarily large binary files.
stderr is accumulated like every other invocation; a non-zero exit
yields KopiaError::NonZeroExit with the stderr tail. NOTE: bytes
already streamed before a late failure have reached the sink — callers
writing to a file should verify the count and discard partial output on
error (kopia’s show either streams the object or fails up front, so in
practice a failure produces no payload). Honors default_timeout.
Sourcepub fn server_start(
&self,
spec: &ServerStartSpec,
password: Option<&str>,
) -> KopiaError
pub fn server_start( &self, spec: &ServerStartSpec, password: Option<&str>, ) -> KopiaError
Run kopia server start, replacing this process with kopia via exec.
On success this never returns (kopia takes over the PID and runs until it is
signalled). It returns a KopiaError only if exec itself fails (e.g. the
binary is missing). The repository must already be connected (call
KopiaClient::repository_connect first) — the server reads the connected
repo from the kopia config file.
password is the UI password for ServerAuthMode::Password; it is appended
to argv here, inside the server pod, so it never reaches the controller,
a ConfigMap, or the pure [server_start_args] builder. For
ServerAuthMode::None it is ignored.
Trait Implementations§
Source§impl Clone for KopiaClient
impl Clone for KopiaClient
Source§fn clone(&self) -> KopiaClient
fn clone(&self) -> KopiaClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more