108 lines
2.9 KiB
Python
Executable file
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()
|
|
|
|
|