view release on metacpan or search on metacpan
# visible to the fs setacl command. Therefore, we need the name of an
# existing pts user or group to use for that test.
#
# Yes, I promise the tests will NOT remove this one, 'cause I did
# all the tests using my own ID. ;-)
#
AFS_COMMAND_PTS_EXISTING = wpm
#
# If you don't have either gzip/gunzip, of bzip2/bunzip2, then comment
# the appropriate line to disable the tests using these compression
# utilities. Then, go download the source and compile them, because
# you shouldn't be without something so basic.
#
AFS_COMMAND_GZIP_ENABLED = 1
AFS_COMMAND_BZIP2_ENABLED = 1
#
# Change this, if you want to scribble temporary files elsewhere. You
# probably don't...
#
AFS_COMMAND_TMP_ROOT = /var/tmp
#
# This parameter is used to test the output filter mechanism for vos
# dump and restore. Obviously, 'cat' is very boring, but we just need
# something in the pipeline that reads from stdin and writes to
# stdout, and it can't break the volume dump format that passes
# through it.
#
# Tweak this at your own peril.
#
AFS_COMMAND_DUMP_FILTER = cat
AFS_COMMAND_RESTORE_FILTER = cat
#
#
=head1 CHanges in 1.9
=head1 Enhancements
A new argument is supported by AFS::Command::Base->new():
my $vos = AFS::Command::VOS->new( timestamps => 1 );
This will result in ISO timestamps being prepended to each line of
output when it is collected into the $vos->errors(). This is useful
for profiling the performance of operations such as vos release:
my $result = $vos->release
(
id => 'somevol',
cell => 'somecell',
) || die $vos->errors();
When this works, the $vos->errors() will have the verbose output,
which can be logged even in the successful case, for diagnostics.
Here's an example for a failure:
[2004-11-18 17:20:36] Could not lock the VLDB entry for the volume 536998569.
[2004-11-18 17:20:36] Error in vos release command.
[2004-11-18 17:20:36] VLDB: no permission access for call
=head1 Changes in 1.8
=head1 Bug Fixes
=head2 vos examine did not pick up the LOCKED flag
The code to parse the VLDB header was missing the LOCKED flag, if it
was present, so this attribute was not being set properly. It is now.
=head2 pts membership error checking was bogus
Well, it still is bogus, actually, since the code has to deal with the
fact that pts has never produced meaningful return codes, so a failed
pts membership command can still exit 0, and we have to figure out if
it failed by other means. This is done by looking for the known error
messages that pts prints out, which is a good example of why parsing
the ASCII test output of commands like this is a weak architecture.
=head1 Changes in 1.7
=head1 Enhancements
=head2 Boolean flags can be turned off, as well as on
If an argument to a method (and its corresponding command line
argument) doesn't take a value, it is treated like a Boolean flag.
However, the code used to assume that the existence of a Boolean key
in the argument list implied the Boolean argument was always true.
Now, the truth of the arguments I<value> is tested to determine if the
flag should be set on or off. This makes it easy to have subroutines
that just blindly pass certain arguments along, without haing to test
them, and allows for much cleaner code.
For example:
my $result = $vos->release
(
name => $name,
force => $force,
);
Will work as you probably expected it to, namely if $force is zero, it
will NOT be passed to the "vos release" command. In previous
releases, regardless of the value of $force, the mere existence of the
force key in the argument hash would have caused the -force option to
be used.
When a volume's status is "offline", there is really more than one
status the volume can be in. A volume might be unattached, and
offline, or it might be attached, but adminitratively offline. For
example, "vos offline" put a vlume in the latter state, and if for
some reason there are two volumes with the same ID on the same
fileserver, they will both be attached (if possible), but only the
first one encountered will be brought online.
Changing the value of status would been a non-backwards compatible
change, and caused some subtle problems for some applications. Rather
than introduce such a change, I have chosen to represent this state
with an additional attribute "attached", which is just a Boolean,
indicating whether or not the volume is attached.
=head1 Bugs
=head1 Changes in 1.5
=head1 Enhancements
=head2 Principal names, as user supplied arguments, are lowercased
As a convenience, when PTS names are passed to methods like
getUserByName(), they will be lower-cased before looking up the user,
or group. Since PTS is a case-insensitive database, this will avoid
the need for applications to lc() some strings, although not in all
cases.
For example, you can pass a mixed case string to pts->creategroup(),
and then use the same string to query the resulting AFS::Object::Group
object using getGroupByName().
The object's "group" attribute, however, will be in lower case, since
that will be the value returned by the pts command itself.
=head2 AFS::Command::VOS->restore arguments added
Documentation for two important new vos restore arguments was added to
the documentation (-creation and -lastupdate). These options are only
available in a patch to vos, which should be in one the next two major
OpenAFS 1.2.X releases.
=head1 Bugs
=head2 AFS::Object::VolumeHeader 'accesses' attribute was incorrect
The actual attribute on the objects was named "access". Oops. The
attribute was changed to "accesses" to match the documentation, and
the string that is parsed in vos output.
=head1 Changes in 1.4
=head1 Enhancements
=head2 Test suite is disabled by default.
There is a well intentioned effort to automatically test all new
submissions to CPAN (see http://testers.cpan.org). Unfortunately, the
AFS-Command package can't be tested automatically, since it requires a
fair amount of configuration. You have to specify a cell name, some
fileserver names and partitions, etc.
By default, the tests will all be skipped if the configured cell name
in the CONFIG file has not been modified, thus allowing the automated
CPAN testing to continue, automatically, without the author getting a
bunch of bogus emails.
=head1 Bugs
getVLDBEntry( id => $id )
The internal method _addEntry() now manages the data by id as well as
name, but you're not supposed to know that anyway...
=head1 Bugs
=head2 AFS::Command::BOS->status
When querying a specific instance, if it wasn't there, the API would
try to add an undefined instance object to the result, and croak.
Now, you just get a result object with no instances.
=head2 AFS::Command::FS->(several methods)
If you pass a list of paths to methods such as whichcell(), then the
error handling was a bit intrusive. The way it used to work, in 1.0,
was to return an error if we didn't see output for one or more of the
paths. Now, the code is more forgiving, and if have no idea what
happened for one of the given paths, we'll return a Path object for
that path which has a generic error.
Changes.html view on Meta::CPAN
<LI><A HREF="#Changes_in_1_6">Changes in 1.6</A>
<LI><A HREF="#Enhancements">Enhancements</A>
<LI><A HREF="#AFS_Object_VolumeHeader_new_a">AFS::Object::VolumeHeader: new attribute 'attached'</A>
<LI><A HREF="#Bugs">Bugs</A>
<LI><A HREF="#Changes_in_1_5">Changes in 1.5</A>
<LI><A HREF="#Enhancements">Enhancements</A>
<UL>
<LI><A HREF="#Principal_names_as_user_supplie">Principal names, as user supplied arguments, are lowercased</A>
<LI><A HREF="#AFS_Command_VOS_restore_argum">AFS::Command::VOS->restore arguments added</A>
</UL>
<LI><A HREF="#Bugs">Bugs</A>
<UL>
<LI><A HREF="#AFS_Object_VolumeHeader_acces">AFS::Object::VolumeHeader 'accesses' attribute was incorrect</A>
</UL>
<LI><A HREF="#Changes_in_1_4">Changes in 1.4</A>
<LI><A HREF="#Enhancements">Enhancements</A>
Changes.html view on Meta::CPAN
A new argument is supported by AFS::Command::Base->new():
<P>
<PRE> my $vos = AFS::Command::VOS->new( timestamps => 1 );
</PRE>
<P>
This will result in ISO timestamps being prepended to each line of output
when it is collected into the $vos->errors(). This is useful for
profiling the performance of operations such as vos release:
<P>
<PRE> my $result = $vos->release
(
id => 'somevol',
cell => 'somecell',
) || die $vos->errors();
</PRE>
<P>
When this works, the $vos->errors() will have the verbose output, which
can be logged even in the successful case, for diagnostics. Here's an
Changes.html view on Meta::CPAN
<HR>
<H1><A NAME="Bug_Fixes">Bug Fixes
</A></H1>
<P>
<HR>
<H2><A NAME="vos_examine_did_not_pick_up_the_">vos examine did not pick up the LOCKED flag
</A></H2>
The code to parse the VLDB header was missing the LOCKED flag, if it was
present, so this attribute was not being set properly. It is now.
<P>
<P>
<HR>
<H2><A NAME="pts_membership_error_checking_wa">pts membership error checking was bogus
</A></H2>
Well, it still is bogus, actually, since the code has to deal with the fact
Changes.html view on Meta::CPAN
<P>
<HR>
<H1><A NAME="Enhancements">Enhancements
</A></H1>
<P>
<HR>
<H2><A NAME="Boolean_flags_can_be_turned_off_">Boolean flags can be turned off, as well as on
</A></H2>
If an argument to a method (and its corresponding command line argument)
doesn't take a value, it is treated like a Boolean flag. However, the code
used to assume that the existence of a Boolean key in the argument list
implied the Boolean argument was always true.
<P>
Now, the truth of the arguments <EM>value</EM> is tested to determine if the flag should be set on or off. This makes it
easy to have subroutines that just blindly pass certain arguments along,
without haing to test them, and allows for much cleaner code.
<P>
For example:
<P>
<PRE> my $result = $vos->release
(
name => $name,
force => $force,
);
</PRE>
<P>
Will work as you probably expected it to, namely if <CODE>$force</CODE> is
zero, it will NOT be passed to the ``vos release'' command. In previous
Changes.html view on Meta::CPAN
offline'' put a vlume in the latter state, and if for some reason there are
two volumes with the same ID on the same fileserver, they will both be
attached (if possible), but only the first one encountered will be brought
online.
<P>
Changing the value of status would been a non-backwards compatible change,
and caused some subtle problems for some applications. Rather than
introduce such a change, I have chosen to represent this state with an
additional attribute ``attached'', which is just a Boolean, indicating
whether or not the volume is attached.
<P>
<P>
<HR>
<H1><A NAME="Bugs">Bugs
Changes.html view on Meta::CPAN
As a convenience, when PTS names are passed to methods like
<CODE>getUserByName(),</CODE> they will be lower-cased before looking up
the user, or group. Since PTS is a case-insensitive database, this will
avoid the need for applications to <CODE>lc()</CODE> some strings, although
not in all cases.
<P>
For example, you can pass a mixed case string to pts->creategroup(), and
then use the same string to query the resulting AFS::Object::Group object
using <CODE>getGroupByName().</CODE>
<P>
The object's ``group'' attribute, however, will be in lower case, since
that will be the value returned by the pts command itself.
<P>
<P>
<HR>
<H2><A NAME="AFS_Command_VOS_restore_argum">AFS::Command::VOS->restore arguments added
</A></H2>
Documentation for two important new vos restore arguments was added to the
documentation (-creation and -lastupdate). These options are only available
in a patch to vos, which should be in one the next two major OpenAFS 1.2.X
releases.
<P>
<P>
<HR>
<H1><A NAME="Bugs">Bugs
Changes.html view on Meta::CPAN
</A></H1>
<P>
<HR>
<H2><A NAME="Test_suite_is_disabled_by_defaul">Test suite is disabled by default.
</A></H2>
There is a well intentioned effort to automatically test all new
submissions to CPAN (see <A
HREF="http://testers.cpan.org).">http://testers.cpan.org).</A>
Unfortunately, the AFS-Command package can't be tested automatically, since
it requires a fair amount of configuration. You have to specify a cell
name, some fileserver names and partitions, etc.
<P>
By default, the tests will all be skipped if the configured cell name in
the CONFIG file has not been modified, thus allowing the automated CPAN
testing to continue, automatically, without the author getting a bunch of
bogus emails.
Changes.html view on Meta::CPAN
<HR>
<H1><A NAME="Bugs">Bugs
</A></H1>
<P>
<HR>
<H2><A NAME="AFS_Command_BOS_status">AFS::Command::BOS->status
</A></H2>
When querying a specific instance, if it wasn't there, the API would try to
add an undefined instance object to the result, and croak. Now, you just
get a result object with no instances.
<P>
<P>
<HR>
<H2><A NAME="AFS_Command_FS_several_metho">AFS::Command::FS->(several methods)
</A></H2>
If you pass a list of paths to methods such as <CODE>whichcell(),</CODE>
involved, and so on. (You will not be required to justify it
to the Copyright Holder, but only to the computing community
at large as a market that must bear the fee.)
"Freely Available" means that no fee is charged for the item
itself, though there may be fees involved in handling the
item. It also means that recipients of the item may
redistribute it under the same conditions they received it.
1. You may make and give away verbatim copies of the source form of
the Standard Version of this Package without restriction, provided
that you duplicate all of the original copyright notices and
associated disclaimers.
2. You may apply bug fixes, portability fixes and other modifications
derived from the Public Domain or from the Copyright Holder. A
Package modified in such a way shall still be considered the
Standard Version.
3. You may otherwise modify your copy of this Package in any way,
provided that you insert a prominent notice in each changed file
so embedded.
6. The scripts and library files supplied as input to or produced as
output from the programs of this Package do not automatically fall
under the copyright of this Package, but belong to whoever
generated them, and may be sold commercially, and may be aggregated
with this Package. If such scripts or library files are aggregated
with this Package via the so-called "undump" or "unexec" methods of
producing a binary executable image, then distribution of such an
image shall neither be construed as a distribution of this Package
nor shall it fall under the restrictions of Paragraphs 3 and 4,
provided that you do not represent such an executable image as a
Standard Version of this Package.
7. C subroutines (or comparably compiled subroutines in other
languages) supplied by you and linked into this Package in order to
emulate subroutines and variables of the language defined by this
Package shall not be considered part of this Package, but are the
equivalent of input as in Paragraph 6, provided these subroutines
donot change the language in any way that would cause it to fail
the regression tests for the language.
8. Aggregation of this Package with a commercial distribution is
always permitted provided that the use of this Package is embedded;
that is, when no overt attempt is made to make this Package's
interfaces visible to the end user of the commercial distribution.
Such use shall not be construed as a distribution of this Package.
9. The name of the Copyright Holder may not be used to endorse or
promote products derived from this software without specific prior
written permission.
lib/AFS/Object/VolServer.pm
lib/AFS/Object/Volume.pm
lib/AFS/Object/VolumeHeader.pm
LICENSE
Makefile.PL
MANIFEST This list of files
META.yml Module meta-data (added by MakeMaker)
README
README.html
t/00vos_basic.t
t/01vos_dumprestore.t
t/02vos_volserver.t
t/10bos_basic.t
t/20fs_basic.t
t/30pts_basic.t
t/40fs_complex.t
t/99pts_cleanup.t
ToDo
ToDo.html
util/bin/check_copyright
util/bin/check_version
--- #YAML:1.0
name: AFS-Command
version: 1.99
abstract: ~
author:
- W. Phillip Moore <Phil.Moore@MorganStanley.com>
license: unknown
distribution_type: module
configure_requires:
ExtUtils::MakeMaker: 0
build_requires:
ExtUtils::MakeMaker: 0
requires: {}
no_index:
directory:
- t
- inc
generated_by: ExtUtils::MakeMaker version 6.56
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
(http://www.ibm.com/software/stormgmt/afs/).
For example, AFS volumes are managed using the command line utility
'vos', for which there is currently no programmatic API, in any
language. This API is a pure perl wrapper around the command line
utility, that implements an OO API that allows for the easy
development of systems management applications for AFS.
=head1 PREREQUISITES
This module requires perl5.6 or later, as well as an installed AFS
infrastructure to work with. The code is pure perl, with no compiled
components, do it should work on any variant of UNIX (sorry, but this
code makes aggressive use of pipe() and fork(), so porting it to
Windows is gonna be painful... but then, why anyone would want to
manage their AFS infrastructure from Windows escapes me).
=head1 INSTALLATION
This module builds like almost everything else on CPAN:
perl Makefile.PL
make
make test
README.html view on Meta::CPAN
applications for AFS.
<P>
<P>
<HR>
<H1><A NAME="PREREQUISITES">PREREQUISITES
</A></H1>
This module requires perl5.6 or later, as well as an installed AFS
infrastructure to work with. The code is pure perl, with no compiled
components, do it should work on any variant of UNIX (sorry, but this code
makes aggressive use of <CODE>pipe()</CODE> and <CODE>fork(),</CODE> so
porting it to Windows is gonna be painful... but then, why anyone would
want to manage their AFS infrastructure from Windows escapes me).
<P>
<P>
<HR>
<H1><A NAME="INSTALLATION">INSTALLATION
calls, but in one set of objects?
Look for this in version 1.1
=head2 stderr handling
stderr processing needs to be handled in the _exec_cmds() method, and
for that matter, _reap_cmds() needs to be folded into _exec_cmds().
The problem is that each API method calls _save_stderr(), and then
later calls _restore_stderr(), and we leave stderr redirected for
longer than necessary. The contents of the redirected output should
be *only* the output from the commands we run, and right now, some of
our own carping can creep in there.
Worse, its possible that a failure in the API can leave stderr
redirected, resulting in a lot of confusion.
Its possible we should just suck in *ALL* of the output, both
stdout/stderr, and drop that data into a couple of arrays. Then,
method calls on the command object get gets individual rows of
stdout/stderr output.
return unless $self->_exec_cmds();
#
# Process stdout
#
while ( defined($_ = $self->_stdout() ) ) {
}
#
# Process stderr (in some cases, there's interesting data in here.
# see the fs examine/diskfree and similar api calls)
#
while ( defined($_ = $self->_stderr() ) ) {
}
Maybe something like that. By the time _exec_cmds returns, we have
reaped the commands, and collected *ALL* of the output into arrays in
the object.
</A></H2>
stderr processing needs to be handled in the <CODE>_exec_cmds()</CODE>
method, and for that matter, <CODE>_reap_cmds()</CODE> needs to be folded
into <CODE>_exec_cmds().</CODE>
<P>
The problem is that each API method calls <CODE>_save_stderr(),</CODE> and
then later calls <CODE>_restore_stderr(),</CODE> and we leave stderr
redirected for longer than necessary. The contents of the redirected output
should be *only* the output from the commands we run, and right now, some
of our own carping can creep in there.
<P>
Worse, its possible that a failure in the API can leave stderr redirected,
resulting in a lot of confusion.
<P>
Its possible we should just suck in *ALL* of the output, both
stdout/stderr, and drop that data into a couple of arrays. Then, method
calls on the command object get gets individual rows of stdout/stderr
output.
</PRE>
<P>
<PRE> }
</PRE>
<P>
<PRE> #
# Process stderr (in some cases, there's interesting data in here.
# see the fs examine/diskfree and similar api calls)
#
while ( defined($_ = $self->_stderr() ) ) {
</PRE>
<P>
<PRE> }
</PRE>
lib/AFS/Command.pod view on Meta::CPAN
The entire API is designed to be pure OO, with the following classes:
=head2 AFS::Command::(VOS|BOS|PTS|FS)
These are the primary classes used by applications directly. All of
the other objects are used internally to encapsulate the data parsed
from the underlying commands, and returned by the primary methods.
Each of these classes has a shared constructor (new), and methods that
correspond to each of the underlying commands. For example, the "vos"
utility has a command called "listvldb", and the AFS::Command::VOS
objects have a "listvldb" method. Each of the methods such as
"listvldb" take a list of key/value pairs that correspond to the
command line options for the "vos listvldb" command.
These classes implement the externally supported interface to the
entire API. If you use anything else, you're mucking with internals,
and you get what you deserver when your code implodes.
For details, see the module documentation for each of the above.
Also, the only reason there is no AFS::Command::KAS is that the
author's AFS infrastructure is an MIT Kerberos site, and since we
lib/AFS/Command.pod view on Meta::CPAN
This is the base class for the command suite, which implements the
shared constructor, and a couple of other useful class and object
methods.
=head2 AFS::Object
This is the base class for the objects returned from the command
methods that encapsulate some form of structured data. Many of the
methods return simple boolean true/false values (either the command
worked, or it failed), with no need for any special objects, so we
don't create them. Anything that has to return interesting data uses
this class, or one of its base classes.
The subclasses are associated with data structures such as volume
headers, a VLDB entry, or a partition on a server. Each of these
classes has methods to retrieve the objects they "contain", such as a
method to query the list of volume names on a partition object, and a
method to get a list of VLDB entries from a VLDB site.
The data structures, and their varying relationships, are documented
in details of the methods for each of the commands, and the specific
interfaces for each object type are documented in the corresponding
class documentation.
The subclasses for encapsulating the VLDB data are:
AFS::Object::VLDB
AFS::Object::VLDBEntry
AFS::Object::VLDBSite
The subclasses for encapsulating the volume headers are:
lib/AFS/Command.pod view on Meta::CPAN
AFS::Object::Volume
AFS::Object::VolumeHeader
The subclasses for encapsulating the bosserver data are:
AFS::Object::BosServer
AFS::Object::Instance
Note that none of these classes are specifically documented, since the
structure of the classes is subject to change. The API for accessin
the results of any given AFS command (eg. vos listvol) is considered
reasonably stable, but the encapsulation may change radically.
Don't get too attached to these class names, because they will likely
be rearranged in a future release.
=cut
lib/AFS/Command/BOS.pm view on Meta::CPAN
use AFS::Object::Instance;
our @ISA = qw(AFS::Command::Base);
our $VERSION = '1.99';
sub getdate {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "getdate";
my $directory = $args{dir} || '/usr/afs/bin';
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
lib/AFS/Command/BOS.pm view on Meta::CPAN
);
if ( /\.BAK dated ([^,]+),/ ) {
$file->_setAttribute( bak => $1 );
}
if ( /\.OLD dated ([^,\.]+)/ ) {
$file->_setAttribute( old => $1 );
}
$result->_addFile($file);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getlog {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "getlog";
my $redirect = undef;
my $redirectname = undef;
if ( $args{redirect} ) {
$redirectname = delete $args{redirect};
$redirect = IO::File->new(">$redirectname") || do {
$self->_Carp("Unable to write to $redirectname: $ERRNO");
lib/AFS/Command/BOS.pm view on Meta::CPAN
} else {
$log .= $_;
}
}
if ( $redirect ) {
$redirect->close()|| do {
$self->_Carp("Unable to close $redirectname: $ERRNO");
$errors++
};
$result->_setAttribute( log => $redirectname );
} else {
$result->_setAttribute( log => $log );
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getrestart {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "getrestart";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /restarts at (.*)/ || /restarts (never)/ ) {
$result->_setAttribute( restart => $1 );
} elsif ( /binaries at (.*)/ || /binaries (never)/ ) {
$result->_setAttribute( binaries => $1 );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listhosts {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "listhosts";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my @hosts = ();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
if ( /Cell name is (\S+)/i ) {
$result->_setAttribute( cell => $1 );
}
if ( /Host \d+ is (\S+)/i ) {
push(@hosts,$1);
}
}
$result->_setAttribute( hosts => \@hosts );
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listkeys {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "listkeys";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
lib/AFS/Command/BOS.pm view on Meta::CPAN
if ( /key (\d+)/ ) {
my $key = AFS::Object->new( index => $1 );
if ( /has cksum (\d+)/ ) {
$key->_setAttribute( cksum => $1 );
} elsif ( /is \'([^\']+)\'/ ) {
$key->_setAttribute( value => $1 );
}
$result->_addKey($key);
}
if ( /last changed on (.*)\./ ) {
$result->_setAttribute( keyschanged => $1 );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listusers {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "listusers";
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;
if ( /^SUsers are: (.*)/ ) {
$result->_setAttribute( susers => [split(/\s+/,$1)] );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
#
# XXX -- we might want to provide parsing of the bos salvage output,
# but for now, this is a non-parsed command.
#
# sub salvage {
# my $self = shift;
# my (%args) = @_;
# my $result = AFS::Object::BosServer->new();
# $self->{operation} = "salvage";
# return unless $self->_parse_arguments(%args);
# return unless $self->_save_stderr();
# my $errors = 0;
# $errors++ unless $self->_exec_cmds();
# while ( defined($_ = $self->{handle}->getline()) ) {
# }
# $errors++ unless $self->_reap_cmds();
# $errors++ unless $self->_restore_stderr();
# return if $errors;
# return $result;
# }
sub status {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "status";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my $instance = undef;
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
if ( /inappropriate access/ ) {
$result->_setAttribute( access => 1 );
next;
}
if ( /Instance (\S+),/ ) {
if ( defined $instance ) {
$result->_addInstance($instance);
}
$instance = AFS::Object::Instance->new( instance => $1 );
#
# This is ugly, since the order and number of these
# strings varies.
#
if ( /\(type is (\S+)\)/ ) {
$instance->_setAttribute( type => $1 );
lib/AFS/Command/BOS.pm view on Meta::CPAN
$instance->_addCommand($command);
}
if ( /Notifier\s+is\s+\'(.*)\'/ ) {
$instance->_setAttribute( notifier => $1 );
}
}
if ( defined $instance ) {
$result->_addInstance($instance);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
1;
lib/AFS/Command/BOS.pod view on Meta::CPAN
=over
=item Arguments
The bos help string is:
bos getdate: get dates for programs
Usage: bos getdate -server <machine name> -file <files to check>+ [-dir <destination dir>]
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->getdate
(
# Required arguments
server => $server,
file => $file, # OR [ $file1, $file2, ... ]
# Optional arguments
dir => $dir,
cell => $cell,
noauth => 1,
localauth => 1,
);
=item Return Values
This method returns an AFS::Object::BosServer object, which
contains one or more generic AFS::Object, one for each file
specified in the arguments.
my $result = $bos->getdate
(
file => [ 'bosserver', 'vlserver', 'ptserver' ],
cell => $cell,
) || die $bos->errors();
foreach my $fileobj ( $result->getFiles() ) {
my ($file,$date) = ($fileobj->file(),$fileobj->date());
print "File $file has date $date\n";
}
Each of these objects has the following attributes and methods:
B<AFS::Object::BosServer>
This object is nothing more than a container for the generic objects
for each file. It has several methods for extracting the file objects:
Methods Returns
------- -------
getFileNames() a list of filenames
getFiles() a list of AFS::Object objects
getFile($filename) the AFS::Object object for $filename
B<AFS::Object>
The following attributes should always be present:
Attributes Values
---------- ------
file fully qualified pathname to the file
date last modified timestamp on the file
The following attributes may be present, if there are .BAK or .OLD
versions of the file.
Attributes Values
---------- ------
bak last modified timestamp on the .BAK file
old last modified timestamp on the .OLD file
=back
=head2 getlog
lib/AFS/Command/BOS.pod view on Meta::CPAN
=over
=item Arguments
The bos help string is:
bos getlog: examine log file
Usage: bos getlog -server <machine name> -file <log file to examine>
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->getlog
(
# Required arguments
server => $server,
file => $file,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
# Enhanced arguments
redirect => $redirect,
lib/AFS/Command/BOS.pod view on Meta::CPAN
The value of this argument is passed directly to IO::File->open().
If this argument is not specified, then the contents of the logfile
are stashed in an attribute of the returned object.
=item Return Values
This method returns an AFS::Object::BosServer object, which
contains one attribute.
my $result = $bos->getlog
(
server => $server,
file => "/usr/afs/logs/VolserLog",
redirect => "/var/tmp/VolserLog.$$",
) || die $bos->errors();
my $logfile = IO::File->new("</var/tmp/VolserLog.$$") ||
die "Unable to open logfile: $ERRNO\n";
while ( defined($_ = $logfile->getline()) ) {
....
}
# Alternately, the memory pig way:
my $result = $bos->getlog
(
server => $server,
file => "/usr/afs/logs/VolserLog",
);
foreach ( split(/\n+/,$result->log()) ) {
....
}
The object has the following attribute:
B<AFS::Object::BosServer>
Attributes Values
---------- ------
log Contents of the logfile, or the redirect pathname
If redirect was given, then this attribute is simply same pathname.
If redirect was not given, then the value of this attribute is the
contents of the requested logfile, as a single (potentially huge)
string.
NOTE: Since this method is usually invoked to retrieve one of the AFS
logfiles, which can be enormous on heavily loaded servers that have
not been restarted in a while, use of the redirect option is strongly
encouraged. If not used, the memory allocated to store the logfile
may be prohibitively large. Developer beware.
=back
=head2 getrestart
=over
=item Arguments
The bos help string is:
bos getrestart: get restart times
Usage: bos getrestart -server <machine name> [-cell <cell name>]
[-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->getrestart
(
# Required arguments
server => $server,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=item Return Values
This method returns an AFS::Object::BosServer object, which
contains two attributes.
my $result = $bos->getrestart
(
server => $server,
cell => $cell,
) || die $bos->errors();
print "Binary restart time is " . $result->binaries() . "\n";
print "Server restart time is " . $result->restart() . "\n";
The object has the following attributes:
B<AFS::Object::BosServer>
Attributes Values
---------- ------
restart The server restart time
binaries The restart time when there are new, updated binaries
=back
=head2 listhosts
=over
=item Arguments
The bos help string is:
bos listhosts: get cell host list
Usage: bos listhosts -server <machine name> [-cell <cell name>]
[-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->listhosts
(
# Required arguments
server => $server,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=item Return Values
This method returns an AFS::Object::BosServer object, which
contains one attribute.
my $result = $bos->listhosts
(
server => $server,
cell => $cell,
) || die $bos->errors();
my $hosts = $result->hosts();
print "Server $server in cell $cell has hosts:\n"
foreach my $host ( @$hosts ) {
print "\t$host\n";
}
The object has the following attributes:
B<AFS::Object::BosServer>
Attributes Values
lib/AFS/Command/BOS.pod view on Meta::CPAN
=item Arguments
The bos help string is:
bos listkeys: list keys
Usage: bos listkeys -server <machine name> [-showkey]
[-cell <cell name>] [-noauth] [-localauth]
Where: -showkey show the actual key rather than the checksum
The corresponding method invocation looks like:
my $result = $bos->listkeys
(
# Required arguments
server => $server,
# Optional arguments
showkey => 1,
cell => $cell,
noauth => 1,
localauth => 1,
);
=item Return Values
This method returns an AFS::Object::BosServer object, which
contains one or more AFS::Object objects, each of which
represents a single authentication key on the server.
my $result = $bos->listkeys
(
server => $server,
cell => $cell,
) || die $bos->errors();
print "Server $server in cell $cell has the following keys:\n";
foreach my $key ( $result->getKeys() ) {
my ($index,$cksum) = ($key->index(),$key->cksum());
print "\t$index => $cksum\n";
}
my $result = $bos->listkeys
(
server => $server,
cell => $cell,
showkey => 1,
) || die $bos->errors();
print "Server $server in cell $cell has the following keys:\n";
foreach my $key ( $result->getKeys() ) {
my ($index,$value) = ($key->index(),$key->value());
print "\t$index => $cksum\n";
}
The objects have the following attributes and methods:
B<AFS::Object::BosServer>
Attributes Values
---------- ------
keychanged Date the keys were last changed
Methods Returns
------- -------
getKeyIndexes() list of numeric key indexes
getKeys() list of AFS::Object objects
getKey($index) the AFS::Object object for the key with index $index
B<AFS::Object>
The following attribute is always present:
Attributes Values
---------- ------
index Numeric index of the key
The following attribute is present when the 'showkey' argument is given:
Attributes Values
---------- ------
value Value of the key, in octal, as a string
The following attribute is present when the 'showkey' argument is B<NOT> given:
Attributes Values
---------- ------
cksum Numeric check sum of the key
=back
=head2 listusers
=over
=item Arguments
The bos help string is:
bos listusers: list super-users
Usage: bos listusers -server <machine name> [-cell <cell name>]
[-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->listusers
(
# Required arguments
server => $server,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=item Return Values
This method returns an AFS::Object::BosServer object, which
contains one attribute.
my $result = $bos->listusers
(
server => $server,
cell => $cell,
) || die $bos->errors();
my $users = $result->susers();
print "Server $server in cell $cell has users:\n"
foreach my $user ( @$users ) {
print "\t$user\n";
}
The object has the following attribute:
B<AFS::Object::BosServer>
Attributes Values
lib/AFS/Command/BOS.pod view on Meta::CPAN
=item Arguments
The bos help string is:
bos status: show server instance status
Usage: bos status -server <machine name> [-instance <server process name>+]
[-long] [-cell <cell name>] [-noauth] [-localauth]
Where: -long long status
The corresponding method invocation looks like:
my $result = $bos->status
(
# Required arguments
server => $server,
# Optional arguments
instance => $instance, # OR [ $inst1, $inst2, ... ],
cell => $cell,
long => 1,
noauth => 1,
localauth => 1,
);
=item Return Values
This method returns an AFS::Object::BosServer object, which
contains one optional attribute, and one or more
AFS::Object::Instance objects, each of which represents a
single instance of a bosserver managed process on the server.
my $result = $bos->status
(
server => $server,
long => 1,
) || die $bos->errors();
foreach my $instanceobj ( $result->getInstances() ) {
my $instance = $instanceobj->instance();
my $status = $instanceobj->status();
print "Instance $instance has status $status\n";
foreach my $commandobj ( $instance->getCommands() ) {
my $index = $commandobj->index();
my $command = $commandobj->command();
print "\tCmd $index is '$command'\n";
}
}
The objects have the following attributes and methods:
B<AFS::Object::BosServer>
The following attribute is only present when "bos status" reports
inappropriate access on directories:
Attributes Values
---------- ------
access Boolean, true indicating a potential security problem
The following methods can be used to extract the instance objects:
Methods Returns
------- -------
getInstanceNames() list of instance names
getInstances() list of AFS::Object::Instance objects
getInstance($name) one AFS::Object::Instance object for the instance $name
B<AFS::Object::Instance>
The following attributes are always present:
Attributes Values
---------- ------
instance Name of the instance
status Status string (running normally, shutdown, etc.)
The following attribute is always present is the instance is of type
'cron':
Attributes Values
---------- ------
auxiliary Auxiliary status (date the next execution)
The following attributes are always available when the 'long' argument
is specified:
Attributes Values
lib/AFS/Command/BOS.pod view on Meta::CPAN
state of the instance, when the 'long' argument is specified:
Attributes Values
---------- ------
notifier Path to the notifier application for this instance
state "temporarily disabled", or "disabled", or "temporarily enabled"
errorstop Boolean, indicating the process was
"stopped for too many errors"
core Boolean, indicating the instance has a core file
errorexitdate Date when the process last exited with an error
errorexitdue "shutdown", or "signal", or "code" (present only when
"errorexitdate" attribute is present)
errorexitsignal Signal that cause the error exit (present only when
"errorexitdue" eq "signal")
errorexitcode Exit code from last error exit (present only when
"errorexitdue" eq "code")
The following methods can be used to extract the command objects,
which are also only present when the 'long' argument is specified.
Methods Returns
------- -------
getCommandIndexes() list of numeric indexes for the commands
getCommands() list of AFS::Object objects for all commands
getCommand($index) the AFS::Object object for the command with index $index
B<AFS::Object> (Commands)
The following pair of attributes are always present:
Attributes Values
---------- ------
index Numerical index of the command
command Command string
=back
=head1 METHODS (with simple return values)
lib/AFS/Command/BOS.pod view on Meta::CPAN
=head2 addhost
The bos help string is:
bos addhost: add host to cell dbase
Usage: bos addhost -server <machine name> -host <host name>+
[-clone] [-cell <cell name>] [-noauth] [-localauth]
Where: -clone vote doesn't count
The corresponding method invocation looks like:
my $result = $bos->addhost
(
# Required arguments
server => $server,
host => $host, # OR [ $host1, $host2, ... ]
# Optional arguments
clone => 1,
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 addkey
The bos help string is:
bos addkey: add keys to key dbase (kvno 999 is bcrypt)
Usage: bos addkey -server <machine name> [-key <key>] -kvno <key version number>
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->addkey
(
# Required arguments
server => $server,
kvno => $kvno,
# Optional arguments
key => $key,
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 adduser
The bos help string is:
bos adduser: add users to super-user list
Usage: bos adduser -server <machine name> -user <user names>+
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->adduser
(
# Required arguments
server => $server,
user => $user, # OR [ $user1, $user2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 blockscanner
The bos help string is:
bos blockscanner: block scanner daemon from making migration requests
Usage: bos blockscanner -server <machine name> [-cell <cell name>]
[-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->blockscanner
(
# Required arguments
server => $server,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 create
The bos help string is:
bos create: create a new server instance
Usage: bos create -server <machine name> -instance <server process name>
-type <server type> -cmd <command lines>+ [-notifier <Notifier program>]
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->create
(
# Required arguments
server => $server,
instance => $instance,
type => $type,
cmd => $cmd, # OR [ $cmd1, $cmd2, ... ]
# Optional arguments
notifier => $notifier,
cell => $cell,
noauth => 1,
lib/AFS/Command/BOS.pod view on Meta::CPAN
);
=head2 delete
The bos help string is:
bos delete: delete a server instance
Usage: bos delete -server <machine name> -instance <server process name>+
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->delete
(
# Required arguments
server => $server,
instance => $instance, # OR [ $inst1, $inst2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 exec
The bos help string is:
bos exec: execute shell command on server
Usage: bos exec -server <machine name> -cmd <command to execute>
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->exec
(
# Required arguments
server => $server,
cmd => $cmd,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 install
The bos help string is:
bos install: install program
Usage: bos install -server <machine name> -file <files to install>+
[-dir <destination dir>] [-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->install
(
# Required arguments
server => $server,
file => $file, # OR [ $file1, $file2, ... ]
# Optional arguments
dir => $dir,
cell => $cell,
noauth => 1,
localauth => 1,
);
lib/AFS/Command/BOS.pod view on Meta::CPAN
The bos help string is:
bos prune: prune server files
Usage: bos prune -server <machine name> [-bak] [-old] [-core] [-all]
[-cell <cell name>] [-noauth] [-localauth]
Where: -bak delete .BAK files
-old delete .OLD files
-core delete core files
-all delete all junk files
The corresponding method invocation looks like:
my $result = $bos->prune
(
# Required arguments
server => $server,
# Optional arguments
bak => 1,
old => 1,
core => 1,
all => 1,
cell => $cell,
noauth => 1,
lib/AFS/Command/BOS.pod view on Meta::CPAN
);
=head2 removehost
The bos help string is:
bos removehost: remove host from cell dbase
Usage: bos removehost -server <machine name> -host <host name>+
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->removehost
(
# Required arguments
server => $server,
host => $host, # OR [ $host1, $host2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 removekey
The bos help string is:
bos removekey: remove keys from key dbase
Usage: bos removekey -server <machine name> -kvno <key version number>+
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->removekey
(
# Required arguments
server => $server,
kvno => $kvno, # OR [ $kvno1, $kvno2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 removeuser
The bos help string is:
bos removeuser: remove users from super-user list
Usage: bos removeuser -server <machine name> -user <user names>+
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->removeuser
(
# Required arguments
server => $server,
user => $user, # OR [ $user1, $user2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 restart
The bos help string is:
bos restart: restart processes
Usage: bos restart -server <machine name> [-instance <instances>+] [-bosserver]
[-all] [-cell <cell name>] [-noauth] [-localauth]
Where: -bosserver restart bosserver
-all restart all processes
The corresponding method invocation looks like:
my $result = $bos->restart
(
# Required arguments
server => $server,
# Optional arguments
instance => $instance, # OR [ $inst1, $inst2, ... ]
bosserver => 1,
all => 1,
cell => $cell,
noauth => 1,
localauth => 1,
lib/AFS/Command/BOS.pod view on Meta::CPAN
[-force] [-oktozap] [-rootfiles] [-salvagedirs] [-blockreads]
[-ListResidencies] [-SalvageRemote] [-SalvageArchival]
[-IgnoreCheck] [-ForceOnLine] [-UseRootDirACL]
[-TraceBadLinkCounts] [-DontAskFS] [-LogLevel <(MR-AFS) log level>]
[-rxdebug] [-cell <cell name>] [-noauth] [-localauth]
Where: -all salvage whole server
-showlog display salvage log
-debug (MR-AFS) Run in Debugging mode
-nowrite (MR-AFS) Run readonly/test mode
-force (MR-AFS) Force full salvaging
-oktozap (MR-AFS) Give permission to destroy bogus file residencies/volumes - debugging flag
-rootfiles (MR-AFS) Show files owned by root - debugging flag
-salvagedirs (MR-AFS) Force rebuild/salvage of all directories
-blockreads (MR-AFS) Read smaller blocks to handle IO/bad blocks
-ListResidencies (MR-AFS) Just list affected file residencies - debugging flag
-SalvageRemote (MR-AFS) Salvage storage systems that are not directly attached
-SalvageArchival (MR-AFS) Salvage HSM storage systems
-IgnoreCheck (MR-AFS) Don't perform VLDB safety check when deleting unreferenced files.
Only a good idea in single server cell.
-ForceOnLine (MR-AFS) Force the volume to come online, even if it hasn't salvaged cleanly.
-UseRootDirACL (MR-AFS) Use the root directory ACL for lost+found directory if it is created.
-TraceBadLinkCounts (MR-AFS) Print out lines about volume reference count changes.
-DontAskFS (MR-AFS) Don't ask fileserver to take volume offline. THIS IS VERY DANGEROUS.
-rxdebug (MR-AFS) Write out rx debug information.
The corresponding method invocation looks like:
my $result = $bos->salvage
(
# Required arguments
server => $server,
# Optional arguments
partition => $partition,
volume => $volume,
file => $file,
all => 1,
showlog => 1,
parallel => $parallel,
lib/AFS/Command/BOS.pod view on Meta::CPAN
=head2 setauth
The bos help string is:
bos setauth: set authentication required flag
Usage: bos setauth -server <machine name>
-authrequired <on or off: authentication required for admin requests>
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->setauth
(
# Required arguments
server => $server,
authrequired => $authrequired,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 setcellname
The bos help string is:
bos setcellname: set cell name
Usage: bos setcellname -server <machine name> -name <cell name>
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->setcellname
(
# Required arguments
server => $server,
name => $name,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 setrestart
The bos help string is:
bos setrestart: set restart times
Usage: bos setrestart -server <machine name> -time <time to restart server>
[-general] [-newbinary] [-cell <cell name>]
[-noauth] [-localauth]
Where: -general set general restart time
-newbinary set new binary restart time
The corresponding method invocation looks like:
my $result = $bos->setrestart
(
# Required arguments
server => $server,
time => $time,
# Optional arguments
general => 1,
newbinary => 1,
cell => $cell,
noauth => 1,
localauth => 1,
lib/AFS/Command/BOS.pod view on Meta::CPAN
=head2 shutdown
The bos help string is:
bos shutdown: shutdown all processes
Usage: bos shutdown -server <machine name> [-instance <instances>+]
[-wait] [-cell <cell name>] [-noauth] [-localauth]
Where: -wait wait for process to stop
The corresponding method invocation looks like:
my $result = $bos->shutdown
(
# Required arguments
server => $server,
# Optional arguments
instance => $instance, # OR [ $inst1, $inst2, ... ]
wait => 1,
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 start
The bos help string is:
bos start: start running a server
Usage: bos start -server <machine name> -instance <server process name>+
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->start
(
# Required arguments
server => $server,
# Optional arguments
instance => $instance, # OR [ $inst1, $inst2, ... ]
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 startup
The bos help string is:
bos startup: start all processes
Usage: bos startup -server <machine name> [-instance <instances>+]
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->startup
(
# Required arguments
server => $server,
# Optional arguments
instance => $instance, # OR [ $inst1, $inst2, ... ]
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 stop
The bos help string is:
bos stop: halt a server instance
Usage: bos stop -server <machine name> -instance <server process name>+
[-wait] [-cell <cell name>] [-noauth] [-localauth]
Where: -wait wait for process to stop
The corresponding method invocation looks like:
my $result = $bos->stop
(
# Required arguments
server => $server,
instance => $instance, # OR [ $inst1, $inst2, ... ]
# Optional arguments
wait => 1,
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 unblockscanner
The bos help string is:
bos unblockscanner: allow scanner daemon to make migration requests again
Usage: bos unblockscanner -server <machine name>
[-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->unblockscanner
(
# Required arguments
server => $server,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
);
=head2 uninstall
The bos help string is:
bos uninstall: uninstall program
Usage: bos uninstall -server <machine name> -file <files to uninstall>+
[-dir <destination dir>] [-cell <cell name>] [-noauth] [-localauth]
The corresponding method invocation looks like:
my $result = $bos->uninstall
(
# Required arguments
server => $server,
file => $file, # OR [ $file1, $file2, ... ]
# Optional arguments
dir => $dir,
cell => $cell,
noauth => 1,
localauth => 1,
);
lib/AFS/Command/Base.pm view on Meta::CPAN
$newerr->close() || do {
$self->_Carp("Unable to close $self->{tmpfile}: $ERRNO");
return;
};
return 1;
}
sub _restore_stderr {
my $self = shift;
STDERR->fdopen( $self->{olderr}->fileno(), "w") || do {
$self->_Carp("Unable to restore stderr: $ERRNO");
return;
};
$self->{olderr}->close() || do {
$self->_Carp("Unable to close saved stderr: $ERRNO");
return;
};
delete $self->{olderr};
lib/AFS/Command/Base.pod view on Meta::CPAN
my $vos = AFS::Command::VOS->new
(
command => "/ms/dist/openafs/PROJ/core/1.2.9/bin/vos",
);
If the path given is invalid, then expect the API to implode on itself
when it can't be found, or it isn't an AFS vos command.
=item localauth, noauth, encrypt
All of these arguments correspond to command line arguments common
across the entire command line suite. Typically, if an application
uses this flag once, it will be using it for B<all> subsequent calls as
well. Therefore, the state of these flags can be set globally by
setting them when creating the command object.
my $vos = AFS::Command::VOS->new
(
localauth => 1,
encrypt => 1,
);
lib/AFS/Command/Base.pod view on Meta::CPAN
will be prepended with the date formatted using Date::Format with:
%Y/%m/%d %H:%M:%S
This is primarily useful for debugging and timing of commands such as
vos release, which can be very time consuming. Since we enable
-verbose by default, this option will let us determine the relative
time required for each step in these complex operations.
This only applies to commands that return simple return values, eg:
release, restore, etc. Commands that return complex structures of
objects, such as listvldb, listvol, etc will not be affected.
=back
=head2 setCarp
This class method configures the carp and/or croak subroutines used
throughout the API. By default, the obviously sensible thing is done:
the carp an croak subroutines exported by the Carp module are used.
These normally print output to stderr, and this method provides a
mechanism for trapping these errors and redirecting them elsewhere.
For example, stderr in a system daemon may be entirely ignored, and
syslog may be a more appropriate destination. In this case, the
setCarp method may be used to configure this, globally, for the entire
API.
lib/AFS/Command/Base.pod view on Meta::CPAN
},
);
This method takes a list of key/value pairs, with only two supported
keys (anything else will be quietly ignored): carp an croak. The
values are CODE references (anonymous subroutines, or references to
existing subroutines). The carp CODE should not be fatal, however the
croak CODE should. The API calls the croak method in very few places,
but when it does, it assumes that call will be fatal, so if you
provide a croak subroutine that doesn't die, the results will be
unpredictable, and unsupportable.
This method returns true of false, depending on whether or not the
carp and/or croak subroutines were properly configured. If the values
are not CODE references, then this method will itself croak.
=head1 INSTANCE METHODS
=head2 errors
This method takes no arguments, and it returns a string, containing the
unparsed errors from the last command method invoked. This string is
reset with each subsequent command method invocation. The string is
normally the output written to stderr by the process, but in the case
of unparsed boolean commands, it contains both the stdout as well as
the stderr output.
my $result = $vos->examine
(
id => $volname,
cell => $cell,
);
unless ( $result ) {
die "Unable to examine volname '$volname' in cell '$cell':" .
$vos->errors();
}
=head2 supportsOperation
This class method allows the developer to test whether or not any
given operation is supported by the underlying command line utility.
For example, the "vos changeloc" operation is not supported in older
release of vos.
lib/AFS/Command/FS.pm view on Meta::CPAN
use AFS::Object::ACL;
our @ISA = qw(AFS::Command::Base);
our $VERSION = '1.99';
sub checkservers {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "checkservers";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my @servers = ();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
if ( /The current down server probe interval is (\d+) secs/ ) {
$result->_setAttribute( interval => $1 );
}
if ( /These servers are still down:/ ) {
while ( defined($_ = $self->{handle}->getline()) ) {
s/^\s+//g;
s/\s+$//g;
push(@servers,$_);
}
}
}
$result->_setAttribute( servers => \@servers );
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub diskfree {
my $self = shift;
return $self->_paths_method('diskfree',@_);
}
sub examine {
my $self = shift;
lib/AFS/Command/FS.pm view on Meta::CPAN
my $self = shift;
return $self->_paths_method('listacl',@_);
}
sub _paths_method {
my $self = shift;
my $operation = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = $operation;
my $pathkey = $operation eq 'storebehind' ? 'files' : 'path';
return unless $self->_parse_arguments(%args);
my $errors = 0;
$errors++ unless $self->_exec_cmds( stderr => 'stdout' );
lib/AFS/Command/FS.pm view on Meta::CPAN
#
# This is a bit lame. We want to be lazy and split on white
# space, so we get rid of this one annoying instance.
#
s/no limit/nolimit/g;
my ($volname,$quota,$used,$percent,$partition) = split;
$quota = 0 if $quota eq "nolimit";
$percent =~ s/\D//g; # want numeric result
$partition =~ s/\D//g; # want numeric result
$path->_setAttribute
(
path => $paths[0],
volname => $volname,
quota => $quota,
used => $used,
percent => $percent,
partition => $partition,
);
delete $paths{$paths[0]};
shift @paths;
}
if ( $operation eq 'diskfree' ) {
my ($volname,$total,$used,$avail,$percent) = split;
$percent =~ s/%//g; # Don't need it -- want numeric result
$path->_setAttribute
(
path => $paths[0],
volname => $volname,
total => $total,
used => $used,
avail => $avail,
percent => $percent,
);
lib/AFS/Command/FS.pm view on Meta::CPAN
delete $paths{$paths[0]};
shift @paths;
}
}
}
$result->_addPath($path);
}
if ( $operation eq 'storebehind' ) {
$result->_setAttribute( asynchrony => $default );
#
# This is ugly, but we get the default last, and it would be nice
# to put this value into the Path objects as well, rather than the
# string 'default'.
#
foreach my $path ( $result->getPaths() ) {
if ( defined($path->asynchrony()) && $path->asynchrony() eq 'default' ) {
$path->_setAttribute( asynchrony => $default );
}
}
}
foreach my $pathname ( keys %paths ) {
my $path = AFS::Object::Path->new
(
path => $pathname,
error => "Unable to determine results",
);
$result->_addPath($path);
}
$errors++ unless $self->_reap_cmds( allowstatus => 1 );
return if $errors;
return $result;
}
sub exportafs {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object->new();
$self->{operation} = "exportafs";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
/translator is (currently )?enabled/ && do {
$result->_setAttribute( enabled => 1 );
};
/translator is disabled/ && do {
$result->_setAttribute( enabled => 0 );
};
/convert owner mode bits/ && do {
$result->_setAttribute( convert => 1 );
};
/strict unix/ && do {
$result->_setAttribute( convert => 0 );
};
/strict \'?passwd sync\'?/ && do {
$result->_setAttribute( uidcheck => 1 );
};
/no \'?passwd sync\'?/ && do {
$result->_setAttribute( uidcheck => 0 );
};
/allow mounts/i && do {
$result->_setAttribute( submounts => 1 );
};
/Only mounts/i && do {
$result->_setAttribute( submounts => 0 );
};
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getcacheparms {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getcacheparms";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /using (\d+) of the cache.s available (\d+) 1K/ ) {
$result->_setAttribute
(
used => $1,
avail => $2,
);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getcellstatus {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getcellstatus";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Cell (\S+) status: (no )?setuid allowed/ ) {
my $cell = AFS::Object::Cell->new
(
cell => $1,
status => $2 ? 0 : 1,
);
$result->_addCell($cell);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getclientaddrs {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getclientaddrs";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my @addresses = ();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
s/^\s+//;
s/\s+$//;
push(@addresses,$_);
}
$result->_setAttribute( addresses => \@addresses );
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getcrypt {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getcrypt";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Security level is currently (crypt|clear)/ ) {
$result->_setAttribute( crypt => ($1 eq 'crypt' ? 1 : 0) );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getserverprefs {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getserverprefs";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
lib/AFS/Command/FS.pm view on Meta::CPAN
s/\s+$//g;
my ($name,$preference) = split;
my $server = AFS::Object::Server->new
(
server => $name,
preference => $preference,
);
$result->_addServer($server);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listaliases {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "listaliases";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Alias (.*) for cell (.*)/ ) {
my $cell = AFS::Object::Cell->new
(
cell => $2,
alias => $1,
);
$result->_addCell($cell);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listcells {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "listcells";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /^Cell (\S+) on hosts (.*)\.$/ ) {
my $cell = AFS::Object::Cell->new
(
cell => $1,
servers => [split(/\s+/,$2)],
);
$result->_addCell($cell);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub lsmount {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "lsmount";
return unless $self->_parse_arguments(%args);
my $errors = 0;
$errors++ unless $self->_exec_cmds( stderr => 'stdout' );
my @dirs = ref $args{dir} eq 'ARRAY' ? @{$args{dir}} : ($args{dir});
lib/AFS/Command/FS.pm view on Meta::CPAN
$path->_setAttribute( cell => $cell) if $cell;
} else {
$self->_Carp("fs lsmount: Unrecognized output: '$_'");
$errors++;
next;
}
$result->_addPath($path);
}
foreach my $dir ( keys %dirs ) {
my $path = AFS::Object::Path->new
(
path => $dir,
error => "Unable to determine results",
);
$result->_addPath($path);
}
$errors++ unless $self->_reap_cmds( allowstatus => 1 );
return if $errors;
return $result;
}
#
# This is deprecated in newer versions of OpenAFS
#
sub monitor {
my $self = shift;
$self->_Carp("fs monitor: This operation is deprecated and no longer supported");
return;
}
sub sysname {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "sysname";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my @sysname = ();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Current sysname is \'?([^\']+)\'?/ ) {
$result->_setAttribute( sysname => $1 );
} elsif ( s/Current sysname list is // ) {
while ( s/\'([^\']+)\'\s*// ) {
push(@sysname,$1);
}
$result->_setAttribute( sysnames => \@sysname );
$result->_setAttribute( sysname => $sysname[0] );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub wscell {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "wscell";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next unless /belongs to cell\s+\'(.*)\'/;
$result->_setAttribute( cell => $1 );
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
1;
lib/AFS/Command/FS.pod view on Meta::CPAN
=head2 NOTE: Error checking for commands that accept a list of paths
A number of these methods accept a list of paths, and will return
information for each path, individually. If you specify a
non-existent path, or one which is not in AFS, then the fs command
returns a non-zero exist status, which normally would mean the command
failed.
If you specify a list of paths to this API, and one or more of them
result in errors, the API call is still considered to succeed, as long
as we can determine the error for each path specified. The API will
still return an AFS::Object::CacheManager object, which contains a set
of AFS::Object::Path object, for each path specified in the arguments,
as long as we saw some kind of output from the fs commands for each
path.
Each AFS::Object::Path object must be examined to determine the
success of failure for that individual path. When errors were
encountered for any given path, then the objects will have an "error"
attribute, and nothing else (no other data attributes, except the path
lib/AFS/Command/FS.pod view on Meta::CPAN
=item Arguments
The fs help string is:
fs checkservers: check local cell's servers
Usage: fs checkservers [-cell <cell to check>] [-all] [-fast]
[-interval <seconds between probes>]
Where: -all check all cells
-fast just list, don't check
The corresponding method invocation looks like:
my $result = $fs->checkservers
(
# Optional arguments
cell => $cell,
interval => $interval,
all => 1,
fast => 1,
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more attributes.
my $result = $fs->checkservers() || die $fs->errors();
my @servers = $result->servers();
foreach my $server ( @servers ) {
print "Server $server appears to be down\n";
}
The object has the following attributes:
Attributes Values
---------- ------
servers ARRAY reference of strings, each of which is
the hostname of a server which is down
interval The value of the probe interval, in seconds
Note that the interval attribute is only present of the internal
argument was specified, and the servers list will be empty if nothing
was down.
=back
=head2 diskfree
=over
=item Arguments
The fs help string is:
fs diskfree: show server disk space usage
Usage: fs diskfree [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->diskfree
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Path objects, one for each path
specified in the arguments.
my $result = $fs->diskfree
(
path => [ $afspath, $ufspath, $boguspath ],
) || die $fs->errors();
foreach my $pathobj ( $result->getPaths() ) {
my $path = $pathobj->path();
if ( $pathobj->hasAttribute('error') ) {
print "Path '$path' has errors '" . $pathobj->error() . "'\n";
} else {
foreach my $attr ( qw( volname used total avail percent ) ) {
print "Path '$path' has '$attr' of '" . $pathobj->$attr() . "'\n";
}
}
}
lib/AFS/Command/FS.pod view on Meta::CPAN
B<AFS::Object::Path>
If errors were encountered for any given path, then its object will
have the following attributes:
Attributes Values
---------- ------
path The pathname
error The error string for that path
If no errors were encountered, then the following attributes will be present:
Attributes Values
---------- ------
path The pathname
volname The AFS volume name that contains the pathname
total The size (in KB) of the partition that contains 'volname'
used The amount of space (in KB) used on that partition
avail The amount of space (in KB) available on that partition
percent The amount of space used, as a percentage
lib/AFS/Command/FS.pod view on Meta::CPAN
=over
=item Arguments
The fs help string is:
fs examine: display volume status
Usage: fs examine [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->examine
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Path objects, one for each path
specified in the arguments.
my $result = $fs->examine
(
path => [ $afspath, $ufspath, $boguspath ],
) || die $fs->errors();
foreach my $pathobj ( $result->getPaths() ) {
my $path = $pathobj->path();
if ( $pathobj->hasAttribute('error') ) {
print "Path '$path' has errors '" . $pathobj->error() . "'\n";
} else {
foreach my $attr ( qw( id volname quota used avail total ) ) {
print "Path '$path' has '$attr' of '" . $pathobj->$attr() . "'\n";
}
}
}
lib/AFS/Command/FS.pod view on Meta::CPAN
B<AFS::Object::Path>
If errors were encountered for any given path, then its object will
have the following attributes:
Attributes Values
---------- ------
path The pathname
error The error string for that path
If no errors were encountered, then the following attributes will be present:
Attributes Values
---------- ------
path The pathname
volname The AFS volume name that contains the pathname
id The numerical volume ID of the above volume
total The size (in KB) of the partition that contains 'volname'
used The amount of space (in KB) used on that partition
avail The amount of space (in KB) available on that partition
quota The quota of the volume (in KB), or 0 if set to "unlimited"
lib/AFS/Command/FS.pod view on Meta::CPAN
=item Arguments
The fs help string is:
fs exportafs: enable/disable translators to AFS
Usage: fs exportafs -type <exporter name> [-start <start/stop translator (on | off)>]
[-convert <convert from afs to unix mode (on | off)>]
[-uidcheck <run on strict 'uid check' mode (on | off)>]
[-submounts <allow nfs mounts to subdirs of /afs/.. (on | off)>]
The corresponding method invocation looks like:
my $result = $fs->exportafs
(
# Required arguments
type => $type, # 'nfs' is the only supported value
# Optional arguments
start => $start, # 'on' or 'off'
convert => $convert, # 'on' or 'off'
uidcheck => $uidcheck, # 'on' or 'off'
submounts => $submounts, # 'on' or 'off'
);
NOTE: In a future release, the 4 optional arguments will probably take
boolean values, with "off" being a special case that means false, in
order to simply the interface (and be backwards compatible).
=item Return Values
This method returns an AFS::Object::CacheManager object with one or
more attributes.
my $result = $fs->exportafs
(
type => 'nfs',
start => 'on',
) || die $fs->errors();
foreach my $attr ( qw( convert uidcheck submounts ) ) {
print "Translator has '$attr' set to '" . $result->$attr() . "'\n";
}
The object has the following attribute:
B<AFS::Object::CacheManager>
Attributes Values
---------- ------
enabled Boolean, true means the translator is on, false means off
convert Boolean, true means mode bits are converted from AFS to UNIX, false means off
lib/AFS/Command/FS.pod view on Meta::CPAN
=over
=item Arguments
The fs help string is:
fs getcacheparms: get cache usage info
Usage: fs getcacheparms
The corresponding method invocation looks like:
my $result = $fs->getcacheparms();
=item Return Values
This method returns an AFS::Object::CacheManager object with one or
more attributes.
my $result = $fs->getcacheparms() || die $fs->errors();
my $used = $result->used();
my $avail = $result->avail();
print "Cache is using $used KB of $availa KB available\n";
The object has the following attributes:
B<AFS::Object::CacheManager>
Attributes Values
---------- ------
used Number of KB of the AFS cache in use
avail Size of the AFS cache, in KB
lib/AFS/Command/FS.pod view on Meta::CPAN
=over
=item Arguments
The fs help string is:
fs getcellstatus: get cell status
Usage: fs getcellstatus -cell <cell name>+
The corresponding method invocation looks like:
my $result = $fs->getcellstatus
(
# Required arguments
cell -> $cell, # OR [ $cell1, $cell2, ... ]
);
=item Return Values
This method returns an AFS::Object::CacheManager object which contains
one or more AFS::Object::Cell objects.
my $result = $fs->getcellstatus
(
cell => [ $cell1 , $cell2 ],
) || die $fs->errors();
foreach my $cellobj ( $result->getCells() ) {
my $cell = $cellobj->cell();
if ( $cellobj->status() ) {
print("This client allows setuid binaries from cell '$cell'\n";
} else {
print("This client does NOT allow setuid binaries from cell '$cell'\n";
}
}
The objects have the following attributes and methods:
lib/AFS/Command/FS.pod view on Meta::CPAN
=back
=head2 getclientaddrs
=over
=item Arguments
The fs help string is:
fs getclientaddrs: get client network interface addresses
Usage: fs getclientaddrs
The corresponding method invocation looks like:
my $result = $fs->getclientaddrs();
=item Return Values
This method returns an AFS::Object::CacheManager object with one attribute.
my $result = $fs->getclientaddrs() || die $fs->errors();
print "This client has the following addressed configured for AFS:\n";
foreach my $address ( @{$result->addresses()} ) {
print "\t$address\n";
}
The object has the following attribute:
B<AFS::Object::CacheManager>
Attributes Values
---------- ------
addresses ARRAY reference of IP addresses
=back
=head2 getcrypt
=over
=item Arguments
The fs help string is:
fs getcrypt: set cache manager encryption flag
Usage: fs getcrypt
The corresponding method invocation looks like:
my $result = $fs->getcrypt();
=item Return Values
This method returns an AFS::Object::CacheManager object with one attribute.
my $result = $fs->getcrypt() || die $fs->errors();
print "This client has encryption turned " . ( $result->crypt() ? "on" : "off" ) . "\n";
The object has the following attribute:
B<AFS::Object::CacheManager>
Attributes Values
---------- ------
crypt Boolean, indicating whether or not encryption is enabled
=back
lib/AFS/Command/FS.pod view on Meta::CPAN
=head2 getserverprefs
=over
=item Arguments
The fs help string is:
fs getserverprefs: get server ranks
Usage: fs getserverprefs [-file <output to named file>] [-numeric] [-vlservers]
Where: -numeric addresses only
-vlservers VL servers
The corresponding method invocation looks like:
my $result = $fs->getserverprefs
(
# Optional arguments
file => $file,
numeric => 1,
vlservers => 1,
);
=item Return Values
This method returns an AFS::Object::CacheManager object which contains
one or more AFS::Object::Server objects.
my $result = $fs->getserverprefs() || die $fs->errors();
foreach my $serverobj ( $result->getServers() ) {
my $server = $serverobj->server();
my $pref = $serverobj->preference();
print "Server '$server' has preference '$preference'\n";
}
The objects have the following attributes and methods:
B<AFS::Object::CacheManager>
Methods Returns
------- -------
getServerNames() list of server hostnames (or addresses)
getServers() list of AFS::Object::Server objects
getServer($server) the AFS::Object::Server object for server $server
B<AFS::Object::Server>
Attributes Values
---------- ------
server Hostname or IP address of the server
preference Numeric preference value
=back
=head2 listacl
=over
=item Arguments
The fs help string is:
fs listacl: list access control list
Usage: fs listacl [-path <dir/file path>+] [-id] [-if]
Where: -id initial directory acl
-if initial file acl
The corresponding method invocation looks like:
my $result = $fs->listacl
(
# Required arguments
path => $path, # OR [ $path1, $path2, ... ]
# Optional arguments
id => 1,
if => 1,
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Path objects, one for each path
specified in the arguments. Each AFS::Object::Path object contains
one or two AFS::Object::ACL objects (one for normal, and one for
negative).
my $result = $fs->listacl
(
path => [ $afspath, $ufspath, $boguspath ],
) || die $fs->errors();
foreach my $pathobj ( $result->getPaths() ) {
my $path = $pathobj->path();
if ( $pathobj->hasAttribute('error') ) {
print "Path '$path' has errors '" . $pathobj->error() . "'\n";
} else {
foreach my $type ( qw( normal negative ) ) {
my $acl = $pathobj->getACL($type);
my %entries = $acl->getEntries();
foreach my $principal ( keys %entries ) {
my $rights = $acl->getRights($principal);
print "$type rights for $principal are $rights\n";
lib/AFS/Command/FS.pod view on Meta::CPAN
=over
=item Arguments
The fs help string is:
fs listaliases: list configured cell aliases
Usage: fs listaliases
The corresponding method invocation looks like:
my $result = $fs->listaliases();
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Cell objects.
my $result = $fs->listaliases() || die $fs->errors();
foreach my $cellobj ( $result->getCells() ) {
my $cell = $cellobj->cell();
my $alias = $cellobj->alias();
print "Cell '$cell' has alias '$alias'\n";
}
The objects have the following attributes and methods:
B<AFS::Object::CacheManager>
Methods Returns
lib/AFS/Command/FS.pod view on Meta::CPAN
=head2 listcells
=over
=item Arguments
The fs help string is:
fs listcells: list configured cells
Usage: fs listcells [-numeric]
Where: -numeric addresses only
The corresponding method invocation looks like:
my $result = $fs->listcells
(
# Optional arguments
numeric => 1,
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Cell objects.
my $result = $fs->listcells() || die $fs->errors();
foreach my $cellobj ( $result->getCells() ) {
my $servers = $cellobj->servers();
print "Cell $cell has servers " . join(" ",@$servers) . "\n";
}
The objects have the following attributes and methods:
B<AFS::Object::CacheManager>
Methods Returns
------- -------
lib/AFS/Command/FS.pod view on Meta::CPAN
=over
=item Arguments
The fs help string is:
fs listquota: list volume quota
Usage: fs listquota [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->listquota
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=item Return Values
=back
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Path objects, one for each path
specified in the arguments.
my $result = $fs->listquota
(
path => [ $afspath, $ufspath, $boguspath ],
) || die $fs->errors();
foreach my $pathobj ( $result->getPaths() ) {
my $path = $pathobj->path();
if ( $pathobj->hasAttribute('error') ) {
print "Path '$path' has errors '" . $pathobj->error() . "'\n";
} else {
foreach my $attr ( qw( volname quota used percent partition ) ) {
print "Path '$path' has '$attr' of '" . $pathobj->$attr() . "'\n";
}
}
}
lib/AFS/Command/FS.pod view on Meta::CPAN
B<AFS::Object::Path>
If errors were encountered for any given path, then its object will
have the following attributes:
Attributes Values
---------- ------
path The pathname
error The error string for that path
If no errors were encountered, then the following attributes will be present:
Attributes Values
---------- ------
path The pathname
volname The AFS volume name that contains the pathname
quota Volume quota, in KB
used The amount of space (in KB) used in that volume
percent The percentage of the allocated quota in use
partition The percentage of space used on the partition where the volume resides
=head2 lsmount
=over
=item Arguments
The fs help string is:
fs lsmount: list mount point
Usage: fs lsmount -dir <directory>+
The corresponding method invocation looks like:
my $result = $fs->lsmount
(
# Required arguments
dir => $dir, # OR [ $dir1, $dir2, ... ]
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Path objects, one for each path
specified in the arguments.
my $result = $fs->lsmount
(
dir => [ $dir1, $dir2 ],
) || die $fs->errors();
foreach my $pathobj ( $result->getPaths() ) {
my $path = $pathobj->path();
if ( $pathobj->hasAttribute('error') ) {
print "Path '$path' has errors '" . $pathobj->error() . "'\n";
} else {
my $volname = $pathobj->volname();
my $cell = $pathobj->cell();
print("Path '$path' is a mtpt for volume $volname" .
( $cell ? ", in cell '$cell'\n" : "\n" ));
}
}
lib/AFS/Command/FS.pod view on Meta::CPAN
If errors were encountered for any given path, then its object will
have the following attributes:
Attributes Values
---------- ------
path The pathname
error The error string for that path
If no errors were encountered, then the following attributes will
always be present:
Attributes Values
---------- ------
path The pathname
volname AFS volname in the mount point
The following attributes may or may not be present:
Attributes Values
---------- ------
symlink Boolean, true if the pathname is a symlink to a mount point
readwrite Boolean, true if the mount point is explicitly readwrite
cell AFS cell name in the mount point
=back
=head2 quota
=over
=item Arguments
The fs help string is:
fs quota: show volume quota usage
Usage: fs quota [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->quota
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Path objects, one for each path
specified in the arguments.
my $result = $fs->quota
(
path => [ $afspath, $ufspath, $boguspath ],
) || die $fs->errors();
foreach my $pathobj ( $result->getPaths() ) {
my $path = $pathobj->path();
if ( $pathobj->hasAttribute('error') ) {
print "Path '$path' has errors '" . $pathobj->error() . "'\n";
} else {
print "Path '$path' has quota '" . $pathobj->quota() . "'\n";
}
}
Each of these objects has the following attributes and methods:
lib/AFS/Command/FS.pod view on Meta::CPAN
B<AFS::Object::Path>
If errors were encountered for any given path, then its object will
have the following attributes:
Attributes Values
---------- ------
path The pathname
error The error string for that path
If no errors were encountered, then the following attributes will be present:
Attributes Values
---------- ------
path The pathname
quota The percentage of the allocated quota in use
=back
=head2 storebehind
lib/AFS/Command/FS.pod view on Meta::CPAN
=item Arguments
The fs help string is:
fs storebehind: store to server after file close
Usage: fs storebehind [-kbytes <asynchrony for specified names>]
[-files <specific pathnames>+] [-allfiles <new default (KB)>]
[-verbose]
Where: -verbose show status
The corresponding method invocation looks like:
my $result = $fs->storebehind
(
# Optional arguments
kbytes => $kbytes,
files => $file, # OR [ $file1, $file2, ... ]
allfiles => $default,
verbose => 1,
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Path objects, one for each path
specified in the arguments.
my $result = $fs->quota
(
path => [ $afspath, $ufspath, $boguspath ],
) || die $fs->errors();
foreach my $pathobj ( $result->getPaths() ) {
my $path = $pathobj->path();
if ( $pathobj->hasAttribute('error') ) {
print "Path '$path' has errors '" . $pathobj->error() . "'\n";
} else {
foreach my $attr ( qw( volname quota used percent partition ) ) {
print "Path '$path' has '$attr' of '" . $pathobj->$attr() . "'\n";
}
}
}
lib/AFS/Command/FS.pod view on Meta::CPAN
B<AFS::Object::Path>
If errors were encountered for any given path, then its object will
have the following attributes:
Attributes Values
---------- ------
path The pathname
error The error string for that path
If no errors were encountered, then the following attributes will be present:
Attributes Values
---------- ------
path The pathname
asynchrony The number of KB of asynchronous writes for this file
=back
=head2 sysname
=over
=item Arguments
The fs help string is:
fs sysname: get/set sysname (i.e. @sys) value
Usage: fs sysname [-newsys <new sysname>+]
The corresponding method invocation looks like:
my $result = $fs->sysname
(
# Optional arguments
newsys => $sysname, # OR [ $sysname1, $sysname2, ... ]
);
=item Return Values
This method returns an AFS::Object::CacheManager object which has one
of two possible attributes.
my $result = $fs->sysname() || die $fs->errors();
my $sysname = $result->sysname();
my $sysnames = $result->sysnames();
print "This client has a primary sysname of '$sysname'\n";
if ( ref $sysnames eq 'ARRAY' ) {
print "This client has a list of sysnames: " . join(" ,",@$sysnames) . "\n";
}
The object has the following attributes:
B<AFS::Object::CacheManager>
Attributes Values
lib/AFS/Command/FS.pod view on Meta::CPAN
=over
=item Arguments
The fs help string is:
fs whereis: list file's location
Usage: fs whereis [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->whereis
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Path objects, one for each path
specified in the arguments.
my $result = $fs->whereis
(
path => [ $afspath, $ufspath, $boguspath ],
) || die $fs->errors();
foreach my $pathobj ( $result->getPaths() ) {
my $path = $pathobj->path();
if ( $pathobj->hasAttribute('error') ) {
print "Path '$path' has errors '" . $pathobj->error() . "'\n";
} else {
print "Path '$path' is on hosts " . join(" ,",@{pathobj->hosts()}) . "\n";
}
}
Each of these objects has the following attributes and methods:
lib/AFS/Command/FS.pod view on Meta::CPAN
B<AFS::Object::Path>
If errors were encountered for any given path, then its object will
have the following attributes:
Attributes Values
---------- ------
path The pathname
error The error string for that path
If no errors were encountered, then the following attributes will be present:
Attributes Values
---------- ------
path The pathname
hosts An ARRAY reference of hostnames
=back
=head2 whichcell
=over
=item Arguments
The fs help string is:
fs whichcell: list file's cell
Usage: fs whichcell [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->whichcell
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=item Return Values
This method returns an AFS::Object::CacheManager object, which
contains one or more AFS::Object::Path objects, one for each path
specified in the arguments.
my $result = $fs->whichcell
(
path => [ $afspath, $ufspath, $boguspath ],
) || die $fs->errors();
foreach my $pathobj ( $result->getPaths() ) {
my $path = $pathobj->path();
if ( $pathobj->hasAttribute('error') ) {
print "Path '$path' has errors '" . $pathobj->error() . "'\n";
} else {
print "Path '$path' is in cell '" . $pathobj->cell() . "'\n";
}
}
Each of these objects has the following attributes and methods:
lib/AFS/Command/FS.pod view on Meta::CPAN
B<AFS::Object::Path>
If errors were encountered for any given path, then its object will
have the following attributes:
Attributes Values
---------- ------
path The pathname
error The error string for that path
If no errors were encountered, then the following attributes will be present:
Attributes Values
---------- ------
path The pathname
cell Cell in which the pathname lives
=back
=head2 wscell
=over
=item Arguments
The fs help string is:
fs wscell: list workstation's cell
Usage: fs wscell
The corresponding method invocation looks like:
my $result = $fs->wscell();
=item Return Values
This method returns an AFS::Object::CacheManager object which has one
attribute.
my $result = $fs->wscell() || die $fs->errors();
print "This client lives in cell '" . $result->cell() . "'\n";
The object has the following attribute:
Attributes Values
---------- ------
cell The AFS cell of the client
=back
=head1 METHODS (with simple return values)
=head2 checkvolumes
The fs help string is:
fs checkvolumes: check volumeID/name mappings
Usage: fs checkvolumes
The corresponding method invocation looks like:
my $result = $fs->checkvolumes();
=head2 cleanacl
The fs help string is:
fs cleanacl: clean up access control list
Usage: fs cleanacl [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->cleanacl
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=head2 copyacl
The fs help string is:
fs copyacl: copy access control list
Usage: fs copyacl -fromdir <source directory (or DFS file)>
-todir <destination directory (or DFS file)>+
[-clear] [-id] [-if]
Where: -clear first clear dest access list
-id initial directory acl
-if initial file acl
The corresponding method invocation looks like:
my $result = $fs->copyacl
(
# Required arguments
fromdir => $fromdir,
todir => $todir, # OR [ $todir1, $todir2, ... ]
# Optional arguments
clear => 1,
id => 1,
if => 1,
);
=head2 flush
The fs help string is:
fs flush: flush file from cache
Usage: fs flush [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->flush
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=head2 flushmount
The fs help string is:
fs flushmount: flush mount symlink from cache
Usage: fs flushmount [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->flushmount
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=head2 flushvolume
The fs help string is:
fs flushvolume: flush all data in volume
Usage: fs flushvolume [-path <dir/file path>+]
The corresponding method invocation looks like:
my $result = $fs->flushvolume
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=head2 messages
The fs help string is:
fs messages: control Cache Manager messages
Usage: fs messages [-show <[user|console|all|none]>]
The corresponding method invocation looks like:
my $result = $fs->messages
(
# Optional arguments
show => $show,
);
=head2 mkmount
The fs help string is:
fs mkmount: make mount point
Usage: fs mkmount -dir <directory> -vol <volume name> [-cell <cell name>] [-rw] [-fast]
Where: -rw force r/w volume
-fast don't check name with VLDB
The corresponding method invocation looks like:
my $result = $fs->mkmount
(
# Required arguments
dir => $dir,
vol => $vol,
# Optional arguments
cell => $cell,
rw => 1,
fast => 1,
);
=head2 newalias
The fs help string is:
fs newalias: configure new cell alias
Usage: fs newalias -alias <alias name> -name <real name of cell>
The corresponding method invocation looks like:
my $result = $fs->newalias
(
# Required arguments
alias => $alias,
name => $name,
);
=head2 newcell
The fs help string is:
fs newcell: configure new cell
Usage: fs newcell -name <cell name> -servers <primary servers>+
[-linkedcell <linked cell name>]
The corresponding method invocation looks like:
my $result = $fs->newcell
(
# Required arguments
name => $name,
servers => $server, # OR [ $server1, $server2, ... ]
# Optional arguments
linkedcell => $linkedcell,
);
=head2 rmmount
The fs help string is:
fs rmmount: remove mount point
Usage: fs rmmount -dir <directory>+
The corresponding method invocation looks like:
my $result = $fs->rmmount
(
# Required arguments
dir => $dir, # OR [ $dir1, $dir2, ... ]
);
=head2 rxstatpeer
The fs help string is:
fs rxstatpeer: Manage per peer RX statistics
Usage: fs rxstatpeer [-enable] [-disable] [-clear]
Where: -enable Enable RX stats
-disable Disable RX stats
-clear Clear RX stats
The corresponding method invocation looks like:
my $result = $fs->rxstatpeer
(
# Optional arguments
enable => 1,
disable => 1,
clear => 1,
);
=head2 rxstatproc
The fs help string is:
fs rxstatproc: Manage per process RX statistics
Usage: fs rxstatproc [-enable] [-disable] [-clear]
Where: -enable Enable RX stats
-disable Disable RX stats
-clear Clear RX stats
The corresponding method invocation looks like:
my $result = $fs->rxstatproc
(
# Optional arguments
enable => 1,
disable => 1,
clear => 1,
);
=head2 setacl
The fs help string is:
fs setacl: set access control list
Usage: fs setacl -dir <directory>+ -acl <access list entries>+
[-clear] [-negative] [-id] [-if]
Where: -clear clear access list
-negative apply to negative rights
-id initial directory acl (DFS only)
-if initial file acl (DFS only)
The corresponding method invocation looks like:
my $result = $fs->setacl
(
# Required arguments
dir => $dir, # OR [ $dir1, $dir2, ... ]
acl => [ <<see below>> ],
# Optional arguments
clear => 1,
negative => 1,
id => 1,
if => 1,
);
lib/AFS/Command/FS.pod view on Meta::CPAN
If you construct a single string, such as "user read group write",
then the method will fail. There is no shell involved in exec'ing fs,
so there will be no splitting of this string on whitespace before we
construct the arguments to fs, so it will look like a single argument,
not four distinct arguments.
Therefore, there are two ways to construct an ACL to pass to setacl():
my @acl = ( $user, 'read', $group, 'write' );
my $result = $fs->setacl
(
dir => $dir,
acl => \@acl,
);
my %acl =
(
$user => 'read',
$group => 'write',
);
my $result = $fs->setacl
(
dir => $dir,
acl => \%acl,
);
In a future release of the API, maybe even 1.1, it will be possible to
pass AFS::Object::ACL objects as arguments to these API
calls, but not yet...
=head2 setcachesize
The fs help string is:
fs setcachesize: set cache size
Usage: fs setcachesize [-blocks <size in 1K byte blocks (0 => reset)>] [-reset]
Where: -reset reset size back to boot value
The corresponding method invocation looks like:
my $result = $fs->setcachesize
(
# Optional arguments
blocks => $blocks,
reset => 1,
);
=head2 setcell
The fs help string is:
fs setcell: set cell status
Usage: fs setcell -cell <cell name>+ [-suid] [-nosuid]
Where: -suid allow setuid programs
-nosuid disallow setuid programs
The corresponding method invocation looks like:
my $result = $fs->setcell
(
# Required arguments
cell => $cell, # OR [ $cell1, $cell2, ... ]
# Optional arguments
suid => 1,
nosuid => 1,
);
=head2 setclientaddrs
The fs help string is:
fs setclientaddrs: set client network interface addresses
Usage: fs setclientaddrs [-address <client network interfaces>+]
The corresponding method invocation looks like:
my $result = $fs->setclientaddrs
(
# Required arguments
address => $address, # OR [ $address1, $address2, ... ]
);
=head2 setcrypt
The fs help string is:
fs setcrypt: set cache manager encryption flag
Usage: fs setcrypt -crypt <on or off>
The corresponding method invocation looks like:
my $result = $fs->setcrypt
(
# Required arguments
crypt => 1,
);
=head2 setquota
The fs help string is:
fs setquota: set volume quota
Usage: fs setquota [-path <dir/file path>] -max <max quota in kbytes>
The corresponding method invocation looks like:
my $result = $fs->setquota
(
# Required arguments
max => $max,
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
);
=head2 setserverprefs
The fs help string is:
fs setserverprefs: set server ranks
Usage: fs setserverprefs [-servers <fileserver names and ranks>+]
[-vlservers <VL server names and ranks>+]
[-file <input from named file>] [-stdin]
Where: -stdin input from stdin
The corresponding method invocation looks like:
my $result = $fs->setserverprefs
(
# Optional arguments
servers => $server, # OR [ $server1, $server2, ... ]
vlservers => $vlserver, # OR [ $vlserver1, $vlserver2, ... ]
file => $file,
stdin => 1,
);
=head2 setvol
The fs help string is:
fs setvol: set volume status
Usage: fs setvol [-path <dir/file path>+] [-max <disk space quota in 1K units>]
[-offlinemsg <offline message>]
The corresponding method invocation looks like:
my $result = $fs->setvol
(
# Optional arguments
path => $path, # OR [ $path1, $path2, ... ]
max => $max,
offlinemsg => $offlinemsg,
);
=head1 SEE ALSO
AFS::Command(1), AFS::Object(1)
lib/AFS/Command/PTS.pm view on Meta::CPAN
use AFS::Object::User;
our @ISA = qw(AFS::Command::Base);
our $VERSION = '1.99';
sub creategroup {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "creategroup";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next unless /group (\S+) has id (-\d+)/;
my $group = AFS::Object::Group->new
(
name => $1,
id => $2,
);
$result->_addGroup($group);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub createuser {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "createuser";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next unless /User (\S+) has id (\d+)/;
my $user = AFS::Object::User->new
(
name => $1,
id => $2,
);
$result->_addUser($user);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub examine {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "examine";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
lib/AFS/Command/PTS.pm view on Meta::CPAN
}
unless ( $data{id} ) {
$self->_Carp("pts examine: Unrecognized output: '$_'");
$errors++;
next;
}
if ( $data{id} > 0 ) {
$result->_addUser( AFS::Object::User->new(%data) );
} else {
$result->_addGroup( AFS::Object::Group->new(%data) );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listentries {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "listentries";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
lib/AFS/Command/PTS.pm view on Meta::CPAN
next if ( ! $name && ! $id && ! $owner && ! $creator );
if ( $id > 0 ) {
my $user = AFS::Object::User->new
(
name => $name,
id => $id,
owner => $owner,
creator => $creator,
);
$result->_addUser($user);
} else {
my $group = AFS::Object::Group->new
(
name => $name,
id => $id,
owner => $owner,
creator => $creator,
);
$result->_addGroup($group);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listmax {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "listmax";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next unless /Max user id is (\d+) and max group id is (-\d+)/;
$result->_setAttribute
(
maxuserid => $1,
maxgroupid => $2,
);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listowned {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "listowned";
return unless $self->_parse_arguments(%args);
my $errors = 0;
$errors++ unless $self->_exec_cmds( stderr => 'stdout' );
my $user = undef;
my $group = undef;
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Groups owned by (\S+) \(id: (-?\d+)\)/ ) {
$result->_addUser($user) if $user;
$result->_addGroup($group) if $group;
my ($name,$id) = ($1,$2);
if ( $id > 0 ) {
$user = AFS::Object::User->new
(
name => $name,
id => $id,
);
$group = undef;
lib/AFS/Command/PTS.pm view on Meta::CPAN
# If we see this string, then let the command fail, even
# though we might have partial data.
#
$self->{errors} .= $_;
$errors++;
}
}
$result->_addUser($user) if $user;
$result->_addGroup($group) if $group;
$errors++ unless $self->_reap_cmds();
return if $errors;
return $result;
}
sub membership {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "membership";
return unless $self->_parse_arguments(%args);
my $errors = 0;
$errors++ unless $self->_exec_cmds( stderr => 'stdout' );
my $user = undef;
my $group = undef;
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /(\S+) \(id: (-?\d+)\)/ ) {
$result->_addUser($user) if $user;
$result->_addGroup($group) if $group;
my ($name,$id) = ($1,$2);
if ( $id > 0 ) {
$user = AFS::Object::User->new
(
name => $name,
id => $id,
);
$group = undef;
lib/AFS/Command/PTS.pm view on Meta::CPAN
# If we see this string, then let the command fail, even
# though we might have partial data.
#
$self->{errors} .= $_;
$errors++;
}
}
$result->_addUser($user) if $user;
$result->_addGroup($group) if $group;
$errors++ unless $self->_reap_cmds();
return if $errors;
return $result;
}
1;
lib/AFS/Command/PTS.pod view on Meta::CPAN
=item Arguments
The pts help string is:
pts creategroup: create a new group
Usage: pts creategroup -name <group name>+ [-owner <owner of the group>]
[-id <id (negated) for the group>+]
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->creategroup
(
# Required arguments
name => $name, # OR [ $name1, $name2, ... ]
# Optional arguments
owner => $owner,
id => $id, # OR [ $id1, $id2, ... ]
cell => $cell,
noauth => 1,
force => 1,
);
=item Return Values
This method returns an AFS::Object::PTServer object, which
contains one AFS::Object::Group for each group created.
my $result = $pts->creategroup
(
name => $name,
owner => $owner,
) || die $pts->errors();
foreach my $group ( $result->getGroups() ) {
my ($grname,$grid) = ($group->name(),$group->id());
print "New group $grname has id $grid\n";
}
Each of these objects has the following attributes and methods:
B<AFS::Object::PTServer>
Methods Returns
------- -------
lib/AFS/Command/PTS.pod view on Meta::CPAN
=over
=item Arguments
The pts help string is:
pts createuser: create a new user
Usage: pts createuser -name <user name>+ [-id <user id>+]
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->createuser
(
# Required arguments
name => $name, # OR [ $name1, $name2, ... ]
# Optional arguments
owner => $owner,
id => $id, # OR [ $id1, $id2, ... ]
cell => $cell,
noauth => 1,
force => 1,
);
=item Return Values
This method returns an AFS::Object::PTServer object, which
contains one AFS::Object::User for each user created.
my $result = $pts->createuser
(
name => $name,
owner => $owner,
) || die $pts->errors();
foreach my $user ( $result->getUsers() ) {
my ($username,$userid) = ($user->name(),$user->id());
print "New user $username has id $userid\n";
}
Each of these objects has the following attributes and methods:
B<AFS::Object::PTServer>
Methods Returns
------- -------
lib/AFS/Command/PTS.pod view on Meta::CPAN
=over
=item Arguments
The pts help string is:
pts examine: examine an entry
Usage: pts examine -nameorid <user or group name or id>+
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->examine
(
# Required arguments
nameorid => $nameorid, # OR [ $nameorid1, $nameorid2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
force => 1,
);
=item Return Values
This method returns an AFS::Object::PTServer object, which
contains one AFS::Object::User or AFS::Object::Group
object for each user/group examined.
my $result = $pts->examine
(
nameorid => [ $name1, $name2 ],
cell => 1,
) || die $pts->errors();
foreach my $userobj ( $result->getUser() ) {
my ($name,$id) = ($userobj->name(),$userobj->id());
print "User $name has id $id\n";
}
foreach my $groupobj ( $result->getGroups() ) {
my ($name,$id) = ($groupobj->name(),$groupobj->id());
print "Group $name has id $id\n";
}
Each of these objects has the following attributes and methods:
B<AFS::Object::PTServer>
Methods Returns
------- -------
lib/AFS/Command/PTS.pod view on Meta::CPAN
=item Arguments
The pts help string is:
pts listentries: list users/groups in the protection database
Usage: pts listentries [-users] [-groups] [-cell <cell name>]
[-noauth] [-force]
Where: -users list user entries
-groups list group entries
The corresponding method invocation looks like:
my $result = $pts->listentries
(
# Optional arguments
users => 1,
groups => 1,
cell => $cell,
noauth => 1,
force => 1,
);
=item Return Values
This method returns an AFS::Object::PTServer object, which
contains one AFS::Object::User or AFS::Object::Group
object for each user/group listed.
my $result = $pts->listentries
(
users => 1,
groups => 1,
cell => $cell,
) || die $pts->errors();
# Starting to see a pattern? The result is parsed in almost the
# same way as shown for examine
Each of these objects has the following attributes and methods:
B<AFS::Object::PTServer>
Methods Returns
------- -------
getGroupNames() list of group names
getGroupIds() list of group ids
lib/AFS/Command/PTS.pod view on Meta::CPAN
=over
=item Arguments
The pts help string is:
pts listmax: list max id
Usage: pts listmax [-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->listmax
(
# Optional arguments
cell => $cell,
noauth => 1,
force => 1,
);
=item Return Values
This method returns an AFS::Object::PTServer object, which
contains two attributes:
my $result = $pts->listmax
(
cell => $cell,
) || die $pts->errors();
print "Maximum group ID is " . $result->maxgroupid() . "\n";
print "Maximum user ID is " . $result->maxuserid() . "\n";
This object has the following attributes, which are always present:
Attributes Values
---------- ------
maxgroupid Numeric value of the highest group ID
maxuserid Numeric value of the highest user ID
=back
=head2 listowned
=over
=item Arguments
The pts help string is:
pts listowned: list groups owned by an entry or zero id gets orphaned groups
Usage: pts listowned -nameorid <user or group name or id>+
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->listowned
(
# Required arguments
nameorid => $nameorid, # OR [ $nameorid1, $nameorid2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
force => 1,
);
=item Return Values
This method returns an AFS::Object::PTServer object, which
contains one AFS::Object::User or AFS::Object::Group
object for each user/group specified.
my $result = $pts->listowned
(
nameorid => $user,
cell => $cell,
) || die $pts->errors();
my $userobj = $result->getUserbyName($user);
print "User $user owns the following groups:\n";
foreach my $owned ( $userobj->getOwned() ) {
print "\t$owned\n";
}
Each of these objects has the following attributes and methods:
B<AFS::Object::PTServer>
Methods Returns
lib/AFS/Command/PTS.pod view on Meta::CPAN
=over
=item Arguments
The pts help string is:
pts membership: list membership of a user or group
Usage: pts membership -nameorid <user or group name or id>+
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->membership
(
# Required arguments
nameorid => $nameorid, # OR [ $nameorid1, $nameorid2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
force => 1,
);
=item Return Values
This method returns an AFS::Object::PTServer object, which
contains one AFS::Object::User or AFS::Object::Group
object for each user/group specified.
my $result = $pts->membership
(
nameorid => $user,
cell => $cell,
) || die $pts->errors();
my $userobj = $result->getUserbyName($user);
print "User $user is a member of these groups:\n";
foreach my $group ( $userobj->getMembership() ) {
print "\t$group\n";
}
Each of these objects has the following attributes and methods:
B<AFS::Object::PTServer>
Methods Returns
lib/AFS/Command/PTS.pod view on Meta::CPAN
value, if they succeed or fail.
=head2 adduser
The pts help string is:
pts adduser: add a user to a group
Usage: pts adduser -user <user name>+ -group <group name>+
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->adduser
(
# Required arguments
user => $user, # OR [ $user1, $user2, ... ]
group => $group, # OR [ $group1, $group2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
force => 1,
);
=head2 chown
The pts help string is:
pts chown: change ownership of a group
Usage: pts chown -name <group name> -owner <new owner>
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->chown
(
# Required arguments
name => $name,
owner => $owner,
# Optional arguments
cell => $cell,
noauth => 1,
force => 1,
);
=head2 delete
The pts help string is:
pts delete: delete a user or group from database
Usage: pts delete -nameorid <user or group name or id>+
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->delete
(
# Required arguments
nameorid => $nameorid, # OR [ $nameorid1, $nameorid2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
force => 1,
);
=head2 removeuser
The pts help string is:
pts removeuser: remove a user from a group
Usage: pts removeuser -user <user name>+ -group <group name>+
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->removeuser
(
# Required arguments
user => $user, # OR [ $user1, $user2, ... ]
group => $group, # OR [ $group1, $group2, ... ]
# Optional arguments
cell => $cell,
noauth => 1,
force => 1,
);
=head2 rename
The pts help string is:
pts rename: rename user or group
Usage: pts rename -oldname <old name> -newname <new name>
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->rename
(
# Required arguments
oldname => $oldname,
newname => $newname,
# Optional arguments
cell => $cell,
noauth => 1,
force => 1,
);
=head2 setfields
The pts help string is:
pts setfields: set fields for an entry
Usage: pts setfields -nameorid <user or group name or id>+ [-access <set privacy flags>]
[-groupquota <set limit on group creation>]
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->setfields
(
# Required arguments
nameorid => $nameorid, # OR [ $nameorid1, $nameorid2, ... ]
# Optional arguments
access => $access,
groupquota => $groupquota,
cell => $cell,
noauth => 1,
force => 1,
);
=head2 setmax
The pts help string is:
pts setmax: set max id
Usage: pts setmax [-group <group max>] [-user <user max>]
[-cell <cell name>] [-noauth] [-force]
The corresponding method invocation looks like:
my $result = $pts->setmax
(
# Optional arguments
user => $user,
group => $group,
cell => $cell,
noauth => 1,
force => 1,
);
=head1 SEE ALSO
lib/AFS/Command/VOS.pm view on Meta::CPAN
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;
lib/AFS/Command/VOS.pm view on Meta::CPAN
);
} 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
lib/AFS/Command/VOS.pm view on Meta::CPAN
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*$: ) {
lib/AFS/Command/VOS.pm view on Meta::CPAN
}
$header->_setAttribute
(
raw => $raw,
author => $author,
);
}
$result->_addVolumeHeader($header);
next;
}
#
# The rest of the information we get will be from the
# VLDB. This will start with the volume ids, which we DO want
# to check against those found above, since they are from a
# different source, and a conflict is cause for concern.
#
if ( /^\s+RWrite:\s+(\d+)/ ) {
if ( /RWrite:\s+(\d+)/ ) { $entry->_setAttribute( rwrite => $1 ); }
if ( /ROnly:\s+(\d+)/ ) { $entry->_setAttribute( ronly => $1 ); }
if ( /Backup:\s+(\d+)/ ) { $entry->_setAttribute( backup => $1 ); }
if ( /RClone:\s+(\d+)/ ) { $entry->_setAttribute( rclone => $1 ); }
next;
} # if ( /^\s+RWrite:....
#
# Next we are looking for the number of sites, and then we'll
# suck that data in as well.
#
# NOTE: Because there is more interesting data after the
# locations, we fall through to the next test once we are done
# parsing them.
#
if ( /^\s+number of sites ->\s+(\d+)/ ) {
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
last unless m:^\s+server\s+(\S+)\s+partition\s+(/vicep\w+)\s+([A-Z]{2})\s+Site\s*(--\s+)?(.*)?:;
lib/AFS/Command/VOS.pm view on Meta::CPAN
#
# Actually, this is the last possibility... The volume name
# leading the VLDB entry stanza.
#
if ( /^(\S+)/ ) {
$entry->_setAttribute( name => $1 );
}
}
$result->_addVLDBEntry($entry);
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listaddrs {
my $self = shift;
my (%args) = @_;
my @result = ();
$self->{operation} = "listaddrs";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
lib/AFS/Command/VOS.pm view on Meta::CPAN
if ( $args{printuuid} ) {
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
if ( /^UUID:\s+(\S+)/ ) {
my $fileserver = AFS::Object::FileServer->new( uuid => $1 );
my @addresses = ();
my $hostname = "";
while ( defined($_ = $self->{handle}->getline()) ) {
s/^\s*//g;
s/\s*$//g;
last if /^\s*$/;
chomp;
if ( /^\d+\.\d+\.\d+\.\d+$/ ) {
push(@addresses,$_);
} else {
$hostname = $_;
}
}
$fileserver->_setAttribute( addresses => \@addresses ) if @addresses;
$fileserver->_setAttribute( hostname => $hostname ) if $hostname;
push(@result,$fileserver);
}
}
} elsif ( $args{uuid} ) {
my @addresses = ();
my $hostname = "";
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
s/^\s*//g;
s/\s*$//g;
if ( /^\d+\.\d+\.\d+\.\d+$/ ) {
push(@addresses,$_);
} else {
$hostname = $_;
}
}
if ( $hostname || @addresses ) {
my $fileserver = AFS::Object::FileServer->new();
$fileserver->_setAttribute( addresses => \@addresses ) if @addresses;
$fileserver->_setAttribute( hostname => $hostname ) if $hostname;
push(@result,$fileserver);
}
} else {
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
s/^\s*//g;
s/\s*$//g;
if ( /^\d+\.\d+\.\d+\.\d+$/ ) {
push(@result,AFS::Object::FileServer->new( addresses => [$_] ));
} else {
push(@result,AFS::Object::FileServer->new( hostname => $_ ));
}
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return @result;
}
sub listpart {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::FileServer->new();
$self->{operation} = "listpart";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
lib/AFS/Command/VOS.pm view on Meta::CPAN
chomp;
next unless m:/vice:;
s/^\s+//g;
s/\s+$//g;
foreach my $partname ( split ) {
my $partition = AFS::Object::Partition->new( partition => $partname );
$result->_addPartition($partition);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listvldb {
my $self = shift;
my (%args) = @_;
$self->{operation} = "listvldb";
my $locked = 0;
my $result = AFS::Object::VLDB->new();
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
lib/AFS/Command/VOS.pm view on Meta::CPAN
#
next if /^VLDB entries for /;
s/\s+$//g; # Might be trailing whitespace...
#
# We either get the total number of volumes, or we assume the
# line is a volume name.
#
if ( /Total entries:\s+(\d+)/ ) {
$result->_setAttribute( total => $1 );
next;
}
my $name = $_;
my $entry = AFS::Object::VLDBEntry->new( name => $name );
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
lib/AFS/Command/VOS.pm view on Meta::CPAN
# Last possibility (that we know of) -- volume might be
# locked.
#
if ( /LOCKED/ ) {
$entry->_setAttribute( locked => 1 );
$locked++;
}
}
$result->_addVLDBEntry( $entry );
}
$result->_setAttribute( locked => $locked );
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
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()) ) {
lib/AFS/Command/VOS.pm view on Meta::CPAN
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+)/ ) {
lib/AFS/Command/VOS.pm view on Meta::CPAN
next;
}
} # while(defined($_ = $self->{handle}->getline())) {
}
$partition->_addVolumeHeader($volume);
}
$result->_addPartition($partition);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub partinfo {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::FileServer->new();
$self->{operation} = "partinfo";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
lib/AFS/Command/VOS.pm view on Meta::CPAN
next unless m|partition (/vice\w+): (-?\d+)\D+(\d+)$|;
my $partition = AFS::Object::Partition->new
(
partition => $1,
available => $2,
total => $3,
);
$result->_addPartition($partition);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
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+)/ ) {
lib/AFS/Command/VOS.pm view on Meta::CPAN
}
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;
if ( $gzip && $bzip2 && $nocompress ) {
$self->_Carp("Invalid argument combination: only one of 'gzip' or 'bzip2' or 'nocompress' may be specified");
return;
}
if ( $file eq 'stdin' ) {
$self->_Carp("Invalid argument 'stdin': you can't write output to stdin");
return;
}
if ( $file ne 'stdout' ) {
if ( $file =~ /\.gz$/ && not defined $gzip and not defined $nocompress ) {
$gzip = $gzip_default;
} elsif ( $file =~ /\.bz2$/ && not defined $bzip2 and not defined $nocompress ) {
$bzip2 = $bzip2_default;
}
if ( $gzip && $file !~ /\.gz$/ ) {
$file .= ".gz";
} elsif ( $bzip2 && $file !~ /\.bz2/ ) {
$file .= ".bz2";
}
unless ( $gzip || $bzip2 || $filterout ) {
lib/AFS/Command/VOS.pm view on Meta::CPAN
my $errors = 0;
$errors++ unless $self->_exec_cmds
(
stdout => ( $args{file} ? "/dev/null" : $file ),
);
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return 1;
}
sub restore {
my $self = shift;
my (%args) = @_;
$self->{operation} = "restore";
my $file = delete $args{file} || do {
$self->_Carp("Missing required argument: 'file'");
return;
};
my $nocompress = delete $args{nocompress} || undef;
my $gunzip = delete $args{gunzip} || undef;
my $bunzip2 = delete $args{bunzip2} || undef;
my $filterin = delete $args{filterin} || undef;;
if ( $gunzip && $bunzip2 && $nocompress ) {
$self->_Carp("Invalid argument combination: only one of 'gunzip' or 'bunzip2' or 'nocompress' may be specified");
return;
}
if ( $file eq 'stdout' ) {
$self->_Carp("Invalid argument 'stdout': you can't read input from stdout");
return;
}
if ( $file ne 'stdin' ) {
if ( $file =~ /\.gz$/ && not defined $gunzip and not defined $nocompress ) {
$gunzip = 1;
} elsif ( $file =~ /\.bz2$/ && not defined $bunzip2 and not defined $nocompress ) {
$bunzip2 = 1;
}
unless ( $gunzip || $bunzip2 || $filterin ) {
$args{file} = $file;
}
}
return unless $self->_parse_arguments(%args);
lib/AFS/Command/VOS.pod view on Meta::CPAN
=item new
=item errors
=item supportsOperation
=item supportsArgument
=back
=head1 METHODS (dump, restore)
Both the 'dump' and 'restore' methods are special, since this API
supports compression to and from the filesystem when dumping or
restoring the volume. Normally, "vos dump -file" will just wrote the
uncompressed volume dump to the file, but this API can compress it.
This is a huge cost savings in disk space, assuming you can afford the
CPU time to perform the compression (this is the 21st century -- you
probably can).
Both of these commands return simply boolean true/false values, but
they have some special case handling for the -file argument, and
support several special arguments that are extensions implemented in
this API only.
=head2 dump
The vos help string is:
vos dump: dump a volume
Usage: vos dump -id <volume name or ID> [-time <dump from time>] [-file <dump file>]
[-server <server>] [-partition <partition>] [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->dump
(
# Required arguments
id => $id,
file => $file, # SPECIAL CASE!!! (see below)
# Optional arguments
time => $time,
server => $server,
partition => $partition,
cell => $cell,
noauth => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
The first thing to notice is that 'file' is optional to the vos dump
command itself, but required in this API. The second thing to notice
is the addition of three new arguments: gzip, bzip2 and filterout.
=over
=item file
This argument specifies the file to which the vos dump output should
be written. If this file ends in '.gz' or '.bz2', then gzip or bzip2
will be used to compress the output before it is written to the
filesystem. This is accomplished using a pipe, so there is no
intermediate file written to disk first.
By default, 'vos dump' will write the volume dump to stdout, which is
not what you want in most applications. If you really want the volume
to be written to stdout, then you have to explicitly say so:
my $result = $vos->dump
(
...
file => 'stdout',
...
);
=item gzip, bzip2
Both of these arguments will turn on compression explicitly, and if
the file specified doesn't end in the appropriate extension already
('.gz' for gzip, and '.bz2' for bzip2), then the extension is appended
to the filename.
The value of these arguments specifies the degree of compression used,
an should be a single numeric digit, from 0 to 9. See the gzip and
bzip2 man pages for more information.
These arguments are also mutually exclusive.
=item filterout
This is an advanced feature, and one that allows the volume dump to be
filtered through any arbitrary number of commands before it is
compressed (optionally) and written to the filesystem. The value of
this argument is either an ARRAY reference to a list of command line
arguments, suitable for passing to exec(), or an ARRAY or such ARRAYS,
when more than one filter command is being used.
For example, the author has a requirement to pass all volume dumps
through a simple filter called 'newversion', which reads a volume
dump, changes the directory version numbers to the current utime
value, and writes the volume dump to stdout. Trust me, you really
don't want to know why.
my $result = $vos->dump
(
...
filterout => [ 'newversion' ],
...
);
If there were command line arguments for this command, then they must
be given as follows:
my $result = $vos->dump
(
...
filterout => [ 'newversion', '-arg1', '-value1' ],
...
);
These args are passed directly to exec, with no shell involved. When
more than one command is given, then an ARRAY or ARRAYs must be
specified as follows:
my $result = $vos->dump
(
...
filterout => [
[ 'command1', '-arg1', '-value1' ],
[ 'command2', '-arg2', '-value2' ],
[ 'command3', '-arg3', '-value3' ],
],
...
);
If B<ANY> of the filterout commands exits with a non-zero status, then
the entire dump method invocation is considered to fail. You may or
may not get a valid volume dump file, compressed or otherwise,
depending on the behavior of the commands you specify.
=back
=head2 restore
The vos help string is:
vos restore: restore a volume
Usage: vos restore -server <machine name> -partition <partition name>
-name <name of volume to be restored> [-file <dump file>]
[-id <volume ID>] [-overwrite <abort | full | incremental>]
[-offline] [-readonly]
[-creation <dump | keep | new>] [-lastupdate <dump | keep | new>]
[-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
Where: -offline leave restored volume offline
-readonly make restored volume read-only
The corresponding method invocation looks like:
my $result = $vos->restore
(
# Required arguments
server => $server,
partition => $partition,
name => $name,
file => $file, # SPECIAL CASE!!! (see below)
# Optional arguments
id => $id,
overwrite => 'abort' | 'full' | 'incremental',
offline => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
encrypt => 1,
# Enhanced arguments
gunzip => 1,
bunzip2 => 1,
filterin => [ @command ], # OR [ [ @cmd1 ], [ @cmd2 ], ... ]
);
NOTE: The 'creation' and 'lastupdate' options are available only in a
very recent patch to the vos command, which should be available in the
OpenAFS 1.2.11 or 1.2.12 releases. These options control how the
Creation and LastUpdate timestamps are set on the restored volume.
The 3 values these options can take, and their meanings, are:
=over
=item dump
Use the timestamp from the volume dump file being restored to the
volume. This is the default behavior for the LastUpdate timestamp.
=item keep
Preserve the existing timestamp on the volume.
=item new
Set the timestamp to the current time. This is the default behavior
for the Creation timestamp.
=back
Note that the default behavior creates the condition where the
Creation time is newer than the LastUpdate time, and when this is
true, "vos examine" (or any command that display the timestamps in the
volume header, really) will show the Creation time as the LastUpdate
time, presumably because it would be confusing to show the volume as
having been updated before it was created.
Similar to 'vos dump', the 'file' argument is optional to 'vos
restore', but required in this API. There are also three new
arguments: gunzip, bunzip2, and filterin. The analogy with 'vos dump'
is by design entirely symmetrical.
=over
=item file
This argument specifies the file from which the vos restore input
should be read. If the file ends in '.gz' or '.bz2', then gunzip or
bunzip2 will be used to uncompress the input before it is read by vos
restore. This is accomplished using a pipe, so there is no
intermediate file written to disk first.
By default, 'vos restore' will read the volume dump from stdin, which
is not what you want in most applications. If you really want the
volume to be read from stdin, then you have to explicitly say so:
my $result = $vos->restore
(
...
file => 'stdin',
...
);
=item gunzip, bunzip2
Both of these arguments will turn on uncompression explicitly,
although they only need to be specified if the need for uncompression
can not be determined dynamically from the filename. If the files are
compressed, but lack the proper extension ('.gz' or '.bz2'), or if the
compressed input is being read from stdin, then uncompression must be
specified explicitly.
These arguments have boolean values, since uncompression is either on
or off. They are mutually exclusive as well.
=item filterin
This is an advanced feature, and one that allows the volume dump to be
filtered through any arbitrary number of commands after it is
uncompressed (optionally) and read by vos restore. The value of this
argument is either an ARRAY reference to a list of command line
arguments, suitable for passing to exec(), or an ARRAY or such ARRAYS,
when more than one filter command is being used.
Lacking a better example, let's assume the author's 'newversion'
utility is being applied to the restore process, rather than the dump.
my $result = $vos->restore
(
...
filterin => [ 'newversion' ],
...
);
If there were command line arguments for this command, then they must
be given as follows:
my $result = $vos->restore
(
...
filterin => [ 'newversion', '-arg1', '-value1' ],
...
);
These args are passed directly to exec, with no shell involved. When
more than one command is given, then an ARRAY or ARRAYs must be
specified as follows:
my $result = $vos->restore
(
...
filterin => [
[ 'command1', '-arg1', '-value1' ],
[ 'command2', '-arg2', '-value2' ],
[ 'command3', '-arg3', '-value3' ],
],
...
);
If B<ANY> of the filterin commands exits with a non-zero status, then
the entire restore method invocation is considered to fail. You may
or may not get a valid volume restored to your fileserver, depending
on the behavior of the commands you specify.
=back
=head1 METHODS (with complex return values)
=head2 examine
=over
=item Arguments
The vos help string is:
vos examine: everything about the volume
Usage: vos examine -id <volume name or ID> [-extended] [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
Where: -extended list extended volume fields
The corresponding method invocation looks like:
my $result = $vos->examine
(
# Required arguments
id => $id,
# Optional arguments
cell => $cell,
extended => 1,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
=item Return Values
This method returns an AFS::Object::Volume object, which in
turn contains one or more AFS::Object::VolumeHeader objects,
as well as an AFS::Object::VLDBEntry, which contains one or
more AFS::Object::VLDBSite objects.
my $result = $vos->examine
(
id => $volname,
cell => $cell,
) || die $vos->errors();
foreach my $header ( $result->getVolumeHeaders() ) {
my ($server,$partition) = ($header->server(),$header->partition());
print "[header] server = $server, partition = $partition\n";
}
my $vldbentry = $result->getVLDBEntry();
foreach my $vldbsite ( $vldbentry->getVLDBSites() ) {
my ($server,$partition) = ($vldbsite->server(),$vldbsite->partition());
print "[vldbsite] server = $server, partition = $partition\n";
}
Each of these objects has the following attributes and methods:
B<AFS::Object::Volume>
lib/AFS/Command/VOS.pod view on Meta::CPAN
server pasafq1 partition /viceph RO Site
server pasafq2 partition /vicepg RO Site
server pasafq4 partition /vicepc RO Site
server pasafq5 partition /vicepg RO Site
The object attributes are taken from the first two lines of output:
root.afs
RWrite: 536918445 ROnly: 536918450
The following attributes should always be present:
Attributes Values
---------- ------
name Volume name
rwrite Numeric Volume ID for the RW volume
locked Boolean value, indicating the VLDB entry is locked or not
The following attributes may be present, if there are volumes of the
associated type in the VLDB entry:
Attributes Values
---------- ------
ronly Numeric Volume ID for the RO volume
backup Numeric Volume ID for the BK volume
rclone Numeric Volume ID for the RClone volume, if present
Note that the 'rclone' attribute is only present if the volume was
actively being cloned while being examined. This is true when a 'vos
release' command is actively updating the RO volumes.
The following methods are available:
Methods Returns
------- -------
getVLDBSites() list of AFS::Object::VLDBSite objects
B<AFS::Object::VLDBSite>
lib/AFS/Command/VOS.pod view on Meta::CPAN
0 accesses in the past day (i.e., vnode references)
Note that there may very well be more than one of these, if a
.readonly is examined, since the volume headers for all of the RO
volumes will be queried.
The attributes available in this object depend on the method
arguments, as well as the state of the volume (less information can be
obtained when a volume is busy, for example).
The following attributes should always be present.
Attributes Values
---------- ------
id Numeric Volume ID
status online | offline | busy
attached Boolean
The 'attached' attribute is a Boolean that indicates whether or not
the volume is attached by the volserver. A volume which can not be
brought online due to volume header problems will be offline, and
unattached (attached == 0), but a volume can be offline for other
reasons, (eg. vos offline, or more than one volume with the same ID on
the same server), and still be attached (attached == 1).
The following attributes are present only if the volume's status is
'online':
Attributes Values
---------- ------
name Volume Name
type "RO" | "RW" | "BK"
size Numeric size in KB
server Fileserver hostname
partition Fileserver /vice partition
maxquota Volume quota in KB
creation Volume creation date (ctime format, eg: Sat Oct 6 04:39:50 2001)
copyTime Volume copy date (also in ctime format)
backupTime Volume backup date (also in ctime format)
access Volume Last Access date (also in ctime format)
update Volume update date (also in ctime format)
accesses Number of volume accesses since the last reset
rwrite Numeric Volume ID for the RW volume
ronly Numeric Volume ID for the RO volume
backup Numeric Volume ID for the BK volume
rclone Numeric Volume ID for the RClone volume, if present
Note that the 'rclone' attribute is only present if the volume was
actively being cloned while being examined. This is true when a 'vos
release' command is actively updating the RO volumes.
The following attributes are only present if the 'extended' argument
was specified (see below for details on access the raw and author
stats):
Attributes Values
---------- ------
files Number of files in the volume
raw Generic AFS::Object object
author Generic AFS::Object object
The 'raw' and 'author' stats are implemented as a hierarchy of simple,
lib/AFS/Command/VOS.pod view on Meta::CPAN
1-10 min | 87 | 0 | 105 | 0 |
10min-1hr | 42 | 0 | 44 | 0 |
1hr-1day | 18 | 0 | 6 | 0 |
1day-1wk | 0 | 0 | 0 | 0 |
> 1wk | 1 | 0 | 0 | 0 |
|-------------------------------------------|
Since attributes can most easily be accessed by calling the method of
the same name, one can easily dig into the hierarchy as follows:
my $result = $vos->examine
(
id => 'user.wpm',
cell => 'q.ny.ms.com',
extended => 1,
);
print $result->raw()->reads()->same()->total(); # 162, in the above output.
print $result->author()->10min()->dir()->same(); # 44, in the above output.
See? It's not as ugly as the pedantic description above implies.
=back
=head2 listaddrs
=over
=item Arguments
The vos help string is:
vos listaddrs: list the IP address of all file servers registered in the VLDB
Usage: vos listaddrs [-uuid <uuid of server>] [-host <address of host>]
[-noresolve] [-printuuid] [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
Where: -noresolve don't resolve addresses
-printuuid print uuid of hosts
The corresponding method invocation looks like:
my $result = $vos->listaddrs
(
# Optional arguments
uuid => $uuid,
host => $host,
noresolve => 1,
printuuid => 1,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
=item Return Values
This method returns a list of AFS::Object::FileServer
objects, each of which has attributes that vary depending on the
arguments to the method call.
In particular, vos will try to map IP addresses into hostnames, and
this may or may not succeed, depending on the stability and
correctness of the hostname resolution mechanism (usually DNS, of
course, but that is outside of vos' control).
my @result = $vos->listaddrs
(
cell => $cell,
);
foreach my $result ( @result ) {
if ( $result->hasAttribute('hostname') {
print "Hostname: " . $result-hostname() . "\n";
} elsif ( $result->hasAttribute('addresses') {
my $addresses = $result->addresses();
foreach my $address ( @addresses ) {
print "IP Address: $address\n";
}
}
}
If a specific 'host' or 'uuid' is specified, then only one object will
be returned (assuming the specified host or uuid is valid, of course,
otherwise, you get nothing).
B<AFS::Object::FileServer>
This object will have one or more of the following attributes,
depending on the choice of arguments to the method, as well as the
ability of vos to map the IP addresses back into hostnames.
Attributes Values
---------- ------
hostname Server's hostname (duh)
addresses ARRAY reference of IP addresses
uuid Servers's UUID (duh)
The 'uuid' will be present if the 'printuuid' or 'uuid' arguments were
passed to the method call. The 'addresses' will be present either
'noresolve' was specified, or vos has problems with hostname
resolution.
=back
=head2 listpart
=over
=item Arguments
The vos help string is:
vos listpart: list partitions
Usage: vos listpart -server <machine name> [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->listpart
(
# Required arguments
server => $server,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
=item Return Values
This method returns an AFS::Object::FileServer object, which
contains one or more AFS::Object::Partition objects. Because
'listpart' returns nothing other than the partition names, the
underlying Partition objects have only one attribute ('partition'), so
the API for access this data is trivial:
my $result = $vos->listpart
(
server => 'fs1.ms.com',
) || die $vos->errors();
foreach my $partition ( $result->getPartitionNames() ) {
print "Server '$server' has partition '$partition'\n";
}
The FileServer object has no attributes at all, it merely contains the
Partition objects. Since the Partition objects are indexed by name,
there's no need to extract the partition objects and query their
attributes, since once you have the names, you have all the information
already.
Compare this with 'vos partinfo', which provides a lot more
lib/AFS/Command/VOS.pod view on Meta::CPAN
B<AFS::Object::Partition>
This object has one boring attribute:
Attributes Values
---------- ------
partition Fileserver /vice partition name
When used to encapsulate 'vos listpart' output, this object has no
relevant methods. Note, however, that this version of the API reuses
this object to represent other partition-related data (see 'vos
listvol' method documentation, for example), but they are not relevant
in this usage of the object. This multiple personality of the objects
may be changed in a future release, so don't get too attached to the
specific class names.
See the AFS::Object documentation for a discussion of the
planned evolution of the API.
=back
lib/AFS/Command/VOS.pod view on Meta::CPAN
The vos help string is:
vos listvldb: list volumes in the VLDB
Usage: vos listvldb [-name <volume name or ID>] [-server <machine name>]
[-partition <partition name>] [-locked] [-quiet] [-nosort]
[-cell <cell name>] [-noauth] [-localauth] [-verbose] [-encrypt]
Where: -locked locked volumes only
-quiet generate minimal information
-nosort do not alphabetically sort the volume names
The corresponding method invocation looks like:
my $result = $vos->listvldb
(
# Optional arguments
name => $name,
server => $server,
partition => $partition,
locked => 1,
quiet => 1,
nosort => 1,
cell => $cell,
noauth => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
AFS::Object::VLDBEntry objects, which in turn contain
AFS::Object::VLDBSite objects, as well as their own
attributes.
NOTE: the VLDBEntry and VLDBSite objects are the same as those used by
the 'examine' method, since that command also queries the VLDB for
part of its return values. See that discussion above for some
relevant details on the parsing of those objects, which will no be
repeated here.
my $result = $vos->listvldb
(
cell => $cell,
) || die $vos->errors();
print("VLDB contains " . $result->total() " volumes, " .
$result->locked() . " of which are locked\n");
foreach my $entry ( $result->getVLDBEntries() ) {
my $name = $entry->name();
foreach my $attr ( $entry->listAttributes() ) {
print "Volume $name has attribute $attr => " . $entry->$attr() . "\n";
}
foreach my $site ( $entry->getVLDBSites() ) {
my %attrs = $site->getAttributes();
while ( my($attr,$value) = each %attrs ) {
print "Site has attribute $attr => $value\n";
}
}
}
Another way to slice and dice this data:
foreach my $name ( $result->getVolumeNames() ) {
my $entry = $result->getVLDBEntry( name => $name );
....
}
Each of these objects has the following attributes and methods:
B<AFS::Object::VLDB>
This object has two attributes, and several methods:
Attributes Values
---------- ------
total Number of VLDBEntries in the results
locked Number of locked volumes in the results
Methods Returns
------- -------
getVolumeNames() list of volume names in the results
getVolumeIds() list of numeric volume IDs
getVLDBEntry(name => $name) the AFS::Object::VLDBEntry for name $name
getVLDBEntry(id => $id) the AFS::Object::VLDBEntry for id $id
getVLDBEntries() list of AFS::Object::VLDBEntry objects
getVLDBEntryByName($name) the AFS::Object::VLDBEntry for $name
getVLDBEntryById($id) the AFS::Object::VLDBEntry for $id
NOTE: name to volume mappings are one to one, but id to volume
mappings are many to one, since a single logical VLDB entry can have
several IDs associated with it (RW, RO, BK, and/or RC).
B<AFS::Object::VLDBEntry>
This object also has a few attributes, and a few methods. The 'name'
attribute is always present, but the others vary, depending on the
volume (again, see the 'examine' documentation for more verbosity).
Attributes Values
---------- ------
name Volume name
rwrite Numeric Volume ID for the RW volume
ronly Numeric Volume ID for the RO volume
backup Numeric Volume ID for the BK volume
rclone Numeric Volume ID for the RClone volume, if present
locked Boolean, indicating whether or not the VLDB entry is locked
Methods Returns
------- -------
getVLDBSites() list of AFS::Object::VLDBSite objects
B<AFS::Object::VLDBSite>
The following attributes are always available:
lib/AFS/Command/VOS.pod view on Meta::CPAN
vos listvol: list volumes on server (bypass VLDB)
Usage: vos listvol -server <machine name> [-partition <partition name>]
[-fast] [-long] [-quiet] [-extended] [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
Where: -fast minimal listing
-long list all normal volume fields
-quiet generate minimal information
-extended list extended volume fields
The corresponding method invocation looks like:
my $result = $vos->listvol
(
# Required arguments
server => $server,
# Optional arguments
partition => $partition,
fast => 1,
long => 1,
quiet => 1,
extended => 1, # Not really... see below
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
NOTE: 'extended' is not supported in this version of the API, and
specifying it will result in a warning, but not an error. However,
'vos examine' does parse the extended output, so if you really want
that data you can get it on a volume by volume basis. Adding support
for 'extended' to 'vos listvol' is on the todo list.
=item Return Values
This method returns an AFS::Object::VolServer object, which
merely contains one or more AFS::Object::Partition objects,
which in turn have a few attributes and contain one or more
AFS::Object::VolumeHeader objects.
my $result = $vos->listvol
(
server => $server,,
cell => $cell,
) || die $vos->errors();
foreach my $partition ( $result->getPartitions() ) {
my $partname = $partition->partition();
my $total = $partition->total();
my $online = $partition->online();
my $offline = $partition->offline();
my $busy = $partition->busy();
print("Partition $partname has $total total volumes, of which " .
"$online are online, $offline are offline, and $busy are busy.\n");
foreach my $header ( $partition->getVolumeHeaders() ) {
# Do something interesting with $header.
}
}
There are several other ways to get at the headers, of course.
foreach my $name ( $partition->getVolumeNames() ) {
my $header = $partition->getVolumeHeaderByName($name)
# Do something interesting with $header.
}
foreach my $id ( $partition->getVolumeIds() ) {
my $header = $partition->getVolumeHeaderById($id);
# Do something interesting with $header.
}
And there is yet one more method to extract the headers (don't say the
author doesn't pander to lots of different programming styles,
provided of course they are one of his own).
foreach my $name ( $partition->getVolumeNames() ) {
my $header = $partition->getVolumeHeader( name => $name );
# Do something interesting with $header.
}
foreach my $id ( $partition->getVolumeIds() ) {
my $header = $partition->getVolumeHeader( id => $id );
# Do something interesting with $header.
}
Each of these objects has the following attributes and methods:
B<AFS::Object::VolServer>
This object has no attributes, and has several methods for extracting
the partition objects.
Methods Returns
lib/AFS/Command/VOS.pod view on Meta::CPAN
getVolumeHeaderById($id)
getVolumeHeader( id => $id )
And it should be obvious, but these are also equivalent we well:
getVolumeHeaderByName($name)
getVolumeHeader( name => $name )
B<AFS::Object::VolumeHeader>
The following attributes should always be present.
Attributes Values
---------- ------
id Numeric Volume ID
status online | offline | busy
attached Boolean
The 'attached' attribute is a Boolean that indicates whether or not
the volume is attached by the volserver. A volume which can not be
brought online due to volume header problems will be offline, and
unattached (attached == 0), but a volume can be offline for other
reasons, (eg. vos offline, or more than one volume with the same ID on
the same server), and still be attached (attached == 1).
If the 'fast' argument was specified, then none of the other
attributes will be present.
The following attributes are present only if the volume's status is
'online':
Attributes Values
---------- ------
name Volume Name
type "RO" | "RW" | "BK"
size Numeric size in KB
The following attributes are present only if the 'long' argument was
specified:
Attributes Values
---------- ------
server Fileserver hostname
partition Fileserver /vice partition
maxquota Volume quota in KB
creation Volume creation date (ctime format, eg: Sat Oct 6 04:39:50 2001)
copyTime Volume copy date (also in ctime format)
backupTime Volume backup date (also in ctime format)
access Volume Last Access date (also in ctime format)
update Volume update date (also in ctime format)
accesses Number of volume accesses since the last reset
rwrite Numeric Volume ID for the RW volume
ronly Numeric Volume ID for the RO volume
backup Numeric Volume ID for the BK volume
rclone Numeric Volume ID for the RClone volume, if present
=back
=head2 partinfo
=over
=item Arguments
The vos help string is:
vos partinfo: list partition information
Usage: vos partinfo -server <machine name> [-partition <partition name>]
[-cell <cell name>] [-noauth] [-localauth]
[-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->partinfo
(
# Required arguments
server => $server,
# Optional arguments
partition => $partition,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
=item Return Values
This method returns an AFS::Object::FileServer object, which
contains one or more AFS::Object::Partition objects, which
have more interesting attributes than those returned by 'vos
partinfo'.
my $result = $vos->partinfo
(
server => $server,
cell => $cell,
) || die $vos->errors();
foreach my $partition ( $result->getPartitions() ) {
my $partname = $partition->partition();
my $available = $partition->available();
my $total = $partition->total();
print("Partition $partname has $available KB of " .
"space available out of $total KB total\n");
}
B<AFS::Object::FileServer>
This object has no attributes, and is merely a container for the
lib/AFS/Command/VOS.pod view on Meta::CPAN
=over
=item Arguments
The vos help string is:
vos status: report on volser status
Usage: vos status -server <machine name> [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->status
(
# Required arguments
server => $server,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
=item Return Values
This method returns an AFS::Object::VolServer object with one
attribute, which also may or may not contain one or more
AFS::Object::Transaction objects.
my $result = $vos->status
(
server => $server,
) || die $vos->errors();
print "Server has " . $result->transactions() . "active transactions\n";
foreach my $transaction ( $result->getTransactions() ) {
print("There are active transactions for volume ID " .
$transaction->volume() . "\n");
}
B<AFS::Object::VolServer>
This object has exactly one attribute, and several methods:
Attributes Values
---------- ------
lib/AFS/Command/VOS.pod view on Meta::CPAN
B<AFS::Object::Transaction>
This object has several attributes:
Attributes Values
---------- ------
transaction Numeric transaction ID
created Creation date (in ctime format)
attachFlags String (exact meaning unclear)
volume Numeric volume ID
partition Vice partition on whcih the volume resides
procedure What is being done to the volume
packetRead Numeric value
lastReceiveTime Time value (utime format)
packetSend Numeric value
lastSendTime Time value (utime format)
NOTE: These attributes just come from a straight parsing of output like this:
--------------------------------------
transaction: 170423 created: Wed Oct 8 15:59:12 2003
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 addsite
The vos help string is:
vos addsite: add a replication site
Usage: vos addsite -server <machine name for new site> -partition <partition name for new site>
-id <volume name or ID> [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->addsite
(
# Required arguments
server => $server,
partition => $partition,
id => $id,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
);
=head2 backup
The vos help string is:
vos backup: make backup of a volume
Usage: vos backup -id <volume name or ID> [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->backup
(
# Required arguments
id => $id,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
lib/AFS/Command/VOS.pod view on Meta::CPAN
The vos help string is:
vos backupsys: en masse backups
Usage: vos backupsys [-prefix <common prefix on volume(s)>+] [-server <machine name>]
[-partition <partition name>] [-exclude]
[-xprefix <negative prefix on volume(s)>+] [-dryrun]
[-cell <cell name>] [-noauth] [-localauth] [-verbose] [-encrypt]
Where: -exclude exclude common prefix volumes
-dryrun no action
The corresponding method invocation looks like:
my $result = $vos->backupsys
(
# Optional arguments
prefix => $prefix, # OR [ $prefix1, $prefix2, ... ]
server => $server,
partition => $partition,
exclude => 1,
prefix => $xprefix, # OR [ $xprefix1, $xprefix2, ... ]
dryrun => 1,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
=head2 changeaddr
The vos help string is:
vos changeaddr: change the IP address of a file server
Usage: vos changeaddr -oldaddr <original IP address> [-newaddr <new IP address>]
[-remove] [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
Where: -remove remove the IP address from the VLDB
The corresponding method invocation looks like:
my $result = $vos->changeaddr
(
# Required arguments
oldaddr => $oldaddr,
# Optional arguments
newaddr => $newaddr,
remove => 1,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 changeloc
The vos help string is:
vos changeloc: change an RW volume's location in the VLDB
Usage: vos changeloc -server <machine name for new location>
-partition <partition name for new location>
-id <volume name or ID> [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->changeloc
(
# Required arguments
server => $server,
partition => $partition,
id => $id,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
The vos help string is:
vos clone: make clone of a volume
Usage: vos clone -id <volume name or ID>
[-server <server>] [-partition <partition>]
[-toname <volume name on destination>] [-toid <volume ID on destination>]
[-offline] [-readonly] [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->clone
(
# Required arguments
id => $id,
# Optional arguments
server => $server,
partition => $partition,
toname => $newname,
toid => $newid,
cell => $cell,
noauth => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 convertROtoRW
The vos help string is:
vos convertROtoRW: convert a RO volume into a RW volume (after loss of old RW volume)
Usage: vos convertROtoRW -server <machine name> -partition <partition name>
-id <volume name or ID> [-force] [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->convertROtoRW
(
# Required arguments
server => $server,
partition => $partition,
id => $id,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
The vos help string is:
vos copy: copy a volume
Usage: vos copy -id <volume name or ID on source> -fromserver <machine name on source>
-frompartition <partition name on source> -toname <volume name on destination>
-toserver <machine name on destination> -topartition <partition name on destination>
[-offline] [-readonly] [-live] [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->copy
(
# Required arguments
id => $id,
fromserver => $server,
frompartition => $partition,
toname => $name
toserver => $newserver,
topartition => $newpartition,
# Optional arguments
cell => $cell,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 create
The vos help string is:
vos create: create a new volume
Usage: vos create -server <machine name> -partition <partition name>
-name <volume name> [-maxquota <initial quota (KB)>]
[-cell <cell name>] [-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->create
(
# Required arguments
server => $server,
partition => $partition,
name => $name,
# Optional arguments
maxquota => $maxquota,
cell => $cell,
noauth => 1,
localauth => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 delentry
The vos help string is:
vos delentry: delete VLDB entry for a volume
Usage: vos delentry [-id <volume name or ID>+]
[-prefix <prefix of the volume whose VLDB entry is to be deleted>]
[-server <machine name>] [-partition <partition name>]
[-cell <cell name>] [-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->delentry
(
# Optional arguments
id => $id, # OR [ $id1, $id2, ... ]
prefix => $prefix,
server => $server,
partition => $partition,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
);
=head2 lock
The vos help string is:
vos lock: lock VLDB entry for a volume
Usage: vos lock -id <volume name or ID> [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->lock
(
# Required arguments
id => $id,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
lib/AFS/Command/VOS.pod view on Meta::CPAN
The vos help string is:
vos move: move a volume
Usage: vos move -id <volume name or ID> -fromserver <machine name on source>
-frompartition <partition name on source>
-toserver <machine name on destination>
-topartition <partition name on destination> [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->move
(
# Required arguments
id => $id,
fromserver => $fromserver,
frompartition => $frompartition,
toserver => $toserver,
topartition => $topartition,
# Optional arguments
cell => $cell,
noauth => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 offline
The vos help string is:
Usage: vos offline -server <server name> -partition <partition name>
-id <volume name or ID> [-sleep <seconds to sleep>]
[-busy] [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->offline
(
# Required arguments
id => $id,
server => $server,
partition => $partition,
# Optional arguments
sleep => $sleep,
busy => 1,
cell => $cell,
noauth => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
);
=head2 online
The vos help string is:
Usage: vos online -server <server name> -partition <partition name>
-id <volume name or ID> [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->online
(
# Required arguments
id => $id,
server => $server,
partition => $partition,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 release
The vos help string is:
vos release: release a volume
Usage: vos release -id <volume name or ID> [-force] [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
Where: -force force a complete release
The corresponding method invocation looks like:
my $result = $vos->release
(
# Required arguments
id => $id,
# Optional arguments
force => 1,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 remove
The vos help string is:
vos remove: delete a volume
Usage: vos remove [-server <machine name>] [-partition <partition name>]
-id <volume name or ID> [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->remove
(
# Required arguments
id => $id,
# Optional arguments
server => $server,
partition => $partition,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 remsite
The vos help string is:
vos remsite: remove a replication site
Usage: vos remsite -server <machine name> -partition <partition name>
-id <volume name or ID> [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->remsite
(
# Required arguments
id => $id,
server => $server,
partition => $partition,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
);
=head2 rename
The vos help string is:
vos rename: rename a volume
Usage: vos rename -oldname <old volume name > -newname <new volume name >
[-cell <cell name>] [-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->rename
(
# Required arguments
oldname => $oldname,
newname => $newname,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 setfields
The vos help string is:
vos setfields: change volume info fields
Usage: vos setfields -id <volume name or ID> [-maxquota <quota (KB)>]
[-clearuse] [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
Where: -clearuse clear dayUse
The corresponding method invocation looks like:
my $result = $vos->setfields
(
# Required arguments
id => $id,
# Optional arguments
maxquota => $maxquota,
clearuse => 1,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
The vos help string is:
vos shadow: make or update a shadow volume
Usage: vos shadow -id <volume name or ID on source> -fromserver <machine name on source>
-frompartition <partition name on source> -toserver <machine name on destination>
-topartition <partition name on destination> [-toname <volume name on destination>]
[-toid <volume ID on destination>] [-offline] [-readonly] [-live] [-incremental]
[-cell <cell name>] [-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->shadow
(
# Required arguments
id => $id,
fromserver => $server,
frompartition => $partition,
toserver => $newserver,
topartition => $newpartition,
# Optional arguments
toname => $newname
toid => $newid
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 syncserv
The vos help string is:
vos syncserv: synchronize server with VLDB
Usage: vos syncserv -server <machine name> [-partition <partition name>]
[-cell <cell name>] [-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->syncserv
(
# Required arguments
server => $server,
# Optional arguments
partition => $partition,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
lib/AFS/Command/VOS.pod view on Meta::CPAN
=head2 syncvldb
The vos help string is:
vos syncvldb: synchronize VLDB with server
Usage: vos syncvldb [-server <machine name>] [-partition <partition name>]
[-volume <volume name or ID>] [-cell <cell name>]
[-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->syncvldb
(
# Optional arguments
server => $server,
partition => $partition,
volume => $volume,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
=head2 unlock
The vos help string is:
vos unlock: release lock on VLDB entry for a volume
Usage: vos unlock -id <volume name or ID> [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->unlock
(
# Required arguments
id => $id,
# Optional arguments
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
=head2 unlockvldb
The vos help string is:
vos unlockvldb: unlock all the locked entries in the VLDB
Usage: vos unlockvldb [-server <machine name>] [-partition <partition name>]
[-cell <cell name>] [-noauth] [-localauth] [-verbose] [-encrypt]
The corresponding method invocation looks like:
my $result = $vos->unlockvldb
(
# Optional arguments
server => $server,
partition => $partition,
cell => $cell,
noauth => 1,
localauth => 1,
verbose => 1,
encrypt => 1,
);
lib/AFS/Command/VOS.pod view on Meta::CPAN
The vos help string is:
vos zap: delete the volume, don't bother with VLDB
Usage: vos zap -server <machine name> -partition <partition name> -id <volume ID>
[-force] [-backup] [-cell <cell name>] [-noauth]
[-localauth] [-verbose] [-encrypt]
Where: -force force deletion of bad volumes
-backup also delete backup volume if one is found
The corresponding method invocation looks like:
my $result = $vos->zap
(
# Required arguments
server => $server,
partition => $partition,
id => $id,
# Optional arguments
force => 1,
backup => 1,
cell => $cell,
noauth => 1,
lib/AFS/Object.pod view on Meta::CPAN
#
# $Id: Object.pod,v 7.1 2004/01/13 19:01:14 wpm Exp $
#
# (c) 2003-2004 Morgan Stanley and Co.
# See ..../src/LICENSE for terms of distribution.
#
=head1 NAME
AFS::Object - Base class for encapsulating AFS::Command results
=head1 SYNOPSIS
This module is not used directly by applications, only indirectly
through the return values of the various AFS::Command::* methods.
=head1 DESCRIPTION
This class is used by the various AFS::Command classes to encapsulate
data returned from any command that has structured return values. In
the simplest case, this object just encapsulates a simple list of
key/value pairs. Each distinct key is represented as an object
attribute, and is query-able via one of several methods documented
below.
There are numerous subclasses of this class, which are used when
objects must contains other objects, and these subclasses just
implement special methods for querying the embedded objects.
=head1 METHODS
In all of the example code snippets below, $result is assumed to be an
AFS::Object object, or an object derived from it.
=head2 listAttributes
This method takes no arguments, and returns a list of the attribute
names available in the object.
my @attrs = $result->listAttributes();
foreach my $attr ( @attrs ) {
my $value = $result->getAttribute($attr);
print "Key '$attr' has value '$value\n";
}
=head2 getAttribute
This methods takes a single argument, the name of an attribute, and
returns the value of the attribute, if it exists in the object.
my $name = $result->getAttribute('name');
NOTE: Attributes may also be queried by calling the method of the same
name. If the attribute doesn't exist, then the method will just
return a false value. The above example is the same as:
my $name = $result->name();
BEWARE: It is impossible to tell the difference between a non-existent
attribute, and one with a false value using this method. If attribute
existence is interesting to you (or to your code, I suppose), use the
hasAttribute method.
=head2 getAttributes
This method takes no arguments, and returns the entire list of
attributes as list of key/value pairs.
my %attrs = $result->getAttributes();
while ( my ($key,$value) = each %attrs ) {
print "Key '$key' has value '$value'\n";
}
=head2 hasAttribute
This method takes a single argument, the name of a potentially
available attribute, and returns a boolean true/false value if the
attribute exists in the object.
if ( $result->hasAttribute('name') ) {
# Well, then it has a name attribute...
}
=head1 SEE ALSO
AFS::Command(1), AFS::Command::Base(1)
=cut
t/00vos_basic.t view on Meta::CPAN
}
#
# Create a volume.
#
my $volname = $volname_prefix . $PID;
my $volname_readonly = $volname . ".readonly";
$Volnames{$volname}++;
my $result = $vos->create
(
server => $server_primary,
partition => $partition_primary,
name => $volname,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to create volume '$volname' on server '$server_primary:$partition_primary' " .
"in cell '$cell'\n" . "Errors from vos command:\n" . $vos->errors());
}
#
# Examine it.
#
$result = $vos->examine
(
id => $volname,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::Volume") ) {
print "ok $TestCounter\n";
$TestCounter++;
my $errors = 0;
#
# First, sanity check the volume header. There should be ONE of them only.
#
my @headers = $result->getVolumeHeaders();
if ( $#headers == 0 ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn "Incorrect number of headers returned by getVolumeHeaders()\n";
$errors++;
}
$TestCounter++;
t/00vos_basic.t view on Meta::CPAN
} else {
warn("Invalid object -- getVolumeHeaders() did not return an " .
"AFS::Object::VolumeHeader object\n");
print "not ok $TestCounter\n";
$errors++;
}
#
# Second, we check the VLDB entry for this volume.
#
my $vldbentry = $result->getVLDBEntry();
if ( ref $vldbentry && $vldbentry->isa("AFS::Object::VLDBEntry") ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Invalid object type: getVLDBEntry() method call returned bogus data\n" .
Data::Dumper->Dump([$result],['result']));
}
$TestCounter++;
if ( $vldbentry->rwrite() =~ /^\d+$/ ) {
print "ok $TestCounter\n";
} else {
warn("VLDB Entry 'rwrite' is '" .
$vldbentry->rwrite() . "', should be a numeric value\n");
print "not ok $TestCounter\n";
$errors++;
t/00vos_basic.t view on Meta::CPAN
}
$TestCounter++;
} else {
warn("Invalid object -- getVLDBSites() did not return an " .
"AFS::Object::VLDBSite object\n");
print "not ok $TestCounter..$TestTotal\n";
$errors++;
}
die Data::Dumper->Dump([$result],['result']) if $errors;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to examine volume '$volname' in cell '$cell':\n" .
$vos->errors());
}
#
# Create a backup, an verify that the changes in the examine output.
#
$result = $vos->backup
(
id => $volname,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to backup volume '$volname' in cell '$cell':\n" .
$vos->errors());
}
$result = $vos->examine
(
id => $volname,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::Volume") ) {
print "ok $TestCounter\n";
$TestCounter++;
my $errors = 0;
my @headers = $result->getVolumeHeaders();
if ( $#headers == 0 ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn "Incorrect number of headers returned by getVolumeHeaders()\n";
$errors++;
}
$TestCounter++;
t/00vos_basic.t view on Meta::CPAN
}
$TestCounter++;
} else {
warn("Invalid object -- getVolumeHeaders() did not return an " .
"AFS::Object::VolumeHeader object\n");
print "not ok $TestCounter\n";
$errors++;
}
die Data::Dumper->Dump([$result],['result']) if $errors;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to examine volume '$volname' in cell '$cell':\n" .
$vos->errors());
}
#
# Now let's add the other replica sites, and release the volume.
#
for ( my $index = 0 ; $index <= $#servers ; $index++ ) {
my $server = $servers[$index];
my $partition = $partitions[$index];
$result = $vos->addsite
(
id => $volname,
server => $server,
partition => $partition,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to addsite '$server:$partition' to volume '$volname' in cell '$cell':\n" .
$vos->errors());
}
}
$result = $vos->listvldb
(
name => $volname,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::VLDB") ) {
print "ok $TestCounter\n";
$TestCounter++;
my $errors = 0;
my @volnames = $result->getVolumeNames();
if ( $#volnames == 0 ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn "Incorrect number of volnames returned by getVolumeNames()\n";
$errors++;
}
$TestCounter++;
t/00vos_basic.t view on Meta::CPAN
} else {
print "not ok $TestCounter\n";
warn "Volname returned by query ($volname_queried) does not match that specified ($volname)\n";
$errors++;
}
$TestCounter++;
#
# If either of the above failed, we can't go on...
#
die Data::Dumper->Dump([$result],['result']) if $errors;
my $vldbentry = $result->getVLDBEntryByName($volname);
if ( ref $vldbentry && $vldbentry->isa("AFS::Object::VLDBEntry") ) {
print "ok $TestCounter\n";
$TestCounter++;
my $rwrite = $vldbentry->rwrite();
my $altentry = $result->getVLDBEntryById($rwrite);
if ( ref $altentry && $altentry->isa("AFS::Object::VLDBEntry") &&
$altentry->rwrite() == $rwrite &&
$altentry->name() eq $volname ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
}
$TestCounter++;
my @vldbsites = $vldbentry->getVLDBSites();
t/00vos_basic.t view on Meta::CPAN
die Data::Dumper->Dump([$vldbentry],['vldbentry']) if $errors;
} else {
warn("Invalid object -- getVLDBEntry() did not return an " .
"AFS::Object::VLDBEntry object\n");
print "not ok $TestCounter\n";
$errors++;
}
die Data::Dumper->Dump([$result],['result']) if $errors;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to listvldb volume '$volname' in cell '$cell':\n" .
$vos->errors());
}
foreach my $force ( qw( none f force ) ) {
$result = $vos->release
(
id => $volname,
cell => $cell,
(
$force eq 'none' ? () :
( $force => 1 )
),
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to release volume '$volname' in cell '$cell':\n" .
$vos->errors());
}
$TestCounter++;
}
#
# The volume is released, so now, let's examine the readonly, and make
# sure we get the correct volume headers.
#
$result = $vos->examine
(
id => $volname_readonly,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::Volume") ) {
print "ok $TestCounter\n";
$TestCounter++;
my $errors = 0;
my @headers = $result->getVolumeHeaders();
if ( $#headers == $#servers ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Number of headers returned by getVolumeHeaders ($#headers) " .
"does not match number of servers ($#servers)\n");
$errors++;
}
$TestCounter++;
t/00vos_basic.t view on Meta::CPAN
} else {
warn("Volume header [$index] 'type' is '" .
$header->type() . "', should be 'RO'\n");
print "not ok $TestCounter\n";
$errors++;
}
$TestCounter++;
}
die Data::Dumper->Dump([$result],['result']) if $errors;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to examine volume '$volname' in cell '$cell':\n" .
$vos->errors());
}
#
# Finally, let's clean up after ourselves.
#
for ( my $index = 0 ; $index <= $#servers ; $index++ ) {
$result = $vos->remove
(
id => $volname_readonly,
server => $servers[$index],
partition => $partitions[$index],
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to remove volume '$volname_readonly' from server '$servers[$index]', " .
"partition '$partitions[$index]', in cell '$cell':\n" .
$vos->errors());
}
$TestCounter++;
}
#
# Test the vos offline functionality, if supported.
#
if ( $vos->supportsOperation('offline') ) {
foreach my $method ( qw(offline online) ) {
$result = $vos->$method
(
id => $volname,
server => $servers[0],
partition => $partitions[0],
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
die("Unable to $method volume '$volname' from server '$servers[0]', " .
"partition '$partitions[0]', in cell '$cell':\n" .
$vos->errors());
}
$TestCounter++;
$result = $vos->examine
(
id => $volname,
cell => $cell,
);
if ( ref $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
die("Unable to examine volume '$volname' on server '$servers[0]', " .
"partition '$partitions[0]', in cell '$cell':\n" .
$vos->errors());
}
$TestCounter++;
my ($header) = $result->getVolumeHeaders();
if ( $header->status() eq $method ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Volume '$volname' on server '$servers[0]', " .
"partition '$partitions[0]', in cell '$cell' was not $method");
}
$TestCounter++;
t/00vos_basic.t view on Meta::CPAN
} else {
for ( my $index = 0 ; $index <= 7 ; $index++ ) {
print "ok $TestCounter\n";
$TestCounter++;
}
}
$result = $vos->remove
(
id => $volname,
server => $servers[0],
partition => $partitions[0],
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
delete $Volnames{$volname};
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to remove volume '$volname' from server '$servers[0]', " .
"partition '$partitions[0]', in cell '$cell':\n" .
$vos->errors());
}
$TestCounter++;
#
# Finally, one we *expect* to fail...
#
$result = $vos->examine
(
id => $volname,
cell => $cell,
);
if ( $result ) {
print "not ok $TestCounter..$TestTotal\n";
die("Volume '$volname' in cell '$cell', still exists after a successful vos remove!!\n");
} elsif ( $vos->errors() =~ /VLDB: no such entry/i ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unexpected result from vos examine:\n" . $vos->errors());
}
$TestCounter++;
exit 0;
END {
#$TestCounter--;
#warn "Total number of tests == $TestCounter\n";
t/01vos_dumprestore.t view on Meta::CPAN
#
# $Id: 01vos_dumprestore.t,v 11.1 2004/11/18 13:31:30 wpm Exp $
#
# (c) 2003-2004 Morgan Stanley and Co.
# See ..../src/LICENSE for terms of distribution.
#
# print STDERR Data::Dumper->Dump([$vos],['vos']);
use strict;
use English;
use Data::Dumper;
t/01vos_dumprestore.t view on Meta::CPAN
my %enabled =
(
gzip => $AFS::Command::Tests::Config{AFS_COMMAND_GZIP_ENABLED},
bzip2 => $AFS::Command::Tests::Config{AFS_COMMAND_BZIP2_ENABLED},
);
$enabled{gunzip} = $enabled{gzip};
$enabled{bunzip2} = $enabled{bzip2};
my $dumpfilter = $AFS::Command::Tests::Config{AFS_COMMAND_DUMP_FILTER};
my $restorefilter = $AFS::Command::Tests::Config{AFS_COMMAND_RESTORE_FILTER};
my $tmproot = $AFS::Command::Tests::Config{AFS_COMMAND_TMP_ROOT};
my @servers = ();
my @partitions = ();
my $server_primary = "";
my $partition_primary = "";
foreach my $serverpart ( split(/\s+/,$partition_list) ) {
t/01vos_dumprestore.t view on Meta::CPAN
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to instantiate AFS::Command::VOS object\n";
}
#
# Create a volume.
#
my $volname = $volname_prefix . $PID;
my $result = $vos->create
(
server => $server_primary,
partition => $partition_primary,
name => $volname,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
$Volnames{$volname}++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to create volume '$volname' on server '$server_primary:$partition_primary'" .
"in cell '$cell'\n" . "Errors from vos command:\n" . $vos->errors());
}
#
t/01vos_dumprestore.t view on Meta::CPAN
#
my %files =
(
raw => "$tmproot/$volname.dump",
gzip => "$tmproot/$volname.dump.gz",
bzip2 => "$tmproot/$volname.dump.bz2",
);
$files{gunzip} = $files{gzip};
$files{bunzip2} = $files{bzip2};
$result = $vos->dump
(
id => $volname,
time => 0,
file => $files{raw},
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to dump volume '$volname' in cell '$cell' to file '$files{raw}':\n" .
$vos->errors());
}
$TestCounter++;
foreach my $ctype ( qw(gzip bzip2) ) {
unless ( $enabled{$ctype} ) {
for ( my $count = 0 ; $count < 3 ; $count++ ) {
print "ok $TestCounter # skip Compression support for $ctype disabled\n";
$TestCounter++;
}
next;
}
#
# Now, with *implicit* use of gzip (via the filename)
#
$result = $vos->dump
(
id => $volname,
time => 0,
file => $files{$ctype},
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to dump volume '$volname' in cell '$cell' to file '$files{$ctype}':\n" .
$vos->errors());
}
$TestCounter++;
#
# Next, explicitly, using the gzip/bzip2 argument
#
$result = $vos->dump
(
id => $volname,
time => 0,
file => $files{raw},
cell => $cell,
$ctype => 4,
);
if ( $result ) {
if ( -f $files{$ctype} ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unexpected result: dump method did not produce an output file\n");
}
} else {
print "not ok $TestCounter\n";
warn("Unable to dump volume '$volname' in cell '$cell' to file '$files{$ctype}':\n" .
$vos->errors());
}
$TestCounter++;
#
# Finally, when both are given.
#
$result = $vos->dump
(
id => $volname,
time => 0,
file => $files{$ctype},
cell => $cell,
$ctype => 4,
);
if ( $result ) {
if ( -f $files{$ctype} ) {
print "ok $TestCounter\n";
} elsif ( -f $files{raw} ) {
print "not ok $TestCounter\n";
warn("Unexpected result: dump method created file '$files{raw}', " .
"should have been '$files{$ctype}'\n" .
"(Both -file $files{$ctype}, and -$ctype specified)\n");
} else {
print "not ok $TestCounter\n";
warn("Unexpected result: dump method did not produce an output file\n");
}
} else {
print "not ok $TestCounter\n";
warn("Unable to dump volume '$volname' in cell '$cell' to file '$files{$ctype}':\n" .
$vos->errors());
die Data::Dumper->Dump([$vos],['vos']);
}
$TestCounter++;
}
if ( $dumpfilter ) {
$result = $vos->dump
(
id => $volname,
time => 0,
file => $files{raw},
cell => $cell,
filterout => [$dumpfilter],
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to dump volume '$volname' in cell '$cell' to file '$files{raw}':\n" .
$vos->errors());
}
$TestCounter++;
my ($ctype) = ( $enabled{gzip} ? 'gzip' :
$enabled{bzip2} ? 'bzip2' : '' );
if ( $ctype ) {
$result = $vos->dump
(
id => $volname,
time => 0,
file => $files{$ctype},
cell => $cell,
filterout => [$dumpfilter],
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to dump volume '$volname' in cell '$cell' to file '$files{raw}':\n" .
"(Testing dump filter with compression)\n" .
$vos->errors());
}
} else {
print "ok $TestCounter # skip Compression support disabled\n";
}
$TestCounter++;
} else {
for ( my $count = 0 ; $count < 2 ; $count++ ) {
print "ok $TestCounter # skip Dump filter tests disabled\n";
$TestCounter++;
}
}
#
# Finally, let's remove that volume, so we can reuse the name for the
# restore tests.
#
$result = $vos->remove
(
server => $server_primary,
partition => $partition_primary,
id => $volname,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to remove volume '$volname' from server '$server_primary', " .
"partition '$partition_primary', in cell '$cell':\n" .
$vos->errors());
}
#
# If we made it this far, dump works fine. Now let's test restore...
#
$result = $vos->restore
(
server => $server_primary,
partition => $partition_primary,
name => $volname,
file => $files{raw},
overwrite => 'full',
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$Volnames{$volname}++;
} else {
print "not ok $TestCounter\n";
warn("Unable to restore volume '$volname' from file '$files{raw}',\n" .
"to server '$server_primary', partition '$partition_primary', name '$volname':\n" .
$vos->errors());
}
$TestCounter++;
foreach my $ctype ( qw(gunzip bunzip2) ) {
unless ( $enabled{$ctype} ) {
for ( my $count = 0 ; $count < 1 ; $count++ ) {
print "ok $TestCounter # skip Compression support for $ctype disabled\n";
$TestCounter++;
}
next;
}
$result = $vos->restore
(
server => $server_primary,
partition => $partition_primary,
name => $volname,
file => $files{$ctype},
overwrite => 'full',
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to restore volume '$volname' from file '$files{$ctype}',\n" .
"to server '$server_primary', partition '$partition_primary', name '$volname':\n" .
$vos->errors());
}
$TestCounter++;
}
if ( $restorefilter ) {
$result = $vos->restore
(
server => $server_primary,
partition => $partition_primary,
name => $volname,
file => $files{raw},
overwrite => 'full',
cell => $cell,
filterin => [$restorefilter],
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to restore volume '$volname' from file '$files{raw}',\n" .
"using restore filter '$restorefilter', " .
"to server '$server_primary', partition '$partition_primary', name '$volname':\n" .
$vos->errors());
}
$TestCounter++;
my ($ctype) = ( $enabled{gunzip} ? 'gunzip' :
$enabled{bunzip2} ? 'bunzip2' : '' );
if ( $ctype ) {
$result = $vos->restore
(
server => $server_primary,
partition => $partition_primary,
name => $volname,
file => $files{$ctype},
overwrite => 'full',
cell => $cell,
filterin => [$restorefilter],
);
if ( $result ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to restore volume '$volname' from file '$files{$ctype}',\n" .
"using restore filter '$restorefilter', " .
"to server '$server_primary', partition '$partition_primary', name '$volname':\n" .
$vos->errors());
}
} else {
print "ok $TestCounter # skip Compression support disabled\n";
}
$TestCounter++;
} else {
for ( my $count = 0 ; $count < 2 ; $count++ ) {
print "ok $TestCounter # skip Restoreg filter tests disabled\n";
$TestCounter++;
}
}
$result = $vos->remove
(
server => $server_primary,
partition => $partition_primary,
id => $volname,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
delete $Volnames{$volname};
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to remove volume '$volname' from server '$server_primary', " .
"partition '$partition_primary', in cell '$cell':\n" .
$vos->errors());
}
t/10bos_basic.t view on Meta::CPAN
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to instantiate AFS::Command::BOS object\n";
}
#
# bos getdate
#
my $result = $bos->getdate
(
server => $dbserver,
cell => $cell,
file => 'bosserver',
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to getdate for bosserver:\n" . $bos->errors());
}
my @files = $result->getFileNames();
if ( grep($_ eq 'bosserver',@files) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Didn't find 'bosserver' in results from bos->getdate()");
}
$TestCounter++;
my $file = $result->getFile('bosserver');
if ( ref $file && $file->isa("AFS::Object") ) {
print "ok $TestCounter\n";
$TestCounter++;
my $date = $file->date();
if ( $date ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("No date found for file 'bosserver' in results from bos->getdate()");
}
$TestCounter++;
} else {
print "not ok $TestCounter\n";
$TestCounter++;
print "not ok $TestCounter\n";
$TestCounter++;
warn("Didn't find 'bosserver' in results from bos->getdate()");
}
#
# bos getlog
#
$result = $bos->getlog
(
server => $dbserver,
cell => $cell,
file => '/usr/afs/logs/BosLog',
);
if ( ref $result && $result->isa("AFS::Object::BosServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to getlog for bosserver:\n" . $bos->errors());
}
my $log = $result->log();
if ( $log ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to getlog for bosserver:\n" . $bos->errors());
}
my ($firstline) = split(/\n+/,$log);
my $tmpfile = "/var/tmp/.bos.getlog.results.$$";
$result = $bos->getlog
(
server => $dbserver,
cell => $cell,
file => '/usr/afs/logs/BosLog',
redirect => $tmpfile,
);
if ( ref $result && $result->isa("AFS::Object::BosServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to getlog for bosserver:\n" . $bos->errors());
}
$log = $result->log();
if ( $log eq $tmpfile ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to getlog for bosserver:\n" . $bos->errors());
}
$file = IO::File->new($tmpfile) || do {
print "not ok $TestCounter..$TestTotal\n";
t/10bos_basic.t view on Meta::CPAN
if ( $file->getline() eq "$firstline\n" ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter..$TestTotal\n";
warn("Contents of bos->getlog() do not match when fetched\n" .
"with and without 'redirect' option\n");
}
$TestCounter++;
#
# bos getrestart
#
$result = $bos->getrestart
(
server => $dbserver,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::BosServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to getrestart for bosserver:\n" . $bos->errors());
}
foreach my $attr ( qw(restart binaries) ) {
if ( $result->$attr() ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to get $attr time from bos->getrestart()\n");
}
$TestCounter++;
}
#
# bos listhosts
#
$result = $bos->listhosts
(
server => $dbserver,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::BosServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to listhosts for bosserver:\n" . $bos->errors());
}
if ( $result->cell() eq $cell ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Cell name returned by listhosts '" . $result->cell() .
"' does not match '$cell'");
}
$TestCounter++;
my $hosts = $result->hosts();
if ( ref $hosts eq 'ARRAY' ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Not an ARRAY ref: bos->listhosts->hosts()\n");
}
$TestCounter++;
#
# bos listkeys
#
$result = $bos->listkeys
(
server => $dbserver,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::BosServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to listkeys for bosserver:\n" . $bos->errors());
}
my @indexes = $result->getKeyIndexes();
if ( @indexes ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to get indexes from listkeys for bosserver\n");
}
foreach my $index ( @indexes ) {
my $key = $result->getKey($index);
if ( ref $result && $result->isa("AFS::Object") ) {
print "ok $TestCounter\n";
$TestCounter++;
if ( $key->cksum() ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Key for index '$index' has no cksum\n");
}
$TestCounter++;
} else {
print "not ok $TestCounter\n";
$TestCounter++;
print "not ok $TestCounter\n";
$TestCounter++;
warn("Unable to get key for index '$index' from listkeys result\n");
}
}
#
# bos listusers
#
$result = $bos->listusers
(
server => $dbserver,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::BosServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to listusers for bosserver:\n" . $bos->errors());
}
my $susers = $result->susers();
if ( ref $susers eq 'ARRAY' ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Not an ARRAY ref: bos->listusers->susers()\n");
}
$TestCounter++;
#
# bos status
#
$result = $bos->status
(
server => $dbserver,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::BosServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to get status from bosserver:\n" . $bos->errors());
}
my @instancenames = $result->getInstanceNames();
if ( @instancenames ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to get instance names from bos->status->getInstanceNames()\n");
}
foreach my $name ( qw(vlserver ptserver) ) {
if ( grep($_ eq $name,@instancenames) ) {
print "ok $TestCounter\n";
$TestCounter++;
my $instance = $result->getInstance($name);
if ( ref $instance && $instance->isa("AFS::Object::Instance") ) {
print "ok $TestCounter\n";
$TestCounter++;
if ( $instance->status() ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("No status attribute for instance '$name' from getInstance()\n");
}
$TestCounter++;
t/10bos_basic.t view on Meta::CPAN
warn("Unable to get instance '$name' from getInstance()\n");
}
} else {
print "not ok $TestCounter.." . ($TestCounter+3) ."\n";
$TestCounter += 3;
warn("Did not find instance '$name' in bos status output\n");
}
}
$result = $bos->status
(
server => $dbserver,
cell => $cell,
long => 1,
);
if ( ref $result && $result->isa("AFS::Object::BosServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to get status from bosserver:\n" . $bos->errors());
}
foreach my $name ( qw(vlserver ptserver) ) {
my $instance = $result->getInstance($name);
if ( ref $instance && $instance->isa("AFS::Object::Instance") ) {
print "ok $TestCounter\n";
$TestCounter++;
foreach my $attr ( qw(status type startdate startcount) ) {
if ( $instance->$attr() ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
t/20fs_basic.t view on Meta::CPAN
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to instantiate AFS::Command::FS object\n";
}
#
# fs checkservers
#
my $result = $fs->checkservers();
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call checkservers:\n" . $fs->errors();
}
my $servers = $result->servers();
if ( ref $servers eq 'ARRAY' ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Not an ARRAY ref: fs->checkservers->servers()\n");
}
$TestCounter++;
$result = $fs->checkservers
(
interval => 0,
);
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call checkservers:\n" . $fs->errors();
}
if ( $result->interval() =~ /^\d+$/ ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Not an integer: fs->checkservers->interval()\n");
}
$TestCounter++;
#
# All the common _paths_method methods
#
t/20fs_basic.t view on Meta::CPAN
unless ( $fs->supportsOperation($pathop) ) {
my $total = scalar(@{$pathops{$pathop}}) + 2;
$total++ if $pathop eq 'storebehind';
for ( my $count = 1 ; $count <= $total ; $count++ ) {
print "ok $TestCounter # skipping... fs->$pathop() is unsupported \n";
$TestCounter++;
}
next;
}
$result = $fs->$pathop
(
( $pathop eq 'storebehind' ? 'files' : 'path' ) => $paths,
);
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to call fs->$pathop:\n" . $fs->errors() .
Data::Dumper->Dump([$fs],['fs']));
}
if ( $pathop eq 'storebehind' ) {
if ( defined($result->asynchrony()) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Result object for fs->storebehind() has no attr 'asynchrony'\n");
}
} else {
print "ok $TestCounter\n";
}
$TestCounter++;
foreach my $pathname ( @$paths ) {
my $path = $result->getPath($pathname);
if ( ref $path && $path->isa("AFS::Object::Path") ) {
print "ok $TestCounter\n";
$TestCounter++;
if ( $pathname eq $pathafs ) {
foreach my $attr ( @{$pathops{$pathop}} ) {
if ( defined($path->$attr()) ) {
print "ok $TestCounter\n";
} else {
t/20fs_basic.t view on Meta::CPAN
}
}
#
# fs exportafs -- this one is hard to really test, since we can't
# verify all the parsing unless it is actually supported and enabled,
# so fake it.
#
$result = $fs->exportafs
(
type => 'nfs',
);
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
if ( defined($result->enabled()) ) {
print "ok $TestCounter\n";
$TestCounter++;
foreach my $attr ( qw(convert uidcheck submounts) ) {
if ( defined($result->$attr()) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("No attr '$attr' for fs->exportafs results\n");
}
$TestCounter++;
}
} else {
warn("Unable to determine if translator is enabled or not\n");
for ( my $count = 1 ; $count <= 4 ; $count++ ) {
print "not ok $TestCounter\n";
$TestCounter++;
}
}
t/20fs_basic.t view on Meta::CPAN
$TestCounter++;
}
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call exportafs:\n" . $fs->errors();
}
#
# fs getcacheparms
#
$result = $fs->getcacheparms();
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call getcacheparms:\n" . $fs->errors();
}
foreach my $attr ( qw(avail used) ) {
if ( defined($result->$attr()) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Result object from getcacheparms has no attr '$attr'\n");
}
$TestCounter++;
}
#
# fs getcellstatus
#
$result = $fs->getcellstatus
(
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call getcellstatus:\n" . $fs->errors();
}
my $cellobj = $result->getCell($cell);
if ( ref $cellobj && $cellobj->isa("AFS::Object::Cell") ) {
print "ok $TestCounter\n";
$TestCounter++;
foreach my $attr ( qw(cell status) ) {
if ( defined($cellobj->$attr()) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
t/20fs_basic.t view on Meta::CPAN
print "no ok $TestCounter\n";
$TestCounter++;
}
}
#
# fs getclientaddrs
#
if ( $fs->supportsOperation('getclientaddrs') ) {
$result = $fs->getclientaddrs();
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call getclientaddrs:\n" . $fs->errors();
}
my $addresses = $result->addresses();
if ( ref $addresses eq 'ARRAY' ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Result object for fs->getclientaddrs() has no attr 'addresses'\n");
}
$TestCounter++;
} else {
for ( my $count = 1 ; $count <= 2 ; $count++ ) {
print "ok $TestCounter\n";
$TestCounter++;
}
}
#
# fs getcrypt
#
if ( $fs->supportsOperation('getcrypt') ) {
$result = $fs->getcrypt();
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call getcrypt:\n" . $fs->errors();
}
if ( defined($result->crypt()) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Result object for fs->getcrypt() has no attr 'crypt'\n");
}
$TestCounter++;
} else {
for ( my $count = 1 ; $count <= 2 ; $count++ ) {
print "ok $TestCounter\n";
$TestCounter++;
}
}
#
# fs getserverprefs
#
$result = $fs->getserverprefs();
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call getserverprefs:\n" . $fs->errors();
}
my ($server) = $result->getServers();
if ( ref $server && $server->isa("AFS::Object::Server") ) {
print "ok $TestCounter\n";
$TestCounter++;
foreach my $attr ( qw(server preference) ) {
if ( defined($server->$attr()) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Server object from fs->getserverprefs() has no attr '$attr'\n");
}
$TestCounter++;
}
} else {
warn("Unable to get server object from fs->getserverprefs result\n");
for ( my $count = 1 ; $count <= 3 ; $count++ ) {
print "not ok $TestCounter\n";
$TestCounter++;
}
}
#
# fs listacl -- tested in 40fs_complex.t
#
#
# fs listaliases -- not tested, but I supposed we could define an
# alias, and then remove it. Might be kinda intrusive, though.
#
#
# fs listcells
#
$result = $fs->listcells();
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call listcells:\n" . $fs->errors();
}
$cellobj = $result->getCell($cell);
if ( ref $cellobj && $cellobj->isa("AFS::Object::Cell") ) {
print "ok $TestCounter\n";
$TestCounter++;
if ( $cellobj->cell() eq $cell ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Cell returned by fs->listcells->getCell() doesn't match '$cell'\n");
t/20fs_basic.t view on Meta::CPAN
}
}
#
# fs lsmount -- tested in 40fs_complex.t
#
#
# fs sysname
#
$result = $fs->sysname();
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call sysname:\n" . $fs->errors();
}
if ( defined($result->sysname()) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Result object for fs->sysname() has no attr 'sysname'\n");
}
$TestCounter++;
END {
#$TestCounter--;
#warn "Total number of tests == $TestCounter\n";
t/30pts_basic.t view on Meta::CPAN
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to instantiate AFS::Command::PTS object\n";
}
#
# pts listmax
#
my $result = $pts->listmax
(
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::PTServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call listmax:\n" . $pts->errors();
}
foreach my $attr ( qw( maxuserid maxgroupid ) ) {
if ( defined($result->$attr()) ) {
my $id = $result->$attr();
my $ok ='not ok';
if ( $attr eq 'maxuserid' ) {
$ok = 'ok' if $id > 0;
} else {
$ok = 'ok' if $id < 0;
}
print "$ok $TestCounter\n";
if ( $ok eq 'not ok' ) {
warn("pts->listmax attr '$attr' has the wrong sign (+/-)\n");
}
} else {
print "not ok $TestCounter\n";
warn("pts->listmax result has no attr '$attr'\n");
}
$TestCounter++;
}
#
# pts creategroup, createuser, examine
#
foreach my $name ( $ptsgroup, $ptsuser ) {
#
# First, let's make sure our test IDs aren't defined, so we can
# redefine them.
#
my $result = $pts->delete
(
nameorid => $name,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
} elsif ( defined($pts->errors()) && $pts->errors() =~ /unable to find entry/ ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to delete the test pts id ($name), or verify it doesn't exist\n" .
Data::Dumper->Dump([$pts],['pts']));
}
$TestCounter++;
my $method = $name eq $ptsgroup ? 'creategroup' : 'createuser';
my $type = $name eq $ptsgroup ? 'Group' : 'User';
my $class = 'AFS::Object::' . ( $name eq $ptsgroup ? 'Group' : 'User' );
$result = $pts->$method
(
name => $name,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::PTServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call $method:\n" . $pts->errors();
}
my $byname = $name eq $ptsgroup ? 'getGroupByName' : 'getUserByName';
my $byid = $name eq $ptsgroup ? 'getGroupById' : 'getUserById';
my $getall = $name eq $ptsgroup ? 'getGroups' : 'getUsers';
my $entry = $result->$byname($name);
if ( ref $entry && $entry->isa($class) ) {
print "ok $TestCounter\n";
$TestCounter++;
my $id = $entry->id();
if ( $name eq $ptsgroup ) {
if ( $id < 0 ) {
print "ok $TestCounter\n";
} else {
t/30pts_basic.t view on Meta::CPAN
if ( $id > 0 ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("User $name doesn't have a positive id as expected\n");
}
}
$TestCounter++;
$entry = $result->$byid($id);
if ( ref $entry && $entry->isa($class) ) {
print "ok $TestCounter\n";
$TestCounter++;
my $othername = $entry->name();
if ( $name eq $othername ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
t/30pts_basic.t view on Meta::CPAN
} else {
warn("Unable to retreive pts entry using $byname\n");
for ( my $count = 1 ; $count <= 4 ; $count++ ) {
print "not ok $TestCounter\n";
$TestCounter++;
}
}
($entry) = $result->$getall();
if ( ref $entry && $entry->isa($class) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to retreive pts entry from pts->$method using $getall\n");
}
$TestCounter++;
$result = $pts->examine
(
nameorid => $name,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::PTServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call examine:\n" . $pts->errors();
}
($entry) = $result->$getall();
if ( ref $entry && $entry->isa($class) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to retreive pts entry from pts->examine using $getall\n");
}
$TestCounter++;
foreach my $attr ( qw( name id owner creator membership flags groupquota ) ) {
if ( defined($entry->$attr()) ) {
t/30pts_basic.t view on Meta::CPAN
warn("Result from pts->examine of '$name' is missing attr '$attr'\n");
}
$TestCounter++;
}
}
#
# pts chown, listowned
#
$result = $pts->chown
(
name => $ptsgroup,
owner => $ptsuser,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter\n";
die("Unable to chown $ptsgroup to $ptsuser:" . $pts->errors());
}
$result = $pts->listowned
(
nameorid => $ptsuser,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::PTServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call listowned:\n" . $pts->errors();
}
my ($user) = $result->getUsers();
if ( ref $user && $user->isa("AFS::Object::User") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to get User object from pts->listowned result\n");
}
my @owned = $user->getOwned();
if ( $#owned == 0 && $owned[0] eq $ptsgroup ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("User $ptsuser doesn't appear to own $ptsgroup\n");
}
$TestCounter++;
#
# pts adduser, membership
#
$result = $pts->adduser
(
user => $ptsuser,
group => $ptsgroup,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call adduser:\n" . $pts->errors();
}
foreach my $name ( $ptsgroup, $ptsuser ) {
$result = $pts->membership
(
nameorid => $name,
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::PTServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call membership:\n" . $pts->errors();
}
my $type = $name eq $ptsgroup ? 'Group' : 'User';
my $class = 'AFS::Object::' . ( $name eq $ptsgroup ? 'Group' : 'User' );
my $getall = $name eq $ptsgroup ? 'getGroups' : 'getUsers';
my ($entry) = $result->$getall();
if ( ref $entry && $entry->isa($class) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Unable to retreive pts entry from pts->membership using $getall\n");
}
$TestCounter++;
my @membership = $entry->getMembership();
if ( $#membership == 0 ) {
t/30pts_basic.t view on Meta::CPAN
#
if ( $pts->supportsOperation('listentries') ) {
foreach my $name ( $ptsgroup, $ptsuser ) {
my $flag = $name eq $ptsgroup ? 'groups' : 'users';
my $type = $name eq $ptsgroup ? 'Group' : 'User';
my $class = 'AFS::Object::' . ( $name eq $ptsgroup ? 'Group' : 'User' );
my $getentry = $name eq $ptsgroup ? 'getGroupByName' : 'getUserByName';
my $result = $pts->listentries
(
cell => $cell,
$flag => 1,
);
if ( ref $result && $result->isa("AFS::Object::PTServer") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to call listentries:\n" . $pts->errors();
}
my $entry = $result->$getentry($name);
if ( ref $entry && $entry->isa($class) ) {
foreach my $attr ( qw(id owner creator) ) {
if ( defined($entry->$attr()) ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("$type $name is missing the attr '$attr'\n");
}
$TestCounter++;
t/30pts_basic.t view on Meta::CPAN
} else {
for ( my $count = 1 ; $count <= 8 ; $count++ ) {
print "ok $TestCounter\n";
$TestCounter++;
}
}
#
# Test membership error checking
#
$result = $pts->membership
(
nameorid => "ThisSurelyDoesNotExist",
cell => $cell,
);
if ( ref $result && $result->isa("AFS::Object::PTServer") ) {
print "not ok $TestCounter\n";
warn("membership should have failed, not succeeded for 'ThisSurelyDoesNotExist'");
} else {
print "ok $TestCounter\n";
}
$TestCounter++;
exit 0;
# END {
t/40fs_complex.t view on Meta::CPAN
die "Unable to instantiate AFS::Command::FS object\n";
}
#
# Create a sample volume
#
my $volname = $volname_prefix . $PID;
$Volnames{$volname}++;
my $result = $vos->create
(
server => $server,
partition => $partition,
name => $volname,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to create volume '$volname' on server '$server:$partition'" .
"in cell '$cell'\n" . "Errors from vos command:\n" . $vos->errors());
}
#
# Mount it (several different ways)
#
my %mtpath =
(
rw => "$pathafs/$volname-rw",
cell => "$pathafs/$volname-cell",
plain => "$pathafs/$volname-plain",
);
foreach my $type ( keys %mtpath ) {
$result = $fs->mkmount
(
dir => $mtpath{$type},
vol => $volname,
(
$type eq 'cell' ?
( cell => $cell ) : ()
),
(
$type eq 'rw' ?
( rw => 1 ) : ()
),
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to create mount point for $volname in $cell on $mtpath{$type}:" .
$fs->errors() .
Data::Dumper->Dump([$fs],['fs']));
}
}
$result = $fs->lsmount
(
dir => [values %mtpath],
);
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to lsmount dirs:" .
$fs->errors() .
Data::Dumper->Dump([$fs],['fs']));
}
foreach my $type ( keys %mtpath ) {
my $mtpath = $mtpath{$type};
my $path = $result->getPath($mtpath);
if ( ref $path && $path->isa("AFS::Object::Path") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to get Path object from result of fs->lsmount:\n" .
Data::Dumper->Dump([$result],['result']));
}
if ( defined($path->volname()) && $path->volname() eq $volname ) {
print "ok $TestCounter\n";
} else {
print "not ok $TestCounter\n";
warn("Volname in mtpt for $mtpath doesn't match '$volname':\n" .
Data::Dumper->Dump([$path],['path']));
}
$TestCounter++;
t/40fs_complex.t view on Meta::CPAN
warn("Mount point $mtpath{$type} doesn't appear to be rw:\n" .
Data::Dumper->Dump([$path],['path']));
}
} else {
print "ok $TestCounter\n";
}
$TestCounter++;
}
$result = $fs->rmmount
(
dir => [ $mtpath{rw}, $mtpath{plain} ],
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to remove mount points for $volname in $cell:\n" .
"[ $mtpath{rw}, $mtpath{plain} ]\n" .
$fs->errors() .
Data::Dumper->Dump([$fs],['fs']));
}
t/40fs_complex.t view on Meta::CPAN
# might NOT be in the same cell you specified, so using the
# cell-specific mount is necessary.
#
my $mtpath = $mtpath{cell};
#
# Set and test the ACL (several different ways)
#
my $paths = [ $mtpath, $pathnotafs, $pathbogus ];
$result = $fs->listacl
(
path => $paths,
);
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to listacl dirs:" .
$fs->errors() .
Data::Dumper->Dump([$fs],['fs']));
}
my %acl = ();
foreach my $pathname ( @$paths ) {
my $path = $result->getPath($pathname);
if ( ref $path && $path->isa("AFS::Object::Path") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to get Path object from result of fs->listacl:\n" .
Data::Dumper->Dump([$result],['result']));
}
if ( $pathname eq $mtpath ) {
my $normal = $path->getACL();
if ( ref $normal && $normal->isa("AFS::Object::ACL") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
t/40fs_complex.t view on Meta::CPAN
# Thus, we use a different, existing pts entry for these tests, and
# not the ones we created above.
#
my %entries =
(
$ptsexisting => 'rlidwk',
);
foreach my $type ( qw(normal negative) ) {
$result = $fs->setacl
(
dir => $mtpath,
acl => \%entries,
(
$type eq 'negative' ?
( negative => 1 ) : ()
),
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to setacl dirs:" .
$fs->errors() .
Data::Dumper->Dump([$fs],['fs']));
}
$result = $fs->listacl
(
path => $mtpath,
);
if ( ref $result && $result->isa("AFS::Object::CacheManager") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to listacl dirs:" .
$fs->errors() .
Data::Dumper->Dump([$fs],['fs']));
}
my $path = $result->getPath($mtpath);
if ( ref $path && $path->isa("AFS::Object::Path") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to get Path object from result of fs->listacl:\n" .
Data::Dumper->Dump([$result],['result']));
}
my $acl = $path->getACL($type);
if ( ref $acl && $acl->isa("AFS::Object::ACL") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to get ACL object from Path object:\n" .
Data::Dumper->Dump([$path],['path']));
t/40fs_complex.t view on Meta::CPAN
}
$TestCounter++;
}
}
#
# Unmount it
#
$result = $fs->rmmount
(
dir => $mtpath,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to remove mount points for $volname in $cell:\n" .
$fs->errors() .
Data::Dumper->Dump([$fs],['fs']));
}
#
# Blow away the volume
#
$result = $vos->remove
(
server => $server,
partition => $partition,
id => $volname,
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to remove volume '$volname' from server '$server:$partition'" .
"in cell '$cell'\n" . "Errors from vos command:\n" . $vos->errors());
}
delete $Volnames{$volname};
END {
t/99pts_cleanup.t view on Meta::CPAN
command => $binary,
);
if ( ref $pts && $pts->isa("AFS::Command::PTS") ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die "Unable to instantiate AFS::Command::PTS object\n";
}
my $result = $pts->delete
(
nameorid => [ $ptsgroup, $ptsuser ],
cell => $cell,
);
if ( $result ) {
print "ok $TestCounter\n";
$TestCounter++;
} else {
print "not ok $TestCounter..$TestTotal\n";
die("Unable to delete pts entries:\n" .
$pts->errors() .
Data::Dumper->Dump([$pts],['pts']));
}
exit 0;
util/lib/parse_config view on Meta::CPAN
#-*-perl-*-
#
# $Id: parse_config,v 7.1 2004/01/13 19:01:45 wpm Exp $
#
# (c) 2003-2004 Morgan Stanley and Co.
# See ..../src/LICENSE for terms of distribution.
#
# Parse our config file to get the parameters we need for the tests
#
# NOTE: this is used ONLY for the installation procedures, and not in
# the production code itself.
package AFS::Command::Tests;
use vars qw(%Config);
my $config = "/no/such/path";
foreach my $relpath ( qw( . .. ../.. ../../.. ) ) {
next unless -f "$relpath/CONFIG";