Merge pull request #113635 from talyz/gitlab-improvements

nixos/gitlab: Clean config dir, switch to puma, split PreStart script and more
This commit is contained in:
Kim Lindberger 2021-03-01 13:37:53 +01:00 committed by GitHub
commit e72375464b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 322 additions and 227 deletions

View file

@ -523,6 +523,13 @@ self: super:
as an hardware RNG, as it will automatically run the krngd task to periodically collect random as an hardware RNG, as it will automatically run the krngd task to periodically collect random
data from the device and mix it into the kernel's RNG. data from the device and mix it into the kernel's RNG.
</para> </para>
<para>
The default SMTP port for GitLab has been changed to
<literal>25</literal> from its previous default of
<literal>465</literal>. If you depended on this default, you
should now set the <xref linkend="opt-services.gitlab.smtp.port" />
option.
</para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>

View file

@ -1,69 +0,0 @@
worker_processes 3
listen ENV["UNICORN_PATH"] + "/tmp/sockets/gitlab.socket", :backlog => 1024
listen "/run/gitlab/gitlab.socket", :backlog => 1024
working_directory ENV["GITLAB_PATH"]
pid ENV["UNICORN_PATH"] + "/tmp/pids/unicorn.pid"
timeout 60
# combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true
check_client_connection false
before_fork do |server, worker|
# the following is highly recommended for Rails + "preload_app true"
# as there's no need for the master process to hold a connection
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
# The following is only recommended for memory/DB-constrained
# installations. It is not needed if your system can house
# twice as many worker_processes as you have configured.
#
# This allows a new master process to incrementally
# phase out the old master process with SIGTTOU to avoid a
# thundering herd (especially in the "preload_app false" case)
# when doing a transparent upgrade. The last worker spawned
# will then kill off the old master process with a SIGQUIT.
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
# Throttle the master from forking too quickly by sleeping. Due
# to the implementation of standard Unix signal handlers, this
# helps (but does not completely) prevent identical, repeated signals
# from being lost when the receiving process is busy.
# sleep 1
end
after_fork do |server, worker|
# per-process listener ports for debugging/admin/migrations
# addr = "127.0.0.1:#{9293 + worker.nr}"
# server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)
# the following is *required* for Rails + "preload_app true",
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
# reset prometheus client, this will cause any opened metrics files to be closed
defined?(::Prometheus::Client.reinitialize_on_pid_change) &&
Prometheus::Client.reinitialize_on_pid_change
# if preload_app is true, then you may also want to check and
# restart any other shared sockets/descriptors such as Memcached,
# and Redis. TokyoCabinet file handles are safe to reuse
# between any number of forked children (assuming your kernel
# correctly implements pread()/pwrite() system calls)
end

View file

