edwyr has asked for the wisdom of the Perl Monks concerning the following question:

Managing multiple servers from a single point I want to make a change to the adm crontab, then I want to document on all servers this change has been made, so I want to update /ChangeLog. I can't push a new /ChangeLog to the servers, the servers have different changes and so different /ChangeLog files. I would like a script that can be called with the changes. The script would search up the tree from it's starting directory and update the first ChangeLog found. If there are no changes yet for that day insert the date. If there are already changes append the message without inserting the date. I can think of a few more switches, but that's a start. Anyone have one of these? Is there a better approach to tracking these kinds of things? I expect to also make the script available to a few development groups within my organization.

Replies are listed 'Best First'.
Re: ChangeLog updates from a perl script?
by Fletch (Bishop) on Aug 26, 2005 at 14:22 UTC

    You might approach it from the opposite direction. Keep the crontab under SVN or the like and embed an $Id$ line in a comment. Then you can look at what revision of that is installed on the server to tell if that change has been made yet on that server.

    And while cfengine would be a good mechanism for pushing the files out I don't think it really logs the change anywhere (at least from my understanding from giving it a quick once over). That's not to say that you couldn't extract what's been pushed where from cfengine's logs after the fact, but that'd just be moving the problem as well.

    --
    We're looking for people in ATL

      I have looked at cfengine a lot and it just won't do what I want. I almost have a system ready to release that answers my wants and what I see lacking about cfengine. The request for a /ChangeLog script fits in with the eventual replacement of cfengine, but I want to use it now. There is no way that cfengine could manage the consolidation I mentioned in the original post. Thanks for the help.
        How about this for a change log script:
        ----------------------------------- #!/usr/bin/perl # $Id: changelog.pl,v 1.1 2005/09/07 11:47:15 megglest Exp $ # $Log: changelog.pl,v $ # Revision 1.1 2005/09/07 11:47:15 megglest # almost done # # given a statement # log that statement in either the specified ChangeLog file # or in the nearest ChangeLog file found use Getopt::Std; use strict; # globals my @months = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ); my $datepattern = '^\d\d\s+\w\w\w\s+\d\d\s+'; # parse the command line our ($opt_h, $opt_v, $opt_u, $opt_m, $opt_f); getopts('hvu:m:f:'); &usage if $opt_h; #&usage if !defined($opt_m) and !defined($opt_f); $opt_u = (getpwuid($>))[0] unless $opt_u; ############### ## main loop ############### my $date = &today; my $time = &now; my $file = &findChangeLog; my $msg = &getMessage($file, $opt_m); my $append = &beenUpdated($file, $date); $append = 2 if ! -f $file; open(OUT, ">> $file") or die "$0: cannot append file '$file': $!"; print OUT "\n" if $append != 2; print OUT "$date\n" if $append; print OUT "\t* $time $opt_u\n"; if(ref($msg) eq 'SCALAR') { print OUT "\t ", ${$msg}, "\n"; } else { print OUT "\t ", join("\n\t ", @{$msg}), "\n"; } close(OUT); ############### ## utility functions ############### # get today's date sub today { my @t = localtime; return sprintf("%02d %-3s %02d", $t[3], $months[$t[4]], $t[5] + 19 +00); } # get today's date sub now { my @t = localtime; return sprintf("%02d:%02d", $t[2], $t[1]); } # find the nearest ChangeLog file sub findChangeLog { return $opt_f if $opt_f; my $pwd = $ENV{'PWD'} || `pwd`; chomp($pwd); my @a = split('/', $pwd); unshift(@a, '/'); my $file; my $keep = &isroot ? '/ChangeLog' : "$pwd/ChangeLog"; foreach my $part (@a) { $file .= '/' if length($file); $file .= $part; my $fn = $file . '/ChangeLog'; $fn =~ s,//,/,go; $keep = $fn if -f $fn; } $keep =~ s,//,/,go; return $keep; } # is the user root? sub isroot { return 1 if $> == 0; return 0; } # has the file been updated today? sub beenUpdated { my $fn = shift; my $date = shift; my $lastdate; return 0 unless -f $fn; open(IN, "< $fn") or die "$0: cannot read file '$fn': $!"; while(<IN>) { chomp; $lastdate = $_ if /$datepattern/o; } close(IN); return $lastdate eq $date; } # if no -m supplied, present an editor asking the user for a message sub getMessage { my $file = shift; my $msg = shift; return \$msg if defined($msg); $msg = 'Not a terminal and no message suppled' if(system('tty -s') + >> 8) == 1; $ENV{'TMPDIR'} = '/tmp' unless $ENV{'TMPDIR'}; # set a defa +ult directory my $tfile = "$ENV{'TMPDIR'}/changelog.$$"; $ENV{'EDITOR'} = 'vi' unless $ENV{'EDITOR'}; # set the defa +ult editor $ENV{'VISUAL'} = 'vi' unless $ENV{'VISUAL'}; # set the defa +ult editor # create the temporary file open(OUT, "> $tfile") or die "$0: cannot create file '$tfile': $!" +; print OUT "CL ------------------------------------------\n"; print OUT "CL Enter a ChangeLog Message for file '$file'\n"; print OUT "CL All lines beginning with 'CL' are ignored\n"; print OUT "CL ------------------------------------------\n"; close(OUT); # ask the user to edit the file system("$ENV{'VISUAL'} $tfile"); # read the file contents in # remove all the junk messages open(IN, "grep -v '^CL' $tfile |") or die "$0: cannot read file '$ +tfile': $!"; my @lines = <IN>; chomp(@lines); close(IN); # retun the message string return \@lines; } # how to use this script sub usage { print "usage: $0: [-m MESSAGE][-f CHANGELOGFILE][-u USERNAME][-vh] +\n"; print "\t-m MESSAGE - message to log\n"; print "\t-f CHANGELOGFILE - specific ChangeLog file to log the mes +sage\n"; print "\t-u USERNAME - username to log the message against\n" +; print "\t-v - verbose\n"; print "\t-h - help (this message)\n"; exit 1; } __END__ =pod TODO =cut -----------------------------------
Re: ChangeLog updates from a perl script?
by tcf03 (Deacon) on Aug 26, 2005 at 14:16 UTC
    cfengine?

    Ted
    --
    "That which we persist in doing becomes easier, not that the task itself has become easier, but that our ability to perform it has improved."
      --Ralph Waldo Emerson