indico: wip: create module
Signed-off-by: Jeltz <jeltz@federez.net>
This commit is contained in:
parent
d75eba0b8e
commit
abbafb082d
2 changed files with 443 additions and 107 deletions
423
modules/indico.nix
Normal file
423
modules/indico.nix
Normal file
|
@ -0,0 +1,423 @@
|
||||||
|
# Inspired by https://git.hubrecht.ovh/hubrecht/nix-infra
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.indico;
|
||||||
|
pythonFmt = pkgs.formats.pythonVars { };
|
||||||
|
yamlFmt = pkgs.formats.yaml {};
|
||||||
|
indico = pkgs.callPackage ../pkgs/indico { };
|
||||||
|
pythonEnv = pkgs.python3.withPackages (ps: [
|
||||||
|
(ps.toPythonModule indico)
|
||||||
|
ps.gunicorn
|
||||||
|
]);
|
||||||
|
redisSocket = config.services.redis.servers.${cfg.redis.name}.unixSocket;
|
||||||
|
indicoSocket = "/run/indico/indico.sock";
|
||||||
|
baseDir = "${pythonEnv}/${pythonEnv.sitePackages}/indico";
|
||||||
|
loggingFile = yamlFmt.generate "logging.yaml" {
|
||||||
|
version = 1;
|
||||||
|
root = {
|
||||||
|
level = "INFO";
|
||||||
|
handlers = [ "stderr" ];
|
||||||
|
};
|
||||||
|
loggers = {
|
||||||
|
indico.handlers = [ "stderr" ];
|
||||||
|
celery.handlers = [ "stderr" ];
|
||||||
|
};
|
||||||
|
handlers.stderr = {
|
||||||
|
class = "logging.StreamHandler";
|
||||||
|
formatter = "default";
|
||||||
|
};
|
||||||
|
formatters.default = {
|
||||||
|
format = "%(levelname)s %(request_id)s %(user_id)s %(name)s %(message)s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
configFile = pythonFmt.generate "indico.conf" {
|
||||||
|
SQLALCHEMY_DATABASE_URI = cfg.database;
|
||||||
|
CACHE_DIR = "${cfg.stateDir}/cache";
|
||||||
|
TEMP_DIR = "${cfg.stateDir}/tmp";
|
||||||
|
LOG_DIR = "/dev/null";
|
||||||
|
STATIC_FILE_METHOD = [
|
||||||
|
"xaccelredirect"
|
||||||
|
{ ${cfg.stateDir} = "/.xsf/indico"; }
|
||||||
|
];
|
||||||
|
STORAGE_BACKENDS = {
|
||||||
|
default = "fs:${cfg.storageDir}";
|
||||||
|
};
|
||||||
|
DEFAULT_LOCALE = cfg.defaultLocale;
|
||||||
|
DEFAULT_TIMEZONE = cfg.defaultTimezone;
|
||||||
|
REDIS_CACHE_URL = cfg.cacheRedis;
|
||||||
|
CELERY_BROKER = cfg.celeryBrokerRedis;
|
||||||
|
USE_PROXY = true;
|
||||||
|
BASE_URL = cfg.baseUrl;
|
||||||
|
SECRET_KEY = cfg.secretKey;
|
||||||
|
LOGGING_CONFIG_FILE = loggingFile;
|
||||||
|
NO_REPLY_EMAIL = cfg.email.noReply;
|
||||||
|
SUPPORT_EMAIL = cfg.email.support;
|
||||||
|
SMTP_SENDER_FALLBACK = cfg.email.senderFallback;
|
||||||
|
PUBLIC_SUPPORT_EMAIL = cfg.email.publicSupport;
|
||||||
|
SMTP_SERVER = [ cfg.email.smtp.host cfg.email.smtp.port ];
|
||||||
|
SMTP_LOGIN = cfg.email.smtp.login;
|
||||||
|
SMTP_PASSWORD = cfg.email.smtp.password;
|
||||||
|
SMTP_USE_TLS = cfg.email.smtp.useTLS;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# TODO cProfile; indico standalone command is *very* slow
|
||||||
|
# (~30s just to print the help)
|
||||||
|
|
||||||
|
options.services.indico = {
|
||||||
|
enable = lib.mkEnableOption "indico";
|
||||||
|
|
||||||
|
# TODO use
|
||||||
|
package = lib.mkPackageOption pkgs "indico" { };
|
||||||
|
|
||||||
|
user = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "indico";
|
||||||
|
description = "User under which indico should run.";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "indico";
|
||||||
|
description = "Group under which indico should run.";
|
||||||
|
};
|
||||||
|
|
||||||
|
email = {
|
||||||
|
noReply = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "No-reply email address.";
|
||||||
|
};
|
||||||
|
|
||||||
|
senderFallback = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = cfg.email.noReply;
|
||||||
|
description = "Sender fallback email address.";
|
||||||
|
};
|
||||||
|
|
||||||
|
publicSupport = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Public support email address.";
|
||||||
|
};
|
||||||
|
|
||||||
|
support = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Support email address.";
|
||||||
|
};
|
||||||
|
|
||||||
|
smtp = {
|
||||||
|
host = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "SMTP host.";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 587;
|
||||||
|
description = "SMTP port.";
|
||||||
|
};
|
||||||
|
|
||||||
|
useTLS = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "SMTP use TLS.";
|
||||||
|
};
|
||||||
|
|
||||||
|
login = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "SMTP login.";
|
||||||
|
};
|
||||||
|
|
||||||
|
password = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "SMTP password.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
secretKey = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Secret key.";
|
||||||
|
};
|
||||||
|
|
||||||
|
baseUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = lib.optionalString
|
||||||
|
cfg.nginx.enable
|
||||||
|
"https://${cfg.nginx.domain}";
|
||||||
|
description = "Base URL.";
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultLocale = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "fr_FR";
|
||||||
|
description = "Default locale.";
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultTimezone = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "Europe/Paris";
|
||||||
|
description = "Default timezone.";
|
||||||
|
};
|
||||||
|
|
||||||
|
nginx = {
|
||||||
|
enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to setup an NGinx virtual host.";
|
||||||
|
};
|
||||||
|
|
||||||
|
domain = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "NGinx virtual host domain.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
redis = {
|
||||||
|
enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to setup a Redis server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
name = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "indico";
|
||||||
|
description = "Redis server name.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
cacheRedis = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = lib.optionalString cfg.redis.enable
|
||||||
|
"unix://${redisSocket}?db=0";
|
||||||
|
description = "Redis cache URL.";
|
||||||
|
};
|
||||||
|
|
||||||
|
celeryBrokerRedis = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = lib.optionalString cfg.redis.enable
|
||||||
|
"redis+socket://${redisSocket}?virtual_host=1";
|
||||||
|
description = "Redis Celery broker URL.";
|
||||||
|
};
|
||||||
|
|
||||||
|
stateDir = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "/var/lib/indico";
|
||||||
|
description = ''
|
||||||
|
State directory (used for cache and temporary files).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
storageDir = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "${cfg.stateDir}/storage";
|
||||||
|
description = "Storage directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
postgresql = {
|
||||||
|
enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to setup a PostgreSQL server.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
database = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = lib.optionalString
|
||||||
|
cfg.postgresql.enable
|
||||||
|
"postgresql://@/${cfg.user}?host=/run/postgresql";
|
||||||
|
description = "Database URL.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
users.users = {
|
||||||
|
${cfg.user} = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = cfg.group;
|
||||||
|
};
|
||||||
|
} // (lib.optionalAttrs cfg.nginx.enable {
|
||||||
|
${config.services.nginx.user}.extraGroups = [ cfg.group ];
|
||||||
|
});
|
||||||
|
|
||||||
|
users.groups.${cfg.group} = { };
|
||||||
|
|
||||||
|
services.postgresql = lib.mkIf cfg.postgresql.enable {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.postgresql_16; # TODO add setting
|
||||||
|
# TODO db name != cfg.user
|
||||||
|
ensureDatabases = [ cfg.user ];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = cfg.user;
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages =
|
||||||
|
let
|
||||||
|
indico = pkgs.writeScriptBin "indico" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
sudo=exec
|
||||||
|
if [[ "$USER" != "indico" ]]; then
|
||||||
|
sudo='exec /run/wrappers/bin/sudo -u indico -E INDICO_CONFIG'
|
||||||
|
fi
|
||||||
|
export INDICO_CONFIG=${configFile}
|
||||||
|
$sudo ${lib.getExe' pythonEnv "indico"} "$@"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
[ indico ];
|
||||||
|
|
||||||
|
services.redis = lib.mkIf cfg.redis.enable {
|
||||||
|
servers.${cfg.redis.name} = {
|
||||||
|
enable = true;
|
||||||
|
group = cfg.group;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -"
|
||||||
|
"d '${cfg.stateDir}/cache' 0750 ${cfg.user} ${cfg.group} - -"
|
||||||
|
"d '${cfg.stateDir}/tmp' 0750 ${cfg.user} ${cfg.group} - -"
|
||||||
|
"d '${cfg.storageDir}' 0750 ${cfg.user} ${cfg.group} - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services =
|
||||||
|
let
|
||||||
|
psqlExtensionsCommands = ''
|
||||||
|
CREATE EXTENSION IF NOT EXISTS unaccent;
|
||||||
|
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||||
|
'';
|
||||||
|
# TODO StateDirectory, CacheDirectory?
|
||||||
|
common = {
|
||||||
|
environment.INDICO_CONFIG = configFile;
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Group = cfg.group;
|
||||||
|
User = cfg.user;
|
||||||
|
# Restart = "on-failure";
|
||||||
|
RuntimeDirectory = "indico";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
indico-db = lib.recursiveUpdate common {
|
||||||
|
description = "Indico database preparation and upgrade";
|
||||||
|
after = [
|
||||||
|
"postgresql.service"
|
||||||
|
];
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
# Source: pretalx module ; passer par un service oneshot
|
||||||
|
script = ''
|
||||||
|
versionFile="${cfg.stateDir}/version"
|
||||||
|
if [[ ! -f "$versionFile" ]]; then
|
||||||
|
${lib.getExe' config.services.postgresql.package "psql"} \
|
||||||
|
-d "${cfg.database}" \
|
||||||
|
-c "${psqlExtensionsCommands}"
|
||||||
|
${lib.getExe' pythonEnv "indico"} db prepare
|
||||||
|
echo "${indico.version}" > "$versionFile"
|
||||||
|
fi
|
||||||
|
version="$(cat "$versionFile" 2>/dev/null || echo 0)"
|
||||||
|
# FIXME: not tested; may not work
|
||||||
|
if [[ "$version" != "${indico.version}" ]]; then
|
||||||
|
${lib.getExe' pythonEnv "indico"} db upgrade
|
||||||
|
echo "${indico.version}" > "$versionFile"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
indico-worker = lib.recursiveUpdate common {
|
||||||
|
description = "Indico background worker";
|
||||||
|
after = [
|
||||||
|
"network.target"
|
||||||
|
"redis-indico.service"
|
||||||
|
"postgresql.service"
|
||||||
|
"indico-db.service"
|
||||||
|
];
|
||||||
|
serviceConfig.ExecStart = ''
|
||||||
|
${lib.getExe' pythonEnv "indico"} celery worker -B
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
indico-web = lib.recursiveUpdate common {
|
||||||
|
description = "Indico web service";
|
||||||
|
after = [
|
||||||
|
"network.target"
|
||||||
|
"redis-indico.service"
|
||||||
|
"postgresql.service"
|
||||||
|
"indico-worker.service"
|
||||||
|
"indico-db.service"
|
||||||
|
];
|
||||||
|
# TODO bind on a TCP socket when cfg.nginx.enable == false?
|
||||||
|
serviceConfig.ExecStart = ''
|
||||||
|
${lib.getExe' pythonEnv "gunicorn"} \
|
||||||
|
--bind unix:${indicoSocket} \
|
||||||
|
--name=indico \
|
||||||
|
indico.web.wsgi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.sockets = lib.mkIf cfg.nginx.enable {
|
||||||
|
indico-web.socketConfig = {
|
||||||
|
ListenStream = indicoSocket;
|
||||||
|
SocketUser = config.services.nginx.user;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = lib.mkIf cfg.nginx.enable {
|
||||||
|
enable = true;
|
||||||
|
recommendedProxySettings = lib.mkDefault true;
|
||||||
|
recommendedOptimisation = lib.mkDefault true;
|
||||||
|
recommendedTlsSettings = lib.mkDefault true;
|
||||||
|
recommendedGzipSettings = lib.mkDefault true;
|
||||||
|
upstreams.indico.servers."unix:${indicoSocket}" = { };
|
||||||
|
virtualHosts.${cfg.nginx.domain} = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations = {
|
||||||
|
"/.xsf/indico/" = {
|
||||||
|
alias = "${cfg.stateDir}/";
|
||||||
|
extraConfig = ''
|
||||||
|
internal;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ ^/(images|fonts)(.*)/(.+?)(__v[0-9a-f]+)?\\.([^.]+)$" = {
|
||||||
|
alias = "${baseDir}/web/static/$1$2/$3.$5";
|
||||||
|
priority = 900;
|
||||||
|
extraConfig = ''
|
||||||
|
access_log off;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ ^/(css|dist|images|fonts)/(.*)$" = {
|
||||||
|
alias = "${baseDir}/web/static/$1/$2";
|
||||||
|
extraConfig = ''
|
||||||
|
access_log off;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"= /robots.txt" = {
|
||||||
|
alias = "${baseDir}/web/static/robots.txt";
|
||||||
|
extraConfig = ''
|
||||||
|
access_log off;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"/" = {
|
||||||
|
proxyPass = "http://indico";
|
||||||
|
# FIXME is it useful?
|
||||||
|
extraConfig = ''
|
||||||
|
client_max_body_size 1G;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,116 +1,29 @@
|
||||||
{ config, lib, pkgs, python3, ... }:
|
|
||||||
let
|
|
||||||
# cfg = config.services.indico;
|
|
||||||
# pythonFmt = pkgs.formats.pythonVars { };
|
|
||||||
indico = pkgs.callPackage ../pkgs/indico { };
|
|
||||||
pythonEnv = indico.python.withPackages (ps: [
|
|
||||||
indico
|
|
||||||
# (ps.toPythonModule indico)
|
|
||||||
ps.gunicorn
|
|
||||||
]);
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
# TODO cProfile; indico is *very* slow (~30s just to print the help)
|
config,
|
||||||
|
lib,
|
||||||
# + sudo indico
|
pkgs,
|
||||||
environment.systemPackages = [ indico ];
|
...
|
||||||
|
}:
|
||||||
services.redis.servers.indico.enable = true;
|
{
|
||||||
|
imports = [
|
||||||
systemd.services.indico-web = {
|
../modules/indico.nix
|
||||||
description = "Indico web service";
|
|
||||||
after = [
|
|
||||||
"network.target"
|
|
||||||
"redis-indico.service"
|
|
||||||
"postgresql.service"
|
|
||||||
];
|
];
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
# TODO migrations
|
|
||||||
serviceConfig = {
|
|
||||||
User = "indico";
|
|
||||||
Group = "indico";
|
|
||||||
ExecStart = "${lib.getExe' pythonEnv "gunicorn"} --bind unix:/run/indico/indico.sock --name=indico indico.wsgi";
|
|
||||||
Restart = "on-failure";
|
|
||||||
};
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.sockets.gunicorn-web = {
|
|
||||||
socketConfig = {
|
|
||||||
ListenStream = "/run/indico/indico.sock";
|
|
||||||
SocketUser = "nginx";
|
|
||||||
};
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
# preStart = ''
|
|
||||||
# echo "create extension if not exists pg_trgm" | runuser -u ${config.services.postgresql.superUser} -- ${config.services.postgresql.package}/bin/psql hydra
|
|
||||||
# ''
|
|
||||||
|
|
||||||
services.postgresql = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.postgresql_16;
|
|
||||||
ensureDatabases = [ "indico" ];
|
|
||||||
ensureUsers = [
|
|
||||||
{
|
|
||||||
name = "indico";
|
|
||||||
ensureDBOwnership = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
|
||||||
services.nginx = let
|
services.indico = {
|
||||||
indicoBaseDir = "/tmp";
|
|
||||||
in {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
recommendedTlsSettings = true;
|
nginx.domain = "events.federez.net";
|
||||||
recommendedOptimisation = true;
|
email = {
|
||||||
recommendedGzipSettings = true;
|
noReply = "indico@federez.net";
|
||||||
recommendedProxySettings = true;
|
support = "admin@federez.net";
|
||||||
upstreams.indico.servers."unix:/run/indico/indico.sock" = { };
|
publicSupport = "bureau@federez.net";
|
||||||
virtualHosts."events.federez.net" = {
|
smtp = {
|
||||||
enableACME = true;
|
host = "dodecagon.federez.net";
|
||||||
forceSSL = true;
|
login = "indico";
|
||||||
locations = {
|
password = "xxx";
|
||||||
"/.xsf/indico/" = {
|
|
||||||
alias = "${indicoBaseDir}/";
|
|
||||||
extraConfig = ''
|
|
||||||
internal;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
# Order? + too lax?
|
|
||||||
"~ ^/(images|fonts)(.*)/(.+?)(__v[0-9a-f]+)?\\.([^.]+)$" = {
|
|
||||||
alias = "${indicoBaseDir}/web/static/$1$2/$3.$5";
|
|
||||||
extraConfig = ''
|
|
||||||
access_log off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"~ ^/(css|dist|images|fonts)/(.*)$" = {
|
|
||||||
alias = "${indicoBaseDir}/web/static/$1/$2";
|
|
||||||
extraConfig = ''
|
|
||||||
access_log off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"= /robots.txt" = {
|
|
||||||
alias = "${indicoBaseDir}/web/static/robots.txt";
|
|
||||||
extraConfig = ''
|
|
||||||
access_log off;
|
|
||||||
'';
|
|
||||||
"/" = {
|
|
||||||
proxyPass = "http://indico";
|
|
||||||
extraConfig = ''
|
|
||||||
client_max_body_size 1G;
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
secretKey = "lQsViT9292sIkObP9ptQADGJ16bk58n7"; # FIXME: dev only
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
users.users.indico = {
|
|
||||||
isSystemUser = true;
|
|
||||||
group = "indico";
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups.indico = {};
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue