1{ config, lib, pkgs, ...}:
2
3with lib;
4let
5 cfg = config.services.hadoop;
6 hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/";
7 mkIfNotNull = x: mkIf (x != null) x;
8 # generic hbase role options
9 hbaseRoleOption = name: extraOpts: {
10 enable = mkEnableOption (mdDoc "HBase ${name}");
11
12 openFirewall = mkOption {
13 type = types.bool;
14 default = false;
15 description = mdDoc "Open firewall ports for HBase ${name}.";
16 };
17
18 restartIfChanged = mkOption {
19 type = types.bool;
20 default = false;
21 description = mdDoc "Restart ${name} con config change.";
22 };
23
24 extraFlags = mkOption {
25 type = with types; listOf str;
26 default = [];
27 example = literalExpression ''[ "--backup" ]'';
28 description = mdDoc "Extra flags for the ${name} service.";
29 };
30
31 environment = mkOption {
32 type = with types; attrsOf str;
33 default = {};
34 example = literalExpression ''
35 {
36 HBASE_MASTER_OPTS = "-Dcom.sun.management.jmxremote.ssl=true";
37 }
38 '';
39 description = mdDoc "Environment variables passed to ${name}.";
40 };
41 } // extraOpts;
42 # generic hbase role configs
43 hbaseRoleConfig = name: ports: (mkIf cfg.hbase."${name}".enable {
44 services.hadoop.gatewayRole = {
45 enable = true;
46 enableHbaseCli = mkDefault true;
47 };
48
49 systemd.services."hbase-${toLower name}" = {
50 description = "HBase ${name}";
51 wantedBy = [ "multi-user.target" ];
52 path = with cfg; [ hbase.package ] ++ optional
53 (with cfg.hbase.master; enable && initHDFS) package;
54 preStart = mkIf (with cfg.hbase.master; enable && initHDFS)
55 (concatStringsSep "\n" (
56 map (x: "HADOOP_USER_NAME=hdfs hdfs --config /etc/hadoop-conf ${x}")[
57 "dfsadmin -safemode wait"
58 "dfs -mkdir -p ${cfg.hbase.rootdir}"
59 "dfs -chown hbase ${cfg.hbase.rootdir}"
60 ]
61 ));
62
63 inherit (cfg.hbase."${name}") environment;
64 script = concatStringsSep " " (
65 [
66 "hbase --config /etc/hadoop-conf/"
67 "${toLower name} start"
68 ]
69 ++ cfg.hbase."${name}".extraFlags
70 ++ map (x: "--${toLower x} ${toString cfg.hbase.${name}.${x}}")
71 (filter (x: hasAttr x cfg.hbase.${name}) ["port" "infoPort"])
72 );
73
74 serviceConfig = {
75 User = "hbase";
76 SyslogIdentifier = "hbase-${toLower name}";
77 Restart = "always";
78 };
79 };
80
81 services.hadoop.hbaseSiteInternal."hbase.rootdir" = cfg.hbase.rootdir;
82
83 networking = {
84 firewall.allowedTCPPorts = mkIf cfg.hbase."${name}".openFirewall ports;
85 hosts = mkIf (with cfg.hbase.regionServer; enable && overrideHosts) {
86 "127.0.0.2" = mkForce [ ];
87 "::1" = mkForce [ ];
88 };
89 };
90
91 });
92in
93{
94 options.services.hadoop = {
95
96 gatewayRole.enableHbaseCli = mkEnableOption (mdDoc "HBase CLI tools");
97
98 hbaseSiteDefault = mkOption {
99 default = {
100 "hbase.regionserver.ipc.address" = "0.0.0.0";
101 "hbase.master.ipc.address" = "0.0.0.0";
102 "hbase.master.info.bindAddress" = "0.0.0.0";
103 "hbase.regionserver.info.bindAddress" = "0.0.0.0";
104
105 "hbase.cluster.distributed" = "true";
106 };
107 type = types.attrsOf types.anything;
108 description = mdDoc ''
109 Default options for hbase-site.xml
110 '';
111 };
112 hbaseSite = mkOption {
113 default = {};
114 type = with types; attrsOf anything;
115 example = literalExpression ''
116 {
117 "hbase.hregion.max.filesize" = 20*1024*1024*1024;
118 "hbase.table.normalization.enabled" = "true";
119 }
120 '';
121 description = mdDoc ''
122 Additional options and overrides for hbase-site.xml
123 <https://github.com/apache/hbase/blob/rel/2.4.11/hbase-common/src/main/resources/hbase-default.xml>
124 '';
125 };
126 hbaseSiteInternal = mkOption {
127 default = {};
128 type = with types; attrsOf anything;
129 internal = true;
130 description = mdDoc ''
131 Internal option to add configs to hbase-site.xml based on module options
132 '';
133 };
134
135 hbase = {
136
137 package = mkOption {
138 type = types.package;
139 default = pkgs.hbase;
140 defaultText = literalExpression "pkgs.hbase";
141 description = mdDoc "HBase package";
142 };
143
144 rootdir = mkOption {
145 description = mdDoc ''
146 This option will set "hbase.rootdir" in hbase-site.xml and determine
147 the directory shared by region servers and into which HBase persists.
148 The URL should be 'fully-qualified' to include the filesystem scheme.
149 If a core-site.xml is provided, the FS scheme defaults to the value
150 of "fs.defaultFS".
151
152 Filesystems other than HDFS (like S3, QFS, Swift) are also supported.
153 '';
154 type = types.str;
155 example = "hdfs://nameservice1/hbase";
156 default = "/hbase";
157 };
158 zookeeperQuorum = mkOption {
159 description = mdDoc ''
160 This option will set "hbase.zookeeper.quorum" in hbase-site.xml.
161 Comma separated list of servers in the ZooKeeper ensemble.
162 '';
163 type = with types; nullOr commas;
164 example = "zk1.internal,zk2.internal,zk3.internal";
165 default = null;
166 };
167 } // (let
168 ports = port: infoPort: {
169 port = mkOption {
170 type = types.int;
171 default = port;
172 description = mdDoc "RPC port";
173 };
174 infoPort = mkOption {
175 type = types.int;
176 default = infoPort;
177 description = mdDoc "web UI port";
178 };
179 };
180 in mapAttrs hbaseRoleOption {
181 master.initHDFS = mkEnableOption (mdDoc "initialization of the hbase directory on HDFS");
182 regionServer.overrideHosts = mkOption {
183 type = types.bool;
184 default = true;
185 description = mdDoc ''
186 Remove /etc/hosts entries for "127.0.0.2" and "::1" defined in nixos/modules/config/networking.nix
187 Regionservers must be able to resolve their hostnames to their IP addresses, through PTR records
188 or /etc/hosts entries.
189 '';
190 };
191 thrift = ports 9090 9095;
192 rest = ports 8080 8085;
193 });
194 };
195
196 config = mkMerge ([
197
198 (mkIf cfg.gatewayRole.enable {
199
200 environment.systemPackages = mkIf cfg.gatewayRole.enableHbaseCli [ cfg.hbase.package ];
201
202 services.hadoop.hbaseSiteInternal = with cfg.hbase; {
203 "hbase.zookeeper.quorum" = mkIfNotNull zookeeperQuorum;
204 };
205
206 users.users.hbase = {
207 description = "Hadoop HBase user";
208 group = "hadoop";
209 isSystemUser = true;
210 };
211 })
212 ] ++ (mapAttrsToList hbaseRoleConfig {
213 master = [ 16000 16010 ];
214 regionServer = [ 16020 16030 ];
215 thrift = with cfg.hbase.thrift; [ port infoPort ];
216 rest = with cfg.hbase.rest; [ port infoPort ];
217 }));
218}