1
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-06-24 02:00:41 +03:00
nixpkgs/nixos/modules/services/web-apps/galene.nix
Silvan Mosberger 374e6bcc40 treewide: Format all Nix files
Format all Nix files using the officially approved formatter,
making the CI check introduced in the previous commit succeed:

  nix-build ci -A fmt.check

This is the next step of the of the [implementation](https://github.com/NixOS/nixfmt/issues/153)
of the accepted [RFC 166](https://github.com/NixOS/rfcs/pull/166).

This commit will lead to merge conflicts for a number of PRs,
up to an estimated ~1100 (~33%) among the PRs with activity in the past 2
months, but that should be lower than what it would be without the previous
[partial treewide format](https://github.com/NixOS/nixpkgs/pull/322537).

Merge conflicts caused by this commit can now automatically be resolved while rebasing using the
[auto-rebase script](8616af08d9/maintainers/scripts/auto-rebase).

If you run into any problems regarding any of this, please reach out to the
[formatting team](https://nixos.org/community/teams/formatting/) by
pinging @NixOS/nix-formatting.
2025-04-01 20:10:43 +02:00

230 lines
6.8 KiB
Nix

{
config,
lib,
options,
pkgs,
...
}:
with lib;
let
cfg = config.services.galene;
opt = options.services.galene;
defaultstateDir = "/var/lib/galene";
defaultrecordingsDir = "${cfg.stateDir}/recordings";
defaultgroupsDir = "${cfg.stateDir}/groups";
defaultdataDir = "${cfg.stateDir}/data";
in
{
options = {
services.galene = {
enable = mkEnableOption "Galene Service";
stateDir = mkOption {
default = defaultstateDir;
type = types.path;
description = ''
The directory where Galene stores its internal state. If left as the default
value this directory will automatically be created before the Galene server
starts, otherwise the sysadmin is responsible for ensuring the directory
exists with appropriate ownership and permissions.
'';
};
user = mkOption {
type = types.str;
default = "galene";
description = "User account under which galene runs.";
};
group = mkOption {
type = types.str;
default = "galene";
description = "Group under which galene runs.";
};
insecure = mkOption {
type = types.bool;
default = false;
description = ''
Whether Galene should listen in http or in https. If left as the default
value (false), Galene needs to be fed a private key and a certificate.
'';
};
certFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/path/to/your/cert.pem";
description = ''
Path to the server's certificate. The file is copied at runtime to
Galene's data directory where it needs to reside.
'';
};
keyFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/path/to/your/key.pem";
description = ''
Path to the server's private key. The file is copied at runtime to
Galene's data directory where it needs to reside.
'';
};
httpAddress = mkOption {
type = types.str;
default = "";
description = "HTTP listen address for galene.";
};
httpPort = mkOption {
type = types.port;
default = 8443;
description = "HTTP listen port.";
};
turnAddress = mkOption {
type = types.str;
default = "auto";
example = "127.0.0.1:1194";
description = "Built-in TURN server listen address and port. Set to \"\" to disable.";
};
staticDir = mkOption {
type = types.path;
default = "${cfg.package.static}/static";
defaultText = literalExpression ''"''${package.static}/static"'';
example = "/var/lib/galene/static";
description = "Web server directory.";
};
recordingsDir = mkOption {
type = types.path;
default = defaultrecordingsDir;
defaultText = literalExpression ''"''${config.${opt.stateDir}}/recordings"'';
example = "/var/lib/galene/recordings";
description = "Recordings directory.";
};
dataDir = mkOption {
type = types.path;
default = defaultdataDir;
defaultText = literalExpression ''"''${config.${opt.stateDir}}/data"'';
example = "/var/lib/galene/data";
description = "Data directory.";
};
groupsDir = mkOption {
type = types.path;
default = defaultgroupsDir;
defaultText = literalExpression ''"''${config.${opt.stateDir}}/groups"'';
example = "/var/lib/galene/groups";
description = "Web server directory.";
};
package = mkPackageOption pkgs "galene" { };
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = cfg.insecure || (cfg.certFile != null && cfg.keyFile != null);
message = ''
Galene needs both certFile and keyFile defined for encryption, or
the insecure flag.
'';
}
];
systemd.services.galene = {
description = "galene";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
preStart = ''
${optionalString (cfg.insecure != true) ''
install -m 700 -o '${cfg.user}' -g '${cfg.group}' ${cfg.certFile} ${cfg.dataDir}/cert.pem
install -m 700 -o '${cfg.user}' -g '${cfg.group}' ${cfg.keyFile} ${cfg.dataDir}/key.pem
''}
'';
serviceConfig = mkMerge [
{
Type = "simple";
User = cfg.user;
Group = cfg.group;
WorkingDirectory = cfg.stateDir;
ExecStart = ''
${cfg.package}/bin/galene \
${optionalString (cfg.insecure) "-insecure"} \
-http ${cfg.httpAddress}:${toString cfg.httpPort} \
-turn ${cfg.turnAddress} \
-data ${cfg.dataDir} \
-groups ${cfg.groupsDir} \
-recordings ${cfg.recordingsDir} \
-static ${cfg.staticDir}'';
Restart = "always";
# Upstream Requirements
LimitNOFILE = 65536;
StateDirectory =
[ ]
++ optional (cfg.stateDir == defaultstateDir) "galene"
++ optional (cfg.dataDir == defaultdataDir) "galene/data"
++ optional (cfg.groupsDir == defaultgroupsDir) "galene/groups"
++ optional (cfg.recordingsDir == defaultrecordingsDir) "galene/recordings";
# Hardening
CapabilityBoundingSet = [ "" ];
DeviceAllow = [ "" ];
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
ReadWritePaths = cfg.recordingsDir;
RemoveIPC = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_NETLINK"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
UMask = "0077";
}
];
};
users.users = mkIf (cfg.user == "galene") {
galene = {
description = "galene Service";
group = cfg.group;
isSystemUser = true;
};
};
users.groups = mkIf (cfg.group == "galene") {
galene = { };
};
};
meta.maintainers = with lib.maintainers; [ rgrunbla ];
}