243 lines
7.3 KiB
Nix
243 lines
7.3 KiB
Nix
|
{
|
||
|
config,
|
||
|
lib,
|
||
|
...
|
||
|
}: let
|
||
|
inherit (lib) mkEnableOption mkOption types mkIf getExe;
|
||
|
|
||
|
writeServiceConfig = config:
|
||
|
lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name}: ${
|
||
|
(
|
||
|
if (lib.isBool value)
|
||
|
then (lib.boolToString value)
|
||
|
else (toString value)
|
||
|
)
|
||
|
}")
|
||
|
config);
|
||
|
|
||
|
cfg = config.services.reposilite;
|
||
|
in {
|
||
|
options.services.reposilite = {
|
||
|
enable = mkEnableOption "reposilite - maven repository manager";
|
||
|
|
||
|
package = mkOption {
|
||
|
type = with types; nullOr package;
|
||
|
default = null; # reposilite is not in nixpkgs
|
||
|
description = "Package to install";
|
||
|
};
|
||
|
|
||
|
dataDir = mkOption {
|
||
|
type = types.path;
|
||
|
default = "/var/lib/reposilite";
|
||
|
description = "Working directory";
|
||
|
};
|
||
|
|
||
|
openFirewall = mkOption {
|
||
|
type = types.bool;
|
||
|
default = false;
|
||
|
description = "Open firewall for reposilite";
|
||
|
};
|
||
|
|
||
|
user = mkOption {
|
||
|
type = types.str;
|
||
|
default = "reposilite";
|
||
|
description = "User to run reposilite as";
|
||
|
};
|
||
|
|
||
|
group = mkOption {
|
||
|
type = types.str;
|
||
|
default = "reposilite";
|
||
|
description = "Group to run reposilite as";
|
||
|
};
|
||
|
|
||
|
settings = mkOption {
|
||
|
default = {};
|
||
|
description = "Settings to pass to reposilite";
|
||
|
type = with types;
|
||
|
submodule {
|
||
|
freeformType = attrs;
|
||
|
options = {
|
||
|
hostname = mkOption {
|
||
|
type = types.str;
|
||
|
default = "0.0.0.0";
|
||
|
description = "Hostname to listen on";
|
||
|
};
|
||
|
|
||
|
port = mkOption {
|
||
|
type = types.int;
|
||
|
default = 8080;
|
||
|
description = "Port to listen on";
|
||
|
};
|
||
|
|
||
|
database = mkOption {
|
||
|
type = types.str;
|
||
|
default = "sqlite reposilite.db";
|
||
|
description = ''
|
||
|
Database configuration. Supported storage providers:
|
||
|
- mysql localhost:3306 database user password
|
||
|
- sqlite reposilite.db
|
||
|
- sqlite --temporary
|
||
|
Experimental providers (not covered with tests):
|
||
|
- postgresql localhost:5432 database user password
|
||
|
- h2 reposilite
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
sslEnabled = mkOption {
|
||
|
type = types.bool;
|
||
|
default = false;
|
||
|
example = true;
|
||
|
description = "Support encrypted connections";
|
||
|
};
|
||
|
|
||
|
sslPort = mkOption {
|
||
|
type = types.int;
|
||
|
default = 443;
|
||
|
description = "Port to listen on for SSL connections";
|
||
|
};
|
||
|
|
||
|
keyPath = mkOption {
|
||
|
type = with types; nullOr str;
|
||
|
default = "$${WORKING_DIRECTORY}/cert.pem $${WORKING_DIRECTORY}/key.pem";
|
||
|
example = "${cfg.dataDir}/cert.pem ${cfg.dataDir}/key.pem";
|
||
|
description = ''
|
||
|
Key file to use. You can specify absolute path to the given file or use {option}`services.reposilite.dataDir` variable.
|
||
|
If you want to use .pem certificate you need to specify its path next to the key path.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
keyPassword = mkOption {
|
||
|
type = with types; nullOr str;
|
||
|
default = "";
|
||
|
example = "reposilite";
|
||
|
description = "Key password to use";
|
||
|
};
|
||
|
|
||
|
enforceSsl = mkOption {
|
||
|
type = types.bool;
|
||
|
default = false;
|
||
|
description = "Redirect http traffic to https";
|
||
|
};
|
||
|
|
||
|
webThreadPoolSize = mkOption {
|
||
|
type = types.addCheck types.int (x: x >= 5);
|
||
|
default = 16;
|
||
|
description = "Max amount of threads used by core thread pool (min: 5)";
|
||
|
};
|
||
|
|
||
|
ioThreadPool = mkOption {
|
||
|
type = types.addCheck types.int (x: x >= 2);
|
||
|
default = 8;
|
||
|
description = "IO thread pool handles all tasks that may benefit from non-blocking IO (min: 2)";
|
||
|
};
|
||
|
|
||
|
databaseThreadPool = mkOption {
|
||
|
type = types.addCheck types.int (x: x >= 1);
|
||
|
default = 8;
|
||
|
description = "Database thread pool manages open connections to database (min: 1)";
|
||
|
};
|
||
|
|
||
|
compressionStrategy = mkOption {
|
||
|
type = types.enum ["none" "gzip"];
|
||
|
default = "none";
|
||
|
description = ''
|
||
|
Select compression strategy used by this instance.
|
||
|
Using 'none' reduces usage of CPU & memory, but ends up with higher transfer usage.
|
||
|
GZIP is better option if you're not limiting resources that much to increase overall request times.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
idleTimeout = mkOption {
|
||
|
type = types.int;
|
||
|
default = 30000;
|
||
|
description = "Default idle timeout used by Jetty";
|
||
|
};
|
||
|
|
||
|
bypassExternalCache = mkOption {
|
||
|
type = types.bool;
|
||
|
default = true;
|
||
|
description = ''
|
||
|
Bypass external cache and use internal one.
|
||
|
Adds cache bypass headers to each request from `/api/*` scope served by this instance
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
cachedLogSize = mkOption {
|
||
|
type = types.int;
|
||
|
default = 50;
|
||
|
description = "Amount of messages stored in cached logger";
|
||
|
};
|
||
|
|
||
|
defaultFrontend = mkOption {
|
||
|
type = types.bool;
|
||
|
default = true;
|
||
|
description = "Enable default frontend with dashboard";
|
||
|
};
|
||
|
|
||
|
basePath = mkOption {
|
||
|
type = types.str;
|
||
|
default = "/";
|
||
|
description = ''
|
||
|
Set custom base path for Reposilite instance.
|
||
|
It's not recommended to mount Reposilite under custom base path
|
||
|
and you should always prioritize subdomain over this option.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
debugEnabled = mkOption {
|
||
|
type = types.bool;
|
||
|
default = false;
|
||
|
description = "Debug mode";
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config = mkIf cfg.enable {
|
||
|
environment = {
|
||
|
systemPackages = [cfg.package];
|
||
|
etc."reposilite/configuration.cdn" = mkIf (cfg.settings != {}) {
|
||
|
text = writeServiceConfig cfg.settings;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [cfg.settings.port];
|
||
|
|
||
|
users = {
|
||
|
groups.reposilite = {
|
||
|
name = cfg.group;
|
||
|
};
|
||
|
|
||
|
users.reposilite = {
|
||
|
group = cfg.user;
|
||
|
home = cfg.dataDir;
|
||
|
|
||
|
isSystemUser = true;
|
||
|
createHome = true;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
systemd.services."reposilite" = {
|
||
|
description = "Reposilite - Maven repository";
|
||
|
wantedBy = ["multi-user.target"];
|
||
|
script = let
|
||
|
inherit (cfg) dataDir;
|
||
|
staticConfig = ''--local-config "/etc/reposilite/configuration.cdn" --local-configuration-mode none'';
|
||
|
in ''
|
||
|
${getExe cfg.package} --working-directory "${dataDir}" ${staticConfig}
|
||
|
'';
|
||
|
|
||
|
serviceConfig = {
|
||
|
inherit (cfg) user group;
|
||
|
|
||
|
WorkingDirectory = cfg.dataDir;
|
||
|
SuccessExitStatus = 0;
|
||
|
TimeoutStopSec = 10;
|
||
|
Restart = "on-failure";
|
||
|
RestartSec = 5;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|