#!/usr/bin/python26 ### ### backmon.commands.updates ### import sys import os import os.path import glob import re import time import datetime import dateutil from optparse import OptionParser from ..lib import * from backup_monitoring.datetime import * from backup_monitoring.math import * usage = 'usage: %prog updates [options] [feeds]' parser = OptionParser(usage=usage) parser.add_option('-c', '--clear-locks', action='store_true', dest='clear_locks', default=False, help='clear locks') parser.add_option('-e', '--expired-only', action='store_true', dest='expired_only', default=False, help='include only expired feeds') parser.add_option('-s', '--stale-only', action='store_true', dest='stale_only', default=False, help='include only stale feeds') parser.add_option('-l', '--locked-only', action='store_true', dest='locked_only', default=False, help='include only locked feeds') def run(args, kwargs): # # add kwargs to local namespace # for key in kwargs.keys(): if re.compile('^[A-Z][A-Z_]+$').match(key): exec(key + ' = kwargs[\'' + key + '\']') (options, args) = parser.parse_args(args) clear_locks = options.clear_locks expired_only = options.expired_only stale_only = options.stale_only locked_only = options.locked_only feeds = args now = int(time.time()) print('') for path in glob.glob('%s/*' % (UPDATES)): share = os.path.basename(path) if( (not HOSTGROUP and not SERVER) or (HOSTGROUP == share and not SERVER) ): print('+ %s' % (share)) print('') for path in glob.glob('%s/%s/*' % (UPDATES, share)): i = 0 if not os.path.isdir(path): continue if os.path.islink(path): continue server = os.path.basename(path) if HOSTGROUP and HOSTGROUP != share: continue if SERVER and SERVER != server: continue updates = Updates(LOGGER, path) for path in glob.glob('%s/%s/%s/*.inf' % (UPDATES, share, server)): locked = False out_file = '%s.out' % (os.path.splitext(path)[0]) out_lock = '%s.out.lock' % (os.path.splitext(path)[0]) txt_file = '%s.txt' % (os.path.splitext(path)[0]) txt_lock = '%s.txt.lock' % (os.path.splitext(path)[0]) if os.path.exists(out_lock): out_lock_exists = True else: out_lock_exists = False if os.path.exists(out_file): out_file_exists = True else: out_file_exists = False if os.path.exists(txt_lock): txt_lock_exists = True else: txt_lock_exists = False if out_lock_exists or txt_lock_exists: locked = True if out_lock_exists and out_file_exists: token = '*' elif out_lock_exists and not out_file_exists: token = '>' elif txt_lock_exists: token = '<' else: token = ' ' feed = os.path.splitext(os.path.basename(path))[0] inf = updates.info(feed, nolock=True) expired = False expired_token = ' ' stale = False overdue = datetime.timedelta(seconds=0) if inf is not None: if 'INTERVAL' in inf: interval = inf['INTERVAL'] else: interval = '???' if 'EXIT_STATUS' in inf: exit_status = inf['EXIT_STATUS'] else: exit_status = ' ?' timestamp = inf['TIMESTAMP_ISO'] expiration = inf['EXPIRATION_ISO'] duration = inf['DURATION_ISO'] utcnow = datetime.datetime.utcnow() expdatetime = datetime.datetime.utcfromtimestamp(int(inf['EXPIRATION'])) if interval == '1m': stalepadding = 60 elif interval == '5m': stalepadding = 300 elif interval == '10m': stalepadding = 600 elif interval == '15m': stalepadding = 900 else: stalepadding = 900 staledatetime = expdatetime + datetime.timedelta(seconds=int(inf['DURATION']) * 1.5 + stalepadding) #print 'utcnow = %s' % (utcnow) #print 'expdatetime = %s' % (expdatetime) if expdatetime < utcnow: expired = True expired_token = 'X' overdue = utcnow - expdatetime if staledatetime < utcnow: stale = True expired_token = 'S' if inf['SIZE'] is not None: size = pp_bytes(inf['SIZE']) else: size = '????.?? ??' suffix = ' B' if inf['MTIME'] is not None: mtime = int(inf['MTIME']) age = dd_hh_mm_ss(now - mtime) else: age = '?? ??:??:??' else: interval = '???' exit_status = ' ?' timestamp = '????-??-?? ??:??:??' expiration = '????-??-?? ??:??:??' duration = '??:??:??' size = '????.?? ??' age = '?? ??:??:??' # # increment counter if we have seen at least one desired feed # if len(feeds) == 0 or feed in feeds: if (not expired_only) or (expired_only and expired): if (not stale_only) or (stale_only and stale): if (not locked_only) or (locked_only and locked): i += 1 # # print header if the first feed has not been printed # if i == 1: print(' + %-10s INT RETURN TIMESTAMP EXPIRATION AGE DURATION SIZE' % (server)) print(' === ====== =================== =================== =========== ======== ==========') i += 1 # # print the feed if it is desired # if len(feeds) == 0 or feed in feeds: if (not expired_only) or (expired_only and expired): if (not stale_only) or (stale_only and stale): if (not locked_only) or (locked_only and locked): if out_lock_exists and clear_locks: os.rmdir(out_lock) if txt_lock_exists and clear_locks: os.rmdir(txt_lock) print(' %s [%s] %-40s %3s %6s %s %s %s %s %s' % (expired_token, token, feed, interval, exit_status, timestamp, expiration, age, duration, size)) if i > 0: print('') return 0