seeding a site's host/ dir

Will Partain <[email protected]>
Newsgroups gmane.comp.sysutils.ark.devel
Message-ID <[email protected]>
Harlan writes:

> I'm noticing it's a lot of work for me to get from try-ark to even a single
> production host.
> 
> I'd like to see a SIMPLE text config file, and perhaps process it with
> autogen or perl.
> 
> For example:
> 
>  HOSTS
> 	clarence
> 	slicker
> 	slimy
> 	slinger
> 
> and then a script can do Something (rsh, ssh, whatever) to see what OS and
> version is running on these hosts, which can be used to generate the host
> proto-templates (ia32-rhlinux.xml, ia32-rhlinux-6.1.xml).

It is Deeply Important that we not constrain what an
individual site's hosts "look like".  We are all thinking in
"Sidai-like" terms, but there is absolutely no reason that
an ARK site couldn't do something entirely different.

For example, if you were using ARK simply as a multiplatform
package manager (very reasonable) and you had four platform
types at your site of (say) 300 hosts, you might very well
have *only four* ARK hosts.  (They would create the bits,
e.g. for /usr/local, which would then be NFS-mounted on all
hosts [via some means outside of the ARK world].)  Such
hosts wouldn't even need <ip-addresses> in them.  Would
creating four six-line .xml files be that big a deal?

Having said that, there is no trouble with the kind of thing
Harlan wants to do.  In fact, it will be Very Cool to have a
bunch of these "seeders" floating about, so people can
choose and adapt.  There's a drafty piece of code at the
bottom (which I will check in eventually) and it gives the
following result when run here:

   % ( echo slicker; echo easter; echo macauley) | ./list-to-hosts.sample --host-dir=/tmp  --test
   <host name="slicker" xml-version="1">
   <status>active</status>
   <prototypes>
     <prototype team="." name="std-sparc-solaris" />
   </prototypes>
   
   <ip-addresses><list>
     <item>130.209.242.51</item>
   </list></ip-addresses>
   </host>
   <host name="easter" xml-version="1">
   <status>active</status>
   <prototypes>
     <prototype team="." name="std-ia32-linux" />
   </prototypes>
   
   <ip-addresses><list>
     <item>130.209.247.6</item>
   </list></ip-addresses>
   </host>
   <host name="macauley" xml-version="1">
   <status>active</status>
   <prototypes>
     <prototype team="." name="std-alpha-osf1" />
   </prototypes>
   
   <ip-addresses><list>
     <item>130.209.240.208</item>
   </list></ip-addresses>
   </host>
   %

Will

======================

#! /usr/local/bin/perl
$^W = 1;
require 5.000;
use strict;

my $Usage = <<EOUSAGE;
This *sample* script sketches one possible way to populate
a site\'s host/ directory.  It takes a list of hostnames,
one per line, on standard input, and then drops a .xml
file for each host in the directory specified.

--host-dir=<dir> Mandatory; say where to drop the files.

--test    Don\'t write files; just display them to stdout.
EOUSAGE

# ***CUSTOMIZE ME***
my $ERSH = '/our/bin/ersh'; # can use rsh/remsh, but this is better

my @UNAME_PATT = ( # ordered regexps for matching against uname -a output
   '^SunOS\s\S+\s5\.6\s.* sparc '
 , '^Linux\s\S+\s2\.4\.2-2\s.* i[3-9]86 '
 , '^OSF1\s\S+\sV3\.2\s.* alpha'
);
my @PROTO_HOST = ( # hit on UNAME_PATT[n] means PROTO_HOST[n]
   'std-sparc-solaris'
 , 'std-ia32-linux'
 , 'std-alpha-osf1'
);
# end of CUSTOMIZE

use Socket;
use Getopt::Long;

my $HostDir = undef;
my $Testing = 0;

my $opts_result = GetOptions (
     'host-dir=s'  => \$HostDir
   , 'test'        => \$Testing
   );
die $Usage if ! $opts_result;

die "--host-dir= not given\n$Usage" unless defined $HostDir;

while (<>) { # read list of hosts...
    chomp;
    s/\s*//g; # no whitespace anywhere, please
    next if /^$/; # ignore blank lines
    my $hostname = $_;

    my ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($_);
    die "$hostname has more than one IP address\n" if @addrs > 1;
    my $ip_addr = inet_ntoa($addrs[0]);

    my $plat_type = undef;
    open(UNAME,"$ERSH $_ 'uname -a' |") || die "ersh $_  uname pipe open failed ($!)\n";
    while (<UNAME>) {
        chomp;
	for (my $i = 0; $i < @UNAME_PATT; $i++) {
	    my $unp = $UNAME_PATT[$i];
	    if ( /$unp/ ) {
	       $plat_type = $PROTO_HOST[$i]; # got it!
	       last;
	    }
	}
	last; # there's only one line
    }
    close(UNAME) || die "ersh $_ uname pipe close failed ($!)\n";

    my $xml = <<EOXML;
<host name="$hostname" xml-version="1">
<status>active</status>
<prototypes>
  <prototype team="." name="$plat_type" />
</prototypes>

<ip-addresses><list>
  <item>$ip_addr</item>
</list></ip-addresses>
</host>
EOXML

    if ( $Testing ) {
       print $xml;
     } else {
       open(HOST,"> $HostDir/$hostname.xml") || die "Can't open $HostDir/$hostname.xml [write] ($!)\n";
       print HOST $xml;
       close(HOST) || die "Can't close $HostDir/$hostname.xml [write] ($!)\n";
     }
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.