Skip to content

Commit

Permalink
fix: grant role before creating database
Browse files Browse the repository at this point in the history
In some postgresql installations, the following fails:

	template1=> create user test;
	CREATE ROLE
	template1=> create database test owner test;
	ERROR:  must be member of role "test"

This is fixed by

	template1=> grant test to azureuser;
	GRANT ROLE
	template1=> create database test owner test;
	CREATE DATABASE

Furthermore, granting privileges to the owner is superfluous according
to the postgresql docs, so we drop it.

The investigation of this issue also surfaces a bug in the error message
for "manual database creation", and that the `--su-db-name` was not
passed on from the commandline.
  • Loading branch information
Leopold Talirz committed Dec 8, 2022
1 parent f3e1968 commit d6f68ad
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 9 deletions.
5 changes: 3 additions & 2 deletions aiida/cmdline/commands/cmd_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ def quicksetup(
'port': db_port,
'user': su_db_username,
'password': su_db_password,
'database': su_db_name,
}
postgres = Postgres(interactive=not non_interactive, quiet=False, dbinfo=dbinfo_su)

Expand All @@ -177,8 +178,8 @@ def quicksetup(
'Oops! quicksetup was unable to create the AiiDA database for you.',
'See `verdi quicksetup -h` for how to specify non-standard parameters for the postgresql connection.\n'
'Alternatively, create the AiiDA database yourself: ',
manual_setup_instructions(dbuser=su_db_username,
dbname=su_db_name), '', 'and then use `verdi setup` instead', ''
manual_setup_instructions(su_db_username=su_db_username, db_username=db_username,
db_name=db_name), '', 'and then use `verdi setup` instead', ''
])
)
raise exception
Expand Down
15 changes: 8 additions & 7 deletions aiida/manage/external/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
'TEMPLATE=template0'
)
_DROP_DB_COMMAND = 'DROP DATABASE "{}"'
_GRANT_PRIV_COMMAND = 'GRANT ALL PRIVILEGES ON DATABASE "{}" TO "{}"'
_GRANT_ROLE_COMMAND = 'GRANT "{}" TO "{}"'
_USER_EXISTS_COMMAND = "SELECT usename FROM pg_user WHERE usename='{}'"
_CHECK_DB_EXISTS_COMMAND = "SELECT datname FROM pg_database WHERE datname='{}'"
_COPY_DB_COMMAND = 'CREATE DATABASE "{}" WITH TEMPLATE "{}" OWNER "{}"'
Expand Down Expand Up @@ -108,6 +108,8 @@ def create_dbuser(self, dbuser, dbpass, privileges=''):
self.connection_mode == PostgresConnectionMode.PSYCOPG
"""
self.execute(_CREATE_USER_COMMAND.format(dbuser, dbpass, privileges))
# this is needed on some postgresql installations
self.execute(_GRANT_ROLE_COMMAND.format(dbuser, self.dsn['user']))

def drop_dbuser(self, dbuser):
"""
Expand Down Expand Up @@ -153,7 +155,6 @@ def create_db(self, dbuser, dbname):
:param str dbname: Name of the database.
"""
self.execute(_CREATE_DB_COMMAND.format(dbname, dbuser))
self.execute(_GRANT_PRIV_COMMAND.format(dbname, dbuser))

def drop_db(self, dbname):
"""
Expand Down Expand Up @@ -220,15 +221,15 @@ def dbinfo(self):
return self.dsn.copy()


def manual_setup_instructions(dbuser, dbname):
def manual_setup_instructions(su_db_username, db_username, db_name):
"""Create a message with instructions for manually creating a database"""
dbpass = '<password>'
db_pass = '<password>'
instructions = '\n'.join([
'Run the following commands as a UNIX user with access to PostgreSQL (Ubuntu: $ sudo su postgres):',
'',
'\t$ psql template1',
f' ==> {_CREATE_USER_COMMAND.format(dbuser, dbpass, "")}',
f' ==> {_CREATE_DB_COMMAND.format(dbname, dbuser)}',
f' ==> {_GRANT_PRIV_COMMAND.format(dbname, dbuser)}',
f' ==> {_CREATE_USER_COMMAND.format(db_username, db_pass, "")}',
f' ==> {_GRANT_ROLE_COMMAND.format(db_username, su_db_username)}',
f' ==> {_CREATE_DB_COMMAND.format(db_name, db_username)}',
])
return instructions

0 comments on commit d6f68ad

Please sign in to comment.