-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
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
nixos/postgresql: add ensureDatabases & ensureUsers options #56720
Conversation
This pull request has been mentioned on Nix community. There might be relevant details there: https://discourse.nixos.org/t/postgresql-module-vs-mysql-module/2243/5 |
Huh, pretty simple! The only thing I'm worrying is that it will generate errors in logs (database already exists, role already exists), even that service boots OK. On the other hand, when there will be real configuration error, it won't be visible after deploy. So I'd propose to remove I've sketched (untested, but based on my config) how I'd like to see the SQL generation part:
It generates following Bash code:
|
And also, this supports the quirks like:
Maybe add as example? |
@danbst wow thank you so much!! I'm assuming ALTER ROLE will remove permissions if existing permissions aren't listed?
This is how mysql operates. While it isn't necessary to keep this behavior the exact same between mysql and postgres so long as properly documented... it would be nice if we could. It's there an easy way to modify this so permissions won't be removed? |
@aanderse as I read docs, alter role won't remove permission unless you do ask it. For example, if you change Also, note that
Code will be simplified a bit. |
Great! Please disregard my last comment then. |
Hey @danbst I've tried a couple variants of the "GRANT" sql you posted but I'm still having some trouble. Given I'm not very familiar with postgresql dialect I'm probably missing something very obvious and thought you might save me a few more minutes banging my head on it.
This generates the code you posted ERROR: syntax error at or near "." Aside from that, everything else look good? |
I've discovered bug-report #56889, which is an example of what can happen when option is not typed. I think "ensureUsers" should be converted to typed submodule, both here and in MySQL. |
4880ca8
to
625870b
Compare
@GrahamcOfBorg test redmine.v4-mysql redmine.v4-pgsql |
6938e34
to
3c87ec3
Compare
@florianjacob As the original author of the ensureDatabases & ensureUsers options in the mysql module would you be motivated to tackle this? |
@aanderse I'll see what I can do this evening for the MySQL part, which you then can integrate here as well (don't have much experience with postgresql). At the time of writing 👍 for bringing this to postgresql too, the amount of code to create postgresql databases splattered all over different services is indeed painstaking to see. |
@florianjacob Thank you very much! |
@aszlig as someone who just made a postgresql PR do you have any opinions on this change? More opinions and feedback on this is always welcome. |
@aanderse: Hmmm... given that we (want to) have this possibly for MySQL as well, what about having a generic For example like this: {
databases.foo = {
type = "mysql";
owner = "someuser";
};
databases.bar = {
type = "postgresql";
schemaFile = "/path/to/foo.sql";
};
} Database creation then would be an extra systemd service, so units requiring Of course, the model mentioned above does have some limitations, for example you can't have the same database name for both MySQL and PostgreSQL and I probably would separate user creation from database creation like you did here. Maybe something like Anyway, don't take this as a "you're wrong do it like this" thing, just random thoughts that sprung into my mind. |
@@ -255,17 +305,30 @@ in | |||
# Wait for PostgreSQL to be ready to accept connections. | |||
postStart = | |||
'' | |||
while ! ${pkgs.sudo}/bin/sudo -u ${cfg.superUser} psql --port=${toString cfg.port} -d postgres -c "" 2> /dev/null; do | |||
PSQL="${pkgs.sudo}/bin/sudo -u ${cfg.superUser} psql --port=${toString cfg.port}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move all this into a separate service that runs as cfg.superUser
instead, because using sudo
here uses PAM and also is dependant on the configuration of sudoers. While at it I'd probably also remove the postStart
step altogether and use systemd notify, since PostgreSQL has support for that since quite a while.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aszlig For other services which depend on having a postgresql database provisioned and have after = [ "postgresql.service" ];
in their systemd unit will this work? My thought was that systemd would spawn both the separate service you are talking about and the service which depends on having a postgresql database provisioned at the same time, which could lead to problems. My systemd skills are very novice, so please forgive my ignorance here... 😞
@aszlig very neat! I'm glad to see another way to approach the problem. I think it would be great to have consistent syntax for creating databases and users so ultimately we could do something like:
The problem so far being that I don't think it is an easy thing to do to make a consistent syntax between mysql and pgsql for granting access to all tables in a database? There was some discussion between @florianjacob and myself in #50403 (comment) (though I think I've since decided the "with grant option" might not really be appropriate as I think these ensureUsers+ensureDatabases options are moreso for provisioning databases for services, less for provisioning regular users...). Any thoughts on a consistent syntax? |
Somehwat 👍 for separate service, it is not fun to restart PG if you want to add a declarative DB. |
I'd personally be very cautious regarding the unified frontend to both databases, as whatever differences the two databases have or will develop in the future might bite us, similar to the issues with I'd focus more on two separate, well-designed frontends for each database type, but them being as similar as possible, and think later whether we can combine those interfaces under a common umbrella somehow. Though I have to say I don't have enough postgresql experience to really be able to tell how different they behave, might work out well in this specific case. |
Hmm... That is a really good point. A little convenience now might end up as a huge pain later. Thanks for mentioning. |
@danbst Given the mysql module has the same issue of creating database+users+permissions in the services postStart would you be happy to merge without a separate service? The separate service sounds like a good idea, but possibly out of scope for what I'm trying to do here (ie. make postgresql on par with mysql, which currently creates databases+users+permissions in the postStart). |
@aszlig What are your thoughts on merging as is? My goal was to bring feature parity between mysql and postgresql as far as I'm not very familiar with postgresql so I'm relying on the tests I ran plus the expertise of the reviewers listed here to confirm everything is correct... but do you have an issue with this PR being merged as is? |
ping @danbst just in case you have some time freed up and can comment on #56720 (comment). |
I'd say it's fine to first bring feature parity between mysql and postgresql in this PR then sketch a solution to allow changing |
@thoughtpolice any thoughts on this PR? |
Lets merge this in, we can split it up into multiple services later. Ran |
Is it possible that this breaks the manual?
|
@dasJ I haven't heard anyone complain about a broken manual... and generally you hear about a broken manual within hours of it breaking. 🤷♂️ |
Don't mind me, just forgetting how releases work :) |
Motivation for this change
Bring feature parity with mysql to postgresql.
https://discourse.nixos.org/t/postgresql-module-vs-mysql-module/2243
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)nix path-info -S
before and after)