[976] | 1 | #!/usr/bin/python26
|
---|
| 2 | ###
|
---|
| 3 | ### backmon.commands.updates
|
---|
| 4 | ###
|
---|
| 5 |
|
---|
| 6 | import sys
|
---|
| 7 | import os
|
---|
| 8 | import os.path
|
---|
| 9 | import glob
|
---|
| 10 | import re
|
---|
| 11 | import time
|
---|
| 12 | import datetime
|
---|
| 13 | import dateutil
|
---|
| 14 |
|
---|
| 15 | from optparse import OptionParser
|
---|
| 16 |
|
---|
| 17 | from ..lib import *
|
---|
| 18 |
|
---|
| 19 | from backup_monitoring.datetime import *
|
---|
| 20 | from backup_monitoring.math import *
|
---|
| 21 |
|
---|
| 22 | usage = 'usage: %prog updates [options] [feeds]'
|
---|
| 23 |
|
---|
| 24 | parser = OptionParser(usage=usage)
|
---|
| 25 |
|
---|
| 26 | parser.add_option('-c', '--clear-locks', action='store_true', dest='clear_locks', default=False, help='clear locks')
|
---|
| 27 | parser.add_option('-e', '--expired-only', action='store_true', dest='expired_only', default=False, help='include only expired feeds')
|
---|
| 28 | parser.add_option('-s', '--stale-only', action='store_true', dest='stale_only', default=False, help='include only stale feeds')
|
---|
| 29 | parser.add_option('-l', '--locked-only', action='store_true', dest='locked_only', default=False, help='include only locked feeds')
|
---|
| 30 |
|
---|
| 31 | def run(args, kwargs):
|
---|
| 32 |
|
---|
| 33 | #
|
---|
| 34 | # add kwargs to local namespace
|
---|
| 35 | #
|
---|
| 36 | for key in kwargs.keys():
|
---|
| 37 |
|
---|
| 38 | if re.compile('^[A-Z][A-Z_]+$').match(key):
|
---|
| 39 | exec(key + ' = kwargs[\'' + key + '\']')
|
---|
| 40 |
|
---|
| 41 | (options, args) = parser.parse_args(args)
|
---|
| 42 |
|
---|
| 43 | clear_locks = options.clear_locks
|
---|
| 44 | expired_only = options.expired_only
|
---|
| 45 | stale_only = options.stale_only
|
---|
| 46 | locked_only = options.locked_only
|
---|
| 47 |
|
---|
| 48 | feeds = args
|
---|
| 49 |
|
---|
| 50 | now = int(time.time())
|
---|
| 51 |
|
---|
| 52 | print('')
|
---|
| 53 |
|
---|
| 54 | for path in glob.glob('%s/*' % (UPDATES)):
|
---|
| 55 |
|
---|
| 56 | share = os.path.basename(path)
|
---|
| 57 |
|
---|
| 58 | if( (not HOSTGROUP and not SERVER) or (HOSTGROUP == share and not SERVER) ):
|
---|
| 59 | print('+ %s' % (share))
|
---|
| 60 | print('')
|
---|
| 61 |
|
---|
| 62 | for path in glob.glob('%s/%s/*' % (UPDATES, share)):
|
---|
| 63 |
|
---|
| 64 | i = 0
|
---|
| 65 |
|
---|
| 66 | if not os.path.isdir(path):
|
---|
| 67 | continue
|
---|
| 68 |
|
---|
| 69 | if os.path.islink(path):
|
---|
| 70 | continue
|
---|
| 71 |
|
---|
| 72 | server = os.path.basename(path)
|
---|
| 73 |
|
---|
| 74 | if HOSTGROUP and HOSTGROUP != share:
|
---|
| 75 | continue
|
---|
| 76 |
|
---|
| 77 | if SERVER and SERVER != server:
|
---|
| 78 | continue
|
---|
| 79 |
|
---|
| 80 | updates = Updates(LOGGER, path)
|
---|
| 81 |
|
---|
| 82 | for path in glob.glob('%s/%s/%s/*.inf' % (UPDATES, share, server)):
|
---|
| 83 |
|
---|
| 84 | locked = False
|
---|
| 85 |
|
---|
| 86 | out_file = '%s.out' % (os.path.splitext(path)[0])
|
---|
| 87 | out_lock = '%s.out.lock' % (os.path.splitext(path)[0])
|
---|
| 88 |
|
---|
| 89 | txt_file = '%s.txt' % (os.path.splitext(path)[0])
|
---|
| 90 | txt_lock = '%s.txt.lock' % (os.path.splitext(path)[0])
|
---|
| 91 |
|
---|
| 92 | if os.path.exists(out_lock):
|
---|
| 93 | out_lock_exists = True
|
---|
| 94 | else:
|
---|
| 95 | out_lock_exists = False
|
---|
| 96 |
|
---|
| 97 | if os.path.exists(out_file):
|
---|
| 98 | out_file_exists = True
|
---|
| 99 | else:
|
---|
| 100 | out_file_exists = False
|
---|
| 101 |
|
---|
| 102 | if os.path.exists(txt_lock):
|
---|
| 103 | txt_lock_exists = True
|
---|
| 104 | else:
|
---|
| 105 | txt_lock_exists = False
|
---|
| 106 |
|
---|
| 107 | if out_lock_exists or txt_lock_exists:
|
---|
| 108 | locked = True
|
---|
| 109 |
|
---|
| 110 | if out_lock_exists and out_file_exists:
|
---|
| 111 | token = '*'
|
---|
| 112 | elif out_lock_exists and not out_file_exists:
|
---|
| 113 | token = '>'
|
---|
| 114 | elif txt_lock_exists:
|
---|
| 115 | token = '<'
|
---|
| 116 | else:
|
---|
| 117 | token = ' '
|
---|
| 118 |
|
---|
| 119 | feed = os.path.splitext(os.path.basename(path))[0]
|
---|
| 120 | inf = updates.info(feed, nolock=True)
|
---|
| 121 |
|
---|
| 122 | expired = False
|
---|
| 123 | expired_token = ' '
|
---|
| 124 | stale = False
|
---|
| 125 | overdue = datetime.timedelta(seconds=0)
|
---|
| 126 |
|
---|
| 127 | if inf is not None:
|
---|
| 128 |
|
---|
| 129 | if 'INTERVAL' in inf:
|
---|
| 130 | interval = inf['INTERVAL']
|
---|
| 131 | else:
|
---|
| 132 | interval = '???'
|
---|
| 133 |
|
---|
| 134 | if 'EXIT_STATUS' in inf:
|
---|
| 135 | exit_status = inf['EXIT_STATUS']
|
---|
| 136 | else:
|
---|
| 137 | exit_status = ' ?'
|
---|
| 138 |
|
---|
| 139 | timestamp = inf['TIMESTAMP_ISO']
|
---|
| 140 | expiration = inf['EXPIRATION_ISO']
|
---|
| 141 | duration = inf['DURATION_ISO']
|
---|
| 142 |
|
---|
| 143 | utcnow = datetime.datetime.utcnow()
|
---|
| 144 | expdatetime = datetime.datetime.utcfromtimestamp(int(inf['EXPIRATION']))
|
---|
| 145 |
|
---|
| 146 | if interval == '1m':
|
---|
| 147 | stalepadding = 60
|
---|
| 148 | elif interval == '5m':
|
---|
| 149 | stalepadding = 300
|
---|
| 150 | elif interval == '10m':
|
---|
| 151 | stalepadding = 600
|
---|
| 152 | elif interval == '15m':
|
---|
| 153 | stalepadding = 900
|
---|
| 154 | else:
|
---|
| 155 | stalepadding = 900
|
---|
| 156 |
|
---|
| 157 | staledatetime = expdatetime + datetime.timedelta(seconds=int(inf['DURATION']) * 1.5 + stalepadding)
|
---|
| 158 |
|
---|
| 159 | #print 'utcnow = %s' % (utcnow)
|
---|
| 160 | #print 'expdatetime = %s' % (expdatetime)
|
---|
| 161 |
|
---|
| 162 | if expdatetime < utcnow:
|
---|
| 163 |
|
---|
| 164 | expired = True
|
---|
| 165 | expired_token = 'X'
|
---|
| 166 | overdue = utcnow - expdatetime
|
---|
| 167 |
|
---|
| 168 | if staledatetime < utcnow:
|
---|
| 169 |
|
---|
| 170 | stale = True
|
---|
| 171 | expired_token = 'S'
|
---|
| 172 |
|
---|
| 173 | if inf['SIZE'] is not None:
|
---|
| 174 |
|
---|
| 175 | size = pp_bytes(inf['SIZE'])
|
---|
| 176 |
|
---|
| 177 | else:
|
---|
| 178 |
|
---|
| 179 | size = '????.?? ??'
|
---|
| 180 | suffix = ' B'
|
---|
| 181 |
|
---|
| 182 | if inf['MTIME'] is not None:
|
---|
| 183 |
|
---|
| 184 | mtime = int(inf['MTIME'])
|
---|
| 185 | age = dd_hh_mm_ss(now - mtime)
|
---|
| 186 |
|
---|
| 187 | else:
|
---|
| 188 |
|
---|
| 189 | age = '?? ??:??:??'
|
---|
| 190 |
|
---|
| 191 | else:
|
---|
| 192 |
|
---|
| 193 | interval = '???'
|
---|
| 194 | exit_status = ' ?'
|
---|
| 195 | timestamp = '????-??-?? ??:??:??'
|
---|
| 196 | expiration = '????-??-?? ??:??:??'
|
---|
| 197 | duration = '??:??:??'
|
---|
| 198 | size = '????.?? ??'
|
---|
| 199 | age = '?? ??:??:??'
|
---|
| 200 |
|
---|
| 201 | #
|
---|
| 202 | # increment counter if we have seen at least one desired feed
|
---|
| 203 | #
|
---|
| 204 | if len(feeds) == 0 or feed in feeds:
|
---|
| 205 |
|
---|
| 206 | if (not expired_only) or (expired_only and expired):
|
---|
| 207 |
|
---|
| 208 | if (not stale_only) or (stale_only and stale):
|
---|
| 209 |
|
---|
| 210 | if (not locked_only) or (locked_only and locked):
|
---|
| 211 |
|
---|
| 212 | i += 1
|
---|
| 213 |
|
---|
| 214 | #
|
---|
| 215 | # print header if the first feed has not been printed
|
---|
| 216 | #
|
---|
| 217 | if i == 1:
|
---|
| 218 | print(' + %-10s INT RETURN TIMESTAMP EXPIRATION AGE DURATION SIZE' % (server))
|
---|
| 219 | print(' === ====== =================== =================== =========== ======== ==========')
|
---|
| 220 | i += 1
|
---|
| 221 |
|
---|
| 222 | #
|
---|
| 223 | # print the feed if it is desired
|
---|
| 224 | #
|
---|
| 225 | if len(feeds) == 0 or feed in feeds:
|
---|
| 226 |
|
---|
| 227 | if (not expired_only) or (expired_only and expired):
|
---|
| 228 |
|
---|
| 229 | if (not stale_only) or (stale_only and stale):
|
---|
| 230 |
|
---|
| 231 | if (not locked_only) or (locked_only and locked):
|
---|
| 232 |
|
---|
| 233 | if out_lock_exists and clear_locks:
|
---|
| 234 | os.rmdir(out_lock)
|
---|
| 235 |
|
---|
| 236 | if txt_lock_exists and clear_locks:
|
---|
| 237 | os.rmdir(txt_lock)
|
---|
| 238 |
|
---|
| 239 | print(' %s [%s] %-40s %3s %6s %s %s %s %s %s' % (expired_token, token, feed, interval, exit_status, timestamp, expiration, age, duration, size))
|
---|
| 240 |
|
---|
| 241 | if i > 0:
|
---|
| 242 | print('')
|
---|
| 243 |
|
---|
| 244 | return 0
|
---|
| 245 |
|
---|