mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-28 18:03:04 +00:00
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";
|
||||
gitalySocket = "${cfg.statePath}/tmp/sockets/gitaly.socket";
|
||||
pathUrlQuote = url: replaceStrings ["/"] ["%2F"] url;
|
||||
pgSuperUser = config.services.postgresql.superUser;
|
||||
|
||||
databaseConfig = {
|
||||
production = {
|
||||
@ -237,8 +236,11 @@ in {
|
||||
|
||||
databaseHost = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Gitlab database hostname.";
|
||||
default = "";
|
||||
description = ''
|
||||
Gitlab database hostname. An empty string means <quote>use
|
||||
local unix socket connection</quote>.
|
||||
'';
|
||||
};
|
||||
|
||||
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 {
|
||||
type = types.str;
|
||||
default = "gitlab";
|
||||
@ -498,12 +511,16 @@ in {
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.initialRootPasswordFile != null;
|
||||
message = "services.gitlab.initialRootPasswordFile must be set!";
|
||||
assertion = cfg.databaseCreateLocally -> (cfg.user == cfg.databaseUsername);
|
||||
message = "For local automatic database provisioning services.gitlab.user and services.gitlab.databaseUsername should be identical.";
|
||||
}
|
||||
{
|
||||
assertion = cfg.databasePasswordFile != null;
|
||||
message = "services.gitlab.databasePasswordFile must be set!";
|
||||
assertion = (cfg.databaseHost != "") -> (cfg.databasePasswordFile != null);
|
||||
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;
|
||||
@ -527,8 +544,31 @@ in {
|
||||
|
||||
# Redis is required for the sidekiq queue runner.
|
||||
services.redis.enable = mkDefault true;
|
||||
|
||||
# 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.
|
||||
services.postfix.enable = mkDefault true;
|
||||
|
||||
@ -675,15 +715,15 @@ in {
|
||||
gnupg
|
||||
];
|
||||
preStart = ''
|
||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} cp -f ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION
|
||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} 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
|
||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db
|
||||
cp -f ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION
|
||||
rm -rf ${cfg.statePath}/db/*
|
||||
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/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 ''
|
||||
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) ''
|
||||
smtp_password=$(<'${cfg.smtp.passwordFile}')
|
||||
${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
|
||||
|
||||
${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
|
||||
rm '${cfg.statePath}/config/secrets.yml'
|
||||
fi
|
||||
@ -708,54 +766,19 @@ in {
|
||||
db_key_base: $ENV.otp,
|
||||
openid_connect_signing_key: $ENV.jws}}' \
|
||||
> '${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}')"
|
||||
|
||||
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'
|
||||
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
|
||||
initial_root_password="$(<'${cfg.initialRootPasswordFile}')"
|
||||
${gitlab-rake}/bin/gitlab-rake gitlab:db:configure GITLAB_ROOT_PASSWORD="$initial_root_password" \
|
||||
GITLAB_ROOT_EMAIL='${cfg.initialRootEmail}'
|
||||
|
||||
# We remove potentially broken links to old gitlab-shell versions
|
||||
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 = {
|
||||
PermissionsStartOnly = true; # preStart must be run as root
|
||||
Type = "simple";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
|
Loading…
Reference in New Issue
Block a user