1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.panamax;
7
8 panamax_api = pkgs.panamax_api.override { dataDir = cfg.dataDir + "/api"; };
9 panamax_ui = pkgs.panamax_ui.override { dataDir = cfg.dataDir + "/ui"; };
10
11in {
12
13 ##### Interface
14 options.services.panamax = {
15 enable = mkOption {
16 type = types.bool;
17 default = false;
18 description = ''
19 Whether to enable Panamax service.
20 '';
21 };
22
23 UIPort = mkOption {
24 type = types.int;
25 default = 8888;
26 description = ''
27 Panamax UI listening port.
28 '';
29 };
30
31 APIPort = mkOption {
32 type = types.int;
33 default = 3000;
34 description = ''
35 Panamax UI listening port.
36 '';
37 };
38
39 dataDir = mkOption {
40 type = types.str;
41 default = "/var/lib/panamax";
42 description = ''
43 Data dir for Panamax.
44 '';
45 };
46
47 fleetctlEndpoint = mkOption {
48 type = types.str;
49 default = "http://127.0.0.1:4001";
50 description = ''
51 Panamax fleetctl endpoint.
52 '';
53 };
54
55 journalEndpoint = mkOption {
56 type = types.str;
57 default = "http://127.0.0.1:19531";
58 description = ''
59 Panamax journal endpoint.
60 '';
61 };
62
63 secretKey = mkOption {
64 type = types.str;
65 default = "SomethingVeryLong.";
66 description = ''
67 Panamax secret key (do change this).
68 '';
69 };
70
71 };
72
73 ##### Implementation
74 config = mkIf cfg.enable {
75 systemd.services.panamax-api = {
76 description = "Panamax API";
77
78 wantedBy = [ "multi-user.target" ];
79 after = [ "network.target" "fleet.service" "etcd.service" "docker.service" ];
80
81 path = [ panamax_api ];
82 environment = {
83 RAILS_ENV = "production";
84 JOURNAL_ENDPOINT = cfg.journalEndpoint;
85 FLEETCTL_ENDPOINT = cfg.fleetctlEndpoint;
86 PANAMAX_DATABASE_PATH = "${cfg.dataDir}/api/db/mnt/db.sqlite3";
87 };
88
89 preStart = ''
90 rm -rf ${cfg.dataDir}/state/tmp
91 mkdir -p ${cfg.dataDir}/api/{db/mnt,state/log,state/tmp}
92 ln -sf ${panamax_api}/share/panamax-api/_db/{schema.rb,seeds.rb,migrate} ${cfg.dataDir}/api/db/
93
94 if [ ! -f ${cfg.dataDir}/.created ]; then
95 bundle exec rake db:setup
96 bundle exec rake db:seed
97 bundle exec rake panamax:templates:load || true
98 touch ${cfg.dataDir}/.created
99 else
100 bundle exec rake db:migrate
101 fi
102 '';
103
104 serviceConfig = {
105 ExecStart = "${panamax_api}/bin/bundle exec rails server --binding 127.0.0.1 --port ${toString cfg.APIPort}";
106 User = "panamax";
107 Group = "panamax";
108 };
109 };
110
111 systemd.services.panamax-ui = {
112 description = "Panamax UI";
113
114 wantedBy = [ "multi-user.target" ];
115 after = [ "network.target" "panamax_api.service" ];
116
117 path = [ panamax_ui ];
118 environment = {
119 RAILS_ENV = "production";
120 JOURNAL_ENDPOINT = cfg.journalEndpoint;
121 PMX_API_PORT_3000_TCP_ADDR = "localhost";
122 PMX_API_PORT_3000_TCP_PORT = toString cfg.APIPort;
123 SECRET_KEY_BASE = cfg.secretKey;
124 };
125
126 preStart = ''
127 mkdir -p ${cfg.dataDir}/ui/state/{log,tmp}
128 chown -R panamax:panamax ${cfg.dataDir}
129 '';
130
131 serviceConfig = {
132 ExecStart = "${panamax_ui}/bin/bundle exec rails server --binding 127.0.0.1 --port ${toString cfg.UIPort}";
133 User = "panamax";
134 Group = "panamax";
135 PermissionsStartOnly = true;
136 };
137 };
138
139 users.extraUsers.panamax =
140 { uid = config.ids.uids.panamax;
141 description = "Panamax user";
142 createHome = true;
143 home = cfg.dataDir;
144 extraGroups = [ "docker" ];
145 };
146
147 services.journald.enableHttpGateway = mkDefault true;
148 services.fleet.enable = mkDefault true;
149 services.cadvisor.enable = mkDefault true;
150 services.cadvisor.port = mkDefault 3002;
151 virtualisation.docker.enable = mkDefault true;
152
153 environment.systemPackages = [ panamax_api panamax_ui ];
154 users.extraGroups.panamax.gid = config.ids.gids.panamax;
155 };
156}