ansible/files/common-scripts/nag-once

108 lines
2.9 KiB
Python
Executable file

#!/usr/bin/python -tt
# nag once
# take stdin and arguments: commandid time-to-ignore-same-output
# if we encounter any kind of error just output whatever we're given
# and prepend our own errors
# so we don't hurt things any worse :)
# copyright (c) 2011 Red Hat, inc
# gpl v2 blah blah
# skvidal - skvidal@fedoraproject.org
import tempfile
import sys
import time
import os
import stat
import glob
def translate_tti(tti):
# translate 1w, 2d, 3d, 1m, 2h, 55m etc to seconds here
if tti is None:
return None
seconds_per_unit = {"s": 1, "m": 60, "h": 3600, "d": 86400, "w": 604800,}
if tti.isdigit():# just seconds
return int(tti)
return int(tti[:-1]) * seconds_per_unit[tti[-1]]
def get_cmdid_dir(cmdid):
"""return a path to a valid and safe cachedir"""
tmpdir="/var/tmp"
prefix = "nag-once:" + cmdid + "#"
dirpath = '%s/%s*' % (tmpdir, prefix)
cachedirs = sorted(glob.glob(dirpath))
for thisdir in cachedirs:
stats = os.lstat(thisdir)
if stat.S_ISDIR(stats[0]) and stat.S_IMODE(stats[0]) == 448 and stats[4] == os.getuid():
return thisdir
# make the dir (tempfile.mkdtemp())
cachedir = tempfile.mkdtemp(prefix=prefix, dir=tmpdir)
return cachedir
def main():
if len(sys.argv) < 2:
raise Exception("Usage: nag-once cmdid [time-to-ignore]")
cmdid = sys.argv[1]
# go through and remove stupid shit from cmdid
cmdid = cmdid.replace('/', '')
cmdid = cmdid.replace('#', '')
cmdid = cmdid.replace('..', '')
cmdid = cmdid.replace(';', '')
cmdid = cmdid.replace('|', '')
cmdid = cmdid.replace('&', '')
cmdid = cmdid.replace('\\', '')
now = time.time()
tti = None
if len(sys.argv) > 2:
tti = sys.argv[2]
tti = translate_tti(tti)
# make up or find our tempdir
mydir = get_cmdid_dir(cmdid)
old_output = None
old_date = 0
if os.path.exists(mydir + '/output'):
old_output = open(mydir + '/output').read()
old_date = os.lstat(mydir + '/output')[stat.ST_MTIME]
# take from stdin
#
theinput = sys.stdin.read()
try:
# at this point we have to handle any outputs more ourself b/c we've just read
# out of sys.stdin :(
if theinput != old_output or (tti and now - old_date > tti):
if theinput.strip(): # if there is nothing here, don't output and don't drop a \n on the end of it
print theinput,
fo = open(mydir + '/output', 'w')
fo.write(theinput)
fo.flush()
fo.close()
except Exception, e:
print >> sys.stderr, e
print >> sys.stderr, theinput
if __name__ == '__main__':
try:
main()
except Exception, e:
print >> sys.stderr, e
if not sys.stdin.isatty():
print >> sys.stderr, sys.stdin.read()