def daemonize(pid, chdir, chroot, umask, files_preserve=None, do_open=True): """ Uses python-daemonize to do all the junk needed to make a server a server. It supports all the features daemonize has, except that chroot probably won't work at all without some serious configuration on the system. """ logs_dir = os.path.join(chdir, "logs") pid_dir = os.path.join(chdir, os.path.dirname(pid) or ".") if chroot: logs_dir = os.path.join(chroot, logs_dir) pid_dir = os.path.join(chroot, pid_dir) if not os.path.exists(logs_dir): os.mkdir(logs_dir) if not os.path.exists(pid_dir): os.mkdir(pid_dir) context = daemon.DaemonContext() context.pidfile = pidlockfile.PIDLockFile(pid) context.stdout = open(os.path.join(logs_dir, "salmon.out"), "a+") context.stderr = open(os.path.join(logs_dir, "salmon.err"), "a+") context.files_preserve = files_preserve or [] context.working_directory = os.path.expanduser(chdir) if chroot: context.chroot_directory = os.path.expanduser(chroot) if umask is not False: context.umask = umask if do_open: context.open() return context
def setup_daemon_context(log_file_handle, program_uid, program_gid): """Creates the daemon context. Specifies daemon permissions, PID file information, and the signal handler. log_file_handle: The file handle to the log file. program_uid: The system user ID that should own the daemon process. program_gid: The system group ID that should be assigned to the daemon process. Returns the daemon context. """ daemon_context = daemon.DaemonContext( working_directory='/', pidfile=pidlockfile.PIDLockFile( os.path.join(SYSTEM_PID_DIR, PROGRAM_PID_DIRS, PID_FILE)), umask=PROGRAM_UMASK, ) daemon_context.signal_map = { signal.SIGTERM: sig_term_handler, } daemon_context.files_preserve = [log_file_handle] # Set the UID and GID to 'batwatch' user and group. daemon_context.uid = program_uid daemon_context.gid = program_gid return daemon_context
def start_daemon(args): def sigterm(d, signum, stackframe): d.shutdown_event.set() conffile = '/root/code/cgroups-monitor-daemon/config' if args.config is not None: conffile = args.config config = MonitorConfig(conf_file=conffile) config.load() ensure_path(config.workdir) detach = True if args.foreground: detach = False logger = logging.getLogger('') logger.setLevel(logging.DEBUG) # create console handler and set level to debug if detach: logfile = os.path.join(config.workdir, config.name + '.log') h = logging.FileHandler(logfile) h.setLevel(logging.DEBUG) # logging.basicConfig(filename=logfile, level=logging.DEBUG) else: h = logging.StreamHandler() h.setLevel(logging.DEBUG) # logging.basicConfig(level=logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s:%(levelname)s: %(message)s') h.setFormatter(formatter) logger.addHandler(h) m = Monitor(config.name, config=config) d = MonitorDaemon(m) on_terminate = partial(sigterm, d) pidfile_path = os.path.join(config.workdir, config.name + '.pid') ctx = daemon.DaemonContext( umask=0o002, pidfile=pidlockfile.PIDLockFile(pidfile_path), detach_process=detach, files_preserve=[h.stream], # TODO fix this stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr) ctx.signal_map = { signal.SIGTERM: on_terminate, } with ctx: d.run_forever()
def main(): import argparse parser = argparse.ArgumentParser(description='Warden Server') parser.add_argument('home', nargs='?', help="the warden home folder") parser.add_argument( '--pid-file', help= "PID file for Daemon mode. This causes Warden to run in Daemon mode", dest='pid_file') parser.add_argument('--stop', help='Stop Warden running in Daemon mode', action='store_true', default=False) args = parser.parse_args() if args.stop and not args.pid_file: log.error( 'Warden cannot stop daemon mode unless the pid-file is specified') sys.exit(1) if args.stop: pid_file = os.path.abspath(os.path.expanduser(args.pid_file)) if not os.path.exists(pid_file): log.error('Warden cannot find pid-file %s', pid_file) sys.exit(1) pid = int(open(pid_file, 'r').readline()) log.info('Killing pid %d', pid) os.kill(pid, signal.SIGINT) # Check if we've managed for 10 seconds for i in range(10): try: os.kill(pid, 0) log.info('Waiting for %d to die', pid) except OSError: log.info('Stop complete') return time.sleep(1) log.warning("Could not end warden process - killing manually") os.kill(pid, signal.SIGHUP) if os.path.exists(pid_file): os.remove(pid_file) return home = AutoConf.get_home(args.home) if not os.path.exists(home): log.error('The warden home specified ("%s") does not exist!' % home) sys.exit(1) if args.pid_file: pid_file = os.path.abspath(os.path.expanduser(args.pid_file)) import daemon from lockfile import pidlockfile context = daemon.DaemonContext( pidfile=pidlockfile.PIDLockFile(pid_file)) with context: warden_server = WardenServer(home) warden_server.start() return warden_server = WardenServer(home) warden_server.start()
def run(self): '''Run.''' if self.pid_file: pidfile = pidlockfile.PIDLockFile(self.pid_file) context = daemon.DaemonContext(pidfile=pidfile) # because of https://github.com/paramiko/paramiko/issues/59 context.files_preserve = self.files_preserve_by_path( '/dev/urandom') else: context = FakeContext() try: self.setup() if self.pid_file: # try and see if we can since it seems that the context doesn't throw a exception pidfile.acquire(timeout=2) pidfile.release() self.logger.info('Attempting to daemonize') else: self.logger.info('Running in foreground') with context: self._initial_checkout() for _, thread in self.threads.items(): thread.start() while True: try: if self.only_once: raise KeyboardInterrupt sleep(60) except KeyboardInterrupt: for i in range(0, self.worker_threads): self.queue.put({'type': 'shutdown'}) break except lockfile.LockTimeout: logging.error('Lockfile timeout while attempting to acquire lock, ' 'are we already running?') except Exception as e: self.logger.error(traceback.format_exception(*sys.exc_info())) finally: self.logger.info('Shutting down') try: cleanup_ssh_wrapper(self.wrapper) except Exception: self.logger.info('No SSH wrapper to clean?') for _, thread in self.threads.items(): if thread.is_alive(): thread.running = False self.logger.debug('waiting for {0}'.format(thread)) thread.join(5) sys.exit(0)
def set_pidlockfile_scenario(testcase, scenario_name, clear_tracker=True): """ Set up the test case to the specified scenario. """ testcase.scenario = testcase.pidlockfile_scenarios[scenario_name] setup_lockfile_method_mocks( testcase, testcase.scenario, u"lockfile.LinkLockFile") testcase.pidlockfile_args = dict( path=testcase.scenario['path'], ) testcase.test_instance = pidlockfile.PIDLockFile( **testcase.pidlockfile_args) if clear_tracker: testcase.mock_tracker.clear()
def get_running_pid(self): pidfile = pidlockfile.PIDLockFile(self.get_pidfile_path()) if not pidfile.is_locked(): return None pid = pidfile.read_pid() # read_pid returns None on IOError or on ValueError if pid is None: raise DaemonControlException("Could not read pidfile %s" \ % self.get_pidfile_path()) return pid
def handle(self, *args, **options): """ Takes the options and starts a daemon context from them. Example:: python manage.py linkconsumer --pidfile=/var/run/cb_link.pid --stdout=/var/log/cb/links.out --stderr=/var/log/cb/links.err """ context = daemon.DaemonContext() context.chroot_directory = self.get_option_value( options, 'chroot_directory') context.working_directory = self.get_option_value( options, 'working_directory', '/') context.umask = self.get_option_value(options, 'umask', 0) context.detach_process = self.get_option_value(options, 'detach_process') context.prevent_core = self.get_option_value(options, 'prevent_core', True) #Get file objects stdin = self.get_option_value(options, 'stdin') if stdin is not None: context.stdin = open(stdin, "r") stdout = self.get_option_value(options, 'stdout') if stdout is not None: context.stdout = open(stdout, "a+") stderr = self.get_option_value(options, 'stderr') if stderr is not None: context.stderr = open(stderr, "a+") #Make pid lock file pidfile = self.get_option_value(options, 'pidfile') if pidfile is not None: context.pidfile = pidlockfile.PIDLockFile(pidfile) uid = self.get_option_value(options, 'uid') if uid is not None: context.uid = uid gid = self.get_option_value(options, 'gid') if gid is not None: context.gid = uid print '------- ready' context.open() self.handle_daemon(*args, **options)
def run(self): '''Run.''' if self.pid_file: pidfile = pidlockfile.PIDLockFile(self.pid_file) context = daemon.DaemonContext(pidfile=pidfile) # because of https://github.com/paramiko/paramiko/issues/59 context.files_preserve = self.files_preserve_by_path( '/dev/urandom') else: context = FakeContext() try: self.setup() if self.pid_file: # try and see if we can since it seems that the context doesn't throw a exception pidfile.acquire(timeout=2) pidfile.release() self.logger.info('Attempting to daemonize') else: self.logger.info('Running in foreground') with context: self._initial_checkout() for _, thread in self.threads.items(): thread.start() self.main_loop() except lockfile.LockTimeout: logging.error('Lockfile timeout while attempting to acquire lock, ' 'are we already running?') finally: self.logger.info('Shutting down') try: self.cleanup_ssh_wrapper(self.wrapper) except Exception: self.logger.info('No SSH wrapper to clean?') for _, thread in self.threads.items(): if thread.is_alive(): thread.join(2) sys.exit(0)
def main(): global pidfile try: action = getattr(Command, sys.argv[1]) except Exception: # Either because no command is given or command is invalid usage_exit(1) # Parse config file config_file = find_config_file() if not config_file: print 'No config file found' sys.exit(1) else: config.read(config_file) pidfile = pidlockfile.PIDLockFile(config.get('config', 'pid_path')) action()
def run_server(): try: # Launch server log.debug("Starting HTTP%s server on %s:%d" % ("S" if options.ssl else "", options.host if options.host else "*", options.port)) server_class = calypso.HTTPSServer if options.ssl else calypso.HTTPServer server = server_class((options.host, options.port), calypso.CollectionHTTPHandler) server.serve_forever(poll_interval=10) except KeyboardInterrupt: server.socket.close() # If foreground execution is requested, just run the server if not options.daemon: run_server() sys.exit(0) # Otherwise, daemonize Calypso context = daemon.DaemonContext() context.umask = 0o002 if options.pidfile: from lockfile import pidlockfile # Generate a pidfile where requested context.pidfile = pidlockfile.PIDLockFile(options.pidfile) with context: run_server() # vim: set ts=4 sw=4 et si :
def __init__(self, name, pidfile_path): self.name = name self._pidfile = pidlockfile.PIDLockFile(os.path.realpath( str(pidfile_path)), timeout=10)
#!/usr/bin/env python __author__ = 'ejcosta' __service_name__ = 'kb_light_stats' import grp import signal import daemon from lockfile import pidlockfile from service_handler import ( initial_program_setup, do_main_program, program_cleanup, ) pidfile = pidlockfile.PIDLockFile("/var/run/{}.pid".format(__service_name__)) context = daemon.DaemonContext( working_directory="/var/lib/{}".format(__service_name__), umask=0o002, pidfile=pidfile, ) context.signal_map = {signal.SIGTERM: program_cleanup} context.gid = grp.getgrnam('root').gr_gid config_file = open("/etc/{0}/{0}.conf".format(__service_name__), 'r') context.files_preserve = [config_file] initial_program_setup(config_file) with context:
def __init__(self, lock_file_name): self.lockfile = pidlockfile.PIDLockFile(lock_file_name)