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