X-Git-Url: https://pwan.org/git/?a=blobdiff_plain;f=certmaster%2Futils.py;h=5544b05e981c0a75518e978c662020d203214218;hb=5bb4be3edcfdf031d7446e434ef4f51309ce32c7;hp=eec3d2b9c8aab870d0a5dbc992fbbe2e8d2a818b;hpb=f9375dad2c0da2be5279dfaa0aa4d0a2754147ba;p=certmaster.git diff --git a/certmaster/utils.py b/certmaster/utils.py index eec3d2b..5544b05 100755 --- a/certmaster/utils.py +++ b/certmaster/utils.py @@ -24,6 +24,7 @@ import certs from config import read_config from commonconfig import MinionConfig import logger +import sub_process # FIXME: module needs better pydoc @@ -31,6 +32,14 @@ import logger # FIXME: can remove this constant? REMOTE_ERROR = "REMOTE_ERROR" +# The standard I/O file descriptors are redirected to /dev/null by default. +if (hasattr(os, "devnull")): + REDIRECT_TO = os.devnull +else: + REDIRECT_TO = "/dev/null" + + + def trace_me(): x = traceback.extract_stack() @@ -43,25 +52,40 @@ def daemonize(pidfile=None): Writes the new PID to the provided file name if not None. """ - print pidfile pid = os.fork() if pid > 0: sys.exit(0) + os.chdir("/") os.setsid() os.umask(0) pid = os.fork() + os.close(0) + os.close(1) + os.close(2) + + # based on http://code.activestate.com/recipes/278731/ + os.open(REDIRECT_TO, os.O_RDWR) # standard input (0) + + os.dup2(0, 1) # standard output (1) + os.dup2(0, 2) # standard error (2) + + + if pid > 0: if pidfile is not None: open(pidfile, "w").write(str(pid)) sys.exit(0) + def nice_exception(etype, evalue, etb): - # FIXME: I believe we can remove this function etype = str(etype) - lefti = etype.index("'") + 1 - righti = etype.rindex("'") - nicetype = etype[lefti:righti] + try: + lefti = etype.index("'") + 1 + righti = etype.rindex("'") + nicetype = etype[lefti:righti] + except: + nicetype = etype nicestack = string.join(traceback.format_list(traceback.extract_tb(etb))) return [ REMOTE_ERROR, nicetype, str(evalue), nicestack ] @@ -191,6 +215,37 @@ def create_minion_keys(): os.write(ca_cert_fd, ca_cert_string) os.close(ca_cert_fd) +def run_triggers(ref, globber): + """ + Runs all the trigger scripts in a given directory. + ref can be a certmaster object, if not None, the name will be passed + to the script. If ref is None, the script will be called with + no argumenets. Globber is a wildcard expression indicating which + triggers to run. Example: "/var/lib/certmaster/triggers/blah/*" + """ + + log = logger.Logger().logger + triggers = glob.glob(globber) + triggers.sort() + for file in triggers: + log.debug("Executing trigger: %s" % file) + try: + if file.find(".rpm") != -1: + # skip .rpmnew files that may have been installed + # in the triggers directory + continue + if ref: + rc = sub_process.call([file, ref], shell=False) + else: + rc = sub_process.call([file], shell=False) + except: + log.warning("Warning: failed to execute trigger: %s" % file) + continue + + if rc != 0: + raise codes.CMException, "certmaster trigger failed: %(file)s returns %(code)d" % { "file" : file, "code" : rc } + + def submit_csr_to_master(csr_file, master_uri): """" gets us our cert back from the certmaster.wait_for_cert() method