Helper scripts: Difference between revisions

From FAIWiki
Jump to navigation Jump to search
No edit summary
Line 196: Line 196:


[[User:OliverOsburg|OliverOsburg]] 20:41, 17 Nov 2006 (CET)
[[User:OliverOsburg|OliverOsburg]] 20:41, 17 Nov 2006 (CET)
== Configure FAI classes depending on IP addresses or a network the host is in ==
getFAIClassesFromIP.pl does loop up if there is an entry for the
given 'ip_address' or a subnet including 'ip_address' in the
'network.conf' file and return the FAI classes specified for the
fitting entries as a space separated list to stdout.
For the format of 'network.conf' see the examples file provided.
The script:
<pre>
#!/usr/bin/perl -w
#
# getFAIClassesFromIP.pl
#
# Get the FAI Classes for the given IP.
# Search in the referenced network.conf
#
# Maximilian Wilhelm <mwilhelm@math.uni-paderborn.de>
#  -- Tue, 04 Apr 2006 15:18:20 +0200
#
use strict;
use Net::CIDR;
# Set to 1 if you want to be told about possible badness...
my $debug = 0;
my $network_conf;
my $ip;
my %classes;
my @indexes;
my $i = 0;
my $output_class_string;
if ( scalar( @ARGV ) == 2 ) {
$network_conf = $ARGV[0];
$ip = $ARGV[1];
my $valid_ip = 0;
if ( Net::CIDR::cidrvalidate( $ip ) ) {
$valid_ip = 1;
} else {
die "Error: Invalid IP $ip provided!\n";
}
} else {
print STDERR "Usage: $0 [network.conf] [ip]\n";
exit 1;
}
if ( -f $network_conf ) {
open ( NETWORK_CONF, "<$network_conf" )
or die "Error: could not open network configuration \"$network_conf\"\n";
while( <NETWORK_CONF> ) {
if ( m/^#|^$/ ) {
next;
}
# Match for a subnet (network/mask)
if ( m/^(\d+\.\d+\.\d+\.\d+\/\d+)\s+(.*)$/ ) {
my @network = ( $1 );
my @network_classes = split ( /\ /, $2 );
if ( Net::CIDR::cidrlookup( $ip, @network ) ) {
print STDERR "Found network \"$network[0]\" fitting to $ip.\n" if ($debug);
foreach my $network_class ( @network_classes ) {
$classes{$network_class} = $i++;
push ( @indexes, "$network_class" );
print STDERR "saved class $network_class at " . ($i-1) . "\n" if ($debug);
}
}
}
# Match for s single IP address
elsif ( m/^(\d+\.\d+\.\d+\.\d+)\s+(.*)$/ ) {
my $read_ip = $1;
my @ip_classes = split ( /\ /, $2 );
chomp $read_ip;
if ( "$read_ip" eq "$ip" ) {
print STDERR "Found IP \"$read_ip\" fitting to $ip.\n" if ($debug);
foreach my $ip_class ( @ip_classes ) {
$classes{$ip_class} = $i++;
push ( @indexes, "$ip_class" );
print STDERR "saved class $ip_class at ". ($i-1) . "\n" if ($debug);
}
}
}
elsif ( $debug ) {
print STDERR "Error: Unparseable line \"$_\" in \"${network_conf}\"...\n";
}
}
close ( NETWORK_CONF );
} else {
die "Error: Network configuration \"$network_conf\" does not exist.";
}
if ($i != 0) {
foreach my $n ( values %classes ) {
$output_class_string .= "$indexes[$n] ";
}
print $output_class_string . "\n";
}
1;
</pre>
The example network.conf
<pre>
#
# network.conf
#
# This file is used to defined relations between IP subnets and FAI classes
# (maybe only one, too).
#
# This file is read by the getFAIClassesFromIP.pl script.
# (See http://files.rfc2324.org/misc_tools/FAI)
#
# It is possible to put single IPs or IP subnet declarations in CIDR notation
# into this file and write some class name on the right of it.
#
# ATTENTION: Order *does* matter.
#  Put more important things at the end of the file.
# If for any IP a class is defined twice, the second (more important) occurance
# will be used when building up the class list pushed to FAI.
#
# Format:
# IP class1 [ class2 [ ...  [ classN ] ] ]
# network/mask class1 [ class2 [ ...  [ classN ] ] ]
#
# Let me show you: (I know, this is a very silly example, but..)
192.168.0.0/24 MY_HOME_NETWORK MY_NETWORK
172.16.0.0/16 COMPANY MY_BIG_COMPANY_NETWORK
192.168.0.1 MY_HOME_ROUTER MY_HOME_NETWORK
</pre>
The current version can be found in may checked out GIT tree at http://files.rfc2324.org/misc_tools/FAI/getFAIClassesFromIP/
or be using my GIT directly via <pre>git clone http://git.rfc2324.org/repositories/misc_tools.git/</pre>
[[User:MaximilianWilhelm|MaximilianWilhelm]] Thu, 21 Jun 2007 17:19:12 +0200

