moved the lib parts into a lib/ dir
authorHeiko Schlittermann <hs@schlittermann.de>
Wed, 20 Jan 2010 21:52:01 +0100
changeset 28 7d7ca3f05f25
parent 27 de0a25512844
child 29 4e40cf0eba95
moved the lib parts into a lib/ dir This avoids the naming conflict in a (v)fat file system
SI/.perltidyrc
SI/blkid.pm
SI/dumper.pm
SI/lvm.pm
SI/mbr.pm
SI/ptable.pm
SI/system.pm
SI/tools.pm
lib/SI/.perltidyrc
lib/SI/blkid.pm
lib/SI/dumper.pm
lib/SI/lvm.pm
lib/SI/mbr.pm
lib/SI/ptable.pm
lib/SI/system.pm
lib/SI/tools.pm
si
--- a/SI/.perltidyrc	Wed Jan 20 21:42:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../.perltidyrc
\ No newline at end of file
--- a/SI/blkid.pm	Wed Jan 20 21:42:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-package SI::blkid;
-
-use if $ENV{DEBUG} ~~ /blkid|all/ => "Smart::Comments";
-
-use strict;
-use warnings;
-use IO::File;
-use File::Basename;
-
-use SI::tools;
-
-sub ids($\%) {
-    my ($file, $devs) = @_;
-
-    my @volumes = sort keys %{ $devs->{volume} };
-    verbose("reading blkids: @volumes");
-    foreach (`blkid -c /dev/null @volumes`) {
-        my $dev = (split /:/)[0];
-
-        my ($uuid)  = /\sUUID=.(.*?).\s/;
-        my ($type)  = /\sTYPE=.(.*?).\s/;
-        my ($label) = /\sLABEL=.(.*?).\s/;
-
-        if (exists $devs->{volume}{$dev}) {
-            $devs->{volume}{$dev}{uuid}  = $uuid;
-            $devs->{volume}{$dev}{type}  = $type;
-            $devs->{volume}{$dev}{label} = $label;
-
-            my ($of, $oh);
-            if (defined $uuid) {
-                $of = sprintf $file, "uuid." . basename $dev;
-                $oh = new IO::File ">$of" or die "ERR: Can't open $of: $!\n";
-                $oh->print("$uuid\n");
-            }
-
-            if (defined $label) {
-                $of = sprintf $file, "label." . basename $dev;
-                $oh = new IO::File ">$of" or die "ERR: Can't open $of: $!\n";
-                $oh->print("$label\n");
-            }
-
-            if (defined $type) {
-                $of = sprintf $file, "type." . basename $dev;
-                $oh = new IO::File ">$of" or die "ERR: Can't open $of: $!\n";
-                $oh->print("$type\n");
-            }
-
-        }
-
-    }
-    verbose("\n");
-}
-
-1;
-
-# vim:sts=4 sw=4 aw ai si:
--- a/SI/dumper.pm	Wed Jan 20 21:42:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-package SI::dumper;
-
-use if $ENV{DEBUG} ~~ /dumper|all/ => "Smart::Comments";
-use strict;
-use warnings;
-use SI::tools;
-use File::Basename;
-
-sub dump($\%) {
-    my ($file, $devs) = @_;
-
-    foreach my $volume (
-        map { { name => $_, %{ $devs->{volume}{$_} } } }
-        keys %{ $devs->{volume} }
-      )
-    {
-        next if !defined $volume->{type} or $volume->{type} !~ /^ext/i;
-
-        verbose("dumping volume $volume->{name}");
-        my $dumpdev = $volume->{name};
-        my $of = sprintf $file, basename($volume->{name});
-        run("dump -0 -z -f $of $dumpdev");
-        verbose("\n");
-    }
-}
-
-1;
-
-# vim:sts=4 sw=4 aw ai sm:
--- a/SI/lvm.pm	Wed Jan 20 21:42:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-package SI::lvm;
-
-use if $ENV{DEBUG} ~~ /lvm|all/ => qw(Smart::Comments);
-
-use strict;
-use warnings;
-use IO::File;
-use Cwd qw(abs_path);
-use File::Basename;
-
-use SI::tools;
-
-my @volumegroups = ();
-
-sub _vgs(\%) {
-    return @volumegroups if @volumegroups;
-
-    my $devs = shift;
-
-    # find the physical volumes we've already recognised as „non-removable“
-    my @known = keys %{ $devs->{volume} }, keys %{ $devs->{disk} };
-
-    my @pvs =
-      grep { $_ ~~ @known } map { s/\s*//; (split /:/)[0] } `pvdisplay -c`;
-    @volumegroups = map { (split /:/)[1] } `pvdisplay -c @pvs 2>/dev/null`;
-    run("vgchange -ay @volumegroups 2>&1 >/dev/null");
-
-    # we wait for the /dev/mapper devices to appear
-    run("udevadm settle");
-    return @volumegroups;
-}
-
-sub volumes(\%) {
-    my ($devs) = @_;
-
-    # we can't just use `pvs', since this would return *all*
-    # physical devices known to lvm, not just the non-removable
-
-    my @vgs = _vgs(%$devs);
-    my @lvs =
-      map { abs_path((dirname $_) . "/" . readlink) }
-      map { s/^\s*//; (split /:/)[0] }
-      grep { (split /:/)[1] ~~ @vgs } `lvdisplay -c`;
-    foreach (@lvs) {
-        $devs->{volume}{$_} = { origin => "lvm" };
-    }
-
-    push @{ $devs->{volumes} }, @lvs;
-}
-
-sub vgcfgbackup($\%) {
-    my ($file, $devs) = @_;
-
-    # we save it vg by vg to have the restore more easy
-    my @vgs = _vgs(%$devs);
-    foreach (map { s/^\s*(.*)/$1/; $_ = (split /:/)[0] }
-        `vgs --noheadings --separator : @vgs`)
-    {
-        verbose("saving vg $_\n");
-        my $file = sprintf $file, $_;
-        run("vgcfgbackup -f '$file' '$_' >/dev/null");
-    }
-
-    # for testing let's save it all
-    verbose("saving vg *\n");
-    $file = sprintf $file, "*";
-    run("vgcfgbackup -f '$file' >/dev/null");
-}
-
-1;
-
-# vim:sts=4 sw=4 aw ai si:
--- a/SI/mbr.pm	Wed Jan 20 21:42:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-package SI::mbr;
-
-use strict;
-use warnings;
-use File::Basename;
-use IO::File;
-use if $ENV{DEBUG} ~~ q(mbr) => "Smart::Comments";
-
-use SI::tools;
-
-sub save($\%) {
-    my ($file, $devs) = @_;
-
-    foreach my $disk (keys %{ $devs->{disk} }) {
-        verbose("saving mbr of $disk\n");
-        open((my $o), $_ = sprintf(">$file", basename($disk)))
-          or die "Can't open $_: $!\n";
-
-        local $/ = \512;
-        my $in = new IO::File $disk or die "Can't open $disk: $!\n";
-        print $o $_ = <$in>;
-    }
-}
-
-1;
--- a/SI/ptable.pm	Wed Jan 20 21:42:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-package SI::ptable;
-
-use if $ENV{DEBUG} ~~ /ptable|all/ => qw(Smart::Comments);
-
-use strict;
-use warnings;
-use File::Find;
-use File::Basename;
-use IO::File;
-
-use SI::tools;
-$ENV{LC_ALL} = "C";
-
-sub volumes($\%) {
-    my ($file, $devs) = @_;
-
-    # find the partition tables of all
-    # non-removable block devices (this may include
-    # LVs (used as disk itself) too)
-    foreach (glob("/sys/block/*")) {
-        my $name = basename($_);
-        my $dev  = "/dev/$name";
-
-        next if !-e "$_/device";
-        next
-          if (grep { /ATTR{removable}/ }
-            `udevadm info --attribute-walk --name $name`)[0] !~ /==.0./;
-        next if (stat $dev)[0] == (stat $0)[0];
-
-        # exclude the device (stick) we're part of - this HACK is
-        # only useful on KVM - the usb stick doesn't appear as a removeable
-        # device
-        next
-          if (stat $0)[0] ~~ [
-            map   { (stat)[6] }
-              map { "/dev/" . basename(dirname $_) } glob("$_/*/partition")
-          ];
-
-        verbose("\n");
-        verbose("device $dev\n");
-
-        die "ERR: $dev does not exist. (should not happen): $!"
-          if !-b $dev;
-
-        # now the physical disk -- let's ask for the partition table
-
-        my @sfdisk = `sfdisk -d /dev/$name 2>/dev/null`;
-
-        my $of = sprintf $file, $name;
-        my $oh = new IO::File ">$of" or die "Can't open >$of: $!\n";
-        print $oh @sfdisk;
-
-        $devs->{disk}{"/dev/$name"} = { pt => \@sfdisk };
-
-        # and let's prepare the volume entries
-        foreach (@sfdisk) {
-            /^(\S+)\s*:.*Id=\s*([[:xdigit:]]+)/ or next;
-            $devs->{volume}{$1} = {
-                origin      => "ptable",
-                ptable_type => $2,
-            };
-            push @{ $devs->{volumes} }, $1;
-        }
-    }
-
-    return;
-}
-1;
-
-# vim:sts=4 sw=4 aw ai si:
--- a/SI/system.pm	Wed Jan 20 21:42:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-package SI::system;
-
-use strict;
-use warnings;
-use File::Temp qw(tempdir);
-use if $ENV{DEBUG} ~~ qw(system) => "Smart::Comments";
-use SI::tools;
-
-$ENV{LC_ALL} = "C";
-
-sub id() {
-
-    # hope it's eth* or wlan*
-    local $_ = (sort grep { /^(eth|wlan)/ } `ifconfig -a`)[0];
-    /^(?<dev>\S+)\s.*HWaddr\s+(?<mac>[\da-f:]+)\s*$/i
-      and return $+{mac};
-    die "ERR: Can't get system identification (MAC address)\n";
-}
-
-sub hostname(\%) {
-    my $devs = shift;
-    my $mnt = tempdir(CLEANUP => 1);
-    my $h;
-
-    foreach my $fs (
-        grep {
-            exists $devs->{volume}{$_}{type}
-              and $devs->{volume}{$_}{type} =~ /^ext/i
-        } @{ $devs->{volumes} }
-      )
-    {
-        run("mount -r $fs $mnt");
-        if (-f "$mnt/etc/hostname") {
-            chomp($h = cat("$mnt/etc/hostname"));
-        }
-        run("umount $mnt");
-        return $h if defined $h;
-    }
-
-    return $h;
-}
-
-sub fsck(\%) {
-    my $devs = shift;
-
-    foreach
-      my $v (grep { exists $devs->{volume}{type} } keys %{ $devs->{volume} })
-    {
-        my $volume = $devs->{volume}{$v};
-        next if $volume->{type} !~ /^ext/i;
-
-        system("fsck -C0 $v");
-        die "ERR: fsck failed\n" if $? > 2;
-    }
-}
-
-1;
-
-# vim:sts=4 sw=4 aw ai si:
--- a/SI/tools.pm	Wed Jan 20 21:42:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-package SI::tools;
-
-use if $ENV{DEBUG} ~~ /tools|all/ => "Smart::Comments";
-
-use strict;
-use warnings;
-use File::Find;
-use Data::Dumper;
-use base "Exporter";
-
-our @EXPORT = qw(&run &verbose &find_by_devid &cat &barf);
-
-sub run(@) {
-    system(@_);
-    die "$_[0] failed with exit code " . ($? >> 8) . "\n"
-      if $?;
-}
-
-sub barf(@) { die Dumper @_ }
-
-sub cat($) {
-    my $fh = new IO::File $_[0]
-      or die "Can't open $_[0]: $!\n";
-    return (<$fh>) if wantarray;
-    return join "", <$fh>;
-}
-
-my $last = "\n";
-
-sub verbose(@) {
-    print $last eq "\n" ? "" : " "
-      if not(@_ == 1 and length($_[0]) == 1);
-    print @_;
-    $last = substr($_[-1], -1, 1);
-}
-
-sub find_by_devid($$) {
-    my ($dir, $id) = @_;
-    my @found;
-    find(
-        sub {
-            push @found, $File::Find::name if (stat)[6] == $id;
-            return;
-        },
-        $dir
-    );
-    die "ERR: found more than one alias (@found) for $id\n" if @found > 1;
-    die "ERR: found no alias for $id\n" if not @found;
-    return $found[0];
-}
-
-1;
-
-# vim:sts=4 sw=4 aw ai si:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/SI/.perltidyrc	Wed Jan 20 21:52:01 2010 +0100
@@ -0,0 +1,1 @@
+../.perltidyrc
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/SI/blkid.pm	Wed Jan 20 21:52:01 2010 +0100
@@ -0,0 +1,56 @@
+package SI::blkid;
+
+use if $ENV{DEBUG} ~~ /blkid|all/ => "Smart::Comments";
+
+use strict;
+use warnings;
+use IO::File;
+use File::Basename;
+
+use SI::tools;
+
+sub ids($\%) {
+    my ($file, $devs) = @_;
+
+    my @volumes = sort keys %{ $devs->{volume} };
+    verbose("reading blkids: @volumes");
+    foreach (`blkid -c /dev/null @volumes`) {
+        my $dev = (split /:/)[0];
+
+        my ($uuid)  = /\sUUID=.(.*?).\s/;
+        my ($type)  = /\sTYPE=.(.*?).\s/;
+        my ($label) = /\sLABEL=.(.*?).\s/;
+
+        if (exists $devs->{volume}{$dev}) {
+            $devs->{volume}{$dev}{uuid}  = $uuid;
+            $devs->{volume}{$dev}{type}  = $type;
+            $devs->{volume}{$dev}{label} = $label;
+
+            my ($of, $oh);
+            if (defined $uuid) {
+                $of = sprintf $file, "uuid." . basename $dev;
+                $oh = new IO::File ">$of" or die "ERR: Can't open $of: $!\n";
+                $oh->print("$uuid\n");
+            }
+
+            if (defined $label) {
+                $of = sprintf $file, "label." . basename $dev;
+                $oh = new IO::File ">$of" or die "ERR: Can't open $of: $!\n";
+                $oh->print("$label\n");
+            }
+
+            if (defined $type) {
+                $of = sprintf $file, "type." . basename $dev;
+                $oh = new IO::File ">$of" or die "ERR: Can't open $of: $!\n";
+                $oh->print("$type\n");
+            }
+
+        }
+
+    }
+    verbose("\n");
+}
+
+1;
+
+# vim:sts=4 sw=4 aw ai si:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/SI/dumper.pm	Wed Jan 20 21:52:01 2010 +0100
@@ -0,0 +1,29 @@
+package SI::dumper;
+
+use if $ENV{DEBUG} ~~ /dumper|all/ => "Smart::Comments";
+use strict;
+use warnings;
+use SI::tools;
+use File::Basename;
+
+sub dump($\%) {
+    my ($file, $devs) = @_;
+
+    foreach my $volume (
+        map { { name => $_, %{ $devs->{volume}{$_} } } }
+        keys %{ $devs->{volume} }
+      )
+    {
+        next if !defined $volume->{type} or $volume->{type} !~ /^ext/i;
+
+        verbose("dumping volume $volume->{name}");
+        my $dumpdev = $volume->{name};
+        my $of = sprintf $file, basename($volume->{name});
+        run("dump -0 -z -f $of $dumpdev");
+        verbose("\n");
+    }
+}
+
+1;
+
+# vim:sts=4 sw=4 aw ai sm:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/SI/lvm.pm	Wed Jan 20 21:52:01 2010 +0100
@@ -0,0 +1,72 @@
+package SI::lvm;
+
+use if $ENV{DEBUG} ~~ /lvm|all/ => qw(Smart::Comments);
+
+use strict;
+use warnings;
+use IO::File;
+use Cwd qw(abs_path);
+use File::Basename;
+
+use SI::tools;
+
+my @volumegroups = ();
+
+sub _vgs(\%) {
+    return @volumegroups if @volumegroups;
+
+    my $devs = shift;
+
+    # find the physical volumes we've already recognised as „non-removable“
+    my @known = keys %{ $devs->{volume} }, keys %{ $devs->{disk} };
+
+    my @pvs =
+      grep { $_ ~~ @known } map { s/\s*//; (split /:/)[0] } `pvdisplay -c`;
+    @volumegroups = map { (split /:/)[1] } `pvdisplay -c @pvs 2>/dev/null`;
+    run("vgchange -ay @volumegroups 2>&1 >/dev/null");
+
+    # we wait for the /dev/mapper devices to appear
+    run("udevadm settle");
+    return @volumegroups;
+}
+
+sub volumes(\%) {
+    my ($devs) = @_;
+
+    # we can't just use `pvs', since this would return *all*
+    # physical devices known to lvm, not just the non-removable
+
+    my @vgs = _vgs(%$devs);
+    my @lvs =
+      map { abs_path((dirname $_) . "/" . readlink) }
+      map { s/^\s*//; (split /:/)[0] }
+      grep { (split /:/)[1] ~~ @vgs } `lvdisplay -c`;
+    foreach (@lvs) {
+        $devs->{volume}{$_} = { origin => "lvm" };
+    }
+
+    push @{ $devs->{volumes} }, @lvs;
+}
+
+sub vgcfgbackup($\%) {
+    my ($file, $devs) = @_;
+
+    # we save it vg by vg to have the restore more easy
+    my @vgs = _vgs(%$devs);
+    foreach (map { s/^\s*(.*)/$1/; $_ = (split /:/)[0] }
+        `vgs --noheadings --separator : @vgs`)
+    {
+        verbose("saving vg $_\n");
+        my $file = sprintf $file, $_;
+        run("vgcfgbackup -f '$file' '$_' >/dev/null");
+    }
+
+    # for testing let's save it all
+    verbose("saving vg *\n");
+    $file = sprintf $file, "*";
+    run("vgcfgbackup -f '$file' >/dev/null");
+}
+
+1;
+
+# vim:sts=4 sw=4 aw ai si:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/SI/mbr.pm	Wed Jan 20 21:52:01 2010 +0100
@@ -0,0 +1,25 @@
+package SI::mbr;
+
+use strict;
+use warnings;
+use File::Basename;
+use IO::File;
+use if $ENV{DEBUG} ~~ q(mbr) => "Smart::Comments";
+
+use SI::tools;
+
+sub save($\%) {
+    my ($file, $devs) = @_;
+
+    foreach my $disk (keys %{ $devs->{disk} }) {
+        verbose("saving mbr of $disk\n");
+        open((my $o), $_ = sprintf(">$file", basename($disk)))
+          or die "Can't open $_: $!\n";
+
+        local $/ = \512;
+        my $in = new IO::File $disk or die "Can't open $disk: $!\n";
+        print $o $_ = <$in>;
+    }
+}
+
+1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/SI/ptable.pm	Wed Jan 20 21:52:01 2010 +0100
@@ -0,0 +1,70 @@
+package SI::ptable;
+
+use if $ENV{DEBUG} ~~ /ptable|all/ => qw(Smart::Comments);
+
+use strict;
+use warnings;
+use File::Find;
+use File::Basename;
+use IO::File;
+
+use SI::tools;
+$ENV{LC_ALL} = "C";
+
+sub volumes($\%) {
+    my ($file, $devs) = @_;
+
+    # find the partition tables of all
+    # non-removable block devices (this may include
+    # LVs (used as disk itself) too)
+    foreach (glob("/sys/block/*")) {
+        my $name = basename($_);
+        my $dev  = "/dev/$name";
+
+        next if !-e "$_/device";
+        next
+          if (grep { /ATTR{removable}/ }
+            `udevadm info --attribute-walk --name $name`)[0] !~ /==.0./;
+        next if (stat $dev)[0] == (stat $0)[0];
+
+        # exclude the device (stick) we're part of - this HACK is
+        # only useful on KVM - the usb stick doesn't appear as a removeable
+        # device
+        next
+          if (stat $0)[0] ~~ [
+            map   { (stat)[6] }
+              map { "/dev/" . basename(dirname $_) } glob("$_/*/partition")
+          ];
+
+        verbose("\n");
+        verbose("device $dev\n");
+
+        die "ERR: $dev does not exist. (should not happen): $!"
+          if !-b $dev;
+
+        # now the physical disk -- let's ask for the partition table
+
+        my @sfdisk = `sfdisk -d /dev/$name 2>/dev/null`;
+
+        my $of = sprintf $file, $name;
+        my $oh = new IO::File ">$of" or die "Can't open >$of: $!\n";
+        print $oh @sfdisk;
+
+        $devs->{disk}{"/dev/$name"} = { pt => \@sfdisk };
+
+        # and let's prepare the volume entries
+        foreach (@sfdisk) {
+            /^(\S+)\s*:.*Id=\s*([[:xdigit:]]+)/ or next;
+            $devs->{volume}{$1} = {
+                origin      => "ptable",
+                ptable_type => $2,
+            };
+            push @{ $devs->{volumes} }, $1;
+        }
+    }
+
+    return;
+}
+1;
+
+# vim:sts=4 sw=4 aw ai si:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/SI/system.pm	Wed Jan 20 21:52:01 2010 +0100
@@ -0,0 +1,59 @@
+package SI::system;
+
+use strict;
+use warnings;
+use File::Temp qw(tempdir);
+use if $ENV{DEBUG} ~~ qw(system) => "Smart::Comments";
+use SI::tools;
+
+$ENV{LC_ALL} = "C";
+
+sub id() {
+
+    # hope it's eth* or wlan*
+    local $_ = (sort grep { /^(eth|wlan)/ } `ifconfig -a`)[0];
+    /^(?<dev>\S+)\s.*HWaddr\s+(?<mac>[\da-f:]+)\s*$/i
+      and return $+{mac};
+    die "ERR: Can't get system identification (MAC address)\n";
+}
+
+sub hostname(\%) {
+    my $devs = shift;
+    my $mnt = tempdir(CLEANUP => 1);
+    my $h;
+
+    foreach my $fs (
+        grep {
+            exists $devs->{volume}{$_}{type}
+              and $devs->{volume}{$_}{type} =~ /^ext/i
+        } @{ $devs->{volumes} }
+      )
+    {
+        run("mount -r $fs $mnt");
+        if (-f "$mnt/etc/hostname") {
+            chomp($h = cat("$mnt/etc/hostname"));
+        }
+        run("umount $mnt");
+        return $h if defined $h;
+    }
+
+    return $h;
+}
+
+sub fsck(\%) {
+    my $devs = shift;
+
+    foreach
+      my $v (grep { exists $devs->{volume}{type} } keys %{ $devs->{volume} })
+    {
+        my $volume = $devs->{volume}{$v};
+        next if $volume->{type} !~ /^ext/i;
+
+        system("fsck -C0 $v");
+        die "ERR: fsck failed\n" if $? > 2;
+    }
+}
+
+1;
+
+# vim:sts=4 sw=4 aw ai si:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/SI/tools.pm	Wed Jan 20 21:52:01 2010 +0100
@@ -0,0 +1,54 @@
+package SI::tools;
+
+use if $ENV{DEBUG} ~~ /tools|all/ => "Smart::Comments";
+
+use strict;
+use warnings;
+use File::Find;
+use Data::Dumper;
+use base "Exporter";
+
+our @EXPORT = qw(&run &verbose &find_by_devid &cat &barf);
+
+sub run(@) {
+    system(@_);
+    die "$_[0] failed with exit code " . ($? >> 8) . "\n"
+      if $?;
+}
+
+sub barf(@) { die Dumper @_ }
+
+sub cat($) {
+    my $fh = new IO::File $_[0]
+      or die "Can't open $_[0]: $!\n";
+    return (<$fh>) if wantarray;
+    return join "", <$fh>;
+}
+
+my $last = "\n";
+
+sub verbose(@) {
+    print $last eq "\n" ? "" : " "
+      if not(@_ == 1 and length($_[0]) == 1);
+    print @_;
+    $last = substr($_[-1], -1, 1);
+}
+
+sub find_by_devid($$) {
+    my ($dir, $id) = @_;
+    my @found;
+    find(
+        sub {
+            push @found, $File::Find::name if (stat)[6] == $id;
+            return;
+        },
+        $dir
+    );
+    die "ERR: found more than one alias (@found) for $id\n" if @found > 1;
+    die "ERR: found no alias for $id\n" if not @found;
+    return $found[0];
+}
+
+1;
+
+# vim:sts=4 sw=4 aw ai si:
--- a/si	Wed Jan 20 21:42:28 2010 +0100
+++ b/si	Wed Jan 20 21:52:01 2010 +0100
@@ -11,9 +11,10 @@
 use IO::File;
 use Sys::Hostname;
 use Getopt::Long;
-use File::Path qw(make_path remove_tree);
+use File::Path;
 use File::Basename;
 
+use lib "lib";
 use SI::ptable;
 use SI::blkid;
 use SI::lvm;
@@ -44,10 +45,11 @@
     }
     else {
         $dir = dirname($0) . "/../image-$id{mac}";
-        remove_tree($dir);
+        rmtree($dir);
         -d $dir or mkdir($dir, 0700) or die "Can't mkdir $dir: $!\n";
     }
-    make_path(map { "$dir/$_" } qw(info ptable lvm blkid mbr dump));
+
+    mkpath(map { "$dir/$_" } qw(info ptable lvm blkid mbr dump));
 
     SI::ptable::volumes("$dir/ptable/%s", %devices);
     die Dumper \%devices if $opt_exit =~ /ptable/;