def stop_maestral_daemon_thread(config_name='maestral', timeout=10): """Stops maestral's thread. This function tries to shut down Maestral gracefully. If it is not successful within the given timeout, a TimeoutError is raised. :param str config_name: The name of the Maestral configuration to use. :param float timeout: Number of sec to wait for daemon to shut down before killing it. :returns: ``Exit.Ok`` if successful,``Exit.NotRunning`` if the daemon was not running, ``Exit.Failed`` if it could not be stopped within timeout. """ logger.debug('Stopping thread') lockfile = PIDLockFile(pidpath_for_config(config_name)) t = _threads[config_name] if not t.is_alive(): lockfile.break_lock() return Exit.NotRunning # tell maestral daemon to shut down try: with MaestralProxy(config_name) as m: m.stop_sync() m.shutdown_pyro_daemon() except Pyro5.errors.CommunicationError: return Exit.Failed # wait for maestral to carry out shutdown t.join(timeout=timeout) if t.is_alive(): return Exit.Failed else: return Exit.Ok
def main(cls, argv): service_name = cls.__name__.lower() pidfilepath = '/var/run/{service_name}.pid'.format( service_name=service_name) usage = '{service_name} [options]\n'.format(service_name=service_name) \ + ' -h display this message\n' \ + ' --pidfile=<pidfile> define pidfile (default = {pidfilepath})\n'.format(pidfilepath=pidfilepath) try: opts, args = getopt.getopt(argv, "h", ["pidfile="]) except getopt.GetoptError: print(usage) exit(2) for opt, arg in opts: if opt == '-h': print(usage) exit(0) elif opt == '--pidfile': pidfilepath = arg pidfile = PIDLockFile(pidfilepath, timeout=-1) try: with pidfile: service = cls() service.run() except AlreadyLocked: print('{service_name} already running? (pid={pid})'.format( service_name=service_name, pid=pidfile.read_pid())) exit(1) except LockFailed: print( 'Cannot write pid file to {pidfilepath}, please fix permissions' .format(pidfilepath=pidfilepath)) exit(1)
def daemon_stop(pid_file=None): """ If pid is provided - then run try to stop daemon. Else - just return. """ logging.debug('Stop daemon') if not pid_file: logging.debug('No pid file provided - nothing to stop') return pid_path = os.path.abspath(pid_file) pidfile = PIDLockFile(pid_path, timeout=-1) try: pid_num = pidfile.read_pid() os.kill(pid_num, signal.SIGTERM) # number of tries to check (every 1 sec) if agent is stoped tries = 600 success = False while tries: tries -= 1 time.sleep(1) try: os.kill(pid_num, 0) except OSError: #No process with locked PID success = True break if success: logging.debug('Daemon successfully stopped') else: logging.warn('Unable to stop daemon') except TypeError: # no pid file logging.debug('Pid file not found') except OSError: logging.debug('Process not running')
def start(options, parser): # Perform common option checks commonOptionsCheck(options, parser) # Setup the loggers fileHandler = setupLogging(options) # Start daemon? if options.daemon: # Make sure the PID file will be created without problems pidDir = utils.getDlgPidDir() utils.createDirIfMissing(pidDir) pidfile = os.path.join(pidDir, "dlg%s.pid" % (options.dmAcronym)) working_dir = options.work_dir if not working_dir: if options.cwd: print( 'The --cwd option is deprecated, prefer -w/--work-dir, continuing anyway' ) working_dir = '.' else: working_dir = '/' with daemon.DaemonContext(pidfile=PIDLockFile(pidfile, 1), files_preserve=[fileHandler.stream], working_directory=working_dir): launchServer(options) # Stop daemon? elif options.stop: pidDir = utils.getDlgPidDir() pidfile = os.path.join(pidDir, "dlg%s.pid" % (options.dmAcronym)) pid = PIDLockFile(pidfile).read_pid() if pid is None: sys.stderr.write( 'Cannot read PID file, is there an instance running?\n') else: try: os.kill(pid, signal.SIGTERM) except OSError as e: # Process is gone and file was left dangling, # let's clean it up ourselves if e.errno == errno.ESRCH: sys.stderr.write( 'Process %d does not exist, removing PID file') os.unlink(pidfile) # Check status elif options.status: socket_is_listening = utils.check_port(options.host, options.port, options.timeout) sys.exit(socket_is_listening is False) # Start directly else: working_dir = options.work_dir or '.' os.chdir(working_dir) launchServer(options)
def start(options, parser): # Perform common option checks commonOptionsCheck(options, parser) # Setup the loggers fileHandler = setupLogging(options) # Start daemon? if options.daemon: # Make sure the PID file will be created without problems pidDir = getDfmsPidDir() createDirIfMissing(pidDir) pidfile = os.path.join(pidDir, "dfms%s.pid" % (options.dmAcronym)) with daemon.DaemonContext(pidfile=PIDLockFile(pidfile, 1), files_preserve=[fileHandler.stream]): launchServer(options) # Stop daemon? elif options.stop: pidDir = getDfmsPidDir() pidfile = os.path.join(pidDir, "dfms%s.pid" % (options.dmAcronym)) pid = PIDLockFile(pidfile).read_pid() if pid is None: sys.stderr.write( 'Cannot read PID file, is there an instance running?\n') else: os.kill(pid, signal.SIGTERM) # Start directly else: launchServer(options)
def pull(dry_run, flavor, interactive, debug): """ Pull down tasks from forges and add them to your taskwarrior tasks. Relies on configuration in bugwarriorrc """ try: main_section = _get_section_name(flavor) config = _try_load_config(main_section, interactive) lockfile_path = os.path.join(get_data_path(config, main_section), 'bugwarrior.lockfile') lockfile = PIDLockFile(lockfile_path) lockfile.acquire(timeout=10) try: # Get all the issues. This can take a while. issue_generator = aggregate_issues(config, main_section, debug) # Stuff them in the taskwarrior db as necessary synchronize(issue_generator, config, main_section, dry_run) finally: lockfile.release() except LockTimeout: log.critical( 'Your taskrc repository is currently locked. ' 'Remove the file at %s if you are sure no other ' 'bugwarrior processes are currently running.' % ( lockfile_path ) ) except RuntimeError as e: log.critical("Aborted (%s)" % e)
def pull(dry_run, flavor): """ Pull down tasks from forges and add them to your taskwarrior tasks. Relies on configuration in bugwarriorrc """ twiggy.quickSetup() try: main_section = _get_section_name(flavor) # Load our config file config = load_config(main_section) tw_config = TaskWarriorBase.load_config(get_taskrc_path(config, main_section)) lockfile_path = os.path.join(os.path.expanduser(tw_config["data"]["location"]), "bugwarrior.lockfile") lockfile = PIDLockFile(lockfile_path) lockfile.acquire(timeout=10) try: # Get all the issues. This can take a while. issue_generator = aggregate_issues(config, main_section) # Stuff them in the taskwarrior db as necessary synchronize(issue_generator, config, main_section, dry_run) finally: lockfile.release() except LockTimeout: log.name("command").critical( "Your taskrc repository is currently locked. " "Remove the file at %s if you are sure no other " "bugwarrior processes are currently running." % (lockfile_path) ) except: log.name("command").trace("error").critical("oh noes")
def get_maestral_pid(config_name): """ Returns Maestral's PID if the daemon is running and responsive, ``None`` otherwise. If the daemon is unresponsive, it will be killed before returning. :param str config_name: The name of the Maestral configuration to use. :returns: The daemon's PID. :rtype: int """ lockfile = PIDLockFile(pidpath_for_config(config_name)) pid = lockfile.read_pid() if pid: try: if not is_pidfile_stale(lockfile): return pid except OSError: os.kill(pid, signal.SIGKILL) logger.debug( f"Daemon process with PID {pid} is not responsive. Killed.") else: logger.debug("Could not find PID file") lockfile.break_lock()
def start_daemon(): # 전역변수로 처리 필요 config = configparser.ConfigParser() config.read('./config.cfg') cfg_server = config['SERVER_INFO'] cfg_default = config['DEFAULT_INFO'] # make logger instance logger = logging.getLogger("DA_daemonLog") # make formatter formatter = logging.Formatter( '[%(levelname)s|%(filename)s:%(lineno)s] %(asctime)s > %(message)s') # make handler to output Log for stream and file fileMaxByte = 1024 * 1024 * 100 #100MB fileHandler = logging.handlers.RotatingFileHandler( cfg_default['test_path'], maxBytes=fileMaxByte, backupCount=10) # fileHandler = logging.FileHandler(cfg_default['logging_path']) streamHandler = logging.StreamHandler() # specify formatter to each handler fileHandler.setFormatter(formatter) streamHandler.setFormatter(formatter) # attach stream and file handler to logger instance logger.addHandler(fileHandler) logger.addHandler(streamHandler) pidfile = PIDLockFile(cfg_default['test_pid_path']) try: pidfile.acquire() except AlreadyLocked: try: os.kill(pidfile.read_pid(), 0) print('Process already running!') exit(1) except OSError: #No process with locked PID pidfile.break_lock() daemon_context = daemon.DaemonContext( working_directory='/home/Toven/da/elda', umask=0o002, pidfile=PIDLockFile('/home/Toven/da/elda_daemon.pid'), ) print("Start daemon for EyeLink in python") with daemon_context: while True: logger.setLevel(logging.INFO) logger.info("==========================") logger.debug("Debug message") logger.info("Info message") logger.warn("Warning message") logger.error("Error message") logger.critical("critical debug message") logger.info("==========================")
def acquire(self, timeout=None): owner = self.read_pid() if owner is not None and owner != os.getpid( ) and self.process_alive(owner) is False: log.warn( "Breaking lock '%s' since owning process %i is dead." % (self.lock_file, owner)) self.break_lock() PIDLockFile.acquire(self, timeout)
def get_lock(workdir): pidfile = PIDLockFile(os.path.join(workdir, 'lobster.pid'), timeout=-1) try: pidfile.acquire() except AlreadyLocked: print "Another instance of lobster is accessing {0}".format(workdir) raise pidfile.break_lock() return pidfile
def main(): args = sys.argv[1:] if not len(args) >= 3: print("Usage: openspendingetld <job_id> <config_file> <task> [args, ...]" % args, file=sys.stderr) sys.exit(1) # No two jobs with the same job_id can run at the same time job_id = args.pop(0) configfile_path = os.path.abspath(args.pop(0)) task = args.pop(0) _create_directories() pidfile = PIDLockFile(pidfile_path(job_id)) context = DaemonContext( stdout=open(logfile_path(job_id), 'w+'), stderr=open(logfile_path(job_id), 'w+', buffering=0), pidfile=pidfile ) # NB: There *is* a possible race condition here, if a job with the same # name is able to start between this job calling is_locked() below, and # acquiring the lock when daemonizing. # # The problem is that we want to provide immediate feedback to the # web front end, which calls this file as "openspendingetld", that it # is trying to start a job with an already used job_id, without having # to open another log file. # # This is unlikely to crop up in practice, but ideally we should FIXME. if pidfile.is_locked(): raise AlreadyLocked("Can't start two jobs with id '%s'!" % job_id) with context: try: # Configure logger log = logging.getLogger('openspending.etl') handler = logging.StreamHandler(sys.stderr) handler.setFormatter(logging.Formatter( '%(asctime)s %(levelname)s: %(message)s', '%Y-%m-%d %H:%M:%S' )) log.addHandler(handler) log.setLevel(logging.INFO) # Load pylons environment from specified config file _load_environment(configfile_path) # Run task, passing leftover arguments tasks.__dict__[task](*args) except KeyError: raise TaskNotFoundError("No task called '%s' exists in openspending.tasks!" % task)
def create_pid_file(path): pid_file = PIDLockFile(arguments['--pid']) if pid_file.is_locked(): pid = pid_file.read_pid() try: os.kill(pid, 0) raise Exception("process already running") except OSError, e: if e.errno in (errno.ESRCH, errno.ENOENT): pid_file.break_lock() else: raise
def get_lock(workdir, force=False): from lockfile.pidlockfile import PIDLockFile from lockfile import AlreadyLocked pidfile = PIDLockFile(os.path.join(workdir, 'lobster.pid'), timeout=-1) try: pidfile.acquire() except AlreadyLocked: if not force: logger.error("another instance of lobster is accessing {0}".format(workdir)) raise pidfile.break_lock() return pidfile
def stop_maestral_daemon_process(config_name='maestral', timeout=10): """Stops maestral by finding its PID and shutting it down. This function first tries to shut down Maestral gracefully. If this fails, it will send SIGTERM. If that fails as well, it will send SIGKILL. :param str config_name: The name of the Maestral configuration to use. :param float timeout: Number of sec to wait for daemon to shut down before killing it. :returns: ``Exit.Ok`` if successful, ``Exit.Killed`` if killed and ``Exit.NotRunning`` if the daemon was not running. """ logger.debug('Stopping daemon') lockfile = PIDLockFile(pidpath_for_config(config_name)) pid = lockfile.read_pid() try: if not pid or not _process_exists(pid): return Exit.NotRunning try: with MaestralProxy(config_name) as m: m.stop_sync() m.shutdown_pyro_daemon() except Pyro5.errors.CommunicationError: logger.debug('Could not communicate with daemon, sending SIGTERM') _send_term(pid) finally: logger.debug('Waiting for shutdown') while timeout > 0: if not _process_exists(pid): logger.debug('Daemon shut down') return Exit.Ok else: time.sleep(0.2) timeout -= 0.2 # send SIGTERM after timeout and delete PID file _send_term(pid) time.sleep(1) if not _process_exists(pid): logger.debug('Daemon shut down') return Exit.Ok else: os.kill(pid, signal.SIGKILL) logger.debug('Daemon killed') return Exit.Killed finally: lockfile.break_lock()
def stop_maestral_daemon_process(config_name="maestral", timeout=10): """Stops maestral by finding its PID and shutting it down. This function first tries to shut down Maestral gracefully. If this fails, it will send SIGTERM. If that fails as well, it will send SIGKILL. :param str config_name: The name of the Maestral configuration to use. :param float timeout: Number of sec to wait for daemon to shut down before killing it. :returns: ``Exit.Ok`` if successful, ``Exit.Killed`` if killed and ``Exit.NotRunning`` if the daemon was not running. """ logger.debug("Stopping daemon") lockfile = PIDLockFile(pidpath_for_config(config_name)) pid = lockfile.read_pid() if pid: try: # tell maestral daemon to shut down with MaestralProxy(config_name) as m: m.stop_sync() m.shutdown_pyro_daemon() except Pyro5.errors.CommunicationError: logger.debug("Could not communicate with daemon") try: os.kill(pid, signal.SIGTERM) # try to send SIGTERM to process logger.debug("Terminating daemon process") except ProcessLookupError: logger.debug("Daemon was not running") return Exit.NotRunning finally: # wait for maestral to carry out shutdown logger.debug("Waiting for shutdown") while timeout > 0: try: os.kill(pid, 0) # query if still running except OSError: logger.debug("Daemon shut down") return Exit.Ok # return True if not running anymore else: time.sleep(0.2) # wait for 0.2 sec and try again timeout -= 0.2 # send SIGKILL after timeout, delete PID file and return False os.kill(pid, signal.SIGKILL) logger.debug("Daemon process killed") lockfile.break_lock() return Exit.Killed else: return Exit.NotRunning
def run_maestral_daemon(config_name="maestral", run=True, log_to_stdout=False): """ Wraps :class:`maestral.main.Maestral` as Pyro daemon object, creates a new instance and start Pyro's event loop to listen for requests on a unix domain socket. This call will block until the event loop shuts down. This command will return silently if the daemon is already running. :param str config_name: The name of the Maestral configuration to use. :param bool run: If ``True``, start syncing automatically. Defaults to ``True``. :param bool log_to_stdout: If ``True``, write logs to stdout. Defaults to ``False``. """ from maestral.main import Maestral sock_name = sockpath_for_config(config_name) pid_name = pidpath_for_config(config_name) lockfile = PIDLockFile(pid_name) # acquire PID lock file try: lockfile.acquire(timeout=1) except AlreadyLocked: if is_pidfile_stale(lockfile): lockfile.break_lock() else: logger.debug(f"Maestral already running") return logger.debug(f"Starting Maestral daemon on socket '{sock_name}'") try: # clean up old socket, create new one try: os.remove(sock_name) except FileNotFoundError: pass daemon = Daemon(unixsocket=sock_name) # start Maestral as Pyro server ExposedMaestral = expose(Maestral) # mark stop_sync and shutdown_daemon as oneway methods # so that they don't block on call ExposedMaestral.stop_sync = oneway(ExposedMaestral.stop_sync) ExposedMaestral.shutdown_pyro_daemon = oneway( ExposedMaestral.shutdown_pyro_daemon) m = ExposedMaestral(config_name, run=run, log_to_stdout=log_to_stdout) daemon.register(m, f"maestral.{config_name}") daemon.requestLoop(loopCondition=m._loop_condition) daemon.close() except Exception: traceback.print_exc() finally: # remove PID lock lockfile.release()
def __init__(self, mainOptions): self.pidfilename = mainOptions.get('pidfilename', None) # the file we're using for locking self.parentpidvar = mainOptions.get('parentpidvar', None) # environment variable holding parent pid self.parentpid = None # parent pid which already has the lock self.ppath = None # complete path to the lock file self.pidlockfile = None # PIDLockFile object self.pidfilepid = None # pid of the process which has the lock self.locktorelease = None # PIDLockFile object we should release when done if self.parentpidvar is not None and self.parentpidvar in os.environ: self.parentpid = int(os.environ[self.parentpidvar]) if self.pidfilename is not None: self.ppath = os.path.join(gp.get_masterdatadir(), self.pidfilename) self.pidlockfile = PIDLockFile(self.ppath)
def main(argv): nablogging.setup_logging("nabd") pidfilepath = "/run/nabd.pid" usage = ( f"nabd [options]\n" f" -h display this message\n" f" --pidfile=<pidfile> define pidfile (default = {pidfilepath})\n") try: opts, args = getopt.getopt(argv, "h", ["pidfile=", "nabio="]) except getopt.GetoptError: print(usage) exit(2) for opt, arg in opts: if opt == "-h": print(usage) exit(0) elif opt == "--pidfile": pidfilepath = arg pidfile = PIDLockFile(pidfilepath, timeout=-1) try: with pidfile: from .nabio_hw import NabIOHW nabio = NabIOHW() Nabd.leds_boot(nabio, 1) nabd = Nabd(nabio) nabd.run() except AlreadyLocked: print(f"nabd already running? (pid={pidfile.read_pid()})") exit(1) except LockFailed: print(f"Cannot write pid file to {pidfilepath}, please fix " f"permissions") exit(1)
def main(argv): nablogging.setup_logging("nabd") pidfilepath = "/run/nabd.pid" hardware_platform = hardware.device_model() matchObj = re.match(r"Raspberry Pi Zero", hardware_platform) if matchObj: # running on Pi Zero or Zero 2 hardware from .nabio_hw import NabIOHW nabiocls = NabIOHW else: # other hardware: go virtual from .nabio_virtual import NabIOVirtual nabiocls = NabIOVirtual usage = ( f"nabd [options]\n" f" -h display this message\n" f" --pidfile=<pidfile> define pidfile (default = {pidfilepath})\n" " --nabio=<nabio> define nabio class " f"(default = {nabiocls.__module__}.{nabiocls.__name__})\n") try: opts, args = getopt.getopt(argv, "h", ["pidfile=", "nabio="]) except getopt.GetoptError: print(usage) exit(2) for opt, arg in opts: if opt == "-h": print(usage) exit(0) elif opt == "--pidfile": pidfilepath = arg elif opt == "--nabio": from pydoc import locate nabiocls = locate(arg) pidfile = PIDLockFile(pidfilepath, timeout=-1) try: with pidfile: nabio = nabiocls() Nabd.leds_boot(nabio, 1) nabd = Nabd(nabio) logging.info(f"running on {hardware_platform}") nabd.run() except AlreadyLocked: error_msg = f"nabd already running? (pid={pidfile.read_pid()})" print(error_msg) logging.critical(error_msg) exit(1) except LockFailed: error_msg = (f"Cannot write pid file to {pidfilepath}, please fix " f"permissions") print(error_msg) logging.critical(error_msg) exit(1) except Exception: error_msg = f"Unhandled error: {traceback.format_exc()}" print(error_msg) logging.critical(error_msg) exit(3)
def get_maestral_pid(config_name): """ Returns Maestral's PID if the daemon is running, ``None`` otherwise. :param str config_name: The name of the Maestral configuration to use. :returns: The daemon's PID. :rtype: int """ lockfile = PIDLockFile(pidpath_for_config(config_name)) pid = lockfile.read_pid() if pid and not is_pidfile_stale(lockfile): return pid else: lockfile.break_lock()
def start_proc(self, proc_name, proc_factory, chroot_dir=None, kill_old=False): if not proc_name.isalnum(): raise Exception('Invalid name: Only Alpha-Numeric Characters Allowed.') procs = self._get_procs() pidfilename = os.path.join( self.lock_dir, f'procz_{proc_name}.pid') if proc_name in procs: if not kill_old: raise Exception('Process is already running!') self.kill_proc(proc_name) with TimedLoop(2) as l: l.run_til(lambda: os.path.isfile(pidfilename), lambda x: not x) pid = os.fork() if pid: return 'starting proc' else: try: with daemon.DaemonContext(pidfile=PIDLockFile(pidfilename), detach_process=True): procd = proc_factory() procd.run() except Exception as e: e_log = os.path.join(self.lock_dir, f'{proc_name}.error.log') with open(e_log, 'w') as f: f.write(traceback.format_exc()+'\n') raise e
def main (interrupt=None): args = parser.parse_args() config = ConfigParser() dirname = os.path.dirname(os.path.realpath(sys.argv[0])) if args.config is None: configfile = None for afile in [ os.path.expanduser('~/.relaykeys.cfg'), os.path.join(dirname, 'relaykeys.cfg') ]: if len(config.read([afile])) > 0: configfile = afile break else: if len(config.read([args.config])) == 0: raise ValueError("Could not read config file: {}".format(args.config)) configfile = args.config if "server" not in config.sections(): config["server"] = {} serverconfig = config["server"] if serverconfig.getboolean("rewritepasswordonce", False): serverconfig["password"] = mkpasswd(24, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") del serverconfig["rewritepasswordonce"] if "client" in config.sections(): config["client"]["password"] = serverconfig["password"] with open(configfile, "w") as f: config.write(f) isdaemon = args.daemon or serverconfig.getboolean("daemon", False) if os.name =='posix' else False if isdaemon: pidfile = os.path.realpath(args.pidfile or serverconfig.get("pidfile", None)) with DaemonContext(working_directory=os.getcwd(), pidfile=PIDLockFile(pidfile)): init_logger(dirname, True, args, serverconfig) return do_main(args, serverconfig, interrupt) else: init_logger(dirname, False, args, serverconfig) return do_main(args, serverconfig, interrupt)
def main(): parser = argparse.ArgumentParser( description='A distributed cron-like daemon') parser.add_argument('-f', dest='foreground', action='store_const', const=False, help='run in foreground') args = parser.parse_args() if os.geteuid() != 0: sys.exit('%s must be run as root.' % os.path.basename(sys.argv[0])) context = daemon.DaemonContext( pidfile=PIDLockFile('/var/run/megacron.pid'), detach_process=args.foreground, ) context.signal_map = { signal.SIGINT: _signal_handler, signal.SIGTERM: _signal_handler } with context: worker.init_worker() events = sched.scheduler(time.time, time.sleep) scheduler.check_scheduler(events) worker.heartbeat(events) worker.update_schedules(events) events.run()
def main(): serverCfg = piccolo.PiccoloServerConfig() # start logging handler = piccoloLogging(logfile=serverCfg.cfg['logging']['logfile'], debug=serverCfg.cfg['logging']['debug']) log = logging.getLogger("piccolo.server") if serverCfg.cfg['daemon']['daemon']: import daemon try: import lockfile except ImportError: print( "The 'lockfile' Python module is required to run Piccolo Server. Ensure that version 0.12 or later of lockfile is installed." ) sys.exit(1) try: from lockfile.pidlockfile import PIDLockFile except ImportError: print( "An outdated version of the 'lockfile' Python module is installed. Piccolo Server requires at least version 0.12 or later of lockfile." ) sys.exit(1) from lockfile import AlreadyLocked, NotLocked # create a pid file and tidy up if required pidfile = PIDLockFile(serverCfg.cfg['daemon']['pid_file'], timeout=-1) try: pidfile.acquire() except AlreadyLocked: try: os.kill(pidfile.read_pid(), 0) print('Process already running!') exit(1) except OSError: #No process with locked PID print('PID file exists but process is dead') pidfile.break_lock() try: pidfile.release() except NotLocked: pass pstd = open(serverCfg.cfg['daemon']['logfile'], 'w') with daemon.DaemonContext(pidfile=pidfile, files_preserve=[handler.stream], stderr=pstd): # start piccolo piccolo_server(serverCfg) else: # start piccolo piccolo_server(serverCfg)
def check_daemon_options(daemon_config): """Returns the pidfile object and non-default daemon settings; dies if there are any illegal settings.""" check_for_illegal_daemon_options(daemon_config) daemon_options = {k: v for k, v in daemon_config.items() if v is not None} pidfile_path = daemon_options.pop('pidfile') pidfile = PIDLockFile(pidfile_path) return pidfile, daemon_options
def wrapped_f(): _ensure_path_exists(os.path.dirname(filename)) lock = PIDLockFile(filename, timeout=timeout) try: lock.acquire() except lockfile.LockTimeout: if suppress_error: logger.info('Unable to acquire lock: %s', filename) # could continue, but probably safer to quit? os._exit(os.EX_OK) # sys.exit raises an exception else: raise else: logger.info('Acquired lock: %s', filename) f() lock.release() logger.info('Released lock: %s', filename)
def main(): # using CaresResolver as DNS resolver # see also: http://www.tornadoweb.org/en/branch3.0/caresresolver.html Resolver.configure('tornado.platform.caresresolver.CaresResolver') # CurlAsyncHTTPClient to be used as httpclient subclass tornado.httpclient.AsyncHTTPClient.configure( "tornado.curl_httpclient.CurlAsyncHTTPClient") define("port", default=8080, help="run on the given port", type=int) # define("address", default=get_listening_address(), help="run on the given address", type=str) define("daemon", default=settings.daemon, help="run as daemon", type=bool) define("webgate", default=settings.webgate, help="run on web gate mode", type=bool) define("log_to_file", default=False, help="log to file", type=bool) define("game_host", default=settings.game_servers['development']['host'], help="bind address", type=str) define("game_port", default=settings.game_servers['development']['port'], help="run on the given port", type=int) define("mode", default="development", help="default run in development mode", type=str) if '--daemon' not in sys.argv: parse_command_line(sys.argv + ['--log_to_stderr']) else: parse_command_line(final=False) game_server = settings.game_servers[options.mode] assert (game_server) if options.daemon: from lockfile.pidlockfile import PIDLockFile import daemon main_log = open(settings.main_log_file, "a+") pid_file = os.path.join(settings.ROOT, "pids", "%s-%s.pid" % (settings.APPNAME, options.port)) if not daemon_running(pid_file): ctx = daemon.DaemonContext( stdout=main_log, stderr=main_log, pidfile=PIDLockFile(pid_file, threaded=False), working_directory=settings.ROOT, ) ctx.open() settings.daemon = options.daemon options.log_to_file = True options.log_file_prefix = settings.tornado_log_prefix % options.port parse_command_line(['--log_file_prefix', options.log_file_prefix]) start()
def exec(self): try: dc = DaemonContext( working_directory=self.work_dir, pidfile=PIDLockFile("/tmp/{}.pid".format(self.basename)), stderr=open("{}.err".format(self.basename), "a+")) with dc: self.__do_process() except Exception as e: raise
def _start(): init_db(configuration) with open(LOG_FILE, "w+") as log_file, \ daemon.DaemonContext(pidfile=PIDLockFile(PID_FILE), detach_process=True, stdout=log_file, stderr=log_file): if no_wsgi: API.run("0.0.0.0", configuration.server_port) else: WSGIServer(API, port=configuration.server_port).start()
def set(key, value): with PIDLockFile(LOCKFILE): try: with open(DATAFILE, 'r+') as jsondata: data = json.load(jsondata) data[key] = value json.dump(data, jsondata) except IOError: # File does not exist. with open(DATAFILE, 'w+') as jsondata: json.dump({key: value}, jsondata)
def get_pid_lock_file(pidfile_path, logger, app_name): pidlock = PIDLockFile(pidfile_path) if pidlock.is_locked(): old_pid = pidlock.read_pid() logger.info("Lock file exists for PID %d." % old_pid) if os.getpid() == old_pid: logger.info("Stale lock since we have the same PID.") else: try: old = psutil.Process(old_pid) if os.path.basename(__file__) in old.cmdline(): try: logger.info("Trying to terminate old instance...") old.terminate() try: old.wait(10) except psutil.TimeoutExpired: logger.info("Trying to kill old instance.") old.kill() except psutil.AccessDenied: logger.error( "The process seems to be %s, but " "can not be stopped. Its command line: %s" % app_name, old.cmdline()) else: logger.info( "Process does not seem to be {}.".format(app_name)) except psutil.NoSuchProcess: pass logger.info("No such process exist anymore.") logger.info("Breaking old lock.") pidlock.break_lock() return pidlock
def pull(dry_run, flavor, interactive, debug): """ Pull down tasks from forges and add them to your taskwarrior tasks. Relies on configuration in bugwarriorrc """ try: main_section = _get_section_name(flavor) config = _try_load_config(main_section, interactive) lockfile_path = os.path.join(get_data_path(config, main_section), 'bugwarrior.lockfile') lockfile = PIDLockFile(lockfile_path) lockfile.acquire(timeout=10) try: # Get all the issues. This can take a while. issue_generator = aggregate_issues(config, main_section, debug) # Stuff them in the taskwarrior db as necessary synchronize(issue_generator, config, main_section, dry_run) finally: lockfile.release() except LockTimeout: log.critical('Your taskrc repository is currently locked. ' 'Remove the file at %s if you are sure no other ' 'bugwarrior processes are currently running.' % (lockfile_path)) except RuntimeError as e: log.exception("Aborted (%s)" % e)
def pull(): """ Pull down tasks from forges and add them to your taskwarrior tasks. Relies on configuration in ~/.bugwarriorrc """ twiggy.quickSetup() try: # Load our config file config = load_config() tw_config = TaskWarriorBase.load_config(get_taskrc_path(config)) lockfile_path = os.path.join( os.path.expanduser(tw_config['data']['location']), 'bugwarrior.lockfile') lockfile = PIDLockFile(lockfile_path) lockfile.acquire(timeout=10) try: # Get all the issues. This can take a while. issue_generator = aggregate_issues(config) # Stuff them in the taskwarrior db as necessary synchronize(issue_generator, config) finally: lockfile.release() except LockTimeout: log.name('command').critical( 'Your taskrc repository is currently locked. ' 'Remove the file at %s if you are sure no other ' 'bugwarrior processes are currently running.' % (lockfile_path)) except: log.name('command').trace('error').critical('oh noes')
def check_if_pidfile_process_is_running(pid_file: str, process_name: str): """ Checks if a pidfile already exists and process is still running. If process is dead then pidfile is removed. :param pid_file: path to the pidfile :param process_name: name used in exception if process is up and running """ pid_lock_file = PIDLockFile(path=pid_file) # If file exists if pid_lock_file.is_locked(): # Read the pid pid = pid_lock_file.read_pid() if pid is None: return try: # Check if process is still running proc = psutil.Process(pid) if proc.is_running(): raise AirflowException( f"The {process_name} is already running under PID {pid}.") except psutil.NoSuchProcess: # If process is dead remove the pidfile pid_lock_file.break_lock()
def run(self): """Startup the processing and go!""" self.terminate = threading.Event() atexit.register(self.shutdown) self.context = daemon.DaemonContext(detach_process=True) iter = 0 if Bcfg2.Options.setup.daemon: self.logger.debug("Daemonizing") try: self.context.pidfile = PIDLockFile(Bcfg2.Options.setup.daemon) self.context.open() except LockFailed: self.logger.error("Failed to daemonize: %s" % sys.exc_info()[1]) self.shutdown() return except LockTimeout: self.logger.error("Failed to daemonize: " "Failed to acquire lock on %s" % self.setup['daemon']) self.shutdown() return except PIDFileError: self.logger.error("Error writing pid file: %s" % sys.exc_info()[1]) self.shutdown() return self.logger.info("Starting daemon") self.transport.start_monitor(self) while not self.terminate.isSet(): try: interaction = self.transport.fetch() if not interaction: continue store_thread = ReportingStoreThread(interaction, self.storage) store_thread.start() self.children.append(store_thread) iter += 1 if iter >= self.cleanup_threshold: self.reap_children() iter = 0 except (SystemExit, KeyboardInterrupt): self.logger.info("Shutting down") self.shutdown() except: self.logger.error("Unhandled exception in main loop %s" % sys.exc_info()[1])
def set(self, key, value): with PIDLockFile(self.lockfile): try: data = self.get_data() except IOError: # File does not exist. with open(self.datafile, 'w') as jsondata: json.dump({key: value}, jsondata) else: with open(self.datafile, 'w') as jsondata: data[key] = value json.dump(data, jsondata) os.chmod(self.datafile, 0o600)
def main(argv): pidfilepath = "/var/run/nabd.pid" if sys.platform == 'linux': from .nabio_hw import NabIOHW nabiocls = NabIOHW else: nabiocls = NabIOVirtual usage = 'nabd [options]\n' \ + ' -h display this message\n' \ + ' --pidfile=<pidfile> define pidfile (default = {pidfilepath})\n'.format(pidfilepath=pidfilepath) \ + ' --nabio=nabio_class define nabio implementation (default = {module}.{name})'.format(module=nabiocls.__module__, name=nabiocls.__name__) try: opts, args = getopt.getopt(argv, "h", ["pidfile=", "nabio="]) except getopt.GetoptError: print(usage) exit(2) for opt, arg in opts: if opt == '-h': print(usage) exit(0) elif opt == '--pidfile': pidfilepath = arg elif opt == '--nabio': nabiocls = locate(arg) pidfile = PIDLockFile(pidfilepath, timeout=-1) try: with pidfile: nabio = nabiocls() nabd = Nabd(nabio) nabd.run() except AlreadyLocked: print('nabd already running? (pid={pid})'.format( pid=pidfile.read_pid())) exit(1) except LockFailed: print( 'Cannot write pid file to {pidfilepath}, please fix permissions' .format(pidfilepath=pidfilepath)) exit(1)
def wrapped(*args, **kwargs): logging.debug('Start daemon') if not pid_file and not force_daemon: if signal_map: for key in signal_map.keys(): signal.signal(key, signal_map[key]) logging.debug('Daemons pid: %s', os.getpid()) f(*args, **kwargs) if clean: clean() return if pid_file and pid_file not in ['-']: pid_path = os.path.abspath(pid_file) # clean old pids pidfile = PIDLockFile(pid_path, timeout=-1) try: pidfile.acquire() pidfile.release() except (AlreadyLocked, LockTimeout): try: os.kill(pidfile.read_pid(), 0) logging.warn('Process already running!') exit(2) except OSError: #No process with locked PID pidfile.break_lock() pidfile = PIDLockFile(pid_path, timeout=-1) context = _daemon.DaemonContext( pidfile=pidfile ) else: context = _daemon.DaemonContext() if signal_map: context.signal_map = signal_map context.open() with context: logging.debug('Daemons pid: %s', os.getpid()) f(*args, **kwargs) if clean: clean()
def pull(): """ Pull down tasks from forges and add them to your taskwarrior tasks. Relies on configuration in ~/.bugwarriorrc """ twiggy.quickSetup() try: # Load our config file config = load_config() tw_config = TaskWarriorBase.load_config(get_taskrc_path(config)) lockfile_path = os.path.join( os.path.expanduser( tw_config['data']['location'] ), 'bugwarrior.lockfile' ) lockfile = PIDLockFile(lockfile_path) lockfile.acquire(timeout=10) try: # Get all the issues. This can take a while. issue_generator = aggregate_issues(config) # Stuff them in the taskwarrior db as necessary synchronize(issue_generator, config) finally: lockfile.release() except LockTimeout: log.name('command').critical( 'Your taskrc repository is currently locked. ' 'Remove the file at %s if you are sure no other ' 'bugwarrior processes are currently running.' % ( lockfile_path ) ) except: log.name('command').trace('error').critical('oh noes')
def run_with_lock(remove=False): lock = PIDLockFile(getattr( settings, "HYPERKITTY_JOBS_UPDATE_INDEX_LOCKFILE", os.path.join(gettempdir(), "hyperkitty-jobs-update-index.lock"))) try: lock.acquire(timeout=-1) except AlreadyLocked: if check_pid(lock.read_pid()): logger.warning("The job 'update_index' is already running") return else: lock.break_lock() lock.acquire(timeout=-1) except LockFailed as e: logger.warning("Could not obtain a lock for the 'update_index' " "job (%s)", e) return try: update_index(remove=remove) except Exception as e: # pylint: disable-msg=broad-except logger.exception("Failed to update the fulltext index: %s", e) finally: lock.release()
def putioCheck(): """ Should probably be in a class """ global instance instance = putioDaemon() instance.getinputs(sys.argv[1:]) instance.readconfig() instance.setuplogging() pidfile = PIDLockFile(instance.pidfile, timeout=-1) try: pidfile.acquire() except AlreadyLocked: try: os.kill(pidfile.read_pid(),0) print 'Process already running!' exit (1) except OSError: pidfile.break_lock() except: print "Something failed:", sys.exc_info() exit (1) logging.debug('Listen is %s', instance.listen) if instance.listen: WebServer() signal.signal(signal.SIGTERM,handler) while True: if os.path.exists(instance.torrentdir): onlyfiles = [ f for f in os.listdir(instance.torrentdir) if os.path.isfile(os.path.join(instance.torrentdir,f))] if len(onlyfiles): client = putio.Client(instance.token) for torrent in onlyfiles: logging.info('working on %s', torrent) # if we are listening then use the callback_url callback_url = None if instance.listen: callback_url = 'http://'+instance.callback+'/'+instance.httppath+'/api/'+instance.token logging.info('Calling add_torrent for %s with %s',torrent,callback_url) client.Transfer.add_torrent(instance.torrentdir+"/"+torrent, callback_url=callback_url) os.remove(instance.torrentdir+"/"+torrent) time.sleep(5)
def __init__( self, pidfile, **kwargs ): argv = list(sys.argv) filename = self.filename = os.path.abspath( argv.pop(0) ) path = os.path.dirname(filename) kwargs.setdefault( 'working_directory', path ) if isinstance( pidfile, basestring ): if pidfile[0] != '/': pidfile = '%s/%s' % (path, pidfile ) pidfile = PIDLockFile( pidfile ) if argv: cmd = argv.pop(0) if cmd=='stop': self._stop( pidfile ) sys.exit(0) elif cmd=='restart': self._stop( pidfile ) c = 10 while pidfile.is_locked(): c-=1 gevent.sleep(1) if not c: raise Exception('Cannot stop daemon (Timed out)') # should just work without this - but it does not :/ cmd = [sys.executable, filename]+argv cmd.append('&') os.system( ' '.join(cmd) ) exit(0) """ elif cmd!='start': sys.stderr.write('try %s %s start|stop|restart\r\n' % (sys.executable, sys.argv[0])) exit(0) """ if pidfile.is_locked(): sys.stderr.write( 'Daemon seems to be already running\r\n' ) sys.exit(-1) self.exit_hooks = kwargs.pop('exit_hooks',[]) files_preserve = kwargs.pop('files_preserve',[]) stderr = kwargs.get('stderr') if stderr: files_preserve.append( stderr ) for logger in kwargs.pop('loggers',()): for handler in logger.handlers: if hasattr( handler, 'stream' ): files_preserve.append( handler.stream ) self.loggers = [] filename = os.path.basename( self.filename) try: from setproctitle import setproctitle setproctitle( filename ) except ImportError: import ctypes try: libc = ctypes.CDLL("libc.so.6") libc.prctl(15, filename, 0, 0, 0) except: pass _DaemonContext.__init__( self, pidfile=pidfile, files_preserve=files_preserve, **kwargs )
if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description='Launch a SageCell web server', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('-p', '--port', type=int, default=8888, help='port to launch the server') parser.add_argument('-b', '--baseurl', default="", help="base url") parser.add_argument('--interface', default=None, help="interface to listen on (default all)") parser.add_argument('--dir', default=config.get("dir"), help="directory for user files") args = parser.parse_args() logger.info("starting tornado web server") from lockfile.pidlockfile import PIDLockFile pidfile_path = config.get('pid_file') pidlock = PIDLockFile(pidfile_path) if pidlock.is_locked(): old_pid = pidlock.read_pid() logger.info("Lock file exists for PID %d." % old_pid) if os.getpid() == old_pid: logger.info("Stale lock since we have the same PID.") else: try: old = psutil.Process(old_pid) if os.path.basename(__file__) in old.cmdline(): try: logger.info("Trying to terminate old instance...") old.terminate() try: old.wait(10) except psutil.TimeoutExpired:
def acquire(self, *args, **kwargs): kwargs.update({'timeout': 0}) PIDLockFile.acquire(self, *args, **kwargs)
def main(): parser = argparse.ArgumentParser() parser.add_argument('interface', nargs='?', help='interface to configure with DHCP') parser.add_argument('-v', '--verbose', help='Set logging level to debug', action='store_true') parser.add_argument('--version', action='version', help='version', version='%(prog)s ' + __version__) parser.add_argument('-s', '--delay_selecting', help='Selecting starts after a ramdon delay.', action='store_true') # options to looks like dhclient parser.add_argument( '-sf', metavar='script-file', nargs='?', const=SCRIPT_PATH, help='Path to the network configuration script invoked by ' 'dhcpcanon when it gets a lease. Without this option ' 'dhcpcanon will configure the network by itself.' 'If unspecified, the ' 'default /sbin/dhcpcanon-script is used, which is a copy of' 'dhclient-script(8) for a description of this file.' 'If dhcpcanon is running with NetworkManager, it will' 'be called with the script nm-dhcp-helper.') parser.add_argument( '-pf', metavar='pid-file', nargs='?', const=PID_PATH, help='Path to the process ID file. If unspecified, the' 'default /var/run/dhcpcanon.pid is used. ' 'This option is used by NetworkManager to check whether ' 'dhcpcanon is already running.') args = parser.parse_args() logger.debug('args %s', args) # do not put interfaces in promiscuous mode conf.sniff_promisc = conf.promisc = 0 conf.checkIPaddr = 1 if args.verbose: logger.setLevel(logging.DEBUG) logger.debug('args %s', args) if args.interface: conf.iface = args.interface logger.debug('interface %s' % conf.iface) if args.pf is not None: # This is only needed for nm pf = PIDLockFile(args.pf, timeout=5) try: pf.acquire() logger.debug('using pid file %s', pf) except AlreadyLocked as e: pf.break_lock() pf.acquire() except (LockTimeout, LockFailed) as e: logger.error(e) dhcpcap = DHCPCAPFSM(iface=conf.iface, server_port=SERVER_PORT, client_port=CLIENT_PORT, scriptfile=args.sf, delay_selecting=args.delay_selecting) dhcpcap.run()
class SimpleMainLock: """ Tools like gprecoverseg prohibit running multiple instances at the same time via a simple lock file created in the MASTER_DATA_DIRECTORY. This class takes care of the work to manage this lock as appropriate based on the mainOptions specified. Note that in some cases, the utility may want to recursively invoke itself (e.g. gprecoverseg -r). To handle this, the caller may specify the name of an environment variable holding the pid already acquired by the parent process. """ def __init__(self, mainOptions): self.pidfilename = mainOptions.get('pidfilename', None) # the file we're using for locking self.parentpidvar = mainOptions.get('parentpidvar', None) # environment variable holding parent pid self.parentpid = None # parent pid which already has the lock self.ppath = None # complete path to the lock file self.pidlockfile = None # PIDLockFile object self.pidfilepid = None # pid of the process which has the lock self.locktorelease = None # PIDLockFile object we should release when done if self.parentpidvar is not None and self.parentpidvar in os.environ: self.parentpid = int(os.environ[self.parentpidvar]) if self.pidfilename is not None: self.ppath = os.path.join(gp.get_masterdatadir(), self.pidfilename) self.pidlockfile = PIDLockFile(self.ppath) def acquire(self): """ Attempts to acquire the lock this process needs to proceed. Returns None on successful acquisition of the lock or the pid of the other process which already has the lock. """ # nothing to do if utiliity requires no locking if self.pidlockfile is None: return None # look for a lock file self.pidfilepid = self.pidlockfile.read_pid() if self.pidfilepid is not None: # we found a lock file # allow the process to proceed if the locker was our parent if self.pidfilepid == self.parentpid: return None # cleanup stale locks try: os.kill(self.pidfilepid, signal.SIG_DFL) except OSError, exc: if exc.errno == errno.ESRCH: self.pidlockfile.break_lock() self.pidfilepid = None # try and acquire the lock try: self.pidlockfile.acquire(1) except LockTimeout: self.pidfilepid = self.pidlockfile.read_pid() return self.pidfilepid # we have the lock # prepare for a later call to release() and take good # care of the process environment for the sake of our children self.locktorelease = self.pidlockfile self.pidfilepid = self.pidlockfile.read_pid() if self.parentpidvar is not None: os.environ[self.parentpidvar] = str(self.pidfilepid) return None