8 cfg = config.services.druid;
23 druidServiceOption = serviceName: {
24 enable = mkEnableOption serviceName;
26 restartIfChanged = mkOption {
29 Automatically restart the service on config change.
30 This can be set to false to defer restarts on clusters running critical applications.
31 Please consider the security implications of inadvertently running an older version,
32 and the possibility of unexpected behavior caused by inconsistent versions across a cluster when disabling this option.
39 type = types.attrsOf types.anything;
41 (key=value) Configuration to be written to runtime.properties of the druid ${serviceName}
42 <https://druid.apache.org/docs/latest/configuration/index.html>
45 "druid.plainTextPort" = "8082";
46 "druid.service" = "servicename";
50 jdk = mkPackageOption pkgs "JDK" { default = [ "jdk17_headless" ]; };
55 description = "Arguments to pass to the JVM";
58 openFirewall = mkOption {
61 description = "Open firewall ports for ${serviceName}.";
64 internalConfig = mkOption {
66 type = types.attrsOf types.anything;
68 description = "Internal Option to add to runtime.properties for ${serviceName}.";
75 serviceOptions ? cfg."${name}",
76 allowedTCPPorts ? [ ],
80 (mkIf serviceOptions.enable (mkMerge [
83 services."druid-${name}" = {
84 after = [ "network.target" ];
86 description = "Druid ${name}";
88 wantedBy = [ "multi-user.target" ];
90 inherit (serviceOptions) restartIfChanged;
100 fileName: properties:
101 pkgs.writeTextDir fileName (
102 concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${toString v}") properties)
105 commonConfigFile = cfgFile "common.runtime.properties" cfg.commonConfig;
107 configFile = cfgFile "runtime.properties" (serviceOptions.config // serviceOptions.internalConfig);
109 extraClassPath = concatStrings (map (path: ":" + path) cfg.extraClassPaths);
111 extraConfDir = concatStrings (map (dir: ":" + dir + "/*") cfg.extraConfDirs);
114 run-java -Dlog4j.configurationFile=file:${cfg.log4j} \
115 -Ddruid.extensions.directory=${cfg.package}/extensions \
116 -Ddruid.extensions.hadoopDependenciesDir=${cfg.package}/hadoop-dependencies \
117 -classpath ${commonConfigFile}:${configFile}:${cfg.package}/lib/\*${extraClassPath}${extraConfDir} \
118 ${serviceOptions.jvmArgs} \
119 org.apache.druid.cli.Main server ${name}
124 SyslogIdentifier = "druid-${name}";
129 tmpfiles.rules = concatMap (x: [ "d ${x} 0755 druid druid" ]) (cfg.commonTmpDirs ++ tmpDirs);
131 networking.firewall.allowedTCPPorts = mkIf (attrByPath [
133 ] false serviceOptions) allowedTCPPorts;
137 description = "Druid user";
148 options.services.druid = {
149 package = mkPackageOption pkgs "apache-druid" { default = [ "druid" ]; };
151 commonConfig = mkOption {
154 type = types.attrsOf types.anything;
156 description = "(key=value) Configuration to be written to common.runtime.properties";
159 "druid.zk.service.host" = "localhost:2181";
160 "druid.metadata.storage.type" = "mysql";
161 "druid.metadata.storage.connector.connectURI" = "jdbc:mysql://localhost:3306/druid";
162 "druid.extensions.loadList" = ''[ "mysql-metadata-storage" ]'';
166 commonTmpDirs = mkOption {
167 default = [ "/var/log/druid/requests" ];
168 type = types.listOf types.str;
169 description = "Common List of directories used by druid processes";
174 description = "Log4j Configuration for the druid process";
177 extraClassPaths = mkOption {
179 type = types.listOf types.str;
180 description = "Extra classpath to include in the jvm";
183 extraConfDirs = mkOption {
185 type = types.listOf types.path;
186 description = "Extra Conf Dirs to include in the jvm";
189 overlord = druidServiceOption "Druid Overlord";
191 coordinator = druidServiceOption "Druid Coordinator";
193 broker = druidServiceOption "Druid Broker";
195 historical = (druidServiceOption "Druid Historical") // {
196 segmentLocations = mkOption {
200 description = "Locations where the historical will store its data.";
209 description = "the path to store the segments";
214 description = "Max size the druid historical can occupy";
217 freeSpacePercent = mkOption {
220 description = "Druid Historical will fail to write if it exceeds this value";
229 middleManager = druidServiceOption "Druid middleManager";
230 router = druidServiceOption "Druid Router";
233 (druidServiceConfig rec {
235 allowedTCPPorts = [ (attrByPath [ "druid.plaintextPort" ] 8090 cfg."${name}".config) ];
238 (druidServiceConfig rec {
239 name = "coordinator";
240 allowedTCPPorts = [ (attrByPath [ "druid.plaintextPort" ] 8081 cfg."${name}".config) ];
243 (druidServiceConfig rec {
246 tmpDirs = [ (attrByPath [ "druid.lookup.snapshotWorkingDir" ] "" cfg."${name}".config) ];
248 allowedTCPPorts = [ (attrByPath [ "druid.plaintextPort" ] 8082 cfg."${name}".config) ];
251 (druidServiceConfig rec {
255 (attrByPath [ "druid.lookup.snapshotWorkingDir" ] "" cfg."${name}".config)
256 ] ++ (map (x: x.path) cfg."${name}".segmentLocations);
258 allowedTCPPorts = [ (attrByPath [ "druid.plaintextPort" ] 8083 cfg."${name}".config) ];
260 extraConfig.services.druid.historical.internalConfig."druid.segmentCache.locations" =
261 builtins.toJSON cfg.historical.segmentLocations;
264 (druidServiceConfig rec {
265 name = "middleManager";
268 "/var/log/druid/indexer"
269 ] ++ [ (attrByPath [ "druid.indexer.task.baseTaskDir" ] "" cfg."${name}".config) ];
271 allowedTCPPorts = [ (attrByPath [ "druid.plaintextPort" ] 8091 cfg."${name}".config) ];
274 services.druid.middleManager.internalConfig = {
275 "druid.indexer.runner.javaCommand" = "${cfg.middleManager.jdk}/bin/java";
276 "druid.indexer.runner.javaOpts" =
277 (attrByPath [ "druid.indexer.runner.javaOpts" ] "" cfg.middleManager.config)
278 + " -Dlog4j.configurationFile=file:${cfg.log4j}";
281 networking.firewall.allowedTCPPortRanges = mkIf cfg.middleManager.openFirewall [
283 from = attrByPath [ "druid.indexer.runner.startPort" ] 8100 cfg.middleManager.config;
284 to = attrByPath [ "druid.indexer.runner.endPort" ] 65535 cfg.middleManager.config;
290 (druidServiceConfig rec {
293 allowedTCPPorts = [ (attrByPath [ "druid.plaintextPort" ] 8888 cfg."${name}".config) ];