From 0f8133d633cf2b4601a7a191a5a2e64a7ea92dd6 Mon Sep 17 00:00:00 2001 From: talyz Date: Sat, 14 Sep 2019 01:38:54 +0200 Subject: [PATCH 1/2] nixos/gitlab: Fix state directory permissions Since the preStart script is no longer running in privileged mode, we reassign the files in the state directory and its config subdirectory to the user we're running as. This is done by splitting the preStart script into a privileged and an unprivileged part where the privileged part does the reassignment. Also, delete the database.yml symlink if it exists, since we want to create a real file in its place. Fixes #68696. --- nixos/modules/services/misc/gitlab.nix | 150 ++++++++++++++----------- 1 file changed, 82 insertions(+), 68 deletions(-) diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index 4c1ffead00c..58ef463c49e 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -763,74 +763,6 @@ in { procps gnupg ]; - preStart = '' - 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 - - ${cfg.packages.gitlab-shell}/bin/install - - ${optionalString cfg.smtp.enable '' - 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' - ''} - ''} - - ( - umask u=rwx,g=,o= - - ${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' - '' - } - - ${utils.genJqSecretsReplacementSnippet - gitlabConfig - "${cfg.statePath}/config/gitlab.yml" - } - - if [[ -h '${cfg.statePath}/config/secrets.yml' ]]; then - rm '${cfg.statePath}/config/secrets.yml' - fi - - export secret="$(<'${cfg.secrets.secretFile}')" - export db="$(<'${cfg.secrets.dbFile}')" - export otp="$(<'${cfg.secrets.otpFile}')" - export jws="$(<'${cfg.secrets.jwsFile}')" - ${pkgs.jq}/bin/jq -n '{production: {secret_key_base: $ENV.secret, - otp_key_base: $ENV.otp, - db_key_base: $ENV.db, - openid_connect_signing_key: $ENV.jws}}' \ - > '${cfg.statePath}/config/secrets.yml' - ) - - 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.git}/bin/git config --global core.autocrlf "input" - ''; serviceConfig = { Type = "simple"; @@ -839,6 +771,88 @@ in { TimeoutSec = "infinity"; Restart = "on-failure"; WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab"; + ExecStartPre = let + preStartFullPrivileges = '' + shopt -s dotglob nullglob + chown --no-dereference '${cfg.user}':'${cfg.group}' '${cfg.statePath}'/* + chown --no-dereference '${cfg.user}':'${cfg.group}' '${cfg.statePath}'/config/* + ''; + preStart = '' + 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 + + ${cfg.packages.gitlab-shell}/bin/install + + ${optionalString cfg.smtp.enable '' + 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' + ''} + ''} + + ( + umask u=rwx,g=,o= + + ${pkgs.openssl}/bin/openssl rand -hex 32 > ${cfg.statePath}/gitlab_shell_secret + + if [[ -h '${cfg.statePath}/config/database.yml' ]]; then + rm '${cfg.statePath}/config/database.yml' + fi + + ${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' + '' + } + + ${utils.genJqSecretsReplacementSnippet + gitlabConfig + "${cfg.statePath}/config/gitlab.yml" + } + + if [[ -h '${cfg.statePath}/config/secrets.yml' ]]; then + rm '${cfg.statePath}/config/secrets.yml' + fi + + export secret="$(<'${cfg.secrets.secretFile}')" + export db="$(<'${cfg.secrets.dbFile}')" + export otp="$(<'${cfg.secrets.otpFile}')" + export jws="$(<'${cfg.secrets.jwsFile}')" + ${pkgs.jq}/bin/jq -n '{production: {secret_key_base: $ENV.secret, + otp_key_base: $ENV.otp, + db_key_base: $ENV.db, + openid_connect_signing_key: $ENV.jws}}' \ + > '${cfg.statePath}/config/secrets.yml' + ) + + 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.git}/bin/git config --global core.autocrlf "input" + ''; + in [ + "+${pkgs.writeShellScript "gitlab-pre-start-full-privileges" preStartFullPrivileges}" + "${pkgs.writeShellScript "gitlab-pre-start" preStart}" + ]; ExecStart = "${cfg.packages.gitlab.rubyEnv}/bin/unicorn -c ${cfg.statePath}/config/unicorn.rb -E production"; }; From c6efa9fd2d0bc9353ffc3dd497f677d7c49a3a11 Mon Sep 17 00:00:00 2001 From: talyz Date: Thu, 3 Oct 2019 14:38:54 +0200 Subject: [PATCH 2/2] nixos/gitlab: Clean up the initializers on start The initializers directory is populated with files from the gitlab distribution on start, but old files will be left in the state folder even if they're removed from the distribution, which can lead to startup failures. Fix this by always purging the directory on start before populating it. --- nixos/modules/services/misc/gitlab.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index 58ef463c49e..0b15b40c72c 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -780,6 +780,7 @@ in { preStart = '' cp -f ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION rm -rf ${cfg.statePath}/db/* + rm -rf ${cfg.statePath}/config/initializers/* 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