--- /dev/null
+{ lib, pkgs, config, ... }:
+let
+ name = "mediagoblin";
+ cfg = config.services.mediagoblin;
+
+ uid = config.ids.uids.mediagoblin;
+ gid = config.ids.gids.mediagoblin;
+
+ fullPackage = cfg.package.withPlugins cfg.plugins;
+ paste_local = pkgs.writeText "paste_local.ini" ''
+ [DEFAULT]
+ debug = false
+
+ [pipeline:main]
+ pipeline = mediagoblin
+
+ [app:mediagoblin]
+ use = egg:mediagoblin#app
+ config = ${cfg.configFile} ${fullPackage}/mediagoblin.ini
+ /mgoblin_static = ${fullPackage}/mediagoblin/static
+
+ [loggers]
+ keys = root
+
+ [handlers]
+ keys = console
+
+ [formatters]
+ keys = generic
+
+ [logger_root]
+ level = INFO
+ handlers = console
+
+ [handler_console]
+ class = StreamHandler
+ args = (sys.stderr,)
+ level = NOTSET
+ formatter = generic
+
+ [formatter_generic]
+ format = %(levelname)-7.7s [%(name)s] %(message)s
+
+ [filter:errors]
+ use = egg:mediagoblin#errors
+ debug = false
+
+ [server:main]
+ use = egg:waitress#main
+ unix_socket = ${cfg.socketsDir}/mediagoblin.sock
+ unix_socket_perms = 777
+ url_scheme = https
+ '';
+in
+{
+ options.services.mediagoblin = {
+ enable = lib.mkEnableOption "Enable Mediagoblin’s service";
+ user = lib.mkOption {
+ type = lib.types.str;
+ default = name;
+ description = "User account under which Mediagoblin runs";
+ };
+ group = lib.mkOption {
+ type = lib.types.str;
+ default = name;
+ description = "Group under which Mediagoblin runs";
+ };
+ dataDir = lib.mkOption {
+ type = lib.types.path;
+ default = "/var/lib/${name}";
+ description = ''
+ The directory where Mediagoblin stores its data.
+ '';
+ };
+ socketsDir = lib.mkOption {
+ type = lib.types.path;
+ default = "/run/${name}";
+ description = ''
+ The directory where Mediagoblin puts runtime files and sockets.
+ '';
+ };
+ configFile = lib.mkOption {
+ type = lib.types.path;
+ description = ''
+ The configuration file path for Mediagoblin.
+ '';
+ };
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = pkgs.webapps.mediagoblin;
+ description = ''
+ Mediagoblin package to use.
+ '';
+ };
+ plugins = lib.mkOption {
+ type = lib.types.listOf lib.types.package;
+ default = [];
+ description = ''
+ Mediagoblin plugins to use.
+ '';
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ users.users = lib.optionalAttrs (cfg.user == name) (lib.singleton {
+ inherit name;
+ inherit uid;
+ group = cfg.group;
+ description = "Mediagoblin user";
+ home = cfg.dataDir;
+ useDefaultShell = true;
+ });
+ users.groups = lib.optionalAttrs (cfg.group == name) (lib.singleton {
+ inherit name;
+ inherit gid;
+ });
+
+ systemd.services.mediagoblin-web = {
+ description = "Mediagoblin service";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ wants = [ "postgresql.service" "redis.service" ];
+
+ environment.SCRIPT_NAME = "/mediagoblin/";
+
+ script = ''
+ exec ./bin/paster serve \
+ ${paste_local} \
+ --pid-file=${cfg.socketsDir}/mediagoblin.pid
+ '';
+ preStop = ''
+ exec ./bin/paster serve \
+ --pid-file=${cfg.socketsDir}/mediagoblin.pid \
+ ${paste_local} stop
+ '';
+ preStart = ''
+ ./bin/gmg -cf ${cfg.configFile} dbupdate
+ '';
+
+ serviceConfig = {
+ User = cfg.user;
+ PrivateTmp = true;
+ Restart = "always";
+ TimeoutSec = 15;
+ Type = "simple";
+ WorkingDirectory = fullPackage;
+ PIDFile = "${cfg.socketsDir}/mediagoblin.pid";
+ };
+
+ unitConfig.RequiresMountsFor = cfg.dataDir;
+ };
+
+ systemd.services.mediagoblin-celeryd = {
+ description = "Mediagoblin service";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" "mediagoblin-web.service" ];
+
+ environment.MEDIAGOBLIN_CONFIG = cfg.configFile;
+ environment.CELERY_CONFIG_MODULE = "mediagoblin.init.celery.from_celery";
+
+ script = ''
+ exec ./bin/celery worker \
+ --logfile=${cfg.dataDir}/celery.log \
+ --loglevel=INFO
+ '';
+
+ serviceConfig = {
+ User = cfg.user;
+ PrivateTmp = true;
+ Restart = "always";
+ TimeoutSec = 60;
+ Type = "simple";
+ WorkingDirectory = fullPackage;
+ PIDFile = "${cfg.socketsDir}/mediagoblin-celeryd.pid";
+ };
+
+ unitConfig.RequiresMountsFor = cfg.dataDir;
+ };
+
+ 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 ${fullPackage}/mediagoblin/plugins/basic_auth/static ${cfg.dataDir}/plugin_static/coreplugin_basic_auth
+ fi
+ '';
+ };
+
+ };
+}
{ lib, pkgs, config, myconfig, mylibs, ... }:
let
env = myconfig.env.tools.mediagoblin;
- socketsDir = "/run/mediagoblin";
- varDir = "/var/lib/mediagoblin";
cfg = config.services.myWebsites.tools.mediagoblin;
- mediagoblin_init = "/var/secrets/webapps/tools-mediagoblin";
- paste_local = pkgs.writeText "paste_local.ini" ''
- [DEFAULT]
- debug = false
-
- [pipeline:main]
- pipeline = mediagoblin
-
- [app:mediagoblin]
- use = egg:mediagoblin#app
- config = ${mediagoblin_init} ${pythonRoot}/mediagoblin.ini
- /mgoblin_static = ${pythonRoot}/mediagoblin/static
-
- [loggers]
- keys = root
-
- [handlers]
- keys = console
-
- [formatters]
- keys = generic
-
- [logger_root]
- level = INFO
- handlers = console
-
- [handler_console]
- class = StreamHandler
- args = (sys.stderr,)
- level = NOTSET
- formatter = generic
-
- [formatter_generic]
- format = %(levelname)-7.7s [%(name)s] %(message)s
-
- [filter:errors]
- use = egg:mediagoblin#errors
- debug = false
-
- [server:main]
- use = egg:waitress#main
- unix_socket = ${socketsDir}/mediagoblin.sock
- unix_socket_perms = 777
- url_scheme = https
- '';
- pythonRoot = pkgs.webapps.mediagoblin-with-plugins;
+ mcfg = config.services.mediagoblin;
in {
options.services.myWebsites.tools.mediagoblin = {
enable = lib.mkEnableOption "enable mediagoblin's website";
permissions = "0400";
text = ''
[DEFAULT]
- data_basedir = "${varDir}"
+ data_basedir = "${mcfg.dataDir}"
[mediagoblin]
direct_remote_path = /mgoblin_static/
'';
}];
- ids.uids.mediagoblin = myconfig.env.tools.mediagoblin.user.uid;
- ids.gids.mediagoblin = myconfig.env.tools.mediagoblin.user.gid;
+ users.users.mediagoblin.extraGroups = [ "keys" ];
- users.users.mediagoblin = {
- name = "mediagoblin";
- uid = config.ids.uids.mediagoblin;
- group = "mediagoblin";
- description = "Mediagoblin user";
- home = varDir;
- useDefaultShell = true;
- extraGroups = [ "keys" ];
- };
-
- users.groups.mediagoblin.gid = config.ids.gids.mediagoblin;
-
- systemd.services.mediagoblin-web = {
- description = "Mediagoblin service";
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" ];
- wants = [ "postgresql.service" "redis.service" ];
-
- environment.SCRIPT_NAME = "/mediagoblin/";
-
- script = ''
- exec ./bin/paster serve \
- ${paste_local} \
- --pid-file=${socketsDir}/mediagoblin.pid
- '';
-
- preStop = ''
- exec ./bin/paster serve \
- --pid-file=${socketsDir}/mediagoblin.pid \
- ${paste_local} stop
- '';
- preStart = ''
- ./bin/gmg -cf ${mediagoblin_init} dbupdate
- '';
-
- serviceConfig = {
- User = "mediagoblin";
- PrivateTmp = true;
- Restart = "always";
- TimeoutSec = 15;
- Type = "simple";
- WorkingDirectory = pythonRoot;
- PIDFile = "${socketsDir}/mediagoblin.pid";
- };
-
- unitConfig.RequiresMountsFor = varDir;
- };
-
- systemd.services.mediagoblin-celeryd = {
- description = "Mediagoblin service";
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" "mediagoblin-web.service" ];
-
- environment.MEDIAGOBLIN_CONFIG = mediagoblin_init;
- environment.CELERY_CONFIG_MODULE = "mediagoblin.init.celery.from_celery";
-
- script = ''
- exec ./bin/celery worker \
- --logfile=${varDir}/celery.log \
- --loglevel=INFO
- '';
-
- serviceConfig = {
- User = "mediagoblin";
- PrivateTmp = true;
- Restart = "always";
- TimeoutSec = 60;
- Type = "simple";
- WorkingDirectory = pythonRoot;
- PIDFile = "${socketsDir}/mediagoblin-celeryd.pid";
- };
-
- unitConfig.RequiresMountsFor = varDir;
- };
-
- system.activationScripts.mediagoblin = {
- deps = [ "users" ];
- text = ''
- install -m 0755 -o mediagoblin -g mediagoblin -d ${socketsDir}
- install -m 0755 -o mediagoblin -g mediagoblin -d ${varDir}
- if [ -d ${varDir}/plugin_static/ ]; then
- rm ${varDir}/plugin_static/coreplugin_basic_auth
- ln -sf ${pythonRoot}/mediagoblin/plugins/basic_auth/static ${varDir}/plugin_static/coreplugin_basic_auth
- fi
- '';
+ services.mediagoblin = {
+ enable = true;
+ plugins = builtins.attrValues pkgs.webapps.mediagoblin-plugins;
+ configFile = "/var/secrets/webapps/tools-mediagoblin";
};
services.myWebsites.tools.modules = [
hosts = ["mgoblin.immae.eu" ];
root = null;
extraConfig = [ ''
- Alias /mgoblin_media ${varDir}/media/public
- <Directory ${varDir}/media/public>
+ Alias /mgoblin_media ${mcfg.dataDir}/media/public
+ <Directory ${mcfg.dataDir}/media/public>
Options -Indexes +FollowSymLinks +MultiViews +Includes
Require all granted
</Directory>
- Alias /theme_static ${varDir}/theme_static
- <Directory ${varDir}/theme_static>
+ Alias /theme_static ${mcfg.dataDir}/theme_static
+ <Directory ${mcfg.dataDir}/theme_static>
Options -Indexes +FollowSymLinks +MultiViews +Includes
Require all granted
</Directory>
- Alias /plugin_static ${varDir}/plugin_static
- <Directory ${varDir}/plugin_static>
+ Alias /plugin_static ${mcfg.dataDir}/plugin_static
+ <Directory ${mcfg.dataDir}/plugin_static>
Options -Indexes +FollowSymLinks +MultiViews +Includes
Require all granted
</Directory>
ProxyPass /theme_static !
ProxyPass /plugin_static !
ProxyPassMatch ^/.well-known/acme-challenge !
- ProxyPass / unix://${socketsDir}/mediagoblin.sock|http://mgoblin.immae.eu/
- ProxyPassReverse / unix://${socketsDir}/mediagoblin.sock|http://mgoblin.immae.eu/
+ ProxyPass / unix://${mcfg.socketsDir}/mediagoblin.sock|http://mgoblin.immae.eu/
+ ProxyPassReverse / unix://${mcfg.socketsDir}/mediagoblin.sock|http://mgoblin.immae.eu/
'' ];
};
};