nixos/gitlab: Use postgresql module options to provision local db
Use the postgresql module to provision a local db (if databaseCreateLocally is true) instead of doing this locally. Switch to using the local unix socket for db connections by default; this is needed since dbs created by the postgresql module only support peer authentication. Instead of running the rake tasks db:schema:load, db:migrate and db:seed_fu, run gitlab:db:configure, which in turn runs these tasks when needed. Solves issue #53852 for gitlab.
This commit is contained in:
parent
cbdf94c0f3
commit
b351454cac
@ -12,7 +12,6 @@ let
|
|||||||
gitlabSocket = "${cfg.statePath}/tmp/sockets/gitlab.socket";
|
gitlabSocket = "${cfg.statePath}/tmp/sockets/gitlab.socket";
|
||||||
gitalySocket = "${cfg.statePath}/tmp/sockets/gitaly.socket";
|
gitalySocket = "${cfg.statePath}/tmp/sockets/gitaly.socket";
|
||||||
pathUrlQuote = url: replaceStrings ["/"] ["%2F"] url;
|
pathUrlQuote = url: replaceStrings ["/"] ["%2F"] url;
|
||||||
pgSuperUser = config.services.postgresql.superUser;
|
|
||||||
|
|
||||||
databaseConfig = {
|
databaseConfig = {
|
||||||
production = {
|
production = {
|
||||||
@ -237,8 +236,11 @@ in {
|
|||||||
|
|
||||||
databaseHost = mkOption {
|
databaseHost = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "127.0.0.1";
|
default = "";
|
||||||
description = "Gitlab database hostname.";
|
description = ''
|
||||||
|
Gitlab database hostname. An empty string means <quote>use
|
||||||
|
local unix socket connection</quote>.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
databasePasswordFile = mkOption {
|
databasePasswordFile = mkOption {
|
||||||
@ -252,6 +254,17 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
databaseCreateLocally = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether a database should be automatically created on the
|
||||||
|
local host. Set this to <literal>false</literal> if you plan
|
||||||
|
on provisioning a local database yourself or use an external
|
||||||
|
one.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
databaseName = mkOption {
|
databaseName = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "gitlab";
|
default = "gitlab";
|
||||||
@ -498,12 +511,16 @@ in {
|
|||||||
|
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
assertion = cfg.initialRootPasswordFile != null;
|
assertion = cfg.databaseCreateLocally -> (cfg.user == cfg.databaseUsername);
|
||||||
message = "services.gitlab.initialRootPasswordFile must be set!";
|
message = "For local automatic database provisioning services.gitlab.user and services.gitlab.databaseUsername should be identical.";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
assertion = cfg.databasePasswordFile != null;
|
assertion = (cfg.databaseHost != "") -> (cfg.databasePasswordFile != null);
|
||||||
message = "services.gitlab.databasePasswordFile must be set!";
|
message = "When services.gitlab.databaseHost is customized, services.gitlab.databasePasswordFile must be set!";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.initialRootPasswordFile != null;
|
||||||
|
message = "services.gitlab.initialRootPasswordFile must be set!";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
assertion = cfg.secrets.secretFile != null;
|
assertion = cfg.secrets.secretFile != null;
|
||||||
@ -527,8 +544,31 @@ in {
|
|||||||
|
|
||||||
# Redis is required for the sidekiq queue runner.
|
# Redis is required for the sidekiq queue runner.
|
||||||
services.redis.enable = mkDefault true;
|
services.redis.enable = mkDefault true;
|
||||||
|
|
||||||
# We use postgres as the main data store.
|
# We use postgres as the main data store.
|
||||||
services.postgresql.enable = mkDefault true;
|
services.postgresql = optionalAttrs cfg.databaseCreateLocally {
|
||||||
|
enable = true;
|
||||||
|
ensureUsers = singleton { name = cfg.databaseUsername; };
|
||||||
|
};
|
||||||
|
# The postgresql module doesn't currently support concepts like
|
||||||
|
# objects owners and extensions; for now we tack on what's needed
|
||||||
|
# here.
|
||||||
|
systemd.services.postgresql.postStart = mkAfter (optionalString cfg.databaseCreateLocally ''
|
||||||
|
$PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${cfg.databaseName}'" | grep -q 1 || $PSQL -tAc 'CREATE DATABASE "${cfg.databaseName}" OWNER "${cfg.databaseUsername}"'
|
||||||
|
current_owner=$($PSQL -tAc "SELECT pg_catalog.pg_get_userbyid(datdba) FROM pg_catalog.pg_database WHERE datname = '${cfg.databaseName}'")
|
||||||
|
if [[ "$current_owner" != "${cfg.databaseUsername}" ]]; then
|
||||||
|
$PSQL -tAc 'ALTER DATABASE "${cfg.databaseName}" OWNER TO "${cfg.databaseUsername}"'
|
||||||
|
if [[ -e "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}" ]]; then
|
||||||
|
echo "Reassigning ownership of database ${cfg.databaseName} to user ${cfg.databaseUsername} failed on last boot. Failing..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
touch "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}"
|
||||||
|
$PSQL "${cfg.databaseName}" -tAc "REASSIGN OWNED BY \"$current_owner\" TO \"${cfg.databaseUsername}\""
|
||||||
|
rm "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}"
|
||||||
|
fi
|
||||||
|
$PSQL '${cfg.databaseName}' -tAc "CREATE EXTENSION IF NOT EXISTS pg_trgm"
|
||||||
|
'');
|
||||||
|
|
||||||
# Use postfix to send out mails.
|
# Use postfix to send out mails.
|
||||||
services.postfix.enable = mkDefault true;
|
services.postfix.enable = mkDefault true;
|
||||||
|
|
||||||
@ -675,15 +715,15 @@ in {
|
|||||||
gnupg
|
gnupg
|
||||||
];
|
];
|
||||||
preStart = ''
|
preStart = ''
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} cp -f ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION
|
cp -f ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} rm -rf ${cfg.statePath}/db/*
|
rm -rf ${cfg.statePath}/db/*
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config
|
cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db
|
cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db
|
||||||
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} ${cfg.packages.gitlab-shell}/bin/install
|
${cfg.packages.gitlab-shell}/bin/install
|
||||||
|
|
||||||
${optionalString cfg.smtp.enable ''
|
${optionalString cfg.smtp.enable ''
|
||||||
install -o ${cfg.user} -g ${cfg.group} -m u=rw ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb
|
install -m u=rw ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb
|
||||||
${optionalString (cfg.smtp.passwordFile != null) ''
|
${optionalString (cfg.smtp.passwordFile != null) ''
|
||||||
smtp_password=$(<'${cfg.smtp.passwordFile}')
|
smtp_password=$(<'${cfg.smtp.passwordFile}')
|
||||||
${pkgs.replace}/bin/replace-literal -e '@smtpPassword@' "$smtp_password" '${cfg.statePath}/config/initializers/smtp_settings.rb'
|
${pkgs.replace}/bin/replace-literal -e '@smtpPassword@' "$smtp_password" '${cfg.statePath}/config/initializers/smtp_settings.rb'
|
||||||
@ -695,6 +735,24 @@ in {
|
|||||||
|
|
||||||
${pkgs.openssl}/bin/openssl rand -hex 32 > ${cfg.statePath}/gitlab_shell_secret
|
${pkgs.openssl}/bin/openssl rand -hex 32 > ${cfg.statePath}/gitlab_shell_secret
|
||||||
|
|
||||||
|
${if cfg.databasePasswordFile != null then ''
|
||||||
|
export db_password="$(<'${cfg.databasePasswordFile}')"
|
||||||
|
|
||||||
|
if [[ -z "$db_password" ]]; then
|
||||||
|
>&2 echo "Database password was an empty string!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
${pkgs.jq}/bin/jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \
|
||||||
|
'.production.password = $ENV.db_password' \
|
||||||
|
>'${cfg.statePath}/config/database.yml'
|
||||||
|
''
|
||||||
|
else ''
|
||||||
|
${pkgs.jq}/bin/jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \
|
||||||
|
>'${cfg.statePath}/config/database.yml'
|
||||||
|
''
|
||||||
|
}
|
||||||
|
|
||||||
if [[ -h '${cfg.statePath}/config/secrets.yml' ]]; then
|
if [[ -h '${cfg.statePath}/config/secrets.yml' ]]; then
|
||||||
rm '${cfg.statePath}/config/secrets.yml'
|
rm '${cfg.statePath}/config/secrets.yml'
|
||||||
fi
|
fi
|
||||||
@ -708,54 +766,19 @@ in {
|
|||||||
db_key_base: $ENV.otp,
|
db_key_base: $ENV.otp,
|
||||||
openid_connect_signing_key: $ENV.jws}}' \
|
openid_connect_signing_key: $ENV.jws}}' \
|
||||||
> '${cfg.statePath}/config/secrets.yml'
|
> '${cfg.statePath}/config/secrets.yml'
|
||||||
|
|
||||||
chown ${cfg.user}:${cfg.group} '${cfg.statePath}/config/secrets.yml' '${cfg.statePath}/gitlab_shell_secret'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
export db_password="$(<'${cfg.databasePasswordFile}')"
|
initial_root_password="$(<'${cfg.initialRootPasswordFile}')"
|
||||||
|
${gitlab-rake}/bin/gitlab-rake gitlab:db:configure GITLAB_ROOT_PASSWORD="$initial_root_password" \
|
||||||
if [[ -z "$db_password" ]]; then
|
GITLAB_ROOT_EMAIL='${cfg.initialRootEmail}'
|
||||||
>&2 echo "Database password was an empty string!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
${pkgs.jq}/bin/jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \
|
|
||||||
'.production.password = $ENV.db_password' \
|
|
||||||
>'${cfg.statePath}/config/database.yml'
|
|
||||||
chown ${cfg.user}:${cfg.group} '${cfg.statePath}/config/database.yml'
|
|
||||||
|
|
||||||
if ! test -e "${cfg.statePath}/db-created"; then
|
|
||||||
if [ "${cfg.databaseHost}" = "127.0.0.1" ]; then
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "CREATE ROLE ${cfg.databaseUsername} WITH LOGIN NOCREATEDB NOCREATEROLE ENCRYPTED PASSWORD '$db_password'"
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} ${config.services.postgresql.package}/bin/createdb --owner ${cfg.databaseUsername} ${cfg.databaseName}
|
|
||||||
|
|
||||||
# enable required pg_trgm extension for gitlab
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql ${cfg.databaseName} -c "CREATE EXTENSION IF NOT EXISTS pg_trgm"
|
|
||||||
fi
|
|
||||||
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} -H ${gitlab-rake}/bin/gitlab-rake db:schema:load
|
|
||||||
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} touch "${cfg.statePath}/db-created"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Always do the db migrations just to be sure the database is up-to-date
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} -H ${gitlab-rake}/bin/gitlab-rake db:migrate
|
|
||||||
|
|
||||||
if ! test -e "${cfg.statePath}/db-seeded"; then
|
|
||||||
initial_root_password="$(<'${cfg.initialRootPasswordFile}')"
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} ${gitlab-rake}/bin/gitlab-rake db:seed_fu \
|
|
||||||
GITLAB_ROOT_PASSWORD="$initial_root_password" GITLAB_ROOT_EMAIL='${cfg.initialRootEmail}'
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} touch "${cfg.statePath}/db-seeded"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# We remove potentially broken links to old gitlab-shell versions
|
# We remove potentially broken links to old gitlab-shell versions
|
||||||
rm -Rf ${cfg.statePath}/repositories/**/*.git/hooks
|
rm -Rf ${cfg.statePath}/repositories/**/*.git/hooks
|
||||||
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} -H ${pkgs.git}/bin/git config --global core.autocrlf "input"
|
${pkgs.git}/bin/git config --global core.autocrlf "input"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
PermissionsStartOnly = true; # preStart must be run as root
|
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Group = cfg.group;
|
Group = cfg.group;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user