--- a/Build.PL Tue Sep 06 15:08:29 2011 +0200
+++ b/Build.PL Fri Sep 09 23:30:58 2011 +0200
@@ -15,5 +15,9 @@
"IO::Uncompress::Gunzip" => 0,
"IO::Compress::Gzip" => 0,
},
+ build_requires => {
+ "Test::More" => "0.92",
+ "File::Temp" => "0.22",
+ },
script_files => [glob "bin/*"],
)->create_build_script;
--- a/bin/imager Tue Sep 06 15:08:29 2011 +0200
+++ b/bin/imager Fri Sep 09 23:30:58 2011 +0200
@@ -16,7 +16,7 @@
);
},
)
- and $ARGV[0] ~~ [qw(save restore fuse check compress)]
+ and $ARGV[0] ~~ [qw(save restore fuse check compress list)]
or pod2usage;
exec "$0." . shift() => @ARGV;
@@ -72,9 +72,13 @@
=item compress
-Check the compression and decompress or compress. See C<--imager
+Check the compression and decompress or compress. See C<imager
compress --help> for more information.
+=item list
+
+List the backups/images available. See C<imager list --help> for more information.
+
=back
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/imager.list Fri Sep 09 23:30:58 2011 +0200
@@ -0,0 +1,94 @@
+#! /usr/bin/perl
+
+use 5.010;
+use strict;
+use warnings;
+use Pod::Usage;
+use Hash::Util qw(lock_keys);
+use File::Find;
+use Digest::MD5 qw(md5_hex);
+use File::Basename;
+use autodie qw(:all);
+use Imager;
+
+use Getopt::Long;
+
+our %o = (
+ latest => undef,
+);
+lock_keys(%o);
+
+MAIN: {
+ my $dir;
+
+ Getopt::Long::Configure qw(Bundling);
+ GetOptions(
+ "latest" => \$o{latest},
+ "h|help" => sub { pod2usage(-verbose => 1, -exit => 0) },
+ "m|man" => sub {
+ pod2usage(
+ -verbose => 2,
+ -exit => 0,
+ -noperldoc => system(
+ "perldoc -V 1>/dev/null
+ 2>&1"
+ )
+ );
+ },
+ )
+ and defined ($dir = shift)
+ or pod2usage;
+
+ my (%by_day, %by_dev);
+ find(sub{
+ return if not (-f and /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$/);
+ my ($host, $dev) = dirname($File::Find::name) =~ /^\Q$dir\/idx\E\/(.+?)(\/.*)/;
+ push @{$by_day{$_}}, "$host\::$dev";
+ push @{$by_dev{"$host\::$dev"}}, $_;
+ }, "$dir/idx");
+
+ # by dev
+ my $l = (sort { $b <=> $a } map { length } keys %by_dev)[0];
+ foreach (sort keys %by_dev) {
+ my $prefix = $_;
+ foreach ((reverse sort @{$by_dev{$_}})) {
+ printf "%-*s: %s\n", $l => $prefix, $_;
+ last if $o{latest};
+ $prefix = " ";
+ }
+ }
+
+}
+
+__END__
+
+=head1 NAME
+
+ imager.list - list the images created by imager
+
+=head1 SYNOPSIS
+
+ imager.list [options] {directory}
+
+=head1 DESCRIPTION
+
+B<imager.list> lists the index files (images) the imager created.
+
+
+=head1 OPTIONS
+
+=over
+
+=item B<--latest>
+
+List only the latest backups. (default: list all)
+
+=item B<-h>|B<--help>
+
+=item B<-m>|B<--man>
+
+The short and longer help.
+
+=back
+
+=cut
--- a/bin/imager.save Tue Sep 06 15:08:29 2011 +0200
+++ b/bin/imager.save Fri Sep 09 23:30:58 2011 +0200
@@ -19,15 +19,15 @@
use constant KiB => 1024;
use constant MiB => 1024 * KiB;
use constant GiB => 1024 * MiB;
-use constant NOW => time();
use constant BS => 4 * MiB;
-use constant DATETIME => strftime("%Y-%m-%dT%H:%M:%SZ" => gmtime(NOW));
+use constant DATEFMT => "%Y-%m-%dT%H:%M:%SZ";
use constant CIPHER => "aes-128-cbc";
sub get_devsize;
sub get_devname;
sub save;
+
$SIG{INT} = sub { die "Got INT\n" };
my %o = (
@@ -36,6 +36,7 @@
blocksize => BS,
pass => undef,
comment => undef,
+ now => time(),
);
lock_keys(%o);
@@ -52,6 +53,7 @@
"c|comment=s" => \$o{comment},
"z|compress:i" => sub { $o{compress} = $_[1] ? $_[1] : Z_BEST_SPEED },
"p|pass=s" => \$o{pass},
+ "now=i" => \$o{now},
"b|blocksize=s" => sub {
given ($_[1]) {
when (/(\d+)G/i) { $o{blocksize} = $1 * GiB };
@@ -117,8 +119,8 @@
filesystem => $src,
blocksize => $o{blocksize},
devsize => $size,
- timestamp => NOW,
- datetime => DATETIME,
+ timestamp => $o{now},
+ datetime => strftime(DATEFMT, gmtime $o{now}),
(defined $o{comment} ? (comment => $o{comment}) : ()),
encryption => $o{pass} ? CIPHER : "none",
};
@@ -219,7 +221,7 @@
"",
@{ $index{BLOCKS} };
close($index);
- rename $index->filename => "$idx/" . DATETIME;
+ rename $index->filename => "$idx/" . strftime(DATEFMT, gmtime $o{now});
say "# $src DONE (runtime " . (time() - $^T) . "s)";
say "# $src WRITTEN $stats{written}, SKIPPED $stats{skipped} blocks";
@@ -279,6 +281,10 @@
Comment to be included in the header of the index file. (default: none)
+=item B<--now> I<timestamp>
+
+Set the timestamp used for naming the idx files. (default: now)
+
=item B<-p>|B<--pass> I<pass>
Use symmetric encryption for writing the data blocks. This option