1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.winstone;
8
9 winstoneOpts = { name, ... }: {
10 options = {
11 name = mkOption {
12 default = name;
13 internal = true;
14 };
15
16 serviceName = mkOption {
17 type = types.str;
18 description = ''
19 The name of the systemd service. By default, it is
20 derived from the winstone instance name.
21 '';
22 };
23
24 warFile = mkOption {
25 type = types.str;
26 description = ''
27 The WAR file that Winstone should serve.
28 '';
29 };
30
31 javaPackage = mkOption {
32 type = types.package;
33 default = pkgs.jre;
34 defaultText = "pkgs.jre";
35 description = ''
36 Which Java derivation to use for running Winstone.
37 '';
38 };
39
40 user = mkOption {
41 type = types.str;
42 description = ''
43 The user that should run this Winstone process and
44 own the working directory.
45 '';
46 };
47
48 group = mkOption {
49 type = types.str;
50 description = ''
51 The group that will own the working directory.
52 '';
53 };
54
55 workDir = mkOption {
56 type = types.str;
57 description = ''
58 The working directory for this Winstone instance. Will
59 contain extracted webapps etc. The directory will be
60 created if it doesn't exist.
61 '';
62 };
63
64 extraJavaOptions = mkOption {
65 type = types.listOf types.str;
66 default = [];
67 description = ''
68 Extra command line options given to the java process running
69 Winstone.
70 '';
71 };
72
73 extraOptions = mkOption {
74 type = types.listOf types.str;
75 default = [];
76 description = ''
77 Extra command line options given to the Winstone process.
78 '';
79 };
80 };
81
82 config = {
83 workDir = mkDefault "/run/winstone/${name}";
84 serviceName = mkDefault "winstone-${name}";
85 };
86 };
87
88 mkService = cfg: let
89 opts = concatStringsSep " " (cfg.extraOptions ++ [
90 "--warfile ${cfg.warFile}"
91 ]);
92
93 javaOpts = concatStringsSep " " (cfg.extraJavaOptions ++ [
94 "-Djava.io.tmpdir=${cfg.workDir}"
95 "-jar ${pkgs.winstone}/lib/winstone.jar"
96 ]);
97 in {
98 wantedBy = [ "multi-user.target" ];
99 description = "winstone service for ${cfg.name}";
100 preStart = ''
101 mkdir -p "${cfg.workDir}"
102 chown ${cfg.user}:${cfg.group} "${cfg.workDir}"
103 '';
104 serviceConfig = {
105 ExecStart = "${cfg.javaPackage}/bin/java ${javaOpts} ${opts}";
106 User = cfg.user;
107 PermissionsStartOnly = true;
108 };
109 };
110
111in {
112
113 options = {
114 services.winstone = mkOption {
115 default = {};
116 type = with types; attrsOf (submodule winstoneOpts);
117 description = ''
118 Defines independent Winstone services, each serving one WAR-file.
119 '';
120 };
121 };
122
123 config = mkIf (cfg != {}) {
124
125 systemd.services = mapAttrs' (n: c: nameValuePair c.serviceName (mkService c)) cfg;
126
127 };
128
129}