# HG changeset patch # User Heiko Schlittermann # Date 1264897052 -3600 # Node ID bdc967bf50d29e21ee910406833a8a79541586c4 # Parent 1c7e99693439ae8c5004fae8a5658132c6550dcf [savepoint] diff -r 1c7e99693439 -r bdc967bf50d2 is --- 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 tool installs the image you saved with B. + +=head1 OPTIONS + +=over + +=item B<-b>|B<--base> I + +The directory where to look for the images. Each image should have +a unique subdirectory there. (default: I<..>) + +=item B<-s>|B<--source> I + +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: diff -r 1c7e99693439 -r bdc967bf50d2 lib/SI/lvm.pm --- 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: diff -r 1c7e99693439 -r bdc967bf50d2 lib/SI/ptable.pm --- 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: diff -r 1c7e99693439 -r bdc967bf50d2 lib/SI/tools.pm --- 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($) {