1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.jira; 8 9 pkg = cfg.package.override (optionalAttrs cfg.sso.enable { 10 enableSSO = cfg.sso.enable; 11 crowdProperties = '' 12 application.name ${cfg.sso.applicationName} 13 application.password ${cfg.sso.applicationPassword} 14 application.login.url ${cfg.sso.crowd}/console/ 15 16 crowd.server.url ${cfg.sso.crowd}/services/ 17 crowd.base.url ${cfg.sso.crowd}/ 18 19 session.isauthenticated session.isauthenticated 20 session.tokenkey session.tokenkey 21 session.validationinterval ${toString cfg.sso.validationInterval} 22 session.lastvalidation session.lastvalidation 23 ''; 24 }); 25 26in 27 28{ 29 options = { 30 services.jira = { 31 enable = mkEnableOption "Atlassian JIRA service"; 32 33 user = mkOption { 34 type = types.str; 35 default = "jira"; 36 description = "User which runs JIRA."; 37 }; 38 39 group = mkOption { 40 type = types.str; 41 default = "jira"; 42 description = "Group which runs JIRA."; 43 }; 44 45 home = mkOption { 46 type = types.str; 47 default = "/var/lib/jira"; 48 description = "Home directory of the JIRA instance."; 49 }; 50 51 listenAddress = mkOption { 52 type = types.str; 53 default = "127.0.0.1"; 54 description = "Address to listen on."; 55 }; 56 57 listenPort = mkOption { 58 type = types.int; 59 default = 8091; 60 description = "Port to listen on."; 61 }; 62 63 catalinaOptions = mkOption { 64 type = types.listOf types.str; 65 default = []; 66 example = [ "-Xms1024m" "-Xmx2048m" ]; 67 description = "Java options to pass to catalina/tomcat."; 68 }; 69 70 proxy = { 71 enable = mkEnableOption "reverse proxy support"; 72 73 name = mkOption { 74 type = types.str; 75 example = "jira.example.com"; 76 description = "Virtual hostname at the proxy"; 77 }; 78 79 port = mkOption { 80 type = types.int; 81 default = 443; 82 example = 80; 83 description = "Port used at the proxy"; 84 }; 85 86 scheme = mkOption { 87 type = types.str; 88 default = "https"; 89 example = "http"; 90 description = "Protocol used at the proxy."; 91 }; 92 93 secure = mkOption { 94 type = types.bool; 95 default = true; 96 description = "Whether the connections to the proxy should be considered secure."; 97 }; 98 }; 99 100 sso = { 101 enable = mkEnableOption "SSO with Atlassian Crowd"; 102 103 crowd = mkOption { 104 type = types.str; 105 example = "http://localhost:8095/crowd"; 106 description = "Crowd Base URL without trailing slash"; 107 }; 108 109 applicationName = mkOption { 110 type = types.str; 111 example = "jira"; 112 description = "Exact name of this JIRA instance in Crowd"; 113 }; 114 115 applicationPassword = mkOption { 116 type = types.str; 117 description = "Application password of this JIRA instance in Crowd"; 118 }; 119 120 validationInterval = mkOption { 121 type = types.int; 122 default = 2; 123 example = 0; 124 description = '' 125 Set to 0, if you want authentication checks to occur on each 126 request. Otherwise set to the number of minutes between request 127 to validate if the user is logged in or out of the Crowd SSO 128 server. Setting this value to 1 or higher will increase the 129 performance of Crowd's integration. 130 ''; 131 }; 132 }; 133 134 package = mkOption { 135 type = types.package; 136 default = pkgs.atlassian-jira; 137 defaultText = literalExpression "pkgs.atlassian-jira"; 138 description = "Atlassian JIRA package to use."; 139 }; 140 141 jrePackage = mkOption { 142 type = types.package; 143 default = pkgs.oraclejre8; 144 defaultText = literalExpression "pkgs.oraclejre8"; 145 description = "Note that Atlassian only support the Oracle JRE (JRASERVER-46152)."; 146 }; 147 }; 148 }; 149 150 config = mkIf cfg.enable { 151 users.users.${cfg.user} = { 152 isSystemUser = true; 153 group = cfg.group; 154 }; 155 156 users.groups.${cfg.group} = {}; 157 158 systemd.tmpfiles.rules = [ 159 "d '${cfg.home}' - ${cfg.user} - - -" 160 "d /run/atlassian-jira - - - - -" 161 162 "L+ /run/atlassian-jira/home - - - - ${cfg.home}" 163 "L+ /run/atlassian-jira/logs - - - - ${cfg.home}/logs" 164 "L+ /run/atlassian-jira/work - - - - ${cfg.home}/work" 165 "L+ /run/atlassian-jira/temp - - - - ${cfg.home}/temp" 166 "L+ /run/atlassian-jira/server.xml - - - - ${cfg.home}/server.xml" 167 ]; 168 169 systemd.services.atlassian-jira = { 170 description = "Atlassian JIRA"; 171 172 wantedBy = [ "multi-user.target" ]; 173 requires = [ "postgresql.service" ]; 174 after = [ "postgresql.service" ]; 175 176 path = [ cfg.jrePackage pkgs.bash ]; 177 178 environment = { 179 JIRA_USER = cfg.user; 180 JIRA_HOME = cfg.home; 181 JAVA_HOME = "${cfg.jrePackage}"; 182 CATALINA_OPTS = concatStringsSep " " cfg.catalinaOptions; 183 }; 184 185 preStart = '' 186 mkdir -p ${cfg.home}/{logs,work,temp,deploy} 187 188 sed -e 's,port="8080",port="${toString cfg.listenPort}" address="${cfg.listenAddress}",' \ 189 '' + (lib.optionalString cfg.proxy.enable '' 190 -e 's,protocol="HTTP/1.1",protocol="HTTP/1.1" proxyName="${cfg.proxy.name}" proxyPort="${toString cfg.proxy.port}" scheme="${cfg.proxy.scheme}" secure="${toString cfg.proxy.secure}",' \ 191 '') + '' 192 ${pkg}/conf/server.xml.dist > ${cfg.home}/server.xml 193 ''; 194 195 serviceConfig = { 196 User = cfg.user; 197 Group = cfg.group; 198 PrivateTmp = true; 199 ExecStart = "${pkg}/bin/start-jira.sh -fg"; 200 ExecStop = "${pkg}/bin/stop-jira.sh"; 201 }; 202 }; 203 }; 204}