Created
December 24, 2015 17:17
-
-
Save jayjanssen/c081e938a247f4e3b552 to your computer and use it in GitHub Desktop.
ZFS full/incrementals to AWS Glacier
This file contains 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/perl | |
use vars qw/ @ARGV /; | |
local $ENV{PATH} = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; | |
die "Usage: $0 <filesystem>\n" unless $#ARGV == 0; | |
my $filesystem = shift @ARGV; | |
my $base_snap = '@glacier'; | |
my $tmp_snap = '@glacier-tmp'; | |
# ZFS Snapshots | |
sub check_snap { | |
my( $snap_name ) = @_; | |
return system( "zfs list -t snap $snap_name > /dev/null" ) == 0; | |
} | |
sub create_snap { | |
my( $snap_name ) = @_; | |
print "Creating snap: $snap_name\n"; | |
system( "zfs snap $snap_name" ); | |
} | |
sub delete_snap { | |
my( $snap_name ) = @_; | |
print "Destroying snap: $snap_name\n"; | |
system( "zfs destroy $snap_name" ); | |
} | |
sub rename_snap { | |
my( $old, $new ) = @_; | |
print "Renaming $old to $new\n"; | |
system( "zfs rename $old $new" ); | |
} | |
# Glacier Vaults | |
sub sanitize_name { | |
my( $vault_name ) = @_; | |
$vault_name =~ s|\/|_|g; | |
return $vault_name | |
} | |
sub check_vault { | |
my $vault_name = &sanitize_name( @_ ); | |
return system( "glacier-cmd describevault $vault_name > /dev/null" ) == 0; | |
} | |
sub create_vault { | |
my $vault_name = &sanitize_name( @_ ); | |
print "Creating Glacier vault $vault_name\n"; | |
return system( "glacier-cmd mkvault $vault_name > /dev/null" ) == 0; | |
} | |
# Glacier upload | |
sub glacier_upload { | |
my( $filesystem, $snap, $base ) = @_; | |
my $vault_name = &sanitize_name( $filesystem ); | |
my $incremental = ""; | |
my $date = `date +"%F"`; chop $date; | |
my $description = "Full for $date"; | |
if( defined( $base )) { | |
$description = "Incremental for $date"; | |
$incremental = "-i $base "; | |
} | |
my $cmd = "zfs send -p $incremental$snap | glacier-cmd upload --description '$description' --stdin $vault_name"; | |
print "$cmd\n"; | |
return (system( $cmd ) == 0); | |
} | |
# Check for glacier vault and create if needed | |
&create_vault( $filesystem ) unless( &check_vault( $filesystem )); | |
# Check for base snapshot | |
my $base = "$filesystem$base_snap"; | |
unless( &check_snap( $base ) ) { | |
print "Missing base snap\n"; | |
&create_snap( $base ); | |
# Upload base snap and exit | |
&glacier_upload( $filesystem, $base ); | |
exit; | |
} | |
my $tmp = "$filesystem$tmp_snap"; | |
if( &check_snap( $tmp ) ) { | |
print "Found tmp snap, dropping it\n"; | |
&delete_snap( $tmp ); | |
} | |
&create_snap( $tmp ); | |
# Check for diffs | |
my $diffs = `zfs diff $base $tmp | wc -l`; chop $diffs; | |
if( $diffs == 0 ) { | |
print "No diffs!\n"; | |
&delete_snap( $tmp ); | |
exit; | |
} | |
# Upload incremental snap | |
if( &glacier_upload( $filesystem, $tmp, $base )) { | |
&delete_snap( $base ); | |
&rename_snap( $tmp, $base ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment