Script to parse cluster table of contents file

From Brandonhutchinson.com

Jump to: navigation, search

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";
}
Personal tools