lib/BlockDev.pm
changeset 5 28392c81e909
parent 3 7e8df0715112
equal deleted inserted replaced
1:d2562d0417a9 5:28392c81e909
     1 package BlockDev;
     1 package BlockDev;
     2 
     2 
     3 use 5.010;
     3 use 5.010;
     4 use strict;
     4 use Moose;
     5 use warnings;
     5 use POSIX;
     6 use Attribute::Params::Validate qw(:all);
     6 use autodie qw(:all);
       
     7 use Cwd qw(abs_path);
     7 
     8 
     8 our $VERSION = "0.0";
     9 our $VERSION = "0.0";
     9 
    10 
    10 my %X;
    11 # extend the PATH with *sbin* if not there already
       
    12 foreach my $p (qw(/sbin /usr/sbin /usr/local/sbin)) {
       
    13     $p ~~ [split(/:/ => $ENV{PATH})]
       
    14 	or $ENV{PATH} = "$p:$ENV{PATH}";
       
    15 }
       
    16 
       
    17 has dev => (is => "ro", isa => "Str");
    11 
    18 
    12 sub list {
    19 sub list {
    13     open(my $fh => "/proc/partitions");
    20     open(my $fh => "/proc/partitions");
    14     return map { (split)[3] } grep /^\s*\d+/ => <$fh>;
    21     return map { (split)[3] } grep /^\s*\d+/ => <$fh>;
    15 }
    22 }
       
    23 
       
    24 # process the arguments before actually calling the
       
    25 # constructor
       
    26 
       
    27 sub BUILDARGS {
       
    28     my $class = shift;
       
    29     my ($key, $value) = @_;
       
    30 
       
    31     given ($key) {
       
    32         when ("dev") {
       
    33 	    $value = "/dev/$value" if $value !~ /^\// and not -e $value and -b "/dev/$value";
       
    34             -b $value or die "no blockdevice `$value'";
       
    35             return { dev => $value };
       
    36         }
       
    37         when ("dir") {
       
    38             -d $value or die "`$value' is not a directory";
       
    39             `df --portability '$value'` =~ /^(?<dev>\/\S+).*?(?<mp>\S+)$/m;
       
    40             die "$value does not have a real file system"
       
    41               if not $+{dev};
       
    42             return { dev => $+{dev} };
       
    43         }
       
    44         when (/^m(?:ount)?p(?:oint)?$/) {
       
    45             -d $value or die "`$value` is not a directory";
       
    46             open(my $mounts => "/proc/mounts");
       
    47             join("" => <$mounts>) =~ /^(?<dev>\S+)\s$value\s/m
       
    48               or die "$value is not a mountpoint";
       
    49             return { dev => $+{dev} };
       
    50         }
       
    51 	when ("uuid") {
       
    52 	    chomp(my $dev = `blkid -c /dev/null -U '$value'`);
       
    53 	    die "'$value' does not exist as UUID" if not $dev;
       
    54 	    return { dev => $dev }
       
    55 	}
       
    56 	when ("label") {
       
    57 	    chomp(my $dev = `blkid -c /dev/null -L '$value'`);
       
    58 	    die "'$value' does not exist as label" if not $dev;
       
    59 	    return { dev => $dev }
       
    60 	}
       
    61         default { die "unknown initialization" }
       
    62     }
       
    63 }
       
    64 
       
    65 sub path  { abs_path shift->dev }
       
    66 sub major { (stat shift->dev)[6] >> 8 }
       
    67 sub minor { (stat shift->dev)[6] & 0xff }
       
    68 sub size  {
       
    69     my $self = shift;
       
    70     open(my $fh => $self->path);
       
    71     seek($fh, 0, SEEK_END);
       
    72     return tell($fh);
       
    73 }
       
    74 
       
    75 
       
    76 1;
       
    77 __END__
    16 
    78 
    17 sub new : Validate(uuid => 0, dev => 0) : method {
    79 sub new : Validate(uuid => 0, dev => 0) : method {
    18     my $class = shift;
    80     my $class = shift;
    19     my $self = bless \my $x => $class;
    81     my $self = bless \my $x => $class;
    20     my %arg = @_;
    82     my %arg = @_;
    47 sub dev {
   109 sub dev {
    48     my $self = shift;
   110     my $self = shift;
    49     return $X{$self}{dev} if exists $X{$self}{dev};
   111     return $X{$self}{dev} if exists $X{$self}{dev};
    50 }
   112 }
    51 
   113 
    52 sub DESTROY {
       
    53     my $self = shift;
       
    54     delete $X{$self};
       
    55 }
       
    56 
       
    57 1;
   114 1;
    58 
   115 
    59 __END__
   116 __END__
    60 
   117 
    61 =head1 NAME
   118 =head1 NAME