Dear All,
<Disclaimer>
I figured if I needed it, maybe someone else will find it helpful. :)
</Disclaimer>
I am using Amanda to backup a large number of hosts, with large number
of disks. Some hosts are similar, some are different. Keeping the
disklist file in proper condition was getting harder and harder. That
pushed me to write the script - disklist-builder.pl (please find
attached).
The idea is to define a list of hosts with corresponding templates,
define templates, and then generate the disklist file painlessly. You
can run "perldoc disklist-builder.pl" for all documentation that is
available and for the example usage.
All comments and feedback are appreciated.
--
Best regards,
Leonid Mamtchenkov, RHCE
System Administrator
Francoudi & Stephanou Ltd.
#!/usr/bin/perl -w
=head1 NAME
disklist-builder.pl - Build disklist definitions for Amanda backup
=cut
use POSIX qw(strftime);
use strict;
=head1 SYNOPSIS
B<disklist-builder.pl> [ B<host_file> [ B<disklist> ] ]
=cut
my $hosts_file = shift;
my $disklist_file = shift;
=head1 DESCRIPTION
disklist-build.pl is my idea of templating system for disklist
definitions for Amanda backup software. This script should help you
in building disklist files when you need to manage a large number of
hosts, which are similar in some ways and different in others.
Consider an example of /home partition being mounted from central
NFS server by some of your servers. Those, which mount the central
/home partition, need it to be excluded from the disklist, since it's
already included with NFS server disklist entry. Instead, you might
want to backup /localhome partition, if system has one.
In order to construct disklist for your network, create a host
definition file, e.g. "hosts.list", which looksl like this:
# The format of the host definition file is:
#
# Hostname Template
server1.mydomain.com unix-default
server2.mydomain.com unix-default,unix-nfs
Above configuration will create Amanda disklist entries using
C<unix-default> template for server1 and server2 of your mydomain.com.
Disklist entries for server2 will be modified by C<unix-nfs> template.
Now you just need to create two templates. Sample C<unix-default>
template may look like this:
# The format of the template is:
#
# [-]Disk Dumptype
/bin system-vital
/boot system-vital
/dev system-vital
/etc system-vital
/home system-home
/opt system-binaries
/usr system-binaries
/var system-var
Now, C<unix-nfs> might look like:
# The format of the template is:
#
# [-]Disk Dumptype
-/home system-home
/localhome system-home
Dumptype column in template definition should be the same as the one
you have defined in Amanda configuration file. Disk column should be
also the same as you used to define in Amanda disklist file before. If
you precede the disk with a minus ("-") character, then it will be
deleted from the disklist.
All empty lines and lines that start with the hash ("#") sign are
ignored in both host definition file and templates. All files are
processed from top to bottom, and from left to right.
=cut
=head1 FILES
=over
=item hosts.list
If no host definition file has been specified on the command line,
then disklist-builder.pl tries to use C<hosts.list> file in the
current directory.
=item disklist
If no disklist (i.e. result) file has been specified, then
disklist-builder.pl will create file C<disklist> in the current
directory.
=item templates
The names of the templates you use in the host definition file are
also the names of files. If you no directory has been specified, then
templates are expected to be found in the current directory.
=back
=cut
# Defaults.
$hosts_file = "hosts.list" if (!defined($hosts_file));
$disklist_file = "disklist" if (!defined($disklist_file));
open(DISKLIST,">$disklist_file") || die "open disklist $disklist_file: $!";
# Print some header to the file
print DISKLIST "# This is disklist definition file for Amanda backup.\n";
print DISKLIST "# Generated by disklist-builder.pl\n";
print DISKLIST "# Generated at ".strftime("%H:%M:%S %d/%m/%Y",localtime(time))."\n";
print DISKLIST "\n";
open(HOSTS, $hosts_file) || die "open hosts file $hosts_file: $!";
while (my $host_line = <HOSTS>) {
chomp($host_line);
next if ($host_line =~ /^\s*$/); # Skip empty lines
next if ($host_line =~ /^#/); # Skip comments
my ($host,$config_list) = split(/\s+/, $host_line);
# Process all proper hosts
if ($host ne "") {
# Cleanup whitespaces
$host =~ s/\s+//g;
$config_list =~ s/\s+//g;
# Print a comment
print DISKLIST "#",$host,"\n";
# Get a list of config files to process for the host.
my @configs = split(/,/, $config_list);
my %disk_list = ();
foreach my $config_file (@configs) {
open (CONFIG, $config_file) || die "open config file
($config_file): $!";
while (my $disklist_line=<CONFIG>) {
chomp($disklist_line);
next if ($disklist_line =~ /^\s*$/); # Skip empty
lines
next if ($disklist_line =~ /^#/); # Skip
comments
my ($disk,$dumptype) = split(/\s+/, $disklist_line);
# Add/delete disks to/from disklist
if ($disk =~ /^-/) {
$disk =~ s/^-//;
delete $disk_list{$disk};
}
else {
$disk_list{$disk} = $dumptype;
}
}
close (CONFIG);
}
# Print resulting disklist for current host to file
foreach my $disk (sort keys %disk_list) {
print DISKLIST $host,"\t",$disk,"\t",$disk_list{$disk},"\n";
}
print DISKLIST "\n";
}
}
close(HOSTS);
close(DISKLIST);
=head1 TODO
=over
=item Execute/Include/Parse templates
Currently, templates are only parsed. Sometimes it would be easier to
execute some program and use it's output in the disklist. In some
other cases, no parsing or external processing is required, but rather
a simple include of part of disklist file.
=item Comments inclusion
Currently, all comments in templates and host definition files are
ignored. I think that they should kind of be passed into resulting
disklist file. Needs more consideration.
=item Proper documentation
=back
=head1 BUGS
None that I know of.
=head1 VERSION
$Id: disklist-builder.pl,v 1.2 2003/05/29 13:49:36 leonid Exp $
=head1 AUTHOR
Leonid Mamtchenkov <[EMAIL PROTECTED]>
=cut