Revision as of 15:25, 21 June 2007

FAI-Tools

Jan Jansen sent me an interesting tool that should help with management of the FAI configdir get the file

his mail:

Hi,
As long as there were no responses to this posting, i don't dealed with
this idea (GPL) but if some user would find it usefull that would be
also nice for me because i don't have that much time anymore now to fix
all known (and probably unknown) bugs alone. A problem could also be the
currently, only with shell-options available, documentation.
So i post some hints here:
- if a file doc/<class> exists in your fairep, it will be shown as
class-description in info mode
- new script styles ([0-9][0-9]-*) can cause little errors
- some extravagant string values can cause qouting errors (shell
problem)
- create mode not fully funtional

Installation:
Unzip the archive to a directory and adjust the lib and tmp paths in
file 'ftool' to the right place. Now the script should be funtional.
Keep attention to test it the first times with a copy of your repository
to not destroy your classes/files in case of missusing or unexpected
errors (which hopefully aren't that much).


FAIlint

failint.sh a lint checker for FAI. (detects common mistakes)

FAI development and testing helpers

I created some scripts that help setting up a FAI developemnt environment, and running builds and tests in there. At the moment it's mostly about creating fai-cd's and testing them in a qemu vm. Eventually I will add functions for network installation testing with a real hardware host and a qemu client, as well as testing network install with a qemu hist and a qemu client. I am quite interested if someboy finds them useful, they are in subversion:

http://svn.debian.org/wsvn/fai/people/lazyboy/fai-dev-helpers/

--lazyboy 11:12, 21 Oct 2005 (CEST)

fast fai-cd creation script

when developing a new fai-cd it can happen that you need to create new fai-cd's very often. It gets annoying that you always need to delete fai-mirror and the old image... unless you use a script like this (change your tmp path for image and mirror):

#!/bin/sh

FAI_MIRROR_LOCATION=/data/produktion/tmp/fai-mirror

DATE=`date +%Y-%m-%d_%h-%M-%S`

if [ -z $1 ];then
  CDIMAGE=/data/produktion/tmp/fai-cd_${DATE}.iso
  echo "using default cdimage location $CDIMAGE"
else
  CDIMAGE=$1
fi

if [ -z $FAI_MIRROR_LOCATION ]; then
  echo "error - FAI_MIRROR_LOCATION is empty - exiting"
  exit 1
else
  echo "cleaning up fai-mirror at $FAI_MIRROR_LOCATION"
  rm -r $FAI_MIRROR_LOCATION
fi


mkdir -p $FAI_MIRROR_LOCATION

fai-mirror -a $FAI_MIRROR_LOCATION

CDIMAGE_BACKUP=${CDIMAGE}_bak_date +%Y-%m-%d_%h-%M-%S

if [ -f $CDIMAGE ];then
  echo "moving old cd image to $CDIMAGE_BACKUP"
fi

fai-cd -m $FAI_MIRROR_LOCATION $CDIMAGE

--lazyboy 10:59, 5 Jan 2006 (CET)

turn kernel bootprompt parameters into classes

Every kernel parameter after the -- separator is changed to uppercase and used as a classname.

class/35-bootprompt :

#!/usr/bin/perl
# this will define classes from all kernel parameters that
# appear after a parameter '--', as defined in $separator
use strict;
use warnings;

my $separator = '--';

my $seen;
foreach ( split /\s+/, `cat /proc/cmdline` )
{
  if ( $_ eq $separator )
  {
    $seen = 1;
    next;
  }
  next unless $seen;
  print uc $_, "\n"
    if m/^\w+$/;
}

--Ingo Wichmann / Linuxhotel 17 Jan 2006 (CET)

Define a class for a list of hosts

This makes it easy to maintain lists of hosts that should share a class.

Just write a list into a file $FAI_CONFIG/class/FOO.list and it will define your (arbitrary) class FOO for each host that appears in that file.

Thus, a new class GRONK is created and defined for hosts zapp and whirr by simply creating a file GRONK.list that looks like this

foo
bar

class/55-host-lists :

#!/bin/sh
# checks for an appearance of this host's name in each list and, if it
# finds this host in any of the lists, will print the name of the
# list (without the postfix '.list')
#
for thislist in *.list ; do
	thisclass=$(basename $thislist .list)
	egrep -q "\<$HOSTNAME\>" $thislist && echo $thisclass
done

--sanso 14:27, 30 Aug 2006 (CEST)

fai-conf-update

Update the FAI config space according to the changes on the running FAI server. produces a shell script so that this tool can be run on any host installed with FAI. the resulting shell script can be used to update the configuration space. For now, only the FAI server config can be updated, as the clients do not have write permission to the FAI config space on the server.

fai-conf-update

#! /bin/sh
# fai-conf-update
# script to update the FAI configspace based on FAI Classes.
#
# ToDo:
# - update of the package config
# - flags to change output: output in patch form.
# - tesing of installscripts with the new config on the running installserver
# 
# FixMe:
# -ugly grep after the find. 
#
# Thanks:
# -fly out to MT for first fixes, MrFai for FAI, h01ger for motivation!

FAI_CONFIGSPACE=/srv/fai/config
CLASSES=`cat /var/log/fai/localhost/last/FAI_CLASSES`
SHELLSCRIPT="/root/update_fai.sh"

if [ -f $SHELLSCRIPT ]; then
    echo "$SHELLSCRIPT exists, aborting."
    exit 1
fi

# Loop through the classes

for i in $CLASSES; do

#    Find the config files, strip off the class name in the end
#    loop through the files

    for j in `find $FAI_CONFIGSPACE/files -type f -name ".svn" -prune -o -name $i -print | grep -v \.svn`; do
	name=`echo $j | sed "s#$FAI_CONFIGSPACE/files##"| sed s/\\\/$i//`

	if [ -f $name ]; then
	    if  ! diff -q $name $j  >& /dev/null ; then
		echo "class $i needs update from $name to $j"
		echo "cp $name $j" >> $SHELLSCRIPT
	    fi
	    if [ ! -f $name ]; then
		echo file "$name is not existing on this machine, removing it from the config space"
		echo "rm $j" >> $SHELLSCRIPT
	    fi
	fi
    done
done

echo "review the results in $SHELLSCRIPT and run it to actually update the FAI config space."

I consider this to be a neat thing together with fai-cd: Install your server with FAI. Run the server. As needs change with time, the config files need to be updated. run fai-cd, the result will be a clone of the old server which is adapted to new hardware with FAI. This script is a starter to do this automatically, see the FixMe and ToDo in the script. Could result in a kind of automatik FAI evolution. ;)

