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
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)
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
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