So, here's the solution I've developed, in case anyone wants to use and/or
critique it. I know that best practice is to use Cfengine's internal
capabilities rather than heavyweight external scripts, but I simply couldn't
come up with a clean way to manage /etc/logadm.conf, especially maintaining the
-P 'timestamp' flags.
One thing I wasn't sure about is how to handle the module script. I put it in
/var/cfengine/modules, but update.cf doesn't include copying down that
directory. I'll probably need to add a promise somewhere to ensure that has
been copied down and to only execute the script if it exists.
Justin
#========================================================
bundle agent manage_solaris_logadm_conf {
vars:
solaris::
"logadm_entries" slist => {
"/var/adm/wtmpx -C 5 -c -p 1m",
"/var/adm/sudo.log -C 5 -N -p 1d -s 1m",
};
methods:
solaris::
"logadm" usebundle => _manage_logfile_rotation("$(logadm_entries)");
}
bundle agent _manage_logfile_rotation(entry) {
vars:
solaris::
"logadm_conf" string => "/etc/logadm.conf";
commands:
solaris.Min00_05::
"$(sys.workdir)/modules/chklogadm $(entry)"
module => "true";
files:
insert_needed::
"$(logadm_conf)"
handle => "insert_new_logadm_entry",
comment => "Insert new entry into $(this.promiser).",
edit_line => insert_logadm_entry("$(entry)"),
classes => if_repaired("inserted_entry");
update_needed.!inserted_entry::
"$(logadm_conf)"
handle => "update_logadm_entry_options",
comment => "Update $(this.promiser) options for a specific
entry.",
edit_line => update_logadm_entry("$(entry)",
"$(chklogadm.new_options)");
}
bundle edit_line insert_logadm_entry(entry) {
insert_lines:
"$(entry)";
}
bundle edit_line update_logadm_entry(old_entry, new_options) {
classes:
"ok" expression => regextract("(\S+)\s+(.*)" ,"$(old_entry)", "entry");
replace_patterns:
ok::
"$(entry[1]).*" replace_with => value("$(entry[1]) $(new_options)");
}
#===========================================================
# modules/chklogadm
#!/usr/bin/perl
use strict;
use warnings;
exit 1 if @ARGV < 2;
my $logfile = shift @ARGV;
my $options = "@ARGV";
my $entry = "";
my $timestamp = "";
open CONF, "/etc/logadm.conf" or exit 1;
while (<CONF>) {
chomp;
next unless /^$logfile/;
$entry = $_;
last;
}
close CONF;
unless ($entry) {
print "+insert_needed\n";
exit 0;
}
if ($entry =~ / (-P '[^']+?')/) {
$timestamp = $1;
$entry =~ s/ -P '[^']+?'//;
}
if ($entry ne "$logfile $options") {
print "+update_needed\n";
print "=new_options=$options $timestamp\n";
}
else {
print "=new_options=$options\n";
}
-----Original Message-----
From: Justin Lloyd
Sent: Thursday, May 27, 2010 10:21 AM
To: 'Seva Gluschenko'
Cc: [email protected]
Subject: RE: Managing Solaris logadm.conf
Seva,
I thought about something like that. One complication is that it's not just the
wtmpx log. I left others out for simplicity. The approach you suggest would
require a similar regex check for each log.
One approach that came to mind this morning when discussing this with a
colleague would be to use a module. I could write a Perl script that can do
much more powerful regex checking than Cfengine can natively and then specify a
class to define if the desired parameters don't match the existing logadm.conf
entry. Also, since modules are a bit heavier weight than using native
capabilities, and since the logadm file doesn't change often anyway, I could
just restrict the command promise to only check maybe once per hour, at most.
I'm going to investigate this approach, but if anyone has any further
suggestions, or even critiques of using a module for this, please speak up. :)
Thanks,
Justin
-----Original Message-----
From: Seva Gluschenko [mailto:[email protected]]
Sent: Thursday, May 27, 2010 12:01 AM
To: Justin Lloyd
Cc: [email protected]
Subject: Re: Managing Solaris logadm.conf
Justin,
perhaps, you shouldn't insist on exact match. It seems to be
sufficient to match vital parts of string you want to maintain, e.g.
classes:
"must_be_changed" not => regcmp(".*-C 3.*-c.*-p 1m.*", "$(args)");
2010/5/26 Justin Lloyd <[email protected]>:
> I'm trying to decide how best to manage certain entries in Solaris
> /etc/logadm.conf files. Initially, I'm just trying to ensure that
> /var/adm/wtmpx is being rotated correctly. However, there are a couple
> of catches in trying to manage this file.
>
> 1. The file is generally maintained through the logadm(1M) command, so
> that would imply that commands promises would be better than files
> promises. However...
>
> 2. Whenever logadm rotates a file, it adds an option to the file's entry
> to record the last rotation time for the file. For example, a new wtmpx
> entry like
>
> /var/adm/wtmpx -C 3 -c -p 1m
>
> might become
>
> /var/adm/wtmpx -C 3 -P 'Sat May 8 03:10:00 2010' -c -p 1m
>
> The location of the "-P 'timestamp'" option does not appear
> deterministic. This complicates trying to determine whether the wtmpx
> entry is correct. For example, say I have a bundle to which I pass a
> filename a list of options:
>
> "wtmpx" usebundle => _rotate_solaris_log("/var/adm/wtmpx", "-C 3 -c
> -p 1m");
>
> In the bundle, I see if there is already an entry that begins with
> /var/adm/wtmpx. If not, I add it. If so, I leave it alone. However,
> if/when I want to change the rotation parameters (say, changing "-p 1m"
> to "-p 1w"), an exact match against the parameter string won't work
> because of the added -P flag, and I'd like to avoid changing the line
> EVERY time Cfengine runs.
>
> Any thoughts that I might not have considered yet on how to approach
> managing this file? Note that the parameters for wtmpx, for example, may
> vary based on classes.
>
> Thanks,
> Justin
>
> --
> Justin C. Lloyd
> Unix Infrastructure Engineer
> DigitalGlobe, An Imaging and Information Company
>
>
>
> This electronic communication and any attachments may contain confidential
> and proprietary
> information of DigitalGlobe, Inc. If you are not the intended recipient, or
> an agent or employee
> responsible for delivering this communication to the intended recipient, or
> if you have received
> this communication in error, please do not print, copy, retransmit,
> disseminate or
> otherwise use the information. Please indicate to the sender that you have
> received this
> communication in error, and delete the copy you received. DigitalGlobe
> reserves the
> right to monitor any electronic communication sent or received by its
> employees, agents
> or representatives.
>
> _______________________________________________
> Help-cfengine mailing list
> [email protected]
> https://cfengine.org/mailman/listinfo/help-cfengine
>
--
SY, Seva Gluschenko.
This electronic communication and any attachments may contain confidential and
proprietary
information of DigitalGlobe, Inc. If you are not the intended recipient, or an
agent or employee
responsible for delivering this communication to the intended recipient, or if
you have received
this communication in error, please do not print, copy, retransmit, disseminate
or
otherwise use the information. Please indicate to the sender that you have
received this
communication in error, and delete the copy you received. DigitalGlobe reserves
the
right to monitor any electronic communication sent or received by its
employees, agents
or representatives.
_______________________________________________
Help-cfengine mailing list
[email protected]
https://cfengine.org/mailman/listinfo/help-cfengine