OliverOsburg 20:41, 17 Nov 2006 (CET)

Configure FAI classes depending on IP addresses or a network the host is in

getFAIClassesFromIP.pl does loop up if there is an entry for the given 'ip_address' or a subnet including 'ip_address' in the 'network.conf' file and return the FAI classes specified for the fitting entries as a space separated list to stdout.

For the format of 'network.conf' see the examples file provided.


The script:

#!/usr/bin/perl -w
#
# getFAIClassesFromIP.pl
#
# Get the FAI Classes for the given IP.
# Search in the referenced network.conf
#
# Maximilian Wilhelm <mwilhelm@math.uni-paderborn.de>
#  -- Tue, 04 Apr 2006 15:18:20 +0200
#

use strict;
use Net::CIDR;

# Set to 1 if you want to be told about possible badness...
my $debug = 0;

my $network_conf;
my $ip;

my %classes;
my @indexes;
my $i = 0;

my $output_class_string;

if ( scalar( @ARGV ) == 2 ) {
	$network_conf = $ARGV[0];
	$ip = $ARGV[1];

	my $valid_ip = 0;
	if ( Net::CIDR::cidrvalidate( $ip ) ) {
		$valid_ip = 1;
	} else {
		die "Error: Invalid IP $ip provided!\n";
	}

} else {
	print STDERR "Usage: $0 [network.conf] [ip]\n";
	exit 1;
}

