Tuesday, January 25, 2011

maintaining entries in linux config files like syslog.conf automagically in a robust manner

sometimes I want to automatically add a config to a conf file that I can scriptably remove later, for example I want to temporarily make 10 hosts log to a remote syslog server. So I so something like this in a script;

##some other commands 
echo "kern.*            @syslog.server.local" >> /etc/syslog.conf
service syslogd restart

however quite often I update the some other commands and run the script again. obviously this is not idempotent, I can't re-apply it without some grep/delete jiggerpokery and I can't easily remove it.

so I have taken to doing something like this;

cat <<HEREDOC >>/etc/syslog.conf
###some unique string###
echo "kern.*            @syslog.server.local"
###end some unique string###
HEREDOC

which allows me to do this to make the operation repeatable...

sed -e 's/###some unique string###(*)###end some unique string###/replacement/g' /tmp/syslog.conf > /tmp/syslog.conf
cat <<HEREDOC >>$dfile
###some unique string###
echo "kecrn.*            @syslog.server.local"
###end some unique string###
HEREDOC

however this all seems a bit much...

(obviously /etc/httpd/conf.d/someconffile.conf arrangements have solved this problem for newer packages)

is there a simpler way to do this ?

any caveats that I should be aware of with this approach?

  • sed doesn't normally do multi-line patterns like that. You could do:

    read -d '' -r replacement<<HEREDOC
    ###some unique string###
    echo "kecrn.*            @syslog.server.local"
    ###end some unique string###
    HEREDOC
    sed -e "/beginmark/i\beginmark\n$replacement\nendmark" -e '/beginmark/,/endmark/d'` filename
    

    You also can't redirect onto the same file. It will first truncate the file and then run sed on it (which is now empty). You have to use a temporary file or use the --in-place (or -i) option:

    sed -i 'sed commands' filename
    

    or

    sed 'sed commands' filename > tmpfile
    mv tmpfile filename
    
  • I have used SVN for this. Assume that

    • You have an svn repository for each host: http://svn.localnet/thishost/ and you want to start making fancy changes to real /etc/syslog.conf on 'thishost'.
    • You already have a local checkout of the config repo for this host in /configs/

    start managing config for this file

    cp /etc/syslog.conf /configs/etc/
    svn add /configs/etc/syslog.conf
    svn commit -m "Managing syslog.conf"
    

    make changes via script

    #echo some stuff into the file.. no need for extra markup/metadata
    cp /etc/syslog.conf /configs/etc/
    svn commit -m "I added some junk temporarily"
    service syslogd restart
    

    Now you can roll back to the previous version. If, between the addition and the rollback, you've made other, permanent, changes, you can use svn to get the differences between the versions, and merge stuff together.

    Of course, substitute in git or whatever you please for revision control. And also make some permanent scripts to reduce the chances for errors, like a bash function that cp's the file into your checkedout repo based on path, takes a commit comment as an argument. or whatever.

    ing you have a configuration repository at svn:///config/ which contains etc/syslog.conf, and you are know that the most recent thing in the repository is the same as the live config file on the filesystem:

    : it interesting, that this is the other strategy that I employed.
    ptman : If you want to go the version control route, there's [etckeeper](http://joey.kitenet.net/code/etckeeper/), but I would recommend puppet and augeas.
    From rjewell
  • AS part of deploying the puppet project, I discovered augeas; http://augeas.net/

    which is a configuration file management tool.

    From

0 comments:

Post a Comment