Skip to content

Commit

Permalink
allows to run 'barman switch-wal --force' when the user has the 'pg_c…
Browse files Browse the repository at this point in the history
…heckpoint' role
  • Loading branch information
T0mmyZ-pa committed Sep 18, 2023
1 parent cb42b10 commit 512a412
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 7 deletions.
6 changes: 6 additions & 0 deletions barman/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@ class BackupFunctionsAccessRequired(PostgresException):
"""


class PostgresCheckpointPrivilegesRequired(PostgresException):
"""
Superuser or role 'pg_checkpoint' is required
"""


class PostgresIsInRecovery(PostgresException):
"""
PostgreSQL is in recovery, so no write operations are allowed
Expand Down
31 changes: 28 additions & 3 deletions barman/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
PostgresReplicationSlotInUse,
PostgresReplicationSlotsFull,
BackupFunctionsAccessRequired,
PostgresSuperuserRequired,
PostgresCheckpointPrivilegesRequired,
PostgresUnsupportedFeature,
)
from barman.infofile import Tablespace
Expand Down Expand Up @@ -638,6 +638,31 @@ def has_backup_privileges(self):
)
return None

@property
def has_checkpoint_privileges(self):
"""
Returns true if the current user is a superuser or if,
for PostgreSQL 14 and above, the user has the "pg_checkpoint" role.
"""

if self.server_version < 140000:
return self.is_superuser

if self.is_superuser:
return True
else:
role_check_query = "select pg_has_role(CURRENT_USER ,'pg_checkpoint', 'MEMBER');"
try:
cur = self._cursor()
cur.execute(role_check_query)
return cur.fetchone()[0]
except (PostgresConnectionError, psycopg2.Error) as e:
_logger.warning(
"Error checking privileges for functions needed for creating checkpoints: %s",
force_str(e).strip(),
)
return None

@property
def current_xlog_info(self):
"""
Expand Down Expand Up @@ -1351,8 +1376,8 @@ def checkpoint(self):
conn = self.connect()

# Requires superuser privilege
if not self.is_superuser:
raise PostgresSuperuserRequired()
if not self.has_checkpoint_privileges:
raise PostgresCheckpointPrivilegesRequired()

cur = conn.cursor()
cur.execute("CHECKPOINT")
Expand Down
6 changes: 4 additions & 2 deletions barman/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
PostgresReplicationSlotInUse,
PostgresReplicationSlotsFull,
PostgresSuperuserRequired,
PostgresCheckpointPrivilegesRequired,
PostgresUnsupportedFeature,
SyncError,
SyncNothingToDo,
Expand Down Expand Up @@ -2910,9 +2911,10 @@ def switch_wal(self, force=False, archive=None, archive_timeout=None):
"No switch performed because server '%s' "
"is a standby." % self.config.name
)
except PostgresSuperuserRequired:
except PostgresCheckpointPrivilegesRequired:
# Superuser rights are required to perform the switch_wal
output.error("Barman switch-wal requires superuser rights")
output.error("Barman switch-wal --force requires superuser rights or "
"the 'pg_checkpoint' role")
return

# If the user has asked to wait for a WAL file to be archived,
Expand Down
10 changes: 8 additions & 2 deletions doc/manual/21-preliminary_steps.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,14 @@ GRANT EXECUTE ON FUNCTION pg_backup_start(text, boolean) to barman;
GRANT EXECUTE ON FUNCTION pg_backup_stop(boolean) to barman;
```

It is worth noting that without a real superuser, the `--force` option
of the `barman switch-wal` command will not work.
It is worth noting that with PostgreSQL version 13 and below without a real
superuser, the `--force` option of the `barman switch-wal` command will not work.
If you are running PostgreSQL version 14 or above, you can grant the `pg_checkpoint`
role, so you can use this feature without a superuser:

``` sql
GRANT pg_checkpoint TO barman;
```

> **IMPORTANT:** The above `createuser` command will prompt for a password,
> which you are then advised to add to the `~barman/.pgpass` file
Expand Down

0 comments on commit 512a412

Please sign in to comment.