def start(self, timeout=300):
        """start server
        return True of False"""
        if self.is_alive:
            return True
        try:
            if self.cfg.get('dbpath', None) and self._is_locked:
                # repair if needed
                process.repair_mongo(self.name, self.cfg['dbpath'])

            self.proc, self.hostname = process.mprocess(self.name, self.config_path, self.cfg.get('port', None), timeout)
            self.pid = self.proc.pid
            logger.debug("pid={pid}, hostname={hostname}".format(pid=self.pid, hostname=self.hostname))
            self.host = self.hostname.split(':')[0]
            self.port = int(self.hostname.split(':')[1])

            # Wait for Server to respond to isMaster.
            for i in range(timeout):
                try:
                    self.run_command('isMaster')
                    break
                except pymongo.errors.ConnectionFailure:
                    time.sleep(1)
            else:
                raise TimeoutError(
                    "Server did not respond to 'isMaster' after %d attempts."
                    % timeout)
        except (OSError, TimeoutError):
            logger.exception("Could not start Server.")
            raise
        if not self.admin_added and self.login:
            self._add_auth()
            self.admin_added = True
        return True
Example #2
0
def mprocess(name, config_path, port=None, timeout=180, silence_stdout=True):
    """start 'name' process with params from config_path.
    Args:
        name - process name or path
        config_path - path to file where should be stored configuration
        port - process's port
        timeout - specify how long, in seconds, a command can take before times out.
                  if timeout <=0 - doesn't wait for complete start process
        silence_stdout - if True (default), redirect stdout to /dev/null
    return tuple (Popen object, host) if process started, return (None, None) if not
    """

    logger.debug(
        "mprocess(name={name!r}, config_path={config_path!r}, port={port!r}, "
        "timeout={timeout!r})".format(**locals()))
    if not (config_path and isinstance(config_path, str)
            and os.path.exists(config_path)):
        raise OSError(
            "can't find config file {config_path}".format(**locals()))

    cfg = read_config(config_path)
    cmd = [name, "--config", config_path]

    if cfg.get('port', None) is None or port:
        port = port or PortPool().port(check=True)
        cmd.extend(['--port', str(port)])
    host = "{host}:{port}".format(host=_host(), port=port)
    try:
        logger.debug("execute process: %s", ' '.join(cmd))
        proc = subprocess.Popen(cmd,
                                stdout=DEVNULL if silence_stdout else None,
                                stderr=subprocess.STDOUT)

        if proc.poll() is not None:
            logger.debug("process is not alive")
            raise OSError("Process started, but died immediately.")
    except (OSError, TypeError) as err:
        message = "exception while executing process: {err}".format(err=err)
        logger.debug(message)
        raise OSError(message)
    if timeout > 0 and wait_for(port, timeout):
        logger.debug(
            "process '{name}' has started: pid={proc.pid}, host={host}".format(
                **locals()))
        return (proc, host)
    elif timeout > 0:
        logger.debug(
            "hasn't connected to pid={proc.pid} with host={host} during timeout {timeout} "
            .format(**locals()))
        logger.debug(
            "terminate process with pid={proc.pid}".format(**locals()))
        kill_mprocess(proc)
        proc_alive(proc) and time.sleep(3)  # wait while process stoped
        message = ("Could not connect to process during "
                   "{timeout} seconds".format(timeout=timeout))
        raise TimeoutError(message, errno.ETIMEDOUT)
    return (proc, host)
def wait_mprocess(process, timeout):
    """Compatibility function for waiting on a process with a timeout.

    Raises TimeoutError when the timeout is reached.
    """
    if PY3:
        try:
            return process.wait(timeout=timeout)
        except subprocess.TimeoutExpired as exc:
            raise TimeoutError(str(exc))

    # On Python 2, simulate the timeout parameter and raise TimeoutError.
    start = time.time()
    while True:
        exit_code = process.poll()
        if exit_code is not None:
            return exit_code
        if time.time() - start > timeout:
            raise TimeoutError("Process %s timed out after %s seconds" %
                               (process.pid, timeout))
        time.sleep(0.05)
