def call(self, *args, **kwargs): for s in ('stdin', 'stdout', 'stderr'): kwargs.pop(s, None) communicate = kwargs.pop('communicate', None) if isinstance(communicate, dict): input_data = communicate.get('input') if input_data: if input_data[-1] != '\n': input_data += '\n' input_data = input_data.encode('utf-8') kwargs['stdin'] = subprocess.PIPE kwargs['stdout'] = subprocess.PIPE kwargs['stderr'] = subprocess.PIPE try: with self._lock: if self._is_cancelled: raise PostgresException('cancelled') self._is_cancelled = False started = self._start_process(*args, **kwargs) if started: if isinstance(communicate, dict): communicate['stdout'], communicate[ 'stderr'] = self._process.communicate(input_data) return self._process.wait() finally: with self._lock: self._process = None self._kill_children()
def bootstrap(self): """ Initialize a new node from scratch and start it. """ if self.initialize() and self.start(): self.create_replication_user() self.create_connection_user() else: raise PostgresException("Could not bootstrap master PostgreSQL")
def call(self, *args, **kwargs): for s in ('stdin', 'stdout', 'stderr'): kwargs.pop(s, None) communicate_input = 'communicate_input' in kwargs if communicate_input: input_data = kwargs.pop('communicate_input', None) if not isinstance(input_data, string_types): input_data = '' if input_data and input_data[-1] != '\n': input_data += '\n' kwargs['stdin'] = subprocess.PIPE kwargs['stdout'] = open(os.devnull, 'w') kwargs['stderr'] = subprocess.STDOUT try: with self._lock: if self._is_cancelled: raise PostgresException('cancelled') self._is_cancelled = False self._process = subprocess.Popen(*args, **kwargs) if communicate_input: if input_data: self._process.communicate(input_data) self._process.stdin.close() return self._process.wait() finally: with self._lock: self._process = None
def bootstrap(self, current_leader=None): """ Initially bootstrap PostgreSQL, either by creating a data directory with initdb, or by initalizing a replica from an exiting leader. Failure in the first case always leads to exception, since there is no point in continuing if initdb failed. In the second case, however, a False is returned on failure, since it is normal for the replica to retry a failed attempt to initialize from the master. """ ret = False if not current_leader: ret = self.initialize() and self.start() if ret: self.create_replication_user() self.create_connection_users() else: raise PostgresException( "Could not bootstrap master PostgreSQL") else: if self.sync_from_leader(current_leader): self.restore_configuration_files() self.write_recovery_conf(current_leader) ret = self.start() return ret
def bootstrap(self, config): """ Initialize a new node from scratch and start it. """ if self._initialize(config) and self.start(): for name, value in config['users'].items(): if name not in (self._superuser.get('username'), self._replication['username']): self.create_or_update_role(name, value['password'], value.get('options', [])) self.create_or_update_role(self._replication['username'], self._replication['password'], ['REPLICATION']) else: raise PostgresException("Could not bootstrap master PostgreSQL")
def postgres_version_to_int(pg_version): """Convert the server_version to integer >>> postgres_version_to_int('9.5.3') 90503 >>> postgres_version_to_int('9.3.13') 90313 >>> postgres_version_to_int('10.1') 100001 >>> postgres_version_to_int('10') # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... PostgresException: 'Invalid PostgreSQL version format: X.Y or X.Y.Z is accepted: 10' >>> postgres_version_to_int('9.6') # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... PostgresException: 'Invalid PostgreSQL version format: X.Y or X.Y.Z is accepted: 9.6' >>> postgres_version_to_int('a.b.c') # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... PostgresException: 'Invalid PostgreSQL version: a.b.c' """ try: components = list(map(int, pg_version.split('.'))) except ValueError: raise PostgresException( 'Invalid PostgreSQL version: {0}'.format(pg_version)) if len(components) < 2 or len( components) == 2 and components[0] < 10 or len(components) > 3: raise PostgresException( 'Invalid PostgreSQL version format: X.Y or X.Y.Z is accepted: {0}'. format(pg_version)) if len(components) == 2: # new style verion numbers, i.e. 10.1 becomes 100001 components.insert(1, 0) return int(''.join('{0:02d}'.format(c) for c in components))
def test_bootstrap_release_initialize_key_on_failure(self): self.ha.cluster = get_cluster_not_initialized_without_leader() self.e.initialize = true self.p.bootstrap = Mock(side_effect=PostgresException("Could not bootstrap master PostgreSQL")) self.assertRaises(PostgresException, self.ha.bootstrap)
def test_update_lock(self): self.p.last_operation = Mock(side_effect=PostgresException('')) self.assertTrue(self.ha.update_lock())