Track server configuration file changes using Git versioning system
BY sujith.s
7 years ago
1 comments comment

When a server is managed by more than one admin, it’s always a challenge to keep track of the changes made to the configuration. And when in a multiserver environment managed by more than one admin, this is going to be more complex. It would have been much saner if there was a utility to handle all this. The ones that we found were quite complicated and was made for handling huge numbers. All we wanted was a very simple utility to do just the job, without much bells and whistles. And so, we started out on our own. Here’s what we have now.

We were using the Git for our Drupal code base version controlling. We thought the same could be made use of for system configuration file versioning. We created a bash script that did just that and scheduled it to execute once every hour.

The script compares configuration files with the ones we have in the git repo, and if changes are found, it copies them to a directory called conf and adds the changes to git. It reads the details of files to be tracked from a configuration file kept for the same.

Cron was used for scheduling jobs.

The script can run both as root as well as any normal user.

If the script finds any difference it sends out an email to the recipient address stored in the script.

The script requires that you have a git server and that you have already created a repo for the same.

Here is the script (you might have to modify the email, hostname variables):. You can also follow this at




 # Debug function
function db {
  if [ $DEBUG -eq 1 ];
    echo "$1"

# Log function
function log {
  # If there are parameters read from parameters
  if [ $# -gt 0 ]; then
    echo "[$(date +"%D %T")] $@" >> $LOG_FILE
    db "$@"
    # If there are no parameters read from stdin
    while read data
      echo "[$(date +"%D %T")] $data" >> $LOG_FILE
      db "$data"

# Change to the dir this script resides in
script_path=`readlink -f $0`
script_dir=`dirname "$script_path"`
cd "$script_dir"
 # Run copy operations if run as root
if [ $(id -u) -eq 0 ]; then
  db "Running copy operations"
  # Copy files to the conf folder
  while read path
    # Ignore comments and empty lines
    echo "$path" | egrep '(^\s*#)|(^\s*$)' >/dev/null 2>&1 && continue
    db "$path read from the file"
    if [ -f "$source" ]; then
      # If file then copy
    elif [ -d $source ]; then
      # If folder then deep copy
      destination="`dirname \"$destination\"`"
      # Create the destination folder if it does not exist
      if [ ! -d "$destination" ]; then
        log "$destination does not exist. Creating dir"
        mkdir -p "$destination"
      log "$path: Illegal path found."
      # Continue on to the next path
    db "Copying $source to $destination"
    (nice cp $param "$source" "$destination" 2>&1) | log
  done < ./`hostname`.conf
  db "Changing ownership of conf/`hostname` to metheuser"
  chown -R metheuser: metheuser "conf/`hostname`"
 # Run git operations if run as normaluser
  db "Running git operations"
  # Run git diff to find changes
  file_diff=`git diff --no-prefix`
  diff_lines=$(($(echo -n "$file_diff" | wc -l)))
  # Run git status to check if untracked files are present
  git status|grep untracked > /dev/null
  if [ $? -eq 0 ]; then
    git_status=`git status`
  # If there is a difference
  if [[ $diff_lines -gt 0 || $has_untracked -eq 1 ]]; then
    log "$diff_lines line(s) of difference found"
    log "Has untracked = $has_untracked"
    # Get latest changes from other servers
    log "Pulling changes (if any) from server"
    (git pull 2>&1) | log
    # Commit the difference on the machine
    (git add -A 2>&1) | log
    (git commit -m "Adding changes from $(hostname)" 2>&1) | log
    (git push 2>&1) | log
    db $file_diff
    subject="[CONFIG-TRACK] `hostname` - Status Report - $(date)"
    git_differences="`echo -e "$file_diff\n$git_status"`"
    log "Sending differences via email"
    log "$git_differences"
    echo -e "$git_differences" | mail -s "$subject" -c $email_cc_address $email_to_address 2>&1 | log
    db "No differences found"



on 01st January 2008 / by webmaster
We have added a few new modules to our site recently. Drupal Technical StumbleThis Leave a reply Your email address will not be published. Required fields are marked * Sean (not verified) access_time 29 May 2020 - 18:57 Hi there, I uploaded the files, enabled the modules to use SU, and now I see the link, but there is no icon... How can I fix this? Thanks, Sean webmaster access_time 29 May 2020 - 18:57 In reply to Icon doesn&#039;t show by Sean (not verified) What do you see when you view the source? Search for stumblethis_button and you should be able to see the code for the image and the URL. Then you should be able to troubleshoot from there. Juicy Couture Addict (not verified) access_time 29 May 2020 - 18:57 thanks for the post. would love to hear more of you. by the way, drupal's really popular nowadays as it has easy and fast features. you agree with me? thanks. Add new comment

on 16th January 2008 / by webmaster
Most webmasters do not realize this, but a lot of the content on lot of websites can be accessed from multiple URLs. A simple example would be where and leads to the same page. This is a fatal mistake in Search Engine Optimization and search engines penalize you for duplicate content. The correct configuration would be where the above two urls will lead you to the same page but will redirect you to with a 301 (Moved permanently) status which will not result in search engines penalizing the page. It is very easy to configure 301 redirects using Apache .htaccess file and the process is the same for a Drupal installation also. Drupal Technical Apache htaccess SEO Leave a reply Your email address will not be published. Required fields are marked * Anonymous (not verified) access_time 29 May 2020 - 18:57 Hello. I'm trying to make show as, and I'm running into difficulties. I'm on Apache 2.0 and using the following lines in my httpd.conf file: RewriteEngine on RewriteCond %{HTTP_HOST} ^xxxxxxxxxx\.com$ [NC] RewriteRule ^(.*)$$1 [L,R=301] When I go to, I get (as expected). However, when I go to (it's a Drupal site), I get a 404 thrown and the URL changes to Same thing with Any suggestions? I want to run without Drupal's .htaccess file (instead incorporating these calls into my httpd.conf file). webmaster access_time 29 May 2020 - 18:57 In reply to Rewrite including filesystem path by Anonymous (not verified) I think the problem is with the base path which results in the redirection to /var/www/ part. The best approach I would think is to start with drupal htaccess and then strip out parts and move to httpd SNVC (not verified) access_time 29 May 2020 - 18:57 This is definitely a good guide. Thanks for this. wellyson access_time 29 May 2020 - 18:57 This is really nice and helpful. Add new comment

on 08th February 2008 / by webmaster
Attachment Size slashdotit.tar.gz 173.55 KB Similar to the StumbleThis module that we had created earlier we have created another bookmarking Drupal Technical Slashdotit Leave a reply Your email address will not be published. Required fields are marked * Shlomi Fish (not verified) access_time 29 May 2020 - 18:57 Hi! I'm interested in this module, but Drupal 6.2 complains that it's incompatible with it. Can you please update it or tell me how? Regards, Shlomi Fish webmaster access_time 29 May 2020 - 18:57 In reply to Can you update it for Drupal-6.x? by Shlomi Fish (not verified) Sure we are working on this currently and will post an update soon. Also we will post this module on as well Cheers Anoop John Team Zyxware Anonymous (not verified) access_time 29 May 2020 - 18:57 Hello! Nice Article very interesting, thanks Add new comment
Leave a reply
Your email address will not be published. Required fields are marked *

Filtered HTML

  • Web page addresses and email addresses turn into links automatically.
  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type='1 A I'> <li> <dl> <dt> <dd> <h2 id='jump-*'> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
The content of this field is kept private and will not be shown publicly.
CAPTCHA This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.

Anonymous (not verified)
access_time 29 May 2020 - 23:00

Thanks it is exactly what I'm looking for.