the conversion procedure is simple: - find all things that look like options, ie calls to either `mkOption` or `lib.mkOption` that take an attrset. remember the attrset as the option - for all options, find a `description` attribute who's value is not a call to `mdDoc` or `lib.mdDoc` - textually convert the entire value of the attribute to MD with a few simple regexes (the set from mdize-module.sh) - if the change produced a change in the manual output, discard - if the change kept the manual unchanged, add some text to the description to make sure we've actually found an option. if the manual changes this time, keep the converted description this procedure converts 80% of nixos options to markdown. around 2000 options remain to be inspected, but most of those fail the "does not change the manual output check": currently the MD conversion process does not faithfully convert docbook tags like <code> and <package>, so any option using such tags will not be converted at all.
275 lines
7.7 KiB
Nix
275 lines
7.7 KiB
Nix
{ config, lib, options, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.services.gogs;
|
|
opt = options.services.gogs;
|
|
configFile = pkgs.writeText "app.ini" ''
|
|
APP_NAME = ${cfg.appName}
|
|
RUN_USER = ${cfg.user}
|
|
RUN_MODE = prod
|
|
|
|
[database]
|
|
DB_TYPE = ${cfg.database.type}
|
|
HOST = ${cfg.database.host}:${toString cfg.database.port}
|
|
NAME = ${cfg.database.name}
|
|
USER = ${cfg.database.user}
|
|
PASSWD = #dbpass#
|
|
PATH = ${cfg.database.path}
|
|
|
|
[repository]
|
|
ROOT = ${cfg.repositoryRoot}
|
|
|
|
[server]
|
|
DOMAIN = ${cfg.domain}
|
|
HTTP_ADDR = ${cfg.httpAddress}
|
|
HTTP_PORT = ${toString cfg.httpPort}
|
|
ROOT_URL = ${cfg.rootUrl}
|
|
|
|
[session]
|
|
COOKIE_NAME = session
|
|
COOKIE_SECURE = ${boolToString cfg.cookieSecure}
|
|
|
|
[security]
|
|
SECRET_KEY = #secretkey#
|
|
INSTALL_LOCK = true
|
|
|
|
[log]
|
|
ROOT_PATH = ${cfg.stateDir}/log
|
|
|
|
${cfg.extraConfig}
|
|
'';
|
|
in
|
|
|
|
{
|
|
options = {
|
|
services.gogs = {
|
|
enable = mkOption {
|
|
default = false;
|
|
type = types.bool;
|
|
description = lib.mdDoc "Enable Go Git Service.";
|
|
};
|
|
|
|
useWizard = mkOption {
|
|
default = false;
|
|
type = types.bool;
|
|
description = lib.mdDoc "Do not generate a configuration and use Gogs' installation wizard instead. The first registered user will be administrator.";
|
|
};
|
|
|
|
stateDir = mkOption {
|
|
default = "/var/lib/gogs";
|
|
type = types.str;
|
|
description = lib.mdDoc "Gogs data directory.";
|
|
};
|
|
|
|
user = mkOption {
|
|
type = types.str;
|
|
default = "gogs";
|
|
description = lib.mdDoc "User account under which Gogs runs.";
|
|
};
|
|
|
|
group = mkOption {
|
|
type = types.str;
|
|
default = "gogs";
|
|
description = lib.mdDoc "Group account under which Gogs runs.";
|
|
};
|
|
|
|
database = {
|
|
type = mkOption {
|
|
type = types.enum [ "sqlite3" "mysql" "postgres" ];
|
|
example = "mysql";
|
|
default = "sqlite3";
|
|
description = lib.mdDoc "Database engine to use.";
|
|
};
|
|
|
|
host = mkOption {
|
|
type = types.str;
|
|
default = "127.0.0.1";
|
|
description = lib.mdDoc "Database host address.";
|
|
};
|
|
|
|
port = mkOption {
|
|
type = types.int;
|
|
default = 3306;
|
|
description = lib.mdDoc "Database host port.";
|
|
};
|
|
|
|
name = mkOption {
|
|
type = types.str;
|
|
default = "gogs";
|
|
description = lib.mdDoc "Database name.";
|
|
};
|
|
|
|
user = mkOption {
|
|
type = types.str;
|
|
default = "gogs";
|
|
description = lib.mdDoc "Database user.";
|
|
};
|
|
|
|
password = mkOption {
|
|
type = types.str;
|
|
default = "";
|
|
description = lib.mdDoc ''
|
|
The password corresponding to {option}`database.user`.
|
|
Warning: this is stored in cleartext in the Nix store!
|
|
Use {option}`database.passwordFile` instead.
|
|
'';
|
|
};
|
|
|
|
passwordFile = mkOption {
|
|
type = types.nullOr types.path;
|
|
default = null;
|
|
example = "/run/keys/gogs-dbpassword";
|
|
description = lib.mdDoc ''
|
|
A file containing the password corresponding to
|
|
{option}`database.user`.
|
|
'';
|
|
};
|
|
|
|
path = mkOption {
|
|
type = types.str;
|
|
default = "${cfg.stateDir}/data/gogs.db";
|
|
defaultText = literalExpression ''"''${config.${opt.stateDir}}/data/gogs.db"'';
|
|
description = lib.mdDoc "Path to the sqlite3 database file.";
|
|
};
|
|
};
|
|
|
|
appName = mkOption {
|
|
type = types.str;
|
|
default = "Gogs: Go Git Service";
|
|
description = lib.mdDoc "Application name.";
|
|
};
|
|
|
|
repositoryRoot = mkOption {
|
|
type = types.str;
|
|
default = "${cfg.stateDir}/repositories";
|
|
defaultText = literalExpression ''"''${config.${opt.stateDir}}/repositories"'';
|
|
description = lib.mdDoc "Path to the git repositories.";
|
|
};
|
|
|
|
domain = mkOption {
|
|
type = types.str;
|
|
default = "localhost";
|
|
description = lib.mdDoc "Domain name of your server.";
|
|
};
|
|
|
|
rootUrl = mkOption {
|
|
type = types.str;
|
|
default = "http://localhost:3000/";
|
|
description = lib.mdDoc "Full public URL of Gogs server.";
|
|
};
|
|
|
|
httpAddress = mkOption {
|
|
type = types.str;
|
|
default = "0.0.0.0";
|
|
description = lib.mdDoc "HTTP listen address.";
|
|
};
|
|
|
|
httpPort = mkOption {
|
|
type = types.int;
|
|
default = 3000;
|
|
description = lib.mdDoc "HTTP listen port.";
|
|
};
|
|
|
|
cookieSecure = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = lib.mdDoc ''
|
|
Marks session cookies as "secure" as a hint for browsers to only send
|
|
them via HTTPS. This option is recommend, if Gogs is being served over HTTPS.
|
|
'';
|
|
};
|
|
|
|
extraConfig = mkOption {
|
|
type = types.str;
|
|
default = "";
|
|
description = lib.mdDoc "Configuration lines appended to the generated Gogs configuration file.";
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
systemd.services.gogs = {
|
|
description = "Gogs (Go Git Service)";
|
|
after = [ "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
path = [ pkgs.gogs ];
|
|
|
|
preStart = let
|
|
runConfig = "${cfg.stateDir}/custom/conf/app.ini";
|
|
secretKey = "${cfg.stateDir}/custom/conf/secret_key";
|
|
in ''
|
|
mkdir -p ${cfg.stateDir}
|
|
|
|
# copy custom configuration and generate a random secret key if needed
|
|
${optionalString (cfg.useWizard == false) ''
|
|
mkdir -p ${cfg.stateDir}/custom/conf
|
|
cp -f ${configFile} ${runConfig}
|
|
|
|
if [ ! -e ${secretKey} ]; then
|
|
head -c 16 /dev/urandom | base64 > ${secretKey}
|
|
fi
|
|
|
|
KEY=$(head -n1 ${secretKey})
|
|
DBPASS=$(head -n1 ${cfg.database.passwordFile})
|
|
sed -e "s,#secretkey#,$KEY,g" \
|
|
-e "s,#dbpass#,$DBPASS,g" \
|
|
-i ${runConfig}
|
|
chmod 440 ${runConfig} ${secretKey}
|
|
''}
|
|
|
|
mkdir -p ${cfg.repositoryRoot}
|
|
# update all hooks' binary paths
|
|
HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 4 -type f -wholename "*git/hooks/*")
|
|
if [ "$HOOKS" ]
|
|
then
|
|
sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gogs,${pkgs.gogs}/bin/gogs,g' $HOOKS
|
|
sed -ri 's,/nix/store/[a-z0-9.-]+/bin/env,${pkgs.coreutils}/bin/env,g' $HOOKS
|
|
sed -ri 's,/nix/store/[a-z0-9.-]+/bin/bash,${pkgs.bash}/bin/bash,g' $HOOKS
|
|
sed -ri 's,/nix/store/[a-z0-9.-]+/bin/perl,${pkgs.perl}/bin/perl,g' $HOOKS
|
|
fi
|
|
'';
|
|
|
|
serviceConfig = {
|
|
Type = "simple";
|
|
User = cfg.user;
|
|
Group = cfg.group;
|
|
WorkingDirectory = cfg.stateDir;
|
|
ExecStart = "${pkgs.gogs}/bin/gogs web";
|
|
Restart = "always";
|
|
};
|
|
|
|
environment = {
|
|
USER = cfg.user;
|
|
HOME = cfg.stateDir;
|
|
GOGS_WORK_DIR = cfg.stateDir;
|
|
};
|
|
};
|
|
|
|
users = mkIf (cfg.user == "gogs") {
|
|
users.gogs = {
|
|
description = "Go Git Service";
|
|
uid = config.ids.uids.gogs;
|
|
group = "gogs";
|
|
home = cfg.stateDir;
|
|
createHome = true;
|
|
shell = pkgs.bash;
|
|
};
|
|
groups.gogs.gid = config.ids.gids.gogs;
|
|
};
|
|
|
|
warnings = optional (cfg.database.password != "")
|
|
''config.services.gogs.database.password will be stored as plaintext
|
|
in the Nix store. Use database.passwordFile instead.'';
|
|
|
|
# Create database passwordFile default when password is configured.
|
|
services.gogs.database.passwordFile =
|
|
(mkDefault (toString (pkgs.writeTextFile {
|
|
name = "gogs-database-password";
|
|
text = cfg.database.password;
|
|
})));
|
|
};
|
|
}
|