From 81b9ff8980a9a235b8915b5779ebc1d2a738a9a3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Isma=C3=ABl=20Bouya?= Date: Sun, 12 May 2019 14:33:46 +0200 Subject: [PATCH] Use systemd RuntimeDirectory and StateDirectory entries to ensure runtime directory existence in apps --- modules/webapps/diaspora.nix | 28 +++++++++++++++++++++---- modules/webapps/mastodon.nix | 32 +++++++++++++++++++++++++++-- modules/webapps/mediagoblin.nix | 26 +++++++++++++++++++++-- nixops/modules/buildbot/default.nix | 9 ++++---- nixops/modules/databases/redis.nix | 8 +++----- nixops/modules/mpd.nix | 4 +--- nixops/modules/task/default.nix | 12 +++++------ 7 files changed, 92 insertions(+), 27 deletions(-) diff --git a/modules/webapps/diaspora.nix b/modules/webapps/diaspora.nix index 8451c6d..2266332 100644 --- a/modules/webapps/diaspora.nix +++ b/modules/webapps/diaspora.nix @@ -52,6 +52,26 @@ in ''; }; # Output variables + systemdStateDirectory = lib.mkOption { + type = lib.types.str; + # Use ReadWritePaths= instead if varDir is outside of /var/lib + default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir; + lib.strings.removePrefix "/var/lib/" cfg.dataDir; + description = '' + Adjusted Diaspora data directory for systemd + ''; + readOnly = true; + }; + systemdRuntimeDirectory = lib.mkOption { + type = lib.types.str; + # Use ReadWritePaths= instead if socketsDir is outside of /run + default = assert lib.strings.hasPrefix "/run/" cfg.socketsDir; + lib.strings.removePrefix "/run/" cfg.socketsDir; + description = '' + Adjusted Diaspora sockets directory for systemd + ''; + readOnly = true; + }; workdir = lib.mkOption { type = lib.types.package; default = cfg.package.override { @@ -134,6 +154,8 @@ in Restart = "always"; Type = "simple"; WorkingDirectory = cfg.workdir; + StateDirectory = cfg.systemdStateDirectory; + RuntimeDirectory = cfg.systemdRuntimeDirectory; StandardInput = "null"; KillMode = "control-group"; }; @@ -144,10 +166,8 @@ in system.activationScripts.diaspora = { deps = [ "users" ]; text = '' - install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.socketsDir} - install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir} \ - ${cfg.dataDir}/uploads ${cfg.dataDir}/tmp \ - ${cfg.dataDir}/log + install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir}/uploads \ + ${cfg.dataDir}/tmp ${cfg.dataDir}/log install -m 0700 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir}/tmp/pids if [ ! -f ${cfg.dataDir}/schedule.yml ]; then echo "{}" | $wrapperDir/sudo -u ${cfg.user} tee ${cfg.dataDir}/schedule.yml diff --git a/modules/webapps/mastodon.nix b/modules/webapps/mastodon.nix index ad6d0c3..f8fbcba 100644 --- a/modules/webapps/mastodon.nix +++ b/modules/webapps/mastodon.nix @@ -62,6 +62,26 @@ in ''; readOnly = true; }; + systemdStateDirectory = lib.mkOption { + type = lib.types.str; + # Use ReadWritePaths= instead if varDir is outside of /var/lib + default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir; + lib.strings.removePrefix "/var/lib/" cfg.dataDir; + description = '' + Adjusted Mastodon data directory for systemd + ''; + readOnly = true; + }; + systemdRuntimeDirectory = lib.mkOption { + type = lib.types.str; + # Use ReadWritePaths= instead if socketsDir is outside of /run + default = assert lib.strings.hasPrefix "/run/" cfg.socketsDir; + lib.strings.removePrefix "/run/" cfg.socketsDir; + description = '' + Adjusted Mastodon sockets directory for systemd + ''; + readOnly = true; + }; sockets = lib.mkOption { type = lib.types.attrsOf lib.types.path; default = { @@ -122,6 +142,9 @@ in TimeoutSec = 15; Type = "simple"; WorkingDirectory = cfg.workdir; + StateDirectory = cfg.systemdStateDirectory; + RuntimeDirectory = cfg.systemdRuntimeDirectory; + RuntimeDirectoryPreserve = "yes"; }; unitConfig.RequiresMountsFor = cfg.dataDir; @@ -155,6 +178,9 @@ in TimeoutSec = 60; Type = "simple"; WorkingDirectory = cfg.workdir; + StateDirectory = cfg.systemdStateDirectory; + RuntimeDirectory = cfg.systemdRuntimeDirectory; + RuntimeDirectoryPreserve = "yes"; }; unitConfig.RequiresMountsFor = cfg.dataDir; @@ -184,6 +210,9 @@ in TimeoutSec = 15; Type = "simple"; WorkingDirectory = cfg.workdir; + StateDirectory = cfg.systemdStateDirectory; + RuntimeDirectory = cfg.systemdRuntimeDirectory; + RuntimeDirectoryPreserve = "yes"; }; unitConfig.RequiresMountsFor = cfg.dataDir; @@ -192,8 +221,7 @@ in system.activationScripts.mastodon = { deps = [ "users" ]; text = '' - install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.socketsDir} - install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir} ${cfg.dataDir}/tmp/cache + install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir}/tmp/cache ''; }; diff --git a/modules/webapps/mediagoblin.nix b/modules/webapps/mediagoblin.nix index 0232aab..5753457 100644 --- a/modules/webapps/mediagoblin.nix +++ b/modules/webapps/mediagoblin.nix @@ -107,6 +107,26 @@ in ''; readOnly = true; }; + systemdStateDirectory = lib.mkOption { + type = lib.types.str; + # Use ReadWritePaths= instead if varDir is outside of /var/lib + default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir; + lib.strings.removePrefix "/var/lib/" cfg.dataDir; + description = '' + Adjusted Mediagoblin data directory for systemd + ''; + readOnly = true; + }; + systemdRuntimeDirectory = lib.mkOption { + type = lib.types.str; + # Use ReadWritePaths= instead if socketsDir is outside of /run + default = assert lib.strings.hasPrefix "/run/" cfg.socketsDir; + lib.strings.removePrefix "/run/" cfg.socketsDir; + description = '' + Adjusted Mediagoblin sockets directory for systemd + ''; + readOnly = true; + }; sockets = lib.mkOption { type = lib.types.attrsOf lib.types.path; default = { @@ -173,6 +193,8 @@ in TimeoutSec = 15; Type = "simple"; WorkingDirectory = cfg.workdir; + RuntimeDirectory = cfg.systemdRuntimeDirectory; + StateDirectory= cfg.systemdStateDirectory; PIDFile = cfg.pids.paster; }; @@ -200,6 +222,8 @@ in TimeoutSec = 60; Type = "simple"; WorkingDirectory = cfg.workdir; + RuntimeDirectory = cfg.systemdRuntimeDirectory; + StateDirectory= cfg.systemdStateDirectory; PIDFile = cfg.pids.celery; }; @@ -209,8 +233,6 @@ in system.activationScripts.mediagoblin = { deps = [ "users" ]; text = '' - install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.socketsDir} - install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir} if [ -d ${cfg.dataDir}/plugin_static/ ]; then rm ${cfg.dataDir}/plugin_static/coreplugin_basic_auth ln -sf ${cfg.workdir}/mediagoblin/plugins/basic_auth/static ${cfg.dataDir}/plugin_static/coreplugin_basic_auth diff --git a/nixops/modules/buildbot/default.nix b/nixops/modules/buildbot/default.nix index d7dd479..c812af9 100644 --- a/nixops/modules/buildbot/default.nix +++ b/nixops/modules/buildbot/default.nix @@ -61,11 +61,7 @@ in system.activationScripts = lib.attrsets.mapAttrs' (k: project: lib.attrsets.nameValuePair "buildbot-${project.name}" { deps = [ "users" "wrappers" ]; - text = '' - install -m 0755 -o buildbot -g buildbot -d /run/buildbot/ - install -m 0755 -o buildbot -g buildbot -d ${varDir} - ${project.activationScript} - ''; + text = project.activationScript; }) myconfig.env.buildbot.projects; secrets.keys = ( @@ -190,6 +186,9 @@ in Type = "forking"; User = "buildbot"; Group = "buildbot"; + RuntimeDirectory = "buildbot"; + RuntimeDirectoryPreserve = "yes"; + StateDirectory = "buildbot"; SupplementaryGroups = "keys"; WorkingDirectory = "${varDir}/${project.name}"; ExecStart = "${buildbot}/bin/buildbot start"; diff --git a/nixops/modules/databases/redis.nix b/nixops/modules/databases/redis.nix index a0917df..75c69a6 100644 --- a/nixops/modules/databases/redis.nix +++ b/nixops/modules/databases/redis.nix @@ -27,11 +27,9 @@ in { maxclients 1024 ''; }; - system.activationScripts.redis = '' - mkdir -p $(dirname ${myconfig.env.databases.redis.socket}) - chown redis $(dirname ${myconfig.env.databases.redis.socket}) - ''; - + systemd.services.redis.serviceConfig.RuntimeDirectory = + assert myconfig.env.databases.redis.socket == "/run/redis/redis.sock"; + "redis"; }; } diff --git a/nixops/modules/mpd.nix b/nixops/modules/mpd.nix index bc8b8df..9903bdf 100644 --- a/nixops/modules/mpd.nix +++ b/nixops/modules/mpd.nix @@ -19,9 +19,7 @@ ]; networking.firewall.allowedTCPPorts = [ 6600 ]; users.users.mpd.extraGroups = [ "wwwrun" "keys" ]; - system.activationScripts.mpd = '' - install -d -m 0755 -o mpd -g mpd /run/mpd - ''; + systemd.services.mpd.serviceConfig.RuntimeDirectory = "mpd"; services.mpd = { enable = true; network.listenAddress = "any"; diff --git a/nixops/modules/task/default.nix b/nixops/modules/task/default.nix index 8454c4b..8370608 100644 --- a/nixops/modules/task/default.nix +++ b/nixops/modules/task/default.nix @@ -245,12 +245,6 @@ in { system.activationScripts.taskwarrior-web = { deps = [ "users" ]; text = '' - install -m 0755 -o ${user} -g ${group} -d ${socketsDir} - install -m 0750 -o ${user} -g ${group} -d ${varDir} - ${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList - (k: v: "install -m 0750 -o ${user} -g ${group} -d ${varDir}/${k}") - env.taskwarrior-web - )} if [ ! -f ${server_vardir}/userkeys/taskwarrior-web.cert.pem ]; then ${taskserver-user-certs}/bin/taskserver-user-certs taskwarrior-web chown taskd:taskd ${server_vardir}/userkeys/taskwarrior-web.cert.pem ${server_vardir}/userkeys/taskwarrior-web.key.pem @@ -315,6 +309,12 @@ in { TimeoutSec = 60; Type = "simple"; WorkingDirectory = taskwarrior-web; + StateDirectoryMode = 0750; + StateDirectory = assert lib.strings.hasPrefix "/var/lib/" varDir; + (lib.strings.removePrefix "/var/lib/" varDir + "/${name}"); + RuntimeDirectoryPreserve = "yes"; + RuntimeDirectory = assert lib.strings.hasPrefix "/run/" socketsDir; + lib.strings.removePrefix "/run/" socketsDir; }; unitConfig.RequiresMountsFor = varDir; -- 2.41.0