depot/third_party/nixpkgs/nixos/modules/services/misc/tandoor-recipes.nix
Default email 94427deb9d Project import generated by Copybara.
GitOrigin-RevId: f91ee3065de91a3531329a674a45ddcb3467a650
2023-05-24 16:37:59 +03:00

145 lines
4.2 KiB
Nix

{ 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";
DEBUG_TOOLBAR = "0";
MEDIA_ROOT = "/var/lib/tandoor-recipes";
} // optionalAttrs (config.time.timeZone != null) {
TIMEZONE = config.time.timeZone;
} // (
lib.mapAttrs (_: toString) cfg.extraConfig
);
manage =
let
setupEnv = lib.concatStringsSep "\n" (mapAttrsToList (name: val: "export ${name}=\"${val}\"") env);
in
pkgs.writeShellScript "manage" ''
${setupEnv}
exec ${pkg}/bin/tandoor-recipes "$@"
'';
in
{
meta.maintainers = with maintainers; [ ambroisie ];
options.services.tandoor-recipes = {
enable = mkOption {
type = lib.types.bool;
default = false;
description = lib.mdDoc ''
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 = lib.mdDoc "Web interface address.";
};
port = mkOption {
type = types.port;
default = 8080;
description = lib.mdDoc "Web interface port.";
};
extraConfig = mkOption {
type = types.attrs;
default = { };
description = lib.mdDoc ''
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";
};
};
package = mkOption {
type = types.package;
default = pkgs.tandoor-recipes;
defaultText = literalExpression "pkgs.tandoor-recipes";
description = lib.mdDoc "The Tandoor Recipes package to use.";
};
};
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";
DynamicUser = true;
StateDirectory = "tandoor-recipes";
WorkingDirectory = "/var/lib/tandoor-recipes";
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";
};
};
};
}