AFS-Command

 view release on metacpan or  search on metacpan

lib/AFS/Command/VOS.pm  view on Meta::CPAN


use AFS::Command::Base;
use AFS::Object;
use AFS::Object::VLDB;
use AFS::Object::VLDBEntry;
use AFS::Object::VLDBSite;
use AFS::Object::Volume;
use AFS::Object::VolumeHeader;
use AFS::Object::VolServer;
use AFS::Object::FileServer;
use AFS::Object::Partition;
use AFS::Object::Transaction;

our @ISA = qw(AFS::Command::Base);
our $VERSION = '1.99';

sub examine {

    my $self = shift;
    my (%args) = @_;

    my $result = AFS::Object::Volume->new();
    my $entry = AFS::Object::VLDBEntry->new( locked => 0 );

    $self->{operation} = "examine";

    return unless $self->_parse_arguments(%args);

    return unless $self->_save_stderr();

    my $errors = 0;

    $errors++ unless $self->_exec_cmds();

    while ( defined($_ = $self->{handle}->getline()) ) {

	chomp;

	#
	# These two lines are part of the verbose output
	#
	next if /Fetching VLDB entry/;
	next if /Getting volume listing/;

	#
	# This code parses the volume header information.  If we match
	# this line, then we go after the information we expect to be
	# right after it.  We also test for this first, because we
	# might very well have several of these chunks of data for RO
	# volumes.
	#
	if ( /^\*{4}/ ) {

	    my $header = AFS::Object::VolumeHeader->new();

	    if ( /Volume (\d+) is busy/ ) {
		$header->_setAttribute
		  (
		   id			=> $1,
		   status		=> 'busy',
		   attached		=> 1,
		  );
	    } elsif ( /Could not attach volume (\d+)/ ) {
		$header->_setAttribute
		  (
		   id			=> $1,
		   status		=> 'offline',
		   attached		=> 0,
		  );
	    }

	    $result->_addVolumeHeader($header);

	    next;

	} elsif ( /^(\S+)\s+(\d+)\s+(RW|RO|BK)\s+(\d+)\s+K/ ) {

	    my $header = AFS::Object::VolumeHeader->new();

	    if ( /^(\S+)\s+(\d+)\s+(RW|RO|BK)\s+(\d+)\s+K\s+([\w-]+)/ ) {

		$header->_setAttribute
		  (
		   name			=> $1,
		   id 			=> $2,
		   type 		=> $3,
		   size 		=> $4,
		  );
		$header->_setAttribute( rwrite	=> $2 ) if $3 eq 'RW';
		$header->_setAttribute( ronly	=> $2 ) if $3 eq 'RO';
		$header->_setAttribute( backup	=> $2 ) if $3 eq 'BK';

		my $status = $5;
		$status = 'offline' if $status eq 'Off-line';
		$status = 'online' if $status eq 'On-line';
		$header->_setAttribute
		  (
		   status 		=> $status,
		   attached		=> 1,
		  );

	    } elsif ( /^(\S+)\s+(\d+)\s+(RW|RO|BK)\s+(\d+)\s+K\s+used\s+(\d+)\s+files\s+([\w-]+)/ ) {

		$header->_setAttribute
		  (
		   name			=> $1,
		   id			=> $2,
		   type 		=> $3,
		   size 		=> $4,
		   files 		=> $5,
		  );
		$header->_setAttribute( rwrite	=> $2 ) if $3 eq 'RW';
		$header->_setAttribute( ronly	=> $2 ) if $3 eq 'RO';
		$header->_setAttribute( backup	=> $2 ) if $3 eq 'BK';

		my $status = $6;
		$status = 'offline' if $status eq 'Off-line';
		$status = 'online' if $status eq 'On-line';
		$header->_setAttribute
		  (
		   status 		=> $status,
		   attached		=> 1,
		  );

	    } else {

		$self->_Carp("Unable to parse volume header: '$_'");

	    }

	    #
	    # We are interested in the next 6 lines as they are also
	    # from the same volume headers as the one we just matched.
	    # Suck data until we get to a blank line.
	    #
	    while ( defined($_ = $self->{handle}->getline()) ) {

		chomp;

		last if /^\s*$/; # Stop when we hit the blank line

		if ( m:^\s+(\S+)\s+(/vicep\w+)\s*$: ) {
		    $header->_setAttribute
		      (
		       server		=> $1,
		       partition	=> $2,
		      );
		    next;
		}

		#
		# Next we get ALL the volume IDs we can off this next
		# line.
		#
		# Q: Do we want to check that the id already found
		# matches one of these??  Not yet...
		#
		if ( /^\s+RWrite\s+(\d+)\s+ROnly\s+(\d+)\s+Backup\s+(\d+)/ ) {

		    $header->_setAttribute
		      (
		       rwrite		=> $1,
		       ronly		=> $2,
		       backup		=> $3,
		      );

		    if ( /RClone\s+(\d+)/ ) {
			$header->_setAttribute( rclone	=> $1 );
		    }
		    next;

		}

		if ( /^\s+MaxQuota\s+(\d+)/ ) {
		    $header->_setAttribute( maxquota	=> $1 );
		    next;
		}

		if ( /^\s+Creation\s+(.*)\s*$/ ) {
		    $header->_setAttribute( creation	=> $1 );
		    next;
		}

lib/AFS/Command/VOS.pm  view on Meta::CPAN

sub listvol {

    my $self = shift;
    my (%args) = @_;

    my $result = AFS::Object::VolServer->new();

    $self->{operation} = "listvol";

    return unless $self->_parse_arguments(%args);

    return unless $self->_save_stderr();

    my $errors = 0;

    $errors++ unless $self->_exec_cmds();

    if ( delete $args{extended} ) {
	$self->_Carp("vos listvol: -extended is not supported by this version of the API");
    }

    while ( defined($_ = $self->{handle}->getline()) ) {

	chomp;

	next if /^\s*$/;	# Blank lines are not interesting

	next unless /^Total number of volumes on server \S+ partition (\/vice[\w]+): (\d+)/;

	my $partition = AFS::Object::Partition->new
	  (
	   partition			=> $1,
	   total			=> $2,
	  );

	while ( defined($_ = $self->{handle}->getline()) ) {

	    chomp;

	    last if /^\s*$/ && $args{fast};

	    next if /^\s*$/;

	    s/\s+$//;

	    if ( /^Total volumes onLine (\d+) ; Total volumes offLine (\d+) ; Total busy (\d+)/ ) {
		$partition->_setAttribute
		  (
		   online		=> $1,
		   offline		=> $2,
		   busy			=> $3,
		  );
		last;		# Done with this partition
	    }

	    if ( /Volume (\d+) is busy/ ) {
		my $volume = AFS::Object::VolumeHeader->new
		  (
		   id			=> $1,
		   status		=> 'busy',
		   attached		=> 1,
		  );
		$partition->_addVolumeHeader($volume);
		next;
	    } elsif ( /Could not attach volume (\d+)/ ) {
		my $volume = AFS::Object::VolumeHeader->new
		  (
		   id			=> $1,
		   status		=> 'offline',
		   attached		=> 0,
		  );
		$partition->_addVolumeHeader($volume);
		next;
	    }

	    #
	    # We have to handle multiple formats here.  For
	    # now, just parse the "fast" and normal output.
	    # Extended is not yet supported.
	    #

	    my (@array) = split;
	    my ($name,$id,$type,$size,$status) = ();

	    my $volume = AFS::Object::VolumeHeader->new();

	    if ( @array == 6 ) {
		($name,$id,$type,$size,$status) = @array[0..3,5];
		$status = 'offline' if $status eq 'Off-line';
		$status = 'online' if $status eq 'On-line';
		$volume->_setAttribute
		  (
		   id			=> $id,
		   name			=> $name,
		   type			=> $type,
		   size			=> $size,
		   status		=> $status,
		   attached		=> 1,
		  );
	    } elsif ( @array == 1 ) {
		$volume->_setAttribute
		  (
		   id			=> $_,
		   status		=> 'online',
		   attached		=> 1,
		  );
	    } else {
		$self->_Carp("Unable to parse header summary line:\n" . $_);
		$errors++;
		next;
	    }

	    #
	    # If the output is long, then we have some more
	    # interesting information to parse.  See vos/examine.pl
	    # for notes.  This code was stolen from there...
	    #

	    if ( $args{long} || $args{extended} ) {

		while ( defined($_ = $self->{handle}->getline()) ) {

		    last if /^\s*$/;

		    if ( /^\s+RWrite\s+(\d+)\s+ROnly\s+(\d+)\s+Backup\s+(\d+)/ ) {
			$volume->_setAttribute
			  (
			   rwrite		=> $1,
			   ronly		=> $2,
			   backup		=> $3,
			  );
			if ( /RClone\s+(\d+)/ ) {
			    $volume->_setAttribute( rclone => $1 );
			}
			next;
		    }

		    if ( /^\s+MaxQuota\s+(\d+)/ ) {
			$volume->_setAttribute( maxquota => $1 );
			next;
		    }

		    if ( /^\s+Creation\s+(.*)\s*$/ ) {
			$volume->_setAttribute( creation => $1 );
			next;
		    }

		if ( /^\s+Copy\s+(.*)\s*$/ ) {
		    $volume->_setAttribute( copyTime	=> $1 );
		    next;
		}

		if ( /^\s+Backup\s+(.*)\s*$/ ) {
		    $volume->_setAttribute( backupTime	=> $1 );
		    next;
		}

		if ( /^\s+Last Access\s+(.*)\s*$/ ) {
		    $volume->_setAttribute( access	=> $1 );
		    next;
		}

		    if ( /^\s+Last Update\s+(.*)\s*$/ ) {
			$volume->_setAttribute( update => $1 );
			next;

lib/AFS/Command/VOS.pm  view on Meta::CPAN


    return if $errors;
    return $result;

}

sub status {

    my $self = shift;
    my (%args) = @_;

    my $result = AFS::Object::VolServer->new();

    $self->{operation} = "status";

    return unless $self->_parse_arguments(%args);

    return unless $self->_save_stderr();

    my $errors = 0;

    $errors++ unless $self->_exec_cmds();

    my $transaction = undef;

    while ( defined($_ = $self->{handle}->getline()) ) {

	chomp;

	if ( /No active transactions/ ) {
	    $result->_setAttribute( transactions => 0 );
	    last;
	}

	if ( /Total transactions: (\d+)/ ) {
	    $result->_setAttribute( transactions => $1 );
	    next;
	}

	if ( /^-+\s*$/ ) {

	    if ( $transaction ) {
		$result->_addTransaction($transaction);
		$transaction = undef;
	    } else {
		$transaction = AFS::Object::Transaction->new();
	    }

	}

	next unless $transaction;

	if ( /transaction:\s+(\d+)/ ) {
	    $transaction->_setAttribute( transaction => $1 );
	}

	if ( /created:\s+(.*)$/ ) {
	    $transaction->_setAttribute( created => $1 );
	}

	if ( /attachFlags:\s+(.*)$/ ) {
	    $transaction->_setAttribute( attachFlags => $1 );
	}

	if ( /volume:\s+(\d+)/ ) {
	    $transaction->_setAttribute( volume => $1 );
	}

	if ( /partition:\s+(\S+)/ ) {
	    $transaction->_setAttribute( partition => $1 );
	}

	if ( /procedure:\s+(\S+)/ ) {
	    $transaction->_setAttribute( procedure => $1 );
	}

	if ( /packetRead:\s+(\d+)/ ) {
	    $transaction->_setAttribute( packetRead => $1 );
	}

	if ( /lastReceiveTime:\s+(\d+)/ ) {
	    $transaction->_setAttribute( lastReceiveTime => $1 );
	}

	if ( /packetSend:\s+(\d+)/ ) {
	    $transaction->_setAttribute( packetSend => $1 );
	}

	if ( /lastSendTime:\s+(\d+)/ ) {
	    $transaction->_setAttribute( lastSendTime => $1 );
	}

    }

    $errors++ unless $self->_reap_cmds();

    $errors++ unless $self->_restore_stderr();

    return if $errors;
    return $result;

}

sub dump {

    my $self = shift;
    my (%args) = @_;

    $self->{operation} = 'dump';

    my $file = delete $args{file} || do {
	$self->_Carp("Missing required argument: 'file'");
	return;
    };

    my $gzip_default = 6;
    my $bzip2_default = 6;

    my $nocompress = delete $args{nocompress} || undef;
    my $gzip = delete $args{gzip} || undef;
    my $bzip2 = delete $args{bzip2} || undef;
    my $filterout = delete $args{filterout} || undef;



( run in 1.113 second using v1.01-cache-2.11-cpan-e1769b4cff6 )