diff options
Diffstat (limited to 'subplot/vendored/daemon.py')
-rw-r--r-- | subplot/vendored/daemon.py | 139 |
1 files changed, 0 insertions, 139 deletions
diff --git a/subplot/vendored/daemon.py b/subplot/vendored/daemon.py deleted file mode 100644 index febf392..0000000 --- a/subplot/vendored/daemon.py +++ /dev/null @@ -1,139 +0,0 @@ -import logging -import os -import signal -import socket -import subprocess -import time - - -# Start a daemon that will open a port on localhost. -def daemon_start_on_port(ctx, path=None, args=None, name=None, port=None): - daemon_start(ctx, path=path, args=args, name=name) - daemon_wait_for_port("localhost", port) - - -# Start a daeamon, get its PID. Don't wait for a port or anything. This is -# meant for background processes that don't have port. Useful for testing the -# lib/daemon library of Subplot, but not much else. -def daemon_start(ctx, path=None, args=None, name=None): - runcmd_run = globals()["runcmd_run"] - runcmd_exit_code_is = globals()["runcmd_exit_code_is"] - runcmd_get_exit_code = globals()["runcmd_get_exit_code"] - runcmd_get_stderr = globals()["runcmd_get_stderr"] - runcmd_prepend_to_path = globals()["runcmd_prepend_to_path"] - - argv = [path] + args.split() - - logging.debug(f"Starting daemon {name}") - logging.debug(f" ctx={ctx.as_dict()}") - logging.debug(f" name={name}") - logging.debug(f" path={path}") - logging.debug(f" args={args}") - logging.debug(f" argv={argv}") - - ns = ctx.declare("_daemon") - - this = ns[name] = { - "pid-file": f"{name}.pid", - "stderr": f"{name}.stderr", - "stdout": f"{name}.stdout", - } - - # Debian installs `daemonize` to /usr/sbin, which isn't part of the minimal - # environment that Subplot sets up. So we add /usr/sbin to the PATH. - runcmd_prepend_to_path(ctx, "/usr/sbin") - runcmd_run( - ctx, - [ - "daemonize", - "-c", - os.getcwd(), - "-p", - this["pid-file"], - "-e", - this["stderr"], - "-o", - this["stdout"], - ] - + argv, - ) - - # Check that daemonize has exited OK. If it hasn't, it didn't start the - # background process at all. If so, log the stderr in case there was - # something useful there for debugging. - exit = runcmd_get_exit_code(ctx) - if exit != 0: - stderr = runcmd_get_stderr(ctx) - logging.error(f"daemon {name} stderr: {stderr}") - runcmd_exit_code_is(ctx, 0) - - # Get the pid of the background process, from the pid file created by - # daemonize. We don't need to wait for it, since we know daemonize already - # exited. If it isn't there now, it's won't appear later. - if not os.path.exists(this["pid-file"]): - raise Exception("daemonize didn't create a PID file") - - this["pid"] = _daemon_wait_for_pid(this["pid-file"], 10.0) - - logging.debug(f"Started daemon {name}") - logging.debug(f" pid={this['pid']}") - logging.debug(f" ctx={ctx.as_dict()}") - - -def _daemon_wait_for_pid(filename, timeout): - start = time.time() - while time.time() < start + timeout: - with open(filename) as f: - data = f.read().strip() - if data: - return int(data) - raise Exception("daemonize created a PID file without a PID") - - -def daemon_wait_for_port(host, port, timeout=3.0): - addr = (host, port) - until = time.time() + timeout - while True: - try: - s = socket.create_connection(addr, timeout=timeout) - s.close() - return - except socket.timeout: - logging.error(f"daemon did not respond at port {port} within {timeout} seconds") - raise - except socket.error as e: - logging.info(f"could not connect to daemon at {port}: {e}") - pass - if time.time() >= until: - logging.error(f"could not connect to daemon at {port} within {timeout} seconds") - raise ConnectionRefusedError() - - -# Stop a daemon. -def daemon_stop(ctx, name=None): - logging.debug(f"Stopping daemon {name}") - ns = ctx.declare("_daemon") - logging.debug(f" ns={ns}") - pid = ns[name]["pid"] - signo = signal.SIGKILL - - logging.debug(f"Terminating process {pid} with signal {signo}") - try: - os.kill(pid, signo) - except ProcessLookupError: - logging.warning("Process did not actually exist (anymore?)") - - -def daemon_no_such_process(ctx, args=None): - assert not _daemon_pgrep(args) - - -def daemon_process_exists(ctx, args=None): - assert _daemon_pgrep(args) - - -def _daemon_pgrep(pattern): - logging.info(f"checking if process exists: pattern={pattern}") - exit = subprocess.call(["pgrep", "-laf", pattern]) - logging.info(f"exit code: {exit}") - return exit == 0 |