diff --git a/nixos/modules/services/misc/gitolite.nix b/nixos/modules/services/misc/gitolite.nix
index 60fc9d58ed07..d803a4e0bf12 100644
--- a/nixos/modules/services/misc/gitolite.nix
+++ b/nixos/modules/services/misc/gitolite.nix
@@ -49,6 +49,35 @@ in
'';
};
+ extraGitoliteRc = mkOption {
+ type = types.lines;
+ default = "";
+ example = literalExample ''
+ $RC{UMASK} = 0027;
+ $RC{SITE_INFO} = 'This is our private repository host';
+ push( @{$RC{ENABLE}}, 'Kindergarten' ); # enable the command/feature
+ @{$RC{ENABLE}} = grep { $_ ne 'desc' } @{$RC{ENABLE}}; # disable the command/feature
+ '';
+ description = ''
+ Extra configuration to append to the default ~/.gitolite.rc.
+
+ This should be Perl code that modifies the %RC
+ configuration variable. The default ~/.gitolite.rc
+ content is generated by invoking gitolite print-default-rc,
+ and extra configuration from this option is appended to it. The result
+ is placed to Nix store, and the ~/.gitolite.rc file
+ becomes a symlink to it.
+
+ If you already have a customized (or otherwise changed)
+ ~/.gitolite.rc file, NixOS will refuse to replace
+ it with a symlink, and the `gitolite-init` initialization service
+ will fail. In this situation, in order to use this option, you
+ will need to take any customizations you may have in
+ ~/.gitolite.rc, convert them to appropriate Perl
+ statements, add them to this option, and remove the file.
+ '';
+ };
+
user = mkOption {
type = types.str;
default = "gitolite";
@@ -59,7 +88,34 @@ in
};
};
- config = mkIf cfg.enable {
+ config = mkIf cfg.enable (
+ let
+ manageGitoliteRc = cfg.extraGitoliteRc != "";
+ rcDir = pkgs.runCommand "gitolite-rc" { } rcDirScript;
+ rcDirScript =
+ ''
+ mkdir "$out"
+ export HOME=temp-home
+ mkdir -p "$HOME/.gitolite/logs" # gitolite can't run without it
+ '${pkgs.gitolite}'/bin/gitolite print-default-rc >>"$out/gitolite.rc.default"
+ cat <>"$out/gitolite.rc"
+ # This file is managed by NixOS.
+ # Use services.gitolite options to control it.
+
+ END
+ cat "$out/gitolite.rc.default" >>"$out/gitolite.rc"
+ '' +
+ optionalString (cfg.extraGitoliteRc != "") ''
+ echo -n ${escapeShellArg ''
+
+ # Added by NixOS:
+ ${removeSuffix "\n" cfg.extraGitoliteRc}
+
+ # per perl rules, this should be the last line in such a file:
+ 1;
+ ''} >>"$out/gitolite.rc"
+ '';
+ in {
users.extraUsers.${cfg.user} = {
description = "Gitolite user";
home = cfg.dataDir;
@@ -77,21 +133,61 @@ in
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
- path = [ pkgs.gitolite pkgs.git pkgs.perl pkgs.bash config.programs.ssh.package ];
- script = ''
- cd ${cfg.dataDir}
- mkdir -p .gitolite/logs
- if [ ! -d repositories ]; then
- gitolite setup -pk ${pubkeyFile}
- fi
- if [ -n "${hooks}" ]; then
- cp ${hooks} .gitolite/hooks/common/
- chmod +x .gitolite/hooks/common/*
- fi
- gitolite setup # Upgrade if needed
- '';
+ path = [ pkgs.gitolite pkgs.git pkgs.perl pkgs.bash pkgs.diffutils config.programs.ssh.package ];
+ script =
+ let
+ rcSetupScriptIfCustomFile =
+ if manageGitoliteRc then ''
+ cat <ERROR: NixOS can't apply declarative configuration
+ <3>to your .gitolite.rc file, because it seems to be
+ <3>already customized manually.
+ <3>See the services.gitolite.extraGitoliteRc option
+ <3>in "man configuration.nix" for more information.
+ END
+ # Not sure if the line below addresses the issue directly or just
+ # adds a delay, but without it our error message often doesn't
+ # show up in `systemctl status gitolite-init`.
+ journalctl --flush
+ exit 1
+ '' else ''
+ :
+ '';
+ rcSetupScriptIfDefaultFileOrStoreSymlink =
+ if manageGitoliteRc then ''
+ ln -sf "${rcDir}/gitolite.rc" "$GITOLITE_RC"
+ '' else ''
+ [[ -L "$GITOLITE_RC" ]] && rm -f "$GITOLITE_RC"
+ '';
+ in
+ ''
+ cd ${cfg.dataDir}
+ mkdir -p .gitolite/logs
+
+ GITOLITE_RC=.gitolite.rc
+ GITOLITE_RC_DEFAULT=${rcDir}/gitolite.rc.default
+ if ( [[ ! -e "$GITOLITE_RC" ]] && [[ ! -L "$GITOLITE_RC" ]] ) ||
+ ( [[ -f "$GITOLITE_RC" ]] && diff -q "$GITOLITE_RC" "$GITOLITE_RC_DEFAULT" >/dev/null ) ||
+ ( [[ -L "$GITOLITE_RC" ]] && [[ "$(readlink "$GITOLITE_RC")" =~ ^/nix/store/ ]] )
+ then
+ '' + rcSetupScriptIfDefaultFileOrStoreSymlink +
+ ''
+ else
+ '' + rcSetupScriptIfCustomFile +
+ ''
+ fi
+
+ if [ ! -d repositories ]; then
+ gitolite setup -pk ${pubkeyFile}
+ fi
+ if [ -n "${hooks}" ]; then
+ cp ${hooks} .gitolite/hooks/common/
+ chmod +x .gitolite/hooks/common/*
+ fi
+ gitolite setup # Upgrade if needed
+ '';
};
environment.systemPackages = [ pkgs.gitolite pkgs.git ];
- };
+ });
}