{ config, lib, pkgs, ... }: with lib; let cfg = config.services.almir; bconsoleconf = pkgs.writeText "bconsole.conf" '' Director { Name = ${cfg.director_name} DIRport = ${toString cfg.director_port} address = ${cfg.director_address} Password = "${cfg.director_password}" } ''; productionini = pkgs.writeText "production.ini" '' [app:main] use = egg:almir pyramid.reload_templates = false pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en pyramid.includes = pyramid_exclog exclog.extra_info = true sqlalchemy.url = ${cfg.sqlalchemy_engine_url} timezone = ${cfg.timezone} bconsole_config = ${bconsoleconf} [server:main] use = egg:waitress#main host = 127.0.0.1 port = ${toString cfg.port} # Begin logging configuration [loggers] keys = root, almir, sqlalchemy, exc_logger [handlers] keys = console [formatters] keys = generic [logger_root] level = WARN handlers = console [logger_almir] level = WARN handlers = qualname = almir [logger_exc_logger] level = ERROR handlers = qualname = exc_logger [logger_sqlalchemy] level = WARN handlers = qualname = sqlalchemy.engine # "level = INFO" logs SQL queries. # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s ''; in { options = { services.almir = { enable = mkOption { type = types.bool; default = false; description = '' Enable Almir web server. Also configures postgresql database and installs bacula. ''; }; port = mkOption { default = 35000; type = types.int; description = '' Port for Almir web server to listen on. ''; }; timezone = mkOption { description = '' Timezone as specified in https://en.wikipedia.org/wiki/List_of_tz_database_time_zones ''; example = "Europe/Ljubljana"; }; sqlalchemy_engine_url = mkOption { default = "postgresql:///bacula"; example = '' postgresql://bacula:bacula@localhost:5432/bacula mysql+mysqlconnector://<user>:<password>@<hostname>/<database>' sqlite:////var/lib/bacula/bacula.db' ''; description = '' Define SQL database connection to bacula catalog as specified in http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls ''; }; director_name = mkOption { description = '' Name of the Director to connect with bconsole. ''; }; director_password = mkOption { description = '' Password for Director to connect with bconsole. ''; }; director_port = mkOption { default = 9101; type = types.int; description = '' Port for Director to connect with bconsole. ''; }; director_address = mkOption { default = "127.0.0.1"; description = '' IP/Hostname for Director to connect with bconsole. ''; }; }; }; config = mkIf cfg.enable { systemd.services.almir = { after = [ "network.target" "postgresql.service" ]; description = "Almir web app"; wantedBy = [ "multi-user.target" ]; path = [ pkgs.pythonPackages.almir ]; environment.PYTHONPATH = "${pkgs.pythonPackages.almir}/lib/${pkgs.pythonPackages.python.libPrefix}/site-packages"; serviceConfig.ExecStart = "${pkgs.pythonPackages.pyramid}/bin/pserve ${productionini}"; }; environment.systemPackages = [ pkgs.pythonPackages.almir ]; users.extraUsers.almir = { group = "almir"; uid = config.ids.uids.almir; createHome = true; shell = "${pkgs.bash}/bin/bash"; }; users.extraGroups.almir.gid = config.ids.gids.almir; }; }