2022-09-17 14:36:39 +00:00
|
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
cfg = config.services.tandoor-recipes;
|
|
|
|
pkg = cfg.package;
|
|
|
|
|
|
|
|
# SECRET_KEY through an env file
|
|
|
|
env = {
|
|
|
|
GUNICORN_CMD_ARGS = "--bind=${cfg.address}:${toString cfg.port}";
|
|
|
|
DEBUG = "0";
|
2023-05-04 22:18:37 +00:00
|
|
|
DEBUG_TOOLBAR = "0";
|
2022-09-17 14:36:39 +00:00
|
|
|
MEDIA_ROOT = "/var/lib/tandoor-recipes";
|
|
|
|
} // optionalAttrs (config.time.timeZone != null) {
|
2023-12-06 22:20:05 +00:00
|
|
|
TZ = config.time.timeZone;
|
2022-09-17 14:36:39 +00:00
|
|
|
} // (
|
|
|
|
lib.mapAttrs (_: toString) cfg.extraConfig
|
|
|
|
);
|
|
|
|
|
2024-02-11 21:21:00 +00:00
|
|
|
manage = pkgs.writeShellScript "manage" ''
|
|
|
|
set -o allexport # Export the following env vars
|
|
|
|
${lib.toShellVars env}
|
2024-03-22 20:48:15 +00:00
|
|
|
eval "$(${config.systemd.package}/bin/systemctl show -pUID,GID,MainPID tandoor-recipes.service)"
|
|
|
|
exec ${pkgs.util-linux}/bin/nsenter \
|
2023-10-23 09:25:19 +00:00
|
|
|
-t $MainPID -m -S $UID -G $GID --wdns=${env.MEDIA_ROOT} \
|
2024-03-22 20:48:15 +00:00
|
|
|
${pkg}/bin/tandoor-recipes "$@"
|
2024-02-11 21:21:00 +00:00
|
|
|
'';
|
2022-09-17 14:36:39 +00:00
|
|
|
in
|
|
|
|
{
|
|
|
|
meta.maintainers = with maintainers; [ ambroisie ];
|
|
|
|
|
|
|
|
options.services.tandoor-recipes = {
|
|
|
|
enable = mkOption {
|
|
|
|
type = lib.types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Enable Tandoor Recipes.
|
|
|
|
|
|
|
|
When started, the Tandoor Recipes database is automatically created if
|
|
|
|
it doesn't exist and updated if the package has changed. Both tasks are
|
|
|
|
achieved by running a Django migration.
|
|
|
|
|
|
|
|
A script to manage the instance (by wrapping Django's manage.py) is linked to
|
|
|
|
`/var/lib/tandoor-recipes/tandoor-recipes-manage`.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
address = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "localhost";
|
|
|
|
description = "Web interface address.";
|
|
|
|
};
|
|
|
|
|
|
|
|
port = mkOption {
|
|
|
|
type = types.port;
|
|
|
|
default = 8080;
|
|
|
|
description = "Web interface port.";
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.attrs;
|
|
|
|
default = { };
|
|
|
|
description = ''
|
|
|
|
Extra tandoor recipes config options.
|
|
|
|
|
|
|
|
See [the example dot-env file](https://raw.githubusercontent.com/vabene1111/recipes/master/.env.template)
|
|
|
|
for available options.
|
|
|
|
'';
|
|
|
|
example = {
|
|
|
|
ENABLE_SIGNUP = "1";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2023-11-27 00:19:27 +00:00
|
|
|
package = mkPackageOption pkgs "tandoor-recipes" { };
|
2022-09-17 14:36:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
systemd.services.tandoor-recipes = {
|
|
|
|
description = "Tandoor Recipes server";
|
|
|
|
|
|
|
|
serviceConfig = {
|
|
|
|
ExecStart = ''
|
|
|
|
${pkg.python.pkgs.gunicorn}/bin/gunicorn recipes.wsgi
|
|
|
|
'';
|
|
|
|
Restart = "on-failure";
|
|
|
|
|
|
|
|
User = "tandoor_recipes";
|
2024-03-22 20:47:55 +00:00
|
|
|
Group = "tandoor_recipes";
|
2022-09-17 14:36:39 +00:00
|
|
|
DynamicUser = true;
|
|
|
|
StateDirectory = "tandoor-recipes";
|
2024-06-19 11:55:33 +00:00
|
|
|
WorkingDirectory = env.MEDIA_ROOT;
|
2022-09-17 14:36:39 +00:00
|
|
|
RuntimeDirectory = "tandoor-recipes";
|
|
|
|
|
|
|
|
BindReadOnlyPaths = [
|
|
|
|
"${config.environment.etc."ssl/certs/ca-certificates.crt".source}:/etc/ssl/certs/ca-certificates.crt"
|
|
|
|
builtins.storeDir
|
|
|
|
"-/etc/resolv.conf"
|
|
|
|
"-/etc/nsswitch.conf"
|
|
|
|
"-/etc/hosts"
|
|
|
|
"-/etc/localtime"
|
|
|
|
"-/run/postgresql"
|
|
|
|
];
|
|
|
|
CapabilityBoundingSet = "";
|
|
|
|
LockPersonality = true;
|
|
|
|
MemoryDenyWriteExecute = true;
|
|
|
|
PrivateDevices = true;
|
|
|
|
PrivateUsers = true;
|
|
|
|
ProtectClock = true;
|
|
|
|
ProtectControlGroups = true;
|
|
|
|
ProtectHome = true;
|
|
|
|
ProtectHostname = true;
|
|
|
|
ProtectKernelLogs = true;
|
|
|
|
ProtectKernelModules = true;
|
|
|
|
ProtectKernelTunables = true;
|
|
|
|
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
|
|
|
|
RestrictNamespaces = true;
|
|
|
|
RestrictRealtime = true;
|
|
|
|
SystemCallArchitectures = "native";
|
|
|
|
# gunicorn needs setuid
|
|
|
|
SystemCallFilter = [ "@system-service" "~@privileged" "@resources" "@setuid" "@keyring" ];
|
|
|
|
UMask = "0066";
|
|
|
|
} // lib.optionalAttrs (cfg.port < 1024) {
|
|
|
|
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
|
|
|
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
|
|
|
|
};
|
|
|
|
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
|
|
|
|
preStart = ''
|
|
|
|
ln -sf ${manage} tandoor-recipes-manage
|
|
|
|
|
|
|
|
# Let django migrate the DB as needed
|
|
|
|
${pkg}/bin/tandoor-recipes migrate
|
|
|
|
'';
|
|
|
|
|
|
|
|
environment = env // {
|
|
|
|
PYTHONPATH = "${pkg.python.pkgs.makePythonPath pkg.propagatedBuildInputs}:${pkg}/lib/tandoor-recipes";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|