first real live test
authorHeiko Schlittermann <hs@schlittermann.de>
Tue, 19 Jan 2010 14:49:43 +0100
changeset 15 4e3753b998a9
parent 14 aecda2763079
child 16 fd87c1e3b451
first real live test
SI/dumper.pm
SI/lvm.pm
SI/ptable.pm
SI/system.pm
SI/tools.pm
si
--- a/SI/dumper.pm	Mon Jan 18 22:55:10 2010 +0100
+++ b/SI/dumper.pm	Tue Jan 19 14:49:43 2010 +0100
@@ -6,44 +6,11 @@
 use SI::tools;
 use File::Basename;
 
-#$VAR1 = {
-#          'volume' => {
-#                        '/dev/mapper/debian-swap' => {
-#                                                       'origin' => 'lvm',
-#                                                       'label' => undef,
-#                                                       'type' => 'swap',
-#                                                       'uuid' => undef
-#                                                     },
-#                        '/dev/hda4' => {
-#                                         'ptable_type' => '0',
-#                                         'origin' => 'ptable'
-#                                       },
-#                        '/dev/hda1' => {
-#                                         'ptable_type' => '83',
-#                                         'origin' => 'ptable',
-#                                         'label' => undef,
-#                                         'type' => 'ext2',
-#                                         'uuid' => 'a1fc3fc0-7bde-49c4-9afe-c71db8c4d08b'
-#                                       },
-#                        '/dev/hda3' => {
-#                                         'ptable_type' => '0',
-#                                         'origin' => 'ptable'
-#                                       },
-#                        '/dev/mapper/debian-root' => {
-#                                                       'origin' => 'lvm',
-#                                                       'label' => undef,
-#                                                       'type' => 'ext3',
-#                                                       'uuid' => 'b30578ac-841f-48b4-8ceb-1cdcbabc7fab'
-#                                                     },
-#                        '/dev/hda2' => {
-#                                         'ptable_type' => '8',
-#                                         'origin' => 'ptable',
-#                                         'label' => undef,
-#                                         'type' => 'lvm2pv',
-#                                         'uuid' => 'S4zDgc-hEWW-h9BY-XHz3-32TE-66W1-W0iMVE'
-#                                       }
-#                      },
-#        };
+my @cleanup;
+END { 
+    #map { eval { run("lvchange -an $_ 2>/dev/null") } } @cleanup;
+    #map { eval { run("lvremove -ff $_ 2>/dev/null") } } @cleanup;
+}
 
 sub dump($\%) {
     my ($file, $devs) = @_;
@@ -54,20 +21,18 @@
 	verbose("dumping volume $volume->{name}");
 	my $dumpdev = $volume->{name};
 
-	if ($volume->{origin} =~ /lvm/i) {
-	    verbose("(lvm)");
-	    my ($vg, $lv) = `lvdisplay -c $volume->{name}` =~ /\s*\/dev\/(.*?)\/(.*?):/;
-	    my $snap = "snap$$";
-
-	    END { eval { run("lvchange -an $vg/$snap 2>/dev/null") };
-		  eval { run("lvremove -ff $vg/$snap 2>/dev/null") }; }
-
-	    eval {
-		run("lvcreate -s -L 1G -n snap$$ $vg/$lv 2>/dev/null");
-	    };
-	    if ($@) { warn "Can't create snapshot\n" }
-	    else { $dumpdev = "/dev/$vg/$snap$$" };
-	}
+#	if ($volume->{origin} =~ /lvm/i) {
+#	    verbose("(lvm)");
+#	    my ($vg, $lv) = `lvdisplay -c $volume->{name}` =~ /\s*\/dev\/(.*?)\/(.*?):/;
+#	    my $snap = "snap$$";
+#	    push @cleanup, "$vg/$lv";
+#
+#	    #eval {
+#	    #	run("lvcreate -s -L 1G -n snap$$ $vg/$lv 2>/dev/null");
+#	    #};
+#	    if ($@) { warn "Can't create snapshot\n" }
+#	    else { $dumpdev = "/dev/$vg/$snap$$" };
+#	}
 
 	my $of = sprintf $file, basename($volume->{name});
 	run("dump -0 -z -f $of $dumpdev");
--- a/SI/lvm.pm	Mon Jan 18 22:55:10 2010 +0100
+++ b/SI/lvm.pm	Tue Jan 19 14:49:43 2010 +0100
@@ -5,7 +5,8 @@
 use strict;
 use warnings;
 use IO::File;
-
+use Cwd qw(abs_path);
+use File::Basename;
 
 use SI::tools;
 
@@ -16,6 +17,7 @@
 
     my $devs = shift;
 
+
     # find the physical volumes we've already recognised as „non-removable“
     my @pvs = grep { $_ ~~ $devs->{known} } map { s/\s*//; (split /:/)[0] } `pvdisplay -c`;
     return @volumegroups = map { (split /:/)[1] } `pvdisplay -c @pvs 2>/dev/null`;
@@ -28,10 +30,12 @@
     # physical devices known to lvm, not just the non-removable
 
     my @vgs = _vgs(%$devs);
-    my @lvs = map { readlink } 
+    run("vgchange -ay @vgs 2>/dev/null");
+
+    my @lvs = 
+	      map { abs_path ((dirname $_) . "/" . readlink) } 
 	      map { s/^\s*//; (split /:/)[0] } 
 	      grep { (split /:/)[1] ~~ @vgs } `lvdisplay -c`;
-
     foreach (@lvs) {
 	$devs->{volume}{$_} = { origin => "lvm" };
     }
--- a/SI/ptable.pm	Mon Jan 18 22:55:10 2010 +0100
+++ b/SI/ptable.pm	Tue Jan 19 14:49:43 2010 +0100
@@ -19,17 +19,18 @@
     # LVs (used as disk itself) too)
     foreach (glob("/sys/block/*")) {
 	    my $name = basename($_);
-	    verbose("device $name");
+	    # verbose("device $name");
 
 	    if (!-e "$_/device") {
-		    verbose("skipping (non-dev)\n");
+		# verbose("skipping (non-dev)\n");
 		    next;
 	    }
 	    if ((grep { /ATTR{removable}/ } `udevadm info --attribute-walk --name $name`)[0] !~ /==.0./) {
-		    verbose("skipping (removable)\n");
+		#   verbose("skipping (removable)\n");
 		    next;
 	    }
 	    verbose("\n");
+	    verbose("device $name\n");
 
 	    die "ERR: /dev/$name does not exist. (should not happen)"
 		if !-e "/dev/$name";
@@ -50,7 +51,7 @@
 
 	    # and let's prepare the volume entries
 	    foreach (@sfdisk) {
-		/^(\S+)\s*:.*Id=\s*(\d+)/ or next;
+		/^(\S+)\s*:.*Id=\s*([[:xdigit:]]+)/ or next;
 		$devs->{volume}{$1} = {
 			origin => "ptable",
 			ptable_type => $2,
--- a/SI/system.pm	Mon Jan 18 22:55:10 2010 +0100
+++ b/SI/system.pm	Tue Jan 19 14:49:43 2010 +0100
@@ -6,14 +6,12 @@
 
 $ENV{LC_ALL} = "C";
 
-sub id($) {
-    my ($file) = @_;
-    open(my $f, ">$file") or die "Can't open $file: $!\n";
-    # hope it's eth*
+sub id() {
+    # hope it's eth* or wlan*
     local $_ = (sort grep { /^(eth|wlan)/ } `ifconfig -a`)[0];
-    return if not $_;
-    return if not /^(?<dev>\S+)\s.*HWaddr\s+(?<mac>[\da-f:]+)\s*$/i;
-    print $f "ethernet $+{dev} $+{mac}\n";
+    /^(?<dev>\S+)\s.*HWaddr\s+(?<mac>[\da-f:]+)\s*$/i
+    	and return $+{mac};
+    die "ERR: Can't get system identification (MAC address)\n";
 }
 
 1;
--- a/SI/tools.pm	Mon Jan 18 22:55:10 2010 +0100
+++ b/SI/tools.pm	Tue Jan 19 14:49:43 2010 +0100
@@ -5,9 +5,10 @@
 use strict;
 use warnings;
 use File::Find;
+use Data::Dumper;
 use base "Exporter";
 
-our @EXPORT = qw(&run &verbose &find_by_devid &cat);
+our @EXPORT = qw(&run &verbose &find_by_devid &cat &barf);
 
 sub run(@) {
 	system(@_);
@@ -15,6 +16,8 @@
 	if $?;
 }
 
+sub barf(@) { die Dumper @_  }
+
 sub cat($) {
     my $fh = new IO::File $_[0] 
 	or die "Can't open $_[0]: $!\n";
--- a/si	Mon Jan 18 22:55:10 2010 +0100
+++ b/si	Tue Jan 19 14:49:43 2010 +0100
@@ -1,5 +1,7 @@
 #! /usr/bin/perl
-# system imager
+# system imager - proof of concept
+# (c) 2010 Heiko Schlittermann <hs@schlittermann.de>
+# see http://keller.schlittermann.de/hg/ius/si
 
 use if $ENV{DEBUG} ~~ /main|all/ => "Smart::Comments";
 
@@ -7,8 +9,10 @@
 use warnings;
 use Data::Dumper;
 use IO::File;
-
 use Sys::Hostname;
+use Getopt::Long;
+use File::Path;
+use File::Basename;
 
 use SI::ptable;
 use SI::blkid;
@@ -17,25 +21,46 @@
 use SI::dumper;
 use SI::system;
 
-MAIN: {
-    my $OUT = "../out-" . hostname;
+my $opt_exit = "";
+my $opt_dir = "";
 
-    unlink(glob("$OUT/*"));
-    -d $OUT or mkdir($OUT, 0700) or die "Can't mkdir $OUT: $!\n";
+MAIN: {
 
-    my %devices;
-
-    SI::system::id("$OUT/system");
+    GetOptions("exit=s" => \$opt_exit,
+    	"dir=s" => \$opt_dir)
+    	or die "Bad usage\n";
 
-    SI::ptable::volumes("$OUT/partitions.%s", %devices);
+    my %devices;	# the overall data collector
+    my $dir;
+    
+    if ($opt_dir ne "") {
+	$dir = $opt_dir;
+    } 
+    else {
+	$dir = dirname($0) . "/../image-" . SI::system::id();
+	rmtree($dir);
+	    -d $dir or mkdir($dir, 0700) or die "Can't mkdir $dir: $!\n";
+    }
+
+    SI::ptable::volumes("$dir/partitions.%s", %devices);
+    die Dumper \%devices if $opt_exit =~ /ptable/;
+
     SI::lvm::volumes(%devices);
-    SI::blkid::ids("$OUT/blkid", %devices);
-    SI::lvm::vgcfgbackup("$OUT/vg.%s", %devices);
-    SI::mbr::save("$OUT/mbr.%s", %devices);
-    SI::dumper::dump("$OUT/dump.%s", %devices);
+    die Dumper \%devices if $opt_exit =~ /lvm::volumes/;
+
+    SI::blkid::ids("$dir/blkid", %devices);
+    die Dumper \%devices if $opt_exit =~ /blkid/;
+
+    SI::lvm::vgcfgbackup("$dir/vg.%s", %devices);
+    die Dumper \%devices if $opt_exit =~ /lvm::vgcfg/;
 
-    my $o = new IO::File ">$OUT/devices"
-	or die "ERR: Can't open $OUT/devices: $!\n";
+    SI::mbr::save("$dir/mbr.%s", %devices);
+    die Dumper \%devices if $opt_exit =~ /mbr/;
+
+    SI::dumper::dump("$dir/dump.%s", %devices);
+
+    my $o = new IO::File ">$dir/devices"
+	or die "ERR: Can't open $dir/devices: $!\n";
     $o->print(Dumper \%devices);