Script to parse cluster table of contents file
From Brandonhutchinson.com
I wrote the following Perl script to parse the Sun cluster table of contents file /var/sadm/system/admin/.clustertoc. Basically, I want to know which individual packages comprise any of the Sun metaclusters. The file can be tricky to parse, as metaclusters contain both individual packages along with clusters.
When run with no arguments, the script will return a list of metaclusters to query. e.g.,
$ ./parse_clustertoc.pl Usage: ./parse_clustertoc.pl metacluster Available metaclusters: SUNWCXall SUNWCall SUNWCprog SUNWCreq SUNWCrnet SUNWCuser $ ./parse_clustertoc.pl SUNWCXall (1054 package names follow for a Solaris 10 11/06 SPARC system)
My Perl programming may leave much to be desired.
Code
#!/usr/bin/perl
# This script parses the Sun cluster table of contents file and returns
# individual package names for a given metacluster. Metaclusters contain both
# invividual packages and clusters, so the table of contents file has to be read
# twice in order to convert clusters into individual packages.
# If a command-line argument is not given, return the list of metaclusters.
my $clustertoc="/var/sadm/system/admin/.clustertoc";
my %metaclusters;
my %cluster_members;
my %package_members;
my $seen_metacluster=0;
open(CLUSTERTOC, "< $clustertoc")
or die "Couldn't open $clustertoc for reading: $!\n";
# SUNWC cluster members are clusters that must be parsed to get the packages.
# Any other SUNW cluster member is an individual package. e.g.,
# SUNW_CSRMEMBER=SUNWCzfs is an additional cluster
# SUNW_CSRMEMBER=SUNWadmap is a package
while(<CLUSTERTOC>) {
# SUNWCmreq is an "internal private metacluster not installable by end users"
next if /METACLUSTER=SUNWCmreq/;
$metaclusters{$1}=1 if /METACLUSTER=(.*)/;
if (defined($ARGV[0])) {
# Is this the metacluster we're looking for?
$seen_metacluster=1 if /METACLUSTER=$ARGV[0]/;
if (/SUNW_CSRMEMBER=(SUNWC.*)/ and $seen_metacluster) {
# SUNWC.* is a cluster
$cluster_members{$1}=1;
next;
}
if (/SUNW_CSRMEMBER=(SUNW.*)/ and $seen_metacluster) {
# Anything else SUNW.* is an individual package
$package_members{$1}=1;
}
# Exit the loop if we're at the end of the metacluster contents
last if /^END$/ and $seen_metacluster;
}
}
if (!defined($ARGV[0])) {
print "Usage: $0 metacluster\n\n";
print "Available metaclusters:\n";
foreach (sort keys %metaclusters) {
print "$_\n";
}
exit 0
}
# Loop through $clustertoc again, get the individual packages comprising
# the %cluster_members clusters.
open(CLUSTERTOC, "< $clustertoc")
or die "Couldn't open $clustertoc for reading: $!\n";
my $get_packages=0;
while(<CLUSTERTOC>) {
if (/CLUSTER=(.*)/) {
# Is this cluster part of our metacluster?
$get_packages=1 if (exists $cluster_members{$1});
}
$package_members{$1}=1 if /SUNW_CSRMEMBER=(.*)/ and $get_packages;
$get_packages=0 if /^END$/;
}
foreach my $key(sort keys %package_members) {
print "$key\n";
}
