diff --git a/hive-c0re/src/bin/hivectl.rs b/hive-c0re/src/bin/hivectl.rs index 65d1f6c8..e2b7a029 100644 --- a/hive-c0re/src/bin/hivectl.rs +++ b/hive-c0re/src/bin/hivectl.rs @@ -650,6 +650,26 @@ enum SnapshotCmd { /// Snapshot label passed to `subvol snapshot create --label`. label: String, }, + /// Export a snapshot to a local file via `btrfs send` (the local-file + /// half of inter-hive migration transport; the cross-hive `ssh ... + /// btrfs receive` leg isn't wired up yet). Also useful standalone as a + /// point-in-time backup: a full send with no `--parent` produces a + /// self-contained archive of the snapshot. + Send { + /// Agent name the snapshot belongs to. + name: String, + /// Snapshot label passed to `subvol snapshot create --label`. + label: String, + /// Optional parent snapshot label for an incremental send + /// (`btrfs send -p`) — must be an existing, older snapshot of the + /// same agent. Omit for a full send. + #[arg(long)] + parent: Option, + /// Destination filename (not a path) under the migrate-staging + /// dir. Refused if it already exists. + #[arg(long)] + dest: String, + }, } #[tokio::main] @@ -726,6 +746,12 @@ async fn main() -> Result<()> { SubvolCmd::Snapshot { cmd } => match cmd { SnapshotCmd::Create { name, label } => subvol_snapshot_create(&name, label).await, SnapshotCmd::Delete { name, label } => subvol_snapshot_delete(&name, &label).await, + SnapshotCmd::Send { + name, + label, + parent, + dest, + } => subvol_snapshot_send(&name, &label, parent.as_deref(), &dest).await, }, }, Cmd::Choom { @@ -1777,6 +1803,24 @@ async fn subvol_snapshot_delete(name: &str, label: &str) -> Result<()> { Ok(()) } +/// `subvol snapshot send