help-cfengine
[Top][All Lists]
Advanced

[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

Attachment: templateconv.cfdb
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]