if ( -f $network_conf ) {
	open ( NETWORK_CONF, "<$network_conf" )
		or die "Error: could not open network configuration \"$network_conf\"\n";
	while( <NETWORK_CONF> ) {
		if ( m/^#|^$/ ) {
			next;
		}

		# Match for a subnet (network/mask)
		if ( m/^(\d+\.\d+\.\d+\.\d+\/\d+)\s+(.*)$/ ) {
			my @network = ( $1 );
			my @network_classes = split ( /\ /, $2 );
			if ( Net::CIDR::cidrlookup( $ip, @network ) ) {
				print STDERR "Found network \"$network[0]\" fitting to $ip.\n" if ($debug);

				foreach my $network_class ( @network_classes ) {
					$classes{$network_class} = $i++;
					push ( @indexes, "$network_class" );

					print STDERR "saved class $network_class at " . ($i-1) . "\n" if ($debug);
				}
			}
		}

		# Match for s single IP address
		elsif ( m/^(\d+\.\d+\.\d+\.\d+)\s+(.*)$/ ) {

			my $read_ip = $1;
			my @ip_classes = split ( /\ /, $2 );
			chomp $read_ip;

			if ( "$read_ip" eq "$ip" ) {
				print STDERR "Found IP \"$read_ip\" fitting to $ip.\n" if ($debug);

				foreach my $ip_class ( @ip_classes ) {
					$classes{$ip_class} = $i++;
					push ( @indexes, "$ip_class" );

					print STDERR "saved class $ip_class at ". ($i-1) . "\n" if ($debug);
				}
			}
		}

		elsif ( $debug ) {
			print STDERR "Error: Unparseable line \"$_\" in \"${network_conf}\"...\n";
		}		
	}
	close ( NETWORK_CONF );

} else {
	die "Error: Network configuration \"$network_conf\" does not exist.";
}

if ($i != 0) {
	foreach my $n ( values %classes ) {
		$output_class_string .= "$indexes[$n] ";
	}

	print $output_class_string . "\n";
}

1;

The example network.conf

# 
# network.conf
#
# This file is used to defined relations between IP subnets and FAI classes
# (maybe only one, too).
#
# This file is read by the getFAIClassesFromIP.pl script.
# (See http://files.rfc2324.org/misc_tools/FAI)
#
# It is possible to put single IPs or IP subnet declarations in CIDR notation
# into this file and write some class name on the right of it.
#
# ATTENTION: Order *does* matter.
#  Put more important things at the end of the file.
# If for any IP a class is defined twice, the second (more important) occurance
# will be used when building up the class list pushed to FAI.
#
# Format:
# IP			class1 [ class2 [ ...  [ classN ] ] ] 
# network/mask		class1 [ class2 [ ...  [ classN ] ] ] 
#
# Let me show you: (I know, this is a very silly example, but..)

192.168.0.0/24		MY_HOME_NETWORK MY_NETWORK

172.16.0.0/16		COMPANY MY_BIG_COMPANY_NETWORK

192.168.0.1		MY_HOME_ROUTER MY_HOME_NETWORK


The current version can be found in may checked out GIT tree at http://files.rfc2324.org/misc_tools/FAI/getFAIClassesFromIP/

or be using my GIT directly via

git clone http://git.rfc2324.org/repositories/misc_tools.git/

MaximilianWilhelm Thu, 21 Jun 2007 17:19:12 +0200