1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.almir;
7
8 bconsoleconf = pkgs.writeText "bconsole.conf"
9 ''
10 Director {
11 Name = ${cfg.director_name}
12 DIRport = ${toString cfg.director_port}
13 address = ${cfg.director_address}
14 Password = "${cfg.director_password}"
15 }
16 '';
17
18 productionini = pkgs.writeText "production.ini"
19 ''
20[app:main]
21use = egg:almir
22
23pyramid.reload_templates = false
24pyramid.debug_authorization = false
25pyramid.debug_notfound = false
26pyramid.debug_routematch = false
27pyramid.debug_templates = false
28pyramid.default_locale_name = en
29pyramid.includes =
30 pyramid_exclog
31exclog.extra_info = true
32
33sqlalchemy.url = ${cfg.sqlalchemy_engine_url}
34timezone = ${cfg.timezone}
35bconsole_config = ${bconsoleconf}
36
37[server:main]
38use = egg:waitress#main
39host = 127.0.0.1
40port = ${toString cfg.port}
41
42
43# Begin logging configuration
44
45[loggers]
46keys = root, almir, sqlalchemy, exc_logger
47
48[handlers]
49keys = console
50
51[formatters]
52keys = generic
53
54[logger_root]
55level = WARN
56handlers = console
57
58[logger_almir]
59level = WARN
60handlers =
61qualname = almir
62
63[logger_exc_logger]
64level = ERROR
65handlers =
66qualname = exc_logger
67
68[logger_sqlalchemy]
69level = WARN
70handlers =
71qualname = sqlalchemy.engine
72# "level = INFO" logs SQL queries.
73# "level = DEBUG" logs SQL queries and results.
74# "level = WARN" logs neither. (Recommended for production systems.)
75
76[handler_console]
77class = StreamHandler
78args = (sys.stderr,)
79level = NOTSET
80formatter = generic
81
82[formatter_generic]
83format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
84 '';
85in {
86 options = {
87 services.almir = {
88 enable = mkOption {
89 type = types.bool;
90 default = false;
91 description = ''
92 Enable Almir web server. Also configures postgresql database and installs bacula.
93 '';
94 };
95
96 port = mkOption {
97 default = 35000;
98 type = types.int;
99 description = ''
100 Port for Almir web server to listen on.
101 '';
102 };
103
104 timezone = mkOption {
105 description = ''
106 Timezone as specified in https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
107 '';
108 example = "Europe/Ljubljana";
109 };
110
111 sqlalchemy_engine_url = mkOption {
112 default = "postgresql:///bacula";
113 example = ''
114 postgresql://bacula:bacula@localhost:5432/bacula
115 mysql+mysqlconnector://<user>:<password>@<hostname>/<database>'
116 sqlite:////var/lib/bacula/bacula.db'
117 '';
118 description = ''
119 Define SQL database connection to bacula catalog as specified in http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls
120 '';
121 };
122
123 director_name = mkOption {
124 description = ''
125 Name of the Director to connect with bconsole.
126 '';
127 };
128
129 director_password = mkOption {
130 description = ''
131 Password for Director to connect with bconsole.
132 '';
133 };
134
135 director_port = mkOption {
136 default = 9101;
137 type = types.int;
138 description = ''
139 Port for Director to connect with bconsole.
140 '';
141 };
142
143 director_address = mkOption {
144 default = "127.0.0.1";
145 description = ''
146 IP/Hostname for Director to connect with bconsole.
147 '';
148 };
149 };
150 };
151
152 config = mkIf cfg.enable {
153 systemd.services.almir = {
154 after = [ "network.target" "postgresql.service" ];
155 description = "Almir web app";
156 wantedBy = [ "multi-user.target" ];
157 path = [ pkgs.pythonPackages.almir ];
158 environment.PYTHONPATH = "${pkgs.pythonPackages.almir}/lib/${pkgs.pythonPackages.python.libPrefix}/site-packages";
159 serviceConfig.ExecStart = "${pkgs.pythonPackages.pyramid}/bin/pserve ${productionini}";
160 };
161
162 environment.systemPackages = [ pkgs.pythonPackages.almir ];
163
164 users.extraUsers.almir = {
165 group = "almir";
166 uid = config.ids.uids.almir;
167 createHome = true;
168 shell = "${pkgs.bash}/bin/bash";
169 };
170
171 users.extraGroups.almir.gid = config.ids.gids.almir;
172 };
173}