Exemple #1
0
    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()
Exemple #2
0
 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")
Exemple #3
0
    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
Exemple #5
0
 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")
Exemple #6
0
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))
Exemple #7
0
 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)
Exemple #8
0
 def test_update_lock(self):
     self.p.last_operation = Mock(side_effect=PostgresException(''))
     self.assertTrue(self.ha.update_lock())