[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: iterators in copy::
From: |
Tim Nelson |
Subject: |
Re: iterators in copy:: |
Date: |
Mon, 2 Feb 2004 10:25:28 +1100 (EST) |
On Sat, 31 Jan 2004, John Gray wrote:
> iterators don't appear to work on the copy stanza? This sure would
> allow me to reduce the length of the stanza (I have a number of options
> of each file, so it gets rather long).
>
> I was hoping to do something like:
>
> files = ( /etc/hosts.allow:/etc/hosts.deny:/etc/inetd.conf:...)
> $(mf)$(files) dest=$(files)
> mode=644
> owner=root
> group=root
> type=checksum
> server=server.domain.com
>
> then repeat this for another set of files with slightly different options.
>
> Over quite a number of files, I only use about 5 different sets of options.
Hmm. I'm using the script both below (bottom) and attached as a
cfdb on my cfengine configuration files. Then, I just put in something
like the config excerpt (immediately below).
:)
cfengine config excerpt:
------------------------------------------------------------------------
copy:
=cfdoc start
<h3>copy section</h3>
<p>This section copies across the files needed to configure a machine to
the basic state. The main components to are:</p>
<ol>
<li>A basic firewall setup</li>
<li>The issue file</li>
</ol>
<p>It also sets a class for these so that if any files are changed, the
appropriate daemon gets reloaded</li>
=cfdoc end
<?
%files = (
# Set up basic iptables settings
'/etc/sysconfig/iptables' => ['600'],
# Copy across pre-login banner (issue file)
'/etc/issue' => ['644'],
);
%classmap = (
'iptables' => 'iptables_reload',
);
foreach $key (sort keys %files) {
($mode) = @{ $files{$key} };
$extra = "";
foreach $classkey (sort keys %classmap) {
$extra .= ($key =~ /$classkey/) ? $classmap{$classkey} : "";
}
$extra !~ /^\s*$/ and $extra = "\t\tdefine=$extra\n";
$OUT .= <<EOT;
/var/cfengine/local/$key
dest=$key
mode=$mode
owner=root
group=root
server=cfengine.bcc.local.
$extra
EOT
}
?>
------------------------------------------------------------------------
cfengine config template converter:
-------------------------------------------------------------------------------------
#!/usr/bin/perl -I /usr/lib/perl5/site_perl/5.005
use Text::Template;
use Getopt::Long;
use File::Basename;
### Deal with command-line options
Getopt::Long::Configure('bundling', 'no_ignore_case');
GetOptions(\%ARGH,
'd=s', 'D|define=s' => \%defines,
);
if(! $ARGH{'d'}) { $ARGH{'d'} = "#"; }
if($#ARGV < 0) { die "Error: List files to be processed on the command line\n";
}
### Set up paths
$pathsearch = '/var/cfengine/';
$pathreplace = '/var/www/html/internal/cfengine-auto/';
$ourpath = `pwd`; chomp $ourpath;
### Set up documentation headers and footers
$xhtml_head = <<EOT;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<title>#TITLE#</title>
<link rel="stylesheet" href="http://www.sunet.com.au/include/dococolors.css"
type="text/css"/>
<!-- #MESSAGE# -->
</head>
<body>
<h1>#TITLE#</h1>
<hr>
EOT
$xhtml_foot = <<EOT;
<hr>
</body>
</html>
EOT
$message = "Do not edit this file; it is generated with templateconv";
### Process each file
foreach $file (@ARGV) {
### Ensure that we're processing the right file, and set up the names
if($file !~ /\.pt$/) { $file .= '.pt'; }
if(! -e $file) { die "File $file does not exist\n"; }
$targetfile = $file; $targetfile =~ s/\.pt$//;
### Set up documentation filename
$docofile = $targetfile . '.cfdoc.html';
if($docofile !~ m#^/#) { $docofile = "$ourpath/$docofile"; }
$docofile =~ s#$pathsearch#$pathreplace#;
$docopath = dirname($docofile);
mkdir($docopath);
### Suck in template
$text = join '', getfile($file);
### Extract doco
while($text =~ s/\n=cfdoc start\n(.*?)\n=cfdoc end\n//s) {
$docotext .= $1;
}
### Print to doco file
if($docotext !~ /^\s*$/) {
print "Doco: $docofile\n";
$docotext = "$xhtml_head$docotext$xhtml_foot";
$docotext =~ s/#TITLE#/Documentation for $targetfile/g;
$docotext =~ s/#MESSAGE#/$message/g;
writefile($docofile, $docotext);
}
### Set up and run template conversion
$template = new Text::Template(
TYPE => STRING,
SOURCE => $text,
DELIMITERS => ['<?', '?>'],
) or die "Can't create template: $Text::Template::ERROR\n";
$text = $template->fill_in(
BROKEN => \&callback
);
### Write to output file
print "Output: $targetfile\n";
$text = "$ARGH{'d'} $message\n$text";
writefile($targetfile, $text);
}
exit $templateretval ? $templateretval : 0;
### Call back for Text::Template function
sub callback {
my(%hash) = @_;
die "Error at $hash{'lineno'}: " . $hash{'error'} . "\n";
}
### Returns the passed $filename in an array of @lines
sub getfile {
my($filename) = @_;
my(@lines);
open(FILE, $filename) or die "Can't open file $filename: $!";
@lines = <FILE>;
close(FILE);
return(@lines);
}
### Writes the $text to the specified $filename
sub writefile {
my($filename, $text) = @_;
open(FILE, '>' . $filename) or die "Can't open file $filename: $!";
print FILE $text;
close(FILE);
}
-------------------------------------------------------------------------------------
--
Tim Nelson
Systems Administrator
Sunet Internet
Tel: +61 3 5241 1155
Fax: +61 3 5241 6187
Web: http://www.sunet.com.au/
Email: sysadmin@sunet.com.au
templateconv.cfdb
Description: Text document