Example #4
0
    def start(self, timeout=300):
        """start server
        return True of False"""
        if self.is_alive:
            return True
        try:
            if self.cfg.get('dbpath', None) and self._is_locked:
                # repair if needed
                process.repair_mongo(self.name, self.cfg['dbpath'])

            self.proc, self.hostname = process.mprocess(
                self.name, self.config_path, self.cfg.get('port', None),
                timeout, self.silence_stdout)
            self.pid = self.proc.pid
            logger.debug("pid={pid}, hostname={hostname}".format(
                pid=self.pid, hostname=self.hostname))
            self.host = self.hostname.split(':')[0]
            self.port = int(self.hostname.split(':')[1])

            # Wait for Server to respond to isMaster.
            for i in range(timeout):
                try:
                    self.run_command('isMaster')
                    break
                except pymongo.errors.ConnectionFailure:
                    time.sleep(0.1)
            else:
                raise TimeoutError(
                    "Server did not respond to 'isMaster' after %d attempts." %
                    timeout)
        except (OSError, TimeoutError):
            logger.exception("Could not start Server.")
            raise
        if self.restart_required:
            if self.login:
                # Add users to the appropriate database.
                self._add_users()
            self.stop()

            # Restart with keyfile and auth.
            if self.is_mongos:
                self.config_path, self.cfg = self.__init_mongos(self.cfg)
            else:
                # Add auth options to this Server's config file.
                self.config_path, self.cfg = self.__init_mongod(self.cfg,
                                                                add_auth=True)
            self.restart_required = False
            self.start()

        return True
Example #5
0
    def start(self, timeout=300):
        """start server
        return True of False"""
        if self.is_alive:
            return True
        try:
            if self.cfg.get('dbpath', None) and self._is_locked:
                # repair if needed
                process.repair_mongo(self.name, self.cfg['dbpath'])

            self.proc, self.hostname = process.mprocess(
                self.name, self.config_path, self.cfg.get('port', None),
                timeout, self.silence_stdout)
            self.pid = self.proc.pid
            logger.debug("pid={pid}, hostname={hostname}".format(pid=self.pid, hostname=self.hostname))
            self.host = self.hostname.split(':')[0]
            self.port = int(self.hostname.split(':')[1])

            # Wait for Server to respond to isMaster.
            for i in range(timeout):
                try:
                    self.run_command('isMaster')
                    break
                except pymongo.errors.ConnectionFailure:
                    logger.exception('isMaster command failed:')
                    time.sleep(0.1)
            else:
                raise TimeoutError(
                    "Server did not respond to 'isMaster' after %d attempts."
                    % timeout)
        except (OSError, TimeoutError):
            logpath = self.cfg.get('logpath')
            if logpath:
                # Copy the server logs into the mongo-orchestration logs.
                logger.error(
                    "Could not start Server. Please find server log below.\n"
                    "=====================================================")
                with open(logpath) as lp:
                    logger.error(lp.read())
            else:
                logger.exception(
                    'Could not start Server, and no logpath was provided!')
            reraise(TimeoutError,
                    'Could not start Server. '
                    'Please check server log located in ' +
                    self.cfg.get('logpath', '<no logpath given>') +
                    ' or the mongo-orchestration log in ' +
                    LOG_FILE + ' for more details.')
        if self.restart_required:
            if self.login:
                # Add users to the appropriate database.
                self._add_users()
            self.stop()

            # Restart with keyfile and auth.
            if self.is_mongos:
                self.config_path, self.cfg = self.__init_mongos(self.cfg)
            else:
                # Add auth options to this Server's config file.
                self.config_path, self.cfg = self.__init_mongod(
                    self.cfg, add_auth=True)
            self.restart_required = False
            self.start()

        return True