Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: grant role before creating database #5828

Merged
merged 5 commits into from
Jan 26, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(db_username=db_username,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not concerning this line, but line 184: should we just reraise the exception? Isn't it better to simply use echo.echo_critical? Usually showing a scary traceback by default to a user from a CLI command is not a good idea.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also just noted that the instructions above (to use verdi quicksetup -h for help) were wrong for a long time and only (coincidentally) got fixed just two weeks ago in 6469e23 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes the traceback can also help to see where the problem is... let me know if you want me to change it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a reusable option that we have --traceback that will optionally show the traceback which I think can be useful. But we can leave it for now, it is not critical

db_name=db_name), '', 'and then use `verdi setup` instead', ''
])
)
raise exception
Expand Down
16 changes: 9 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 current_user'
_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,9 @@ def create_dbuser(self, dbuser, dbpass, privileges=''):
self.connection_mode == PostgresConnectionMode.PSYCOPG
"""
self.execute(_CREATE_USER_COMMAND.format(dbuser, dbpass, privileges))
# Ensure the database superuser (current_user) has the rights to grant `dbuser` access to new databases.
ltalirz marked this conversation as resolved.
Show resolved Hide resolved
# Required for some postgresql installations.
self.execute(_GRANT_ROLE_COMMAND.format(dbuser))

def drop_dbuser(self, dbuser):
"""
Expand Down Expand Up @@ -153,7 +156,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 +222,15 @@ def dbinfo(self):
return self.dsn.copy()


def manual_setup_instructions(dbuser, dbname):
def manual_setup_instructions(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)}',
f' ==> {_CREATE_DB_COMMAND.format(db_name, db_username)}',
])
return instructions