#!/usr/local/bin/python # # check_svn_backup_helper: remote helper script for check_svn_backup # Dan R. K. Ports # # Copyright (c) 2007-2008 Dan R. K. Ports # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # $Revision$ $Date$ import sys, os, re, subprocess, optparse, traceback SVNADMIN = "/usr/local/bin/svnadmin" SVNLOOK = "/usr/local/bin/svnlook" parser = optparse.OptionParser() parser.add_option("-d", "--directory", dest="backup_dir", help="location of backup directory", metavar="BACKUP_DIR") parser.add_option("-o", "--oldest", dest="oldest_acceptable", type="int", help="oldest acceptable revision", metavar="REVNO") (options, args) = parser.parse_args() # # Nagios helpers # OK = 0 WARN = 1 CRIT = 2 stat = OK def updateStat(x): global stat stat = max(stat,x) msgs = [] # # SVN backup helpers # def comparator(a, b): # We pass in filenames so there is never a case where they are equal. regexp = re.compile("-(?P[0-9]+)(-(?P[0-9]+))?$") matcha = regexp.search(a) matchb = regexp.search(b) reva = int(matcha.groupdict()['revision']) revb = int(matchb.groupdict()['revision']) if (reva < revb): return -1 elif (reva > revb): return 1 else: inca = matcha.groupdict()['increment'] incb = matchb.groupdict()['increment'] if not inca: return -1 elif not incb: return 1; elif (int(inca) < int(incb)): return -1 else: return 1 try: # Find youngest backup directory_list = os.listdir(options.backup_dir) directory_list.sort(comparator) youngest_full = directory_list.pop(); regexp = re.compile("repos-(?P[0-9]+)(-(?P[0-9]+))?$") youngest_full_revision = int(regexp.match(youngest_full).group('revision')) youngest_full_path = os.path.join(options.backup_dir, youngest_full) # Check repository is valid ret = subprocess.call([SVNADMIN, "verify", youngest_full_path]) if (ret != 0): msgs.append("failed to verify") updateStat(CRIT) # Check youngest revision in backup proc = subprocess.Popen([SVNLOOK, "youngest", youngest_full_path], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) if (proc.wait() != 0): msgs.append("failed to svnlook youngest") updateStat(CRIT) revision = int(proc.stdout.readline()) msgs.append("Youngest revision is " + str(revision)) # Check date proc = subprocess.Popen([SVNLOOK, "date", youngest_full_path], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) if (proc.wait() != 0): msgs.append("failed to svnlook date") updateStat(CRIT) revdate = proc.stdout.readline().rstrip() msgs.append("last commit " + revdate) # Check revision not too old if revision < options.oldest_acceptable: msgs.append("older than " + str(options.oldest_acceptable)) updateStat(CRIT) except Exception, e: traceback.print_exc(file=sys.stdout) msgs.append(str(e)) updateStat(CRIT) if stat == OK: out = "OK " elif stat == WARN: out = "WARN " else: out = "CRIT " out += "; ".join(msgs) print out sys.exit(stat)