--- a/is Fri Jan 29 00:35:46 2010 +0100
+++ b/is Sun Jan 31 01:17:32 2010 +0100
@@ -8,13 +8,17 @@
use Getopt::Long;
use Pod::Usage;
use File::Basename;
+use Data::Dumper;
use lib "lib";
use SI::system;
+use SI::ptable;
+use SI::lvm;
my $ME = basename $0;
my $opt_base = "..";
my $opt_src = undef;
+my $opt_verbose = undef;
MAIN: {
@@ -22,19 +26,69 @@
GetOptions(
"base=s" => \$opt_base,
"src=s" => \$opt_src,
+ "help" => sub { pod2usage(-verbose => 1, exit => 0) },
+ "man" => sub { pod2usage(-verbose => 2, exit => 0) },
+ "verbose" => \$opt_verbose,
) or pod2usage;
my $id = SI::system::id();
# now check if we find a suitable image
- my $src = defined $opt_src ? $opt_src : "$opt_base/image-$id";
+ my $src = defined $opt_src ? $opt_src : "image-$id";
+ $src = "$opt_base/$src" if $src !~ /\//;
+
-d $src or die "$ME: $src: $!\n";
our $VAR1;
do "$src/info/devices";
my %devices = %$VAR1;
- die %devices;
+# SI::ptable::restore(%devices);
+# SI::ptable::mkfs(%devices);
+ SI::lvm::pvcreate(%devices);
+ SI::lvm::vgcfgrestore("$src/lvm/vg.*", %devices);
+
+
+ exit;
+ die Dumper \%devices;
}
+
+__END__
+
+=head1 NAME
+
+is - revert si (recover from system image)
+
+=head1 SYNOPSIS
+
+ is [--base=BASE] [--source=SOURCE]
+ is --help
+ is --man
+
+=head1 DESCRIPTION
+
+This B<is> tool installs the image you saved with B<si>.
+
+=head1 OPTIONS
+
+=over
+
+=item B<-b>|B<--base> I<base>
+
+The directory where to look for the images. Each image should have
+a unique subdirectory there. (default: I<..>)
+
+=item B<-s>|B<--source> I<source>
+
+The source of the image. If the source does not contain a slash ("/"), the
+it is expected to be a subdirectory of the base (see option B<--base>).
+
+Normally the source directories are named by the MAC address of the system.
+For convenience a symbolic link with the hostname of the saved systems may be
+in place. (default: mac address)
+
+=back
+
+=cut
# vim:sts=4 sw=4 aw ai si:
--- a/lib/SI/lvm.pm Fri Jan 29 00:35:46 2010 +0100
+++ b/lib/SI/lvm.pm Sun Jan 31 01:17:32 2010 +0100
@@ -7,6 +7,7 @@
use IO::File;
use Cwd qw(abs_path);
use File::Basename;
+use feature "switch";
use SI::tools;
@@ -67,6 +68,49 @@
run("vgcfgbackup -f '$file' >/dev/null");
}
+sub pvcreate(\%) {
+ my $devs = shift;
+ foreach my $volume ( keys %{$devs->{volume}} ) {
+ my $v = $devs->{volume}{$volume};
+ next if $v->{origin} ne "ptable"
+ or not defined $v->{type}
+ or $v->{type} !~ /^lvm/i;
+ run("pvcreate -y -ff -u $v->{uuid} $volume");
+ }
+}
+
+sub vgcfgrestore($\%) {
+ my @cfgs = glob($_[0]);
+ my $devs = shift;
+
+ foreach (@cfgs) {
+ my $vg = basename($_);
+ next if $vg eq "vg.*";
+ print $vg, "\n";
+ }
+}
+
+sub mkfs(\%) {
+ my $devs = shift;
+ foreach my $volume ( keys %{$devs->{volume}} ) {
+ my $v = $devs->{volume}{$volume};
+ next if $v->{origin} ne "lvm"
+ or not defined $v->{type};
+
+ my $label = default("" => $v->{label});
+ my $uuid = default("" => $v->{uuid});
+
+ given($v->{type}) {
+ when(/ext/) {
+ run("mkfs -t $v->{type} -L '$label' -U '$uuid' $volume");
+ };
+ when(/swap/) {
+ run("mkswap -L '$label' -U '$uuid' $volume");
+ };
+ }
+ }
+}
+
1;
# vim:sts=4 sw=4 aw ai si:
--- a/lib/SI/ptable.pm Fri Jan 29 00:35:46 2010 +0100
+++ b/lib/SI/ptable.pm Sun Jan 31 01:17:32 2010 +0100
@@ -7,6 +7,7 @@
use File::Find;
use File::Basename;
use IO::File;
+use feature "switch";
use SI::tools;
$ENV{LC_ALL} = "C";
@@ -65,6 +66,46 @@
return;
}
+
+sub restore(\%) {
+ my $devs = shift;
+
+ foreach my $disk (keys %{$devs->{disk}}) {
+ verbose("restoring partition table of $disk\n");
+ die "I won't use the disk ($disk) I'm running on!"
+ if (stat $0)[0] ~~ [ map { (stat)[6] } map { "/dev/" . basename dirname $_ } glob ("/sys/block/" . basename($disk) . "/*/partition")];
+
+ my $sfdisk = new IO::File "|sfdisk $disk >/dev/null"
+ or die "Can't open |sfdisk $disk: $!\n";
+ print {$sfdisk} @{$devs->{disk}{$disk}{pt}};
+ $sfdisk->close or die $? >> 8;
+ run("partprobe $disk");
+ }
+}
+
+sub mkfs(\%) {
+ my $devs = shift;
+ foreach my $volume ( keys %{$devs->{volume}} ) {
+ my $v = $devs->{volume}{$volume};
+ next if $v->{origin} ne "ptable";
+ warn $volume, "\n";
+ next if not defined $v->{type};
+ given ($v->{type}) {
+ when(/ext\d/) {
+ my $label = defined $v->{label} ? $v->{label} : "";
+ my $uuid = defined $v->{uuid} ? $v->{uuid} : "";
+ run("mkfs -t $v->{type} -L '$label' -U '$uuid' $volume");
+ };
+ when("swap") {
+ my $label = defined $v->{label} ? $v->{label} : "";
+ my $uuid = defined $v->{uuid} ? $v->{uuid} : "";
+ run("mkswap -L '$label' -U '$uuid' $volume");
+ };
+ };
+
+ }
+
+}
1;
# vim:sts=4 sw=4 aw ai si:
--- a/lib/SI/tools.pm Fri Jan 29 00:35:46 2010 +0100
+++ b/lib/SI/tools.pm Sun Jan 31 01:17:32 2010 +0100
@@ -8,7 +8,7 @@
use Data::Dumper;
use base "Exporter";
-our @EXPORT = qw(&run &verbose &find_by_devid &cat &barf);
+our @EXPORT = qw(&run &verbose &find_by_devid &cat &barf &default);
sub run(@) {
system(@_);
@@ -16,6 +16,10 @@
if $?;
}
+sub default($$) {
+ return defined $_[1] ? $_[1] : $_[0];
+}
+
sub barf(@) { die Dumper @_ }
sub cat($) {