Created
August 9, 2024 19:04
-
-
Save stigtsp/1671ab2847c777a5b2e970d7e4d7624b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# Hack to incrementally pull/sync btrfs snapshots from a remote server over ssh | |
# The snapshots are in "/volume/snapshot/" and in lexical order, like "2024-01-01", "2024-01-02", "2024-02-01" | |
# | |
# Barely tested, be careful | |
use experimental qw(signatures); | |
use feature qw(say); | |
use strict; | |
use warnings; | |
use autodie; | |
use Data::Dumper; | |
use File::Spec::Functions qw(catdir); | |
my $local_snap_dir = "/volume/snapshot/"; | |
my $remote_snap_dir = "/volume/snapshot/"; | |
my $remote_ssh_host = "root\@192.168.1.1"; | |
my $ssh_ls_cmd = "ssh $remote_ssh_host 'ls $remote_snap_dir'"; | |
warn "Listing remote snapshots via: $ssh_ls_cmd\n"; | |
# TODO: Check if they are actually snapshots and read only on the remote side | |
my @snapshots = sort split(/\s+/, qx($ssh_ls_cmd)); | |
warn "Found ".scalar(@snapshots)." snapshots\n"; | |
warn " First: ".$snapshots[0]."\n"; | |
warn " Last: ".$snapshots[-1]."\n"; | |
my @ops; | |
for (my $i=0; $i<@snapshots; $i++) { | |
my $is_first = !$i; | |
my $is_last = !$snapshots[$i+1]; | |
my $snap = $snapshots[$i]; | |
my $prev = $is_first ? undef : $snapshots[$i-1]; | |
unless (local_exists($snap)) { | |
push @ops, [ $prev ? ($prev, $snap) : ($snap) ]; | |
} else { | |
warn "Local $snap exists\n"; | |
if (@ops) { | |
die "Woops! $snap already exists, but we didn't expect it to! Already have ".scalar(@ops)." ops\n"; | |
} | |
} | |
} | |
foreach my $op (@ops) { | |
my $cmd; | |
if (@$op == 1) { | |
$cmd = "ssh $remote_ssh_host 'btrfs send " . catdir($local_snap_dir, $op->[0]) . "' | btrfs receive $local_snap_dir"; | |
} elsif (@$op == 2) { | |
$cmd = "ssh $remote_ssh_host 'btrfs send -p " | |
. catdir($local_snap_dir, $op->[0]) | |
." " | |
. catdir($local_snap_dir, $op->[1]) | |
. "' | btrfs receive $local_snap_dir"; | |
} | |
warn "Executing: $cmd\n"; | |
(system($cmd) == 0) || die "Failed: $!"; | |
} | |
sub local_exists ($snap) { | |
my $local_dir = catdir($local_snap_dir, $snap); | |
if (-d $local_dir) { | |
warn "local_exists($local_dir) exists"; | |
return 1; | |
} else { | |
warn "local_exists($local_dir) does not exists"; | |
return; | |
} | |
# TODO: Check if state of directory is ok, I.e. if it is read only | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment