Esempio n. 1
0
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
Esempio n. 2
0
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)
Esempio n. 3
0
File: main.py Progetto: yalon/etos
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
Esempio n. 4
0
def _get_atm_process(pid_path):
    """Return `psutil.Process` of the `pid` file. If the pidfile is stale it will release it."""
    pid_file = PIDLockFile(pid_path, timeout=1.0)

    if pid_file.is_locked():
        pid = pid_file.read_pid()

        try:
            process = psutil.Process(pid)
            if process.name() == 'atm':
                return process
            else:
                pid_file.break_lock()

        except psutil.NoSuchProcess:
            pid_file.break_lock()
Esempio n. 5
0
def _get_lock(theargs, stage):
    """Create lock file to prevent this process from running on same data.

       This uses ``PIDLockFile`` to create a pid lock file in celppdir
       directory named celprunner.<stage>.lockpid
       If pid exists it is assumed the lock is held otherwise lock
       is broken and recreated

       :param theargs: return value from argparse and should contain
                       theargs.celppdir should be set to path
       :param stage: set to stage that is being run
       :return: ``PIDLockFile`` upon success
       :raises: LockException: If there was a problem locking
       :raises: Exception: If valid pid lock file already exists
       """
    mylockfile = os.path.join(theargs.celppdir,
                              "celpprunner." + stage + ".lockpid")
    logger.debug("Looking for lock file: " + mylockfile)
    lock = PIDLockFile(mylockfile, timeout=10)

    if lock.i_am_locking():
        logger.debug("My process id" + str(lock.read_pid()) +
                     " had the lock so I am breaking")
        lock.break_lock()
        lock.acquire(timeout=10)
        return lock

    if lock.is_locked():
        logger.debug("Lock file exists checking pid")
        if psutil.pid_exists(lock.read_pid()):
            raise Exception("celpprunner with pid " + str(lock.read_pid()) +
                            " is running")

    lock.break_lock()
    logger.info("Acquiring lock")
    lock.acquire(timeout=10)
    return lock
Esempio n. 6
0
        #self.ioloop.set_blocking_log_threshold(.5)

        super(PermalinkServer, self).__init__(handlers_list)


if __name__ == "__main__":
    import tornado.options
    from tornado.options import define, options

    define("port", default=8080, help="run on the given port", type=int)
    tornado.options.parse_command_line()

    from lockfile.pidlockfile import PIDLockFile
    pidfile_path = PERMALINK_PID_FILE
    pidlock = PIDLockFile(pidfile_path)
    if pidlock.is_locked():
        old_pid = pidlock.read_pid()
        if os.getpid() != old_pid:
            try:
                old = psutil.Process(old_pid)
                if os.path.basename(__file__) in old.cmdline():
                    try:
                        old.terminate()
                        try:
                            old.wait(10)
                        except psutil.TimeoutExpired:
                            old.kill()
                    except psutil.AccessDenied:
                        pass
            except psutil.NoSuchProcess:
                pass
Esempio n. 7
0
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:
                            logger.info("Trying to kill old instance.")
Esempio n. 8
0
def main():
    """Standard main function."""
    parser = ArgumentParser(
        description="HTTP/WSGI server for Python",
        usage="poorhttp [options] command"
    )
    parser.add_argument(
        "command", nargs='?', default="start", type=str,
        help="Daemon action (start|stop|logrotate|restart|status)")
    parser.add_argument(
        "-v", "--version", action="store_true",
        help="only print server version")

    parser.add_argument(
        "-f", "--foreground", action="store_true",
        help="Run as script on foreground")
    parser.add_argument(
        "-c", "--config", type=str,
        help="Path to config file.", metavar="<FILE>")
    parser.add_argument(
        "-p", "--pidfile", type=str,
        help="Path to pid file", metavar="<FILE>")
    parser.add_argument(
        "-a", "--address", type=str,
        help="IP listening address (host or IP)", metavar="<ADDRESS>")
    parser.add_argument(
        "-b", "--port", type=str,
        help="TCP/IP listening port", metavar="<PORT>")
    parser.add_argument(
        "-w", "--wsgi", type=str,
        help="wsgi application (Python module or file)", metavar="<MODULE>")
    parser.add_argument(
        "-i", "--info", action="store_true",
        help="More verbose logging level INFO is set.")
    parser.add_argument(
        "-d", "--debug", action="store_true",
        help="DEBUG logging level is set.")

    args = parser.parse_args()
    if args.version:
        print("%s %s version." % (__name__, __version__))
        return 0

    try:
        config = Config(args)

        pid_file = PIDLockFile(config.pid_file)

        if args.command == "stop":
            if pid_file.is_locked():
                log.info(
                    "Stoping service with pid %d", pid_file.read_pid())
                kill(pid_file.read_pid(), SIGTERM)
            return 0
        elif args.command == "status":
            if pid_file.is_locked():
                log.info(
                    "Service running with pid %d", pid_file.read_pid())
                return 0
            log.info("Service not running")
            return 1
        elif args.command == "logrotate":
            if pid_file.is_locked():
                log.info(
                    "Reopening service logs")
                kill(pid_file.read_pid(), SIGHUP)
                return 0
            log.info("Service not running")
            return 1
        elif args.command == "restart":
            if pid_file.is_locked():
                log.info(
                    "Restarting service with pid %d", pid_file.read_pid())
                kill(pid_file.read_pid(), SIGTERM)
        elif args.command == "start":
            pass
        elif not args.foreground:
            parser.error("Unknown command %s")
            return 1

        daemon = Daemon(config)
        daemon.check(not args.foreground)

        if args.foreground:
            return daemon.run(False)

        context = DaemonContext(
            working_directory="./",
            pidfile=pid_file,
            stderr=daemon.stderr, stdout=daemon.stdout,
            signal_map={SIGTERM: daemon.shutdown,
                        SIGHUP: daemon.logrotate},
            files_preserve=[daemon.stderr, daemon.stdout])

        if geteuid() == 0:
            context.uid = config.uid
            context.gid = config.gid
            daemon.set_chown()

        with context:
            daemon.logger.info(
                "Starting service with pid %d", pid_file.read_pid())
            daemon.run()
        return 0

    except KeyboardInterrupt:
        log.info('Shotdown server (keyboard interrupt)')
        return 1
    except SocketError:
        log.exception("Shutdown by SocketError")
        return 1
    except Exception as err:
        log.info("%s", args)
        log.debug("%s", format_exc())
        log.fatal("%s", err)
        parser.print_usage()
        return 1
Esempio n. 9
0
    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 )
Esempio n. 10
0
    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)
Esempio n. 11
0
def proxy_command(ctx, auth_type, auth_url, port, user, domain, password,
                  foreground, no_check):
    """
    Start a caching proxy server to the Keystone service
    """
    address = ('127.0.0.1', port)

    # Скрытие аргументов запуска прокси из списка процессов
    setproctitle.setproctitle('ostoken proxy')

    if not user:
        click.echo('Username required', err=True)
        sys.exit(1)

    if 'password' in auth_type:
        if not domain:
            click.echo('User domain name required', err=True)
            sys.exit(1)

        if not password:
            click.echo('Password required', err=True)
            sys.exit(1)

        PasswordAuth.user = user
        PasswordAuth.domain = domain
        PasswordAuth.password = password

        KeystoneProxyServer.auth_plugin = PasswordAuth
    else:
        KerberosAuth.user = user
        KeystoneProxyServer.auth_plugin = KerberosAuth

    if not auth_url:
        click.echo('Keystone URL required', err=True)
        sys.exit(1)

    # Удялем из URL параметры запроса и фрагменты
    p = urlparse(auth_url)
    path = p.path.strip('/')
    auth_url = '{scheme:s}://{netloc:s}/{path:s}'.format(scheme=p.scheme,
                                                         netloc=p.netloc,
                                                         path=path +
                                                         '/' if path else '')
    # Удаляем избыточное указание версии протокола
    auth_url = auth_url.replace('/v3', '')
    KeystoneProxyServer.auth_url = auth_url

    if not no_check:
        try:
            resp = requests.post(
                auth_url + 'v3/auth/tokens',
                auth=KeystoneProxyServer.auth_plugin('unscoped'))
        except requests.ConnectionError as e:
            click.echo(e, err=True)
            sys.exit(1)

        if resp.status_code != 201:
            click.echo('Failed to get unscope token to check credentials: '
                       '%s %s\n%s' %
                       (resp.status_code, resp.reason, resp.content),
                       err=True)
            sys.exit(1)

        token_info = resp.json()
        headers = resp.headers.copy()
        CACHE.set(token_info, headers)

    proxy_access_f, proxy_error_f = \
        setup_logging(debug=ctx.obj.get('debug', False), console=foreground)

    logger.info('auth_type: %s', auth_type)
    logger.info('auth_url: %s', auth_url)
    logger.info('user: %s@%s', user, domain)
    logger.info('password: %s', '*' * len(password))
    logger.info('uid: %d', KeystoneProxyServer.uid)

    server = HTTPServer(address, KeystoneProxyServer)
    host, port = server.socket.getsockname()[:2]
    click.echo('export OS_AUTH_URL=http://%s:%d/%s/v3' %
               (host, port, KeystoneProxyServer.access_key))

    # Проверяем наличие уже запущенного сервера
    pidfile = PIDLockFile(os.path.join(CACHE_DIR, 'proxy.pid'), timeout=5)
    if pidfile.is_locked():
        # Останавливаем предыдущий сервер
        prev_pid = pidfile.read_pid()
        os.kill(prev_pid, signal.SIGTERM)

    try:
        if foreground:
            with pidfile:
                try:
                    server.serve_forever()
                except KeyboardInterrupt:
                    logger.info('Stopping server: '
                                'keyboard interrupt received.')
        else:
            daemon_ctx = daemon.DaemonContext(
                working_directory=CACHE_DIR,
                umask=0o077,
                pidfile=pidfile,
                files_preserve=[proxy_access_f, proxy_error_f, server.socket],
                signal_map={
                    signal.SIGTERM: 'terminate',
                    signal.SIGINT: 'terminate'
                })
            try:
                with daemon_ctx:
                    # После старта демона перенаправляем stdout/stderr в
                    # систему логирования
                    sys.stdout = StreamToLogger('STDOUT', logging.INFO)
                    sys.stderr = StreamToLogger('STDERR', logging.ERROR)
                    logger.info('Server started')
                    server.serve_forever()
            except SystemExit as e:
                logger.info('Stopping server: %s', e)
    finally:
        server.server_close()
    logger.info('Server stopped')
Esempio n. 12
0
    def __init__(self, cfg, debug=False):
        """Create and run a daemon.
        cfg: a DaemonConfig object
        debug: True if debug messages should be logged
        """

        logging.getLogger('hifi_appliance').setLevel(LOGGING_LEVEL)

        self._daemon_config = cfg
        self._log_debug = debug
        self._io_loop = None

        self._preserve_files = []

        if debug:
            self._log_file = sys.stderr
        else:
            try:
                self._log_file = open(cfg.log_file, 'at')
            except IOError as e:
                sys.exit('error opening {0}: {1}'.format(cfg.log_file, e))

            self._preserve_files.append(self._log_file)

        # Figure out which IDs to run as, if any
        self._uid = None
        self._gid = None

        if cfg.user:
            try:
                pw = pwd.getpwnam(cfg.user)
                self._uid = pw.pw_uid
                self._gid = pw.pw_gid
            except KeyError:
                raise DaemonError('unknown user: {0}'.format(cfg.user))

        if cfg.group:
            if not cfg.user:
                raise DaemonError("can't set group without user in config")

            try:
                gr = grp.getgrnam(cfg.group)
                self._gid = gr.gr_gid
            except KeyError:
                raise DaemonError('unknown group: {0}'.format(cfg.user))

        # Now kick off the daemon

        self.log('-' * 60)
        self.log('starting {}', sys.argv[0])

        if debug:
            # Just run directly without forking off.
            self.setup_prefork()
            self.setup_postfork()
            self._drop_privs()
            self.run()

        else:
            self.create_pid_directory(cfg.pid_file)

            # Fail early if daemon appear to be locked
            pid_lock = PIDLockFile(path=cfg.pid_file, timeout=0)
            if pid_lock.is_locked():
                sys.exit(
                    'daemon already running (pid {}) since lock file is present: {}'
                    .format(pid_lock.read_pid(), cfg.pid_file))

            # Run in daemon context, forking off and all that
            self.setup_prefork()

            context = DaemonContext(
                initgroups=False,  # We'll drop privs ourselves
                files_preserve=self._preserve_files,
                pidfile=pid_lock,
                stdout=self._log_file,
                stderr=self._log_file,
            )

            with context:
                self.setup_postfork()
                self._drop_privs()
                self.run()