@ -142,7 +142,7 @@ let
gitlabEnv = { gitlabEnv = {
HOME = "${cfg.statePath}/home"; HOME = "${cfg.statePath}/home";
UNICORN_PATH = "${cfg.statePath}/"; PUMA_PATH = "${cfg.statePath}/";
GITLAB_PATH = "${cfg.packages.gitlab}/share/gitlab/"; GITLAB_PATH = "${cfg.packages.gitlab}/share/gitlab/";
SCHEMA = "${cfg.statePath}/db/structure.sql"; SCHEMA = "${cfg.statePath}/db/structure.sql";
GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads"; GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads";
@ -424,7 +424,7 @@ in {
port = mkOption { port = mkOption {
type = types.int; type = types.int;
default = 465; default = 25;
description = "Port of the SMTP server for Gitlab."; description = "Port of the SMTP server for Gitlab.";
}; };
@ -641,6 +641,11 @@ in {
environment.systemPackages = [ pkgs.git gitlab-rake gitlab-rails cfg.packages.gitlab-shell ]; environment.systemPackages = [ pkgs.git gitlab-rake gitlab-rails cfg.packages.gitlab-shell ];
systemd.targets.gitlab = {
description = "Common target for all GitLab services.";
wantedBy = [ "multi-user.target" ];
};
# 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;
@ -655,36 +660,45 @@ in {
# here. # here.
systemd.services.gitlab-postgresql = let pgsql = config.services.postgresql; in mkIf databaseActuallyCreateLocally { systemd.services.gitlab-postgresql = let pgsql = config.services.postgresql; in mkIf databaseActuallyCreateLocally {
after = [ "postgresql.service" ]; after = [ "postgresql.service" ];
wantedBy = [ "multi-user.target" ]; bindsTo = [ "postgresql.service" ];
path = [ pgsql.package ]; wantedBy = [ "gitlab.target" ];
partOf = [ "gitlab.target" ];
path = [
pgsql.package
pkgs.util-linux
];
script = '' script = ''
set -eu set -eu
PSQL="${pkgs.util-linux}/bin/runuser -u ${pgsql.superUser} -- psql --port=${toString pgsql.port}" PSQL() {
psql --port=${toString pgsql.port} "$@"
}
$PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${cfg.databaseName}'" | grep -q 1 || $PSQL -tAc 'CREATE DATABASE "${cfg.databaseName}" OWNER "${cfg.databaseUsername}"' 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}'") 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 if [[ "$current_owner" != "${cfg.databaseUsername}" ]]; then
$PSQL -tAc 'ALTER DATABASE "${cfg.databaseName}" OWNER TO "${cfg.databaseUsername}"' PSQL -tAc 'ALTER DATABASE "${cfg.databaseName}" OWNER TO "${cfg.databaseUsername}"'
if [[ -e "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}" ]]; then 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..." echo "Reassigning ownership of database ${cfg.databaseName} to user ${cfg.databaseUsername} failed on last boot. Failing..."
exit 1 exit 1
fi fi
touch "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}" touch "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}"
$PSQL "${cfg.databaseName}" -tAc "REASSIGN OWNED BY \"$current_owner\" TO \"${cfg.databaseUsername}\"" PSQL "${cfg.databaseName}" -tAc "REASSIGN OWNED BY \"$current_owner\" TO \"${cfg.databaseUsername}\""
rm "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}" rm "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}"
fi fi
$PSQL '${cfg.databaseName}' -tAc "CREATE EXTENSION IF NOT EXISTS pg_trgm" PSQL '${cfg.databaseName}' -tAc "CREATE EXTENSION IF NOT EXISTS pg_trgm"
$PSQL '${cfg.databaseName}' -tAc "CREATE EXTENSION IF NOT EXISTS btree_gist;" PSQL '${cfg.databaseName}' -tAc "CREATE EXTENSION IF NOT EXISTS btree_gist;"
''; '';
serviceConfig = { serviceConfig = {
User = pgsql.superUser;
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true;
}; };
}; };
# Use postfix to send out mails. # Use postfix to send out mails.
services.postfix.enable = mkDefault true; services.postfix.enable = mkDefault (cfg.smtp.enable && cfg.smtp.address == "localhost");
users.users.${cfg.user} = users.users.${cfg.user} =
{ group = cfg.group; { group = cfg.group;
@ -703,7 +717,6 @@ in {
"d ${cfg.statePath} 0750 ${cfg.user} ${cfg.group} -" "d ${cfg.statePath} 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/builds 0750 ${cfg.user} ${cfg.group} -" "d ${cfg.statePath}/builds 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/config 0750 ${cfg.user} ${cfg.group} -" "d ${cfg.statePath}/config 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/config/initializers 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/db 0750 ${cfg.user} ${cfg.group} -" "d ${cfg.statePath}/db 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/log 0750 ${cfg.user} ${cfg.group} -" "d ${cfg.statePath}/log 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/repositories 2770 ${cfg.user} ${cfg.group} -" "d ${cfg.statePath}/repositories 2770 ${cfg.user} ${cfg.group} -"
@ -726,13 +739,156 @@ in {
"L+ /run/gitlab/uploads - - - - ${cfg.statePath}/uploads" "L+ /run/gitlab/uploads - - - - ${cfg.statePath}/uploads"
"L+ /run/gitlab/shell-config.yml - - - - ${pkgs.writeText "config.yml" (builtins.toJSON gitlabShellConfig)}" "L+ /run/gitlab/shell-config.yml - - - - ${pkgs.writeText "config.yml" (builtins.toJSON gitlabShellConfig)}"
"L+ ${cfg.statePath}/config/unicorn.rb - - - - ${./defaultUnicornConfig.rb}"
]; ];
systemd.services.gitlab-config = {
wantedBy = [ "gitlab.target" ];
partOf = [ "gitlab.target" ];
path = with pkgs; [
jq
openssl
replace
git
];
serviceConfig = {
Type = "oneshot";
User = cfg.user;
Group = cfg.group;
TimeoutSec = "infinity";
Restart = "on-failure";
WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab";
RemainAfterExit = true;
ExecStartPre = let
preStartFullPrivileges = ''
shopt -s dotglob nullglob
set -eu
chown --no-dereference '${cfg.user}':'${cfg.group}' '${cfg.statePath}'/*
if [[ -n "$(ls -A '${cfg.statePath}'/config/)" ]]; then
chown --no-dereference '${cfg.user}':'${cfg.group}' '${cfg.statePath}'/config/*
fi
'';
in "+${pkgs.writeShellScript "gitlab-pre-start-full-privileges" preStartFullPrivileges}";
ExecStart = pkgs.writeShellScript "gitlab-config" ''
set -eu
umask u=rwx,g=rx,o=
cp -f ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION
rm -rf ${cfg.statePath}/db/*
rm -f ${cfg.statePath}/lib
find '${cfg.statePath}/config/' -maxdepth 1 -mindepth 1 -type d -execdir rm -rf {} \;
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
ln -sf ${extraGitlabRb} ${cfg.statePath}/config/initializers/extra-gitlab.rb
${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}')
replace-literal -e '@smtpPassword@' "$smtp_password" '${cfg.statePath}/config/initializers/smtp_settings.rb'
''}
''}
(
umask u=rwx,g=,o=
openssl rand -hex 32 > ${cfg.statePath}/gitlab_shell_secret
rm -f '${cfg.statePath}/config/database.yml'
${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
jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \
'.production.password = $ENV.db_password' \
>'${cfg.statePath}/config/database.yml'
''
else ''
jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \
>'${cfg.statePath}/config/database.yml'
''
}
${utils.genJqSecretsReplacementSnippet
gitlabConfig
"${cfg.statePath}/config/gitlab.yml"
}
rm -f '${cfg.statePath}/config/secrets.yml'
export secret="$(<'${cfg.secrets.secretFile}')"
export db="$(<'${cfg.secrets.dbFile}')"
export otp="$(<'${cfg.secrets.otpFile}')"
export jws="$(<'${cfg.secrets.jwsFile}')"
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'
)
# We remove potentially broken links to old gitlab-shell versions
rm -Rf ${cfg.statePath}/repositories/**/*.git/hooks
git config --global core.autocrlf "input"
'';
};
};
systemd.services.gitlab-db-config = {
after = [ "gitlab-config.service" "gitlab-postgresql.service" "postgresql.service" ];
bindsTo = [
"gitlab-config.service"
] ++ optional (cfg.databaseHost == "") "postgresql.service"
++ optional databaseActuallyCreateLocally "gitlab-postgresql.service";
wantedBy = [ "gitlab.target" ];
partOf = [ "gitlab.target" ];
serviceConfig = {
Type = "oneshot";
User = cfg.user;
Group = cfg.group;
TimeoutSec = "infinity";
Restart = "on-failure";
WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab";
RemainAfterExit = true;
ExecStart = pkgs.writeShellScript "gitlab-db-config" ''
set -eu
umask u=rwx,g=rx,o=
initial_root_password="$(<'${cfg.initialRootPasswordFile}')"
${gitlab-rake}/bin/gitlab-rake gitlab:db:configure GITLAB_ROOT_PASSWORD="$initial_root_password" \
GITLAB_ROOT_EMAIL='${cfg.initialRootEmail}' > /dev/null
'';
};
};
systemd.services.gitlab-sidekiq = { systemd.services.gitlab-sidekiq = {
after = [ "network.target" "redis.service" "gitlab.service" ]; after = [
wantedBy = [ "multi-user.target" ]; "network.target"
"redis.service"
"postgresql.service"
"gitlab-config.service"
"gitlab-db-config.service"
];
bindsTo = [
"redis.service"
"gitlab-config.service"
"gitlab-db-config.service"
] ++ optional (cfg.databaseHost == "") "postgresql.service";
wantedBy = [ "gitlab.target" ];
partOf = [ "gitlab.target" ];
environment = gitlabEnv; environment = gitlabEnv;
path = with pkgs; [ path = with pkgs; [
postgresqlPackage postgresqlPackage
@ -758,9 +914,10 @@ in {
}; };
systemd.services.gitaly = { systemd.services.gitaly = {
after = [ "network.target" "gitlab.service" ]; after = [ "network.target" "gitlab-config.service" ];
bindsTo = [ "gitlab.service" ]; bindsTo = [ "gitlab-config.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "gitlab.target" ];
partOf = [ "gitlab.target" ];
path = with pkgs; [ path = with pkgs; [
openssh openssh
procps # See https://gitlab.com/gitlab-org/gitaly/issues/1562 procps # See https://gitlab.com/gitlab-org/gitaly/issues/1562
@ -783,8 +940,10 @@ in {
systemd.services.gitlab-pages = mkIf (gitlabConfig.production.pages.enabled or false) { systemd.services.gitlab-pages = mkIf (gitlabConfig.production.pages.enabled or false) {
description = "GitLab static pages daemon"; description = "GitLab static pages daemon";
after = [ "network.target" "redis.service" "gitlab.service" ]; # gitlab.service creates configs after = [ "network.target" "gitlab-config.service" ];
wantedBy = [ "multi-user.target" ]; bindsTo = [ "gitlab-config.service" ];
wantedBy = [ "gitlab.target" ];
partOf = [ "gitlab.target" ];
path = [ pkgs.unzip ]; path = [ pkgs.unzip ];
@ -803,7 +962,8 @@ in {
systemd.services.gitlab-workhorse = { systemd.services.gitlab-workhorse = {
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "gitlab.target" ];
partOf = [ "gitlab.target" ];
path = with pkgs; [ path = with pkgs; [
exiftool exiftool
git git
@ -832,8 +992,10 @@ in {
systemd.services.gitlab-mailroom = mkIf (gitlabConfig.production.incoming_email.enabled or false) { systemd.services.gitlab-mailroom = mkIf (gitlabConfig.production.incoming_email.enabled or false) {
description = "GitLab incoming mail daemon"; description = "GitLab incoming mail daemon";
after = [ "network.target" "redis.service" "gitlab.service" ]; # gitlab.service creates configs after = [ "network.target" "redis.service" "gitlab-config.service" ];
wantedBy = [ "multi-user.target" ]; bindsTo = [ "gitlab-config.service" ];
wantedBy = [ "gitlab.target" ];
partOf = [ "gitlab.target" ];
environment = gitlabEnv; environment = gitlabEnv;
serviceConfig = { serviceConfig = {
Type = "simple"; Type = "simple";
@ -842,15 +1004,26 @@ in {
User = cfg.user; User = cfg.user;
Group = cfg.group; Group = cfg.group;
ExecStart = "${cfg.packages.gitlab.rubyEnv}/bin/bundle exec mail_room -c ${cfg.packages.gitlab}/share/gitlab/config.dist/mail_room.yml"; ExecStart = "${cfg.packages.gitlab.rubyEnv}/bin/bundle exec mail_room -c ${cfg.statePath}/config/mail_room.yml";
WorkingDirectory = gitlabEnv.HOME; WorkingDirectory = gitlabEnv.HOME;
}; };
}; };
systemd.services.gitlab = { systemd.services.gitlab = {
after = [ "gitlab-workhorse.service" "network.target" "gitlab-postgresql.service" "redis.service" ]; after = [
requires = [ "gitlab-sidekiq.service" ]; "gitlab-workhorse.service"
wantedBy = [ "multi-user.target" ]; "network.target"
"redis.service"
"gitlab-config.service"
"gitlab-db-config.service"
];
bindsTo = [
"redis.service"
"gitlab-config.service"
"gitlab-db-config.service"
] ++ optional (cfg.databaseHost == "") "postgresql.service";
wantedBy = [ "gitlab.target" ];
partOf = [ "gitlab.target" ];
environment = gitlabEnv; environment = gitlabEnv;
path = with pkgs; [ path = with pkgs; [
postgresqlPackage postgresqlPackage
@ -868,96 +1041,7 @@ in {
TimeoutSec = "infinity"; TimeoutSec = "infinity";
Restart = "on-failure"; Restart = "on-failure";
WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab"; WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab";
ExecStartPre = let ExecStart = "${cfg.packages.gitlab.rubyEnv}/bin/puma -C ${cfg.statePath}/config/puma.rb -e production";
preStartFullPrivileges = ''
shopt -s dotglob nullglob
set -eu
chown --no-dereference '${cfg.user}':'${cfg.group}' '${cfg.statePath}'/*
chown --no-dereference '${cfg.user}':'${cfg.group}' '${cfg.statePath}'/config/*
'';
preStart = ''
set -eu
cp -f ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION
rm -rf ${cfg.statePath}/db/*
rm -rf ${cfg.statePath}/config/initializers/*
rm -f ${cfg.statePath}/lib
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
ln -sf ${extraGitlabRb} ${cfg.statePath}/config/initializers/extra-gitlab.rb
${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}' > /dev/null
# 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";
}; };
}; };

View file

@ -11,6 +11,8 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; {
nodes = { nodes = {
gitlab = { ... }: { gitlab = { ... }: {
imports = [ common/user-account.nix ];
virtualisation.memorySize = if pkgs.stdenv.is64bit then 4096 else 2047; virtualisation.memorySize = if pkgs.stdenv.is64bit then 4096 else 2047;
systemd.services.gitlab.serviceConfig.Restart = mkForce "no"; systemd.services.gitlab.serviceConfig.Restart = mkForce "no";
systemd.services.gitlab-workhorse.serviceConfig.Restart = mkForce "no"; systemd.services.gitlab-workhorse.serviceConfig.Restart = mkForce "no";
@ -27,11 +29,31 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; {
}; };
}; };
services.dovecot2 = {
enable = true;
enableImap = true;
};
services.gitlab = { services.gitlab = {
enable = true; enable = true;
databasePasswordFile = pkgs.writeText "dbPassword" "xo0daiF4"; databasePasswordFile = pkgs.writeText "dbPassword" "xo0daiF4";
initialRootPasswordFile = pkgs.writeText "rootPassword" initialRootPassword; initialRootPasswordFile = pkgs.writeText "rootPassword" initialRootPassword;
smtp.enable = true; smtp.enable = true;
extraConfig = {
incoming_email = {
enabled = true;
mailbox = "inbox";
address = "alice@localhost";
user = "alice";
password = "foobar";
host = "localhost";
port = 143;
};
pages = {
enabled = true;
host = "localhost";
};
};
secrets = { secrets = {
secretFile = pkgs.writeText "secret" "r8X9keSKynU7p4aKlh4GO1Bo77g5a7vj"; secretFile = pkgs.writeText "secret" "r8X9keSKynU7p4aKlh4GO1Bo77g5a7vj";
otpFile = pkgs.writeText "otpsecret" "Zu5hGx3YvQx40DvI8WoZJQpX2paSDOlG"; otpFile = pkgs.writeText "otpsecret" "Zu5hGx3YvQx40DvI8WoZJQpX2paSDOlG";
@ -64,12 +86,16 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; {
in in
'' ''
gitlab.start() gitlab.start()
gitlab.wait_for_unit("gitaly.service") gitlab.wait_for_unit("gitaly.service")
gitlab.wait_for_unit("gitlab-workhorse.service") gitlab.wait_for_unit("gitlab-workhorse.service")
gitlab.wait_for_unit("gitlab-pages.service")
gitlab.wait_for_unit("gitlab-mailroom.service")
gitlab.wait_for_unit("gitlab.service") gitlab.wait_for_unit("gitlab.service")
gitlab.wait_for_unit("gitlab-sidekiq.service") gitlab.wait_for_unit("gitlab-sidekiq.service")
gitlab.wait_for_file("/var/gitlab/state/tmp/sockets/gitlab.socket") gitlab.wait_for_file("/var/gitlab/state/tmp/sockets/gitlab.socket")
gitlab.wait_until_succeeds("curl -sSf http://gitlab/users/sign_in") gitlab.wait_until_succeeds("curl -sSf http://gitlab/users/sign_in")
gitlab.succeed( gitlab.succeed(
"curl -isSf http://gitlab | grep -i location | grep -q http://gitlab/users/sign_in" "curl -isSf http://gitlab | grep -i location | grep -q http://gitlab/users/sign_in"
) )

View file

@ -137,6 +137,7 @@ stdenv.mkDerivation {
sed -i '/ask_to_continue/d' lib/tasks/gitlab/two_factor.rake sed -i '/ask_to_continue/d' lib/tasks/gitlab/two_factor.rake
sed -ri -e '/log_level/a config.logger = Logger.new(STDERR)' config/environments/production.rb sed -ri -e '/log_level/a config.logger = Logger.new(STDERR)' config/environments/production.rb
mv config/puma.rb.example config/puma.rb
# Always require lib-files and application.rb through their store # Always require lib-files and application.rb through their store
# path, not their relative state directory path. This gets rid of # path, not their relative state directory path. This gets rid of
# warnings and means we don't have to link back to lib from the # warnings and means we don't have to link back to lib from the

View file

@ -1,8 +1,8 @@
diff --git a/config/environments/production.rb b/config/environments/production.rb diff --git a/config/environments/production.rb b/config/environments/production.rb
index c5cbfcf64c..4d01f6fab8 100644 index d9b3ee354b0..1eb0507488b 100644
--- a/config/environments/production.rb --- a/config/environments/production.rb
+++ b/config/environments/production.rb +++ b/config/environments/production.rb
@@ -70,10 +70,10 @@ Rails.application.configure do @@ -69,10 +69,10 @@
config.action_mailer.delivery_method = :sendmail config.action_mailer.delivery_method = :sendmail
# Defaults to: # Defaults to:
@ -11,17 +11,17 @@ index c5cbfcf64c..4d01f6fab8 100644
- # # arguments: '-i -t' - # # arguments: '-i -t'
- # # } - # # }
+ config.action_mailer.sendmail_settings = { + config.action_mailer.sendmail_settings = {
+ location: '/usr/sbin/sendmail', + location: '/run/wrappers/bin/sendmail',
+ arguments: '-i -t' + arguments: '-i -t'
+ } + }
config.action_mailer.perform_deliveries = true config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true config.action_mailer.raise_delivery_errors = true
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index bd696a7f2c..44e3863736 100644 index 92e7501d49d..4ee5a1127df 100644
--- a/config/gitlab.yml.example --- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example +++ b/config/gitlab.yml.example
@@ -590,7 +590,7 @@ production: &base @@ -1168,7 +1168,7 @@ production: &base
# CAUTION! # CAUTION!
# Use the default values unless you really know what you are doing # Use the default values unless you really know what you are doing
git: git:
@ -31,10 +31,10 @@ index bd696a7f2c..44e3863736 100644
## Webpack settings ## Webpack settings
# If enabled, this will tell rails to serve frontend assets from the webpack-dev-server running # If enabled, this will tell rails to serve frontend assets from the webpack-dev-server running
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 0bea8a4f4b..290248547b 100644 index bbed08f5044..2906e5c44af 100644
--- a/config/initializers/1_settings.rb --- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb
@@ -177,7 +177,7 @@ Settings.gitlab['ssh_user'] ||= Settings.gitlab['user'] @@ -183,7 +183,7 @@
Settings.gitlab['user_home'] ||= begin Settings.gitlab['user_home'] ||= begin
Etc.getpwnam(Settings.gitlab['user']).dir Etc.getpwnam(Settings.gitlab['user']).dir
rescue ArgumentError # no user configured rescue ArgumentError # no user configured
@ -43,7 +43,7 @@ index 0bea8a4f4b..290248547b 100644
end end
Settings.gitlab['time_zone'] ||= nil Settings.gitlab['time_zone'] ||= nil
Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil? Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil?
@@ -507,7 +507,7 @@ Settings.backup['upload']['storage_class'] ||= nil @@ -751,7 +751,7 @@
# Git # Git
# #
Settings['git'] ||= Settingslogic.new({}) Settings['git'] ||= Settingslogic.new({})
@ -52,37 +52,94 @@ index 0bea8a4f4b..290248547b 100644
# Important: keep the satellites.path setting until GitLab 9.0 at # Important: keep the satellites.path setting until GitLab 9.0 at
# least. This setting is fed to 'rm -rf' in # least. This setting is fed to 'rm -rf' in
diff --git a/config/puma.rb.example b/config/puma.rb.example
index 9fc354a8fe8..2352ca9b58c 100644
--- a/config/puma.rb.example
+++ b/config/puma.rb.example
@@ -5,12 +5,8 @@
# The default is "config.ru".
#
rackup 'config.ru'
-pidfile '/home/git/gitlab/tmp/pids/puma.pid'
-state_path '/home/git/gitlab/tmp/pids/puma.state'
-
-stdout_redirect '/home/git/gitlab/log/puma.stdout.log',
- '/home/git/gitlab/log/puma.stderr.log',
- true
+pidfile ENV['PUMA_PATH'] + '/tmp/pids/puma.pid'
+state_path ENV['PUMA_PATH'] + '/tmp/pids/puma.state'
# Configure "min" to be the minimum number of threads to use to answer
# requests and "max" the maximum.
@@ -31,12 +27,12 @@ queue_requests false
# Bind the server to "url". "tcp://", "unix://" and "ssl://" are the only
# accepted protocols.
-bind 'unix:///home/git/gitlab/tmp/sockets/gitlab.socket'
+bind "unix://#{ENV['PUMA_PATH']}/tmp/sockets/gitlab.socket"
workers 3
-require_relative "/home/git/gitlab/lib/gitlab/cluster/lifecycle_events"
-require_relative "/home/git/gitlab/lib/gitlab/cluster/puma_worker_killer_initializer"
+require_relative ENV['GITLAB_PATH'] + "lib/gitlab/cluster/lifecycle_events"
+require_relative ENV['GITLAB_PATH'] + "lib/gitlab/cluster/puma_worker_killer_initializer"
on_restart do
# Signal application hooks that we're about to restart
@@ -80,7 +76,7 @@ if defined?(nakayoshi_fork)
end
# Use json formatter
-require_relative "/home/git/gitlab/lib/gitlab/puma_logging/json_formatter"
+require_relative ENV['GITLAB_PATH'] + "lib/gitlab/puma_logging/json_formatter"
json_formatter = Gitlab::PumaLogging::JSONFormatter.new
log_formatter do |str|
diff --git a/lib/api/api.rb b/lib/api/api.rb diff --git a/lib/api/api.rb b/lib/api/api.rb
index e953f3d2ec..3a8d9f076b 100644 index ada0da28749..8a3f5824008 100644
--- a/lib/api/api.rb --- a/lib/api/api.rb
+++ b/lib/api/api.rb +++ b/lib/api/api.rb
@@ -2,7 +2,7 @@ module API @@ -4,7 +4,7 @@ module API
class API < Grape::API class API < ::API::Base
include APIGuard include APIGuard
- LOG_FILENAME = Rails.root.join("log", "api_json.log") - LOG_FILENAME = Rails.root.join("log", "api_json.log")
+ LOG_FILENAME = File.join(ENV["GITLAB_LOG_PATH"], "api_json.log") + LOG_FILENAME = File.join(ENV["GITLAB_LOG_PATH"], "api_json.log")
NO_SLASH_URL_PART_REGEX = %r{[^/]+} NO_SLASH_URL_PART_REGEX = %r{[^/]+}.freeze
PROJECT_ENDPOINT_REQUIREMENTS = { id: NO_SLASH_URL_PART_REGEX }.freeze NAMESPACE_OR_PROJECT_REQUIREMENTS = { id: NO_SLASH_URL_PART_REGEX }.freeze
diff --git a/lib/gitlab/authorized_keys.rb b/lib/gitlab/authorized_keys.rb
index 50cd15b7a10..3ac89e5b8e9 100644
--- a/lib/gitlab/authorized_keys.rb
+++ b/lib/gitlab/authorized_keys.rb
@@ -157,7 +157,7 @@ def command(id)
raise KeyError, "Invalid ID: #{id.inspect}"
end
- "#{File.join(Gitlab.config.gitlab_shell.path, 'bin', 'gitlab-shell')} #{id}"
+ "#{File.join('/run/current-system/sw/bin', 'gitlab-shell')} #{id}"
end
def strip(key)
diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb
index a42e312b5d..ccaab9229e 100644 index 89a4e36a232..ae379ffb27a 100644
--- a/lib/gitlab/logger.rb --- a/lib/gitlab/logger.rb
+++ b/lib/gitlab/logger.rb +++ b/lib/gitlab/logger.rb
@@ -26,7 +26,7 @@ module Gitlab @@ -37,7 +37,7 @@ def self.build
end end
def self.full_log_path def self.full_log_path
- Rails.root.join("log", file_name) - Rails.root.join("log", file_name)
+ File.join(ENV["GITLAB_LOG_PATH"], file_name) + File.join(ENV["GITLAB_LOG_PATH"], file_name)
end end
def self.cache_key def self.cache_key
diff --git a/lib/gitlab/uploads_transfer.rb b/lib/gitlab/uploads_transfer.rb diff --git a/lib/gitlab/uploads_transfer.rb b/lib/gitlab/uploads_transfer.rb
index 7d7400bdab..cb25211d44 100644 index e0e7084e27e..19fab855b90 100644
--- a/lib/gitlab/uploads_transfer.rb --- a/lib/gitlab/uploads_transfer.rb
+++ b/lib/gitlab/uploads_transfer.rb +++ b/lib/gitlab/uploads_transfer.rb
@@ -1,7 +1,7 @@ @@ -3,7 +3,7 @@
module Gitlab module Gitlab
class UploadsTransfer < ProjectTransfer class UploadsTransfer < ProjectTransfer
def root_dir def root_dir
@ -92,10 +149,10 @@ index 7d7400bdab..cb25211d44 100644
end end
end end
diff --git a/lib/system_check/app/log_writable_check.rb b/lib/system_check/app/log_writable_check.rb diff --git a/lib/system_check/app/log_writable_check.rb b/lib/system_check/app/log_writable_check.rb
index 3e0c436d6e..28cefc5514 100644 index 2c108f0c18d..3a16ff52d01 100644
--- a/lib/system_check/app/log_writable_check.rb --- a/lib/system_check/app/log_writable_check.rb
+++ b/lib/system_check/app/log_writable_check.rb +++ b/lib/system_check/app/log_writable_check.rb
@@ -21,7 +21,7 @@ module SystemCheck @@ -23,7 +23,7 @@ def show_error
private private
def log_path def log_path
@ -105,10 +162,10 @@ index 3e0c436d6e..28cefc5514 100644
end end
end end
diff --git a/lib/system_check/app/uploads_directory_exists_check.rb b/lib/system_check/app/uploads_directory_exists_check.rb diff --git a/lib/system_check/app/uploads_directory_exists_check.rb b/lib/system_check/app/uploads_directory_exists_check.rb
index 7026d0ba07..c56e1f7ed9 100644 index 54dff63ab61..882da702f29 100644
--- a/lib/system_check/app/uploads_directory_exists_check.rb --- a/lib/system_check/app/uploads_directory_exists_check.rb
+++ b/lib/system_check/app/uploads_directory_exists_check.rb +++ b/lib/system_check/app/uploads_directory_exists_check.rb
@@ -4,12 +4,13 @@ module SystemCheck @@ -6,12 +6,13 @@ class UploadsDirectoryExistsCheck < SystemCheck::BaseCheck
set_name 'Uploads directory exists?' set_name 'Uploads directory exists?'
def check? def check?
@ -120,15 +177,15 @@ index 7026d0ba07..c56e1f7ed9 100644
+ uploads_dir = ENV['GITLAB_UPLOADS_PATH'] || Rails.root.join('public/uploads') + uploads_dir = ENV['GITLAB_UPLOADS_PATH'] || Rails.root.join('public/uploads')
try_fixing_it( try_fixing_it(
- "sudo -u #{gitlab_user} mkdir #{Rails.root}/public/uploads" - "sudo -u #{gitlab_user} mkdir #{Rails.root}/public/uploads"
+ "sudo -u #{gitlab_user} mkdir #{uploads_dir}" + "sudo -u #{gitlab_user} mkdir #{uploads_dir}"
) )
for_more_information( for_more_information(
see_installation_guide_section 'GitLab' see_installation_guide_section('GitLab')
diff --git a/lib/system_check/app/uploads_path_permission_check.rb b/lib/system_check/app/uploads_path_permission_check.rb diff --git a/lib/system_check/app/uploads_path_permission_check.rb b/lib/system_check/app/uploads_path_permission_check.rb
index 7df6c06025..bb447c16b2 100644 index 2e1cc687c43..ca69d63bcf6 100644
--- a/lib/system_check/app/uploads_path_permission_check.rb --- a/lib/system_check/app/uploads_path_permission_check.rb
+++ b/lib/system_check/app/uploads_path_permission_check.rb +++ b/lib/system_check/app/uploads_path_permission_check.rb
@@ -25,7 +25,7 @@ module SystemCheck @@ -27,7 +27,7 @@ def show_error
private private
def rails_uploads_path def rails_uploads_path
@ -138,10 +195,10 @@ index 7df6c06025..bb447c16b2 100644
def uploads_fullpath def uploads_fullpath
diff --git a/lib/system_check/app/uploads_path_tmp_permission_check.rb b/lib/system_check/app/uploads_path_tmp_permission_check.rb diff --git a/lib/system_check/app/uploads_path_tmp_permission_check.rb b/lib/system_check/app/uploads_path_tmp_permission_check.rb
index b276a81eac..070e3ebd81 100644 index 567c7540777..29906b1c132 100644
--- a/lib/system_check/app/uploads_path_tmp_permission_check.rb --- a/lib/system_check/app/uploads_path_tmp_permission_check.rb
+++ b/lib/system_check/app/uploads_path_tmp_permission_check.rb +++ b/lib/system_check/app/uploads_path_tmp_permission_check.rb
@@ -33,7 +33,7 @@ module SystemCheck @@ -35,7 +35,7 @@ def upload_path_tmp
end end
def uploads_fullpath def uploads_fullpath
@ -150,14 +207,3 @@ index b276a81eac..070e3ebd81 100644
end end
end end
end end
--- a/lib/gitlab/authorized_keys.rb
+++ b/lib/gitlab/authorized_keys.rb
@@ -157,7 +157,7 @@
raise KeyError, "Invalid ID: #{id.inspect}"
end
- "#{File.join(Gitlab.config.gitlab_shell.path, 'bin', 'gitlab-shell')} #{id}"
+ "#{File.join('/run/current-system/sw/bin', 'gitlab-shell')} #{id}"
end
def strip(key)