#!/usr/local/bin/perl #Copyright (C) 2009, Tom Judge # ---------------------------------------------------------------------------- # "THE BEER-WARE LICENSE" (Revision 42): # wrote this file. As long as you retain this notice you # can do whatever you want with this stuff. If we meet some day, and you think # this stuff is worth it, you can buy me a beer in return Tom Judge. # ---------------------------------------------------------------------------- use strict; use warnings; my $REPOS = $ARGV[0]; my $TXN = $ARGV[1]; my $SVNLOOK ="/usr/local/bin/svnlook"; my $SVN = "/usr/local/bin/svn"; my $PATCH = "/usr/bin/patch"; my $CFAGENT = "/usr/local/sbin/cfagent"; my $CFSERVD = "/usr/local/sbin/cfservd"; my $DEBUG =1; my $exit_status=0; ### Setup a tempory working directory. $ENV{'TMPDIR'} = "/var/tmp"; my $WORKDIR = `/usr/bin/mktemp -d -t cfengine-svn-commit`; if ($? != 0) { print STDERR "Failed to make temp working dir.\n"; exit 1; } chomp $WORKDIR; print STDERR "Temp Working Dir: $WORKDIR\n\n"; ### ### Get the list of directories that have changed ### my @CHANGED_DIRS = `$SVNLOOK dirs-changed -t $TXN $REPOS`; if ($? != 0) { $exit_status = 1; print STDERR "Failed to get changed dirs\n"; goto cleanup; } my $cfengine_changed =0; foreach my $dir (@CHANGED_DIRS) { chomp $dir; print STDERR "Changed Dir: $dir\n"; if ($dir =~ m#^config/cfengine/inputs/#) { $cfengine_changed =1; } } print STDERR "\n"; ## Check if the config changed that we are insterested in ## If nothing changed jump to cleanup and delete the temp folder. goto cleanup if ($cfengine_changed ==0); ### ### Get the diff of the commit ### my @DIFF = `$SVNLOOK diff -t $TXN $REPOS > $WORKDIR/diff`; if ($? != 0) { $exit_status = 1; print STDERR "Failed to get diff\n"; goto cleanup; } ### ### Check out a working copy to run the tests on. ### print STDERR "Checking out working copy from $REPOS ...."; `$SVN co --quiet --ignore-externals file://$REPOS $WORKDIR/wc 1>&2`; if ($? != 0) { $exit_status = 1; print STDERR "Failed to get fresh working copy\n"; goto cleanup; } print STDERR "OK.\n\n"; ### ### Change cwd to working copy to apply patch. ### chdir "$WORKDIR/wc"; ### ### Apply the patch ### print STDERR "Applying commited changes to working copy....\n"; `patch -p0 < $WORKDIR/diff 1>/dev/null`; if ($? != 0) { $exit_status = 1; print STDERR "Failed to patch working copy\n"; goto cleanup; } print STDERR "Patched OK.\n\n"; ### ### Test the configuration for syntax errors ### $ENV{'CFINPUTS'} = "$WORKDIR/wc/config/cfengine/inputs"; $ENV{'HOME'} = "/home/system/svn"; print STDERR "Running Cfagent against new configuration....\n\n"; my @cfagent_output = `$CFAGENT --no-splay --verbose --parse-only 2>&1`; if ($? != 0) { foreach my $line (@cfagent_output) { print STDERR $line; } print STDERR "\n\n\n##### Syntax error in CFAgent Config\n\n\n\n"; print STDERR "#####\n"; print STDERR "#####\n"; print STDERR "#####\n"; print STDERR "##### YOUR COMMIT FAILED THE SANITY CHECK AND HAS BEEN REJECTED.\n"; print STDERR "#####\n"; print STDERR "##### THE OUTPUT OF THE CFENGINE RUN IS ABOVE THIS MESSAGE.\n"; print STDERR "#####\n"; print STDERR "#####\n"; print STDERR "#####\n"; $exit_status=1; goto cleanup; } print STDERR "Cfagent completed successfully\n\n"; print STDERR "Running Cfservd against new configuration....\n\n"; my @cfservd_output = `$CFSERVD --verbose --parse-only 1>&2`; if ($? != 0) { foreach my $line (@cfservd_output) { print STDERR $line; } print STDERR "\n\n\n##### Syntax error in CFServD Config\n\n\n\n"; print STDERR "#####\n"; print STDERR "#####\n"; print STDERR "#####\n"; print STDERR "##### YOUR COMMIT FAILED THE SANITY CHECK AND HAS BEEN REJECTED.\n"; print STDERR "#####\n"; print STDERR "##### THE OUTPUT OF THE CFENGINE RUN IS ABOVE THIS MESSAGE.\n"; print STDERR "#####\n"; print STDERR "#####\n"; print STDERR "#####\n"; $exit_status=1; goto cleanup; } cleanup: `/bin/rm -Rf $WORKDIR`; exit $exit_status;