#!/usr/bin/python """looks at the amanda database, and the currently loaded set of tapes, and decides which tape slots need to come out and what to replace them with. """ import sys, os, re, string from email.MIMEText import MIMEText debug = 0 def usage(): print "usage: %s config" % sys.argv[0] def dprint(s): if debug: print s # get the config from the commmand line try: config = sys.argv[1] except IndexError: usage() print "please specify the config to print next tapes for" sys.exit(1) # the list of tapes in the loader, from amtape $config show current_tapes = [None] * 10 # retardo magic number current_re = re.compile('^slot (\d+): date (\d+) label (.*)$') for line in os.popen4("/usr/sbin/amtape %s show" % config)[1].readlines(): stuff = current_re.match(line) if stuff: tape = stuff.group(3) slot = int(stuff.group(1)) dprint("tape %s in slot %s" % (tape, slot)) current_tapes[slot] = tape dprint("current tapes: %s" % current_tapes) # the latest tapes, required to do a complete restore of every DLE latest_tapes = [] stats_re = re.compile('^stats:') for line in os.popen4("/usr/sbin/amadmin %s export" % config)[1].readlines(): if stats_re.match(line): tape = line.split(' ')[7][:-1] #print tape if tape not in latest_tapes: latest_tapes.append(tape) dprint("latest tapes: %s" % latest_tapes) # the available tapes, which amanda expects tobe able to write to in the next # $runtapes days available_tapes = [] for line in open("/var/lib/amanda/%s/tapelist" % config, 'r').readlines(): tape = line.split(' ')[1] available_tapes.append(tape) # this file is in reverse order, i.e. the LRU tape is at the bottom available_tapes.reverse() dprint("available_tapes = %s" % available_tapes) # the next tapes, that amanda expects to use next_tapes = [] next_re = re.compile("^The next Amanda run should go onto tape ([^ ]+) or a new tape.$") for line in os.popen4("/usr/sbin/amadmin %s tape" % config)[1].readlines(): tape = next_re.match(line) next_tapes.append(tape.group(1)) dprint("next tapes: %s" % next_tapes) # work out which tapes need to come out remove_tapes = [] for tape in current_tapes: if tape in latest_tapes and tape not in next_tapes: remove_tapes.append(tape) if len(remove_tapes) > 0: dprint("these tapes need to come out: %s" % remove_tapes) slots = [str(current_tapes.index(tape)) for tape in remove_tapes] dprint("slots: %s" % slots) # work out which tapes to replace them with replace_tapes = [] for tape in available_tapes: if tape not in current_tapes: replace_tapes.append(tape) if len(replace_tapes) == len(remove_tapes): break dprint("these tapes need to go in: %s" % replace_tapes) msg = """Hello! Tape time! Please remove the tapes in the following slots: %(slots)s and replace them with the following tapes: %(tapes)s Thanks! """ filler = {'tapes': string.join(replace_tapes, ', '), 'slots': string.join(slots, ', '), } mail = MIMEText(msg % filler) mail['Subject'] = "amanda tape helper for %s" % config mail['To'] = "root" mail['From'] = "amanda" dprint(mail.as_string()) s = os.popen("/usr/sbin/sendmail -t", 'w') s.write(mail.as_string()) s.close()