New site creation with a different DB user than Root
See original GitHub issueExpected Behaviour
When using the option --mariadb-root-username, the system should allow the creation of a new site without having to use the ‘root’ user.
Actual Behaviour
As described in https://discuss.erpnext.com/t/new-site-creation-with-another-user-than-mariadbs-root/23939/ I am getting the following error when trying to create a new site with a ‘frappe’ user granted all privileges and grant option:
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 79, in <module>
main()
File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 16, in main
click.Group(commands=commands)(prog_name='bench')
File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/site.py", line 27, in new_site
verbose=verbose, install_apps=install_app, source_sql=source_sql, force=force)
File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/site.py", line 58, in _new_site
admin_password=admin_password, verbose=verbose, source_sql=source_sql,force=force, reinstall=reinstall)
File "/home/frappe/frappe-bench/apps/frappe/frappe/installer.py", line 35, in install_db
create_database_and_user(force, verbose)
File "/home/frappe/frappe-bench/apps/frappe/frappe/installer.py", line 59, in create_database_and_user
if force or (db_name not in dbman.get_database_list()):
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/db_schema.py", line 543, in get_database_list
return [d[0] for d in self.db.sql("SHOW DATABASES")]
File "/home/frappe/frappe-bench/apps/frappe/frappe/database.py", line 107, in sql
self.connect()
File "/home/frappe/frappe-bench/apps/frappe/frappe/database.py", line 64, in connect
self.use(self.user)
File "/home/frappe/frappe-bench/apps/frappe/frappe/database.py", line 69, in use
self._conn.select_db(db_name)
_mysql_exceptions.OperationalError: (1049, "Unknown database 'frappe'")
The problem seems to come from the fact that in database.py, the root name is hard coded:
if self.user != 'root':
self.use(self.user)
frappe.local.rollback_observers = []
def use(self, db_name):
"""`USE` db_name."""
self._conn.select_db(db_name)
self.cur_db_name = db_name
When entering if self.user != 'root' and self.user != 'frappe
: ` the creation of the new-site works without issues.
I have been trying to find a way to get the root_login passed in --mariadb-root-username to replace this statement, but unfortunately I haven’t found a way…
If someone has any clue and can help me, I will happily correct this issue.
Steps to reproduce:
With a DB user named frappe (password = frappe) you can try to create a new site using:
bench new-site site10 --mariadb-root-username frappe --mariadb-root-password frappe --verbose
Frappe version: v8.0.48
Issue Analytics
- State:
- Created 6 years ago
- Reactions:3
- Comments:12 (5 by maintainers)
Top GitHub Comments
Hello,
I was trying to create similar setup using external MySQL server with limited permissions of main mysql user. What i noticed are following things:
If I create a special MySQL user that has all privileges granted, but ‘frappe’ db doesn’t exist, then we get the exception for unknown database ‘frappe’. Temporary workaround without modifying the code is to create frappe db, but still i would be happy to have this solved inside the code, because db is not in use at all. As @chdecultot mentioned db name must match the name of the mysql user that pass as root user.
If i create a special MySQL user that will be used instead of root and I set for it only limited permissions (create, drop, create user and grant permissions), then i see that when i run bench new-site passing that user and its pass, site is created, db and user for that site are created, but we get an error from bench that special mysql user, used as replacement of root user, doesn’t have access to newly created dbs. That special mysql user grant privileges ONLY to newly created user for the site, but it doesn’t grant privileges for dbs to itself. Like this it cannot access databases and fails to work.
Third problem that i noticed (this is critical for docker installations with external MySQL) - mysql users are created with set specific IP address instead of % for host. This is a problem, because docker IP is not static and will change if instance is recreated and like this access to mysql will not work. So it is best if we can control what host to be used for creation of mysql user or make default one to be %.
NOTE: Everything works ok if mysql user that we use in bench for site creation has all privileges just as root and frappe db exist. But it is best if we can limit permissions of that user.
Another option would be if we don’t want to use root user, then to be able to create manually the db and create a special user that has access only to that db with all privileges granted and let we pass this data with bench instead of root and this data to be used for the new site.
In additional tests we have made with Danyal, it seems that if you create an empty DB with a name identical to the one of your root user, it works.
Example: mariadb-root-username = testuser
If I create an empty DB called “testuser” in MariaDB, then I can create a new site with mariadb-root-username.
But this can only be a workaround and cannot be considered as a real solution.
I guess here we haven’t fully understand the different behavior between the ‘root’ user and another user behaving as root…