Unverified Commit 8f1c823a authored by illustris's avatar illustris
Browse files

nixos/hbase: add thrift and rest servers

parent 5d4dea59
Loading
Loading
Loading
Loading
+115 −103
Original line number Diff line number Diff line
@@ -5,11 +5,89 @@ let
  cfg = config.services.hadoop;
  hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/";
  mkIfNotNull = x: mkIf (x != null) x;
  # generic hbase role options
  hbaseRoleOption = name: extraOpts: {
    enable = mkEnableOption (mdDoc "HBase ${name}");

    openFirewall = mkOption {
      type = types.bool;
      default = false;
      description = mdDoc "Open firewall ports for HBase ${name}.";
    };

    restartIfChanged = mkOption {
      type = types.bool;
      default = false;
      description = mdDoc "Restart ${name} con config change.";
    };

    extraFlags = mkOption {
      type = with types; listOf str;
      default = [];
      description = mdDoc "Extra flags for the ${name} service.";
    };

    environment = mkOption {
      type = with types; attrsOf str;
      default = {};
      description = mdDoc "Environment variables passed to ${name}.";
    };
  } // extraOpts;
  # generic hbase role configs
  hbaseRoleConfig = name: ports: (mkIf cfg.hbase."${name}".enable {
    services.hadoop.gatewayRole = {
      enable = true;
      enableHbaseCli = mkDefault true;
    };

    systemd.services."hbase-${toLower name}" = {
      description = "HBase ${name}";
      wantedBy = [ "multi-user.target" ];
      path = with cfg; [ hbase.package ] ++ optional
        (with cfg.hbase.master; enable && initHDFS) package;
      preStart = mkIf (with cfg.hbase.master; enable && initHDFS)
        (concatStringsSep "\n" (
          map (x: "HADOOP_USER_NAME=hdfs hdfs --config /etc/hadoop-conf ${x}")[
            "dfsadmin -safemode wait"
            "dfs -mkdir -p ${cfg.hbase.rootdir}"
            "dfs -chown hbase ${cfg.hbase.rootdir}"
          ]
        ));

      inherit (cfg.hbase."${name}") environment;
      script = concatStringsSep " " (
        [
          "hbase --config /etc/hadoop-conf/"
          "${toLower name} start"
        ]
        ++ cfg.hbase."${name}".extraFlags
        ++ map (x: "--${toLower x} ${toString cfg.hbase.${name}.${x}}")
          (filter (x: hasAttr x cfg.hbase.${name}) ["port" "infoPort"])
      );

      serviceConfig = {
        User = "hbase";
        SyslogIdentifier = "hbase-${toLower name}";
        Restart = "always";
      };
    };

    services.hadoop.hbaseSiteInternal."hbase.rootdir" = cfg.hbase.rootdir;

    networking = {
      firewall.allowedTCPPorts = mkIf cfg.hbase."${name}".openFirewall ports;
      hosts = mkIf (with cfg.hbase.regionServer; enable && overrideHosts) {
        "127.0.0.2" = mkForce [ ];
        "::1" = mkForce [ ];
      };
    };

  });
in
{
  options.services.hadoop = {

    gatewayRole.enableHbaseCli = mkEnableOption (lib.mdDoc "HBase CLI tools");
    gatewayRole.enableHbaseCli = mkEnableOption (mdDoc "HBase CLI tools");

    hbaseSiteDefault = mkOption {
      default = {
@@ -21,7 +99,7 @@ in
        "hbase.cluster.distributed" = "true";
      };
      type = types.attrsOf types.anything;
      description = lib.mdDoc ''
      description = mdDoc ''
        Default options for hbase-site.xml
      '';
    };
@@ -30,7 +108,7 @@ in
      type = with types; attrsOf anything;
      example = literalExpression ''
      '';
      description = lib.mdDoc ''
      description = mdDoc ''
        Additional options and overrides for hbase-site.xml
        <https://github.com/apache/hbase/blob/rel/2.4.11/hbase-common/src/main/resources/hbase-default.xml>
      '';
@@ -39,7 +117,7 @@ in
      default = {};
      type = with types; attrsOf anything;
      internal = true;
      description = lib.mdDoc ''
      description = mdDoc ''
        Internal option to add configs to hbase-site.xml based on module options
      '';
    };
@@ -50,11 +128,11 @@ in
        type = types.package;
        default = pkgs.hbase;
        defaultText = literalExpression "pkgs.hbase";
        description = lib.mdDoc "HBase package";
        description = mdDoc "HBase package";
      };

      rootdir = mkOption {
        description = lib.mdDoc ''
        description = mdDoc ''
          This option will set "hbase.rootdir" in hbase-site.xml and determine
          the directory shared by region servers and into which HBase persists.
          The URL should be 'fully-qualified' to include the filesystem scheme.
@@ -68,7 +146,7 @@ in
        default = "/hbase";
      };
      zookeeperQuorum = mkOption {
        description = lib.mdDoc ''
        description = mdDoc ''
          This option will set "hbase.zookeeper.quorum" in hbase-site.xml.
          Comma separated list of servers in the ZooKeeper ensemble.
        '';
@@ -76,107 +154,36 @@ in
        example = "zk1.internal,zk2.internal,zk3.internal";
        default = null;
      };
      master = {
        enable = mkEnableOption (lib.mdDoc "HBase Master");
        initHDFS = mkEnableOption (lib.mdDoc "initialization of the hbase directory on HDFS");

        openFirewall = mkOption {
          type = types.bool;
          default = false;
          description = lib.mdDoc ''
            Open firewall ports for HBase master.
          '';
    } // (let
      ports = port: infoPort: {
        port = mkOption {
          type = types.int;
          default = port;
          description = mdDoc "RPC port";
        };
        infoPort = mkOption {
          type = types.int;
          default = infoPort;
          description = mdDoc "web UI port";
        };
      regionServer = {
        enable = mkEnableOption (lib.mdDoc "HBase RegionServer");

        overrideHosts = mkOption {
      };
    in mapAttrs hbaseRoleOption {
      master.initHDFS = mkEnableOption (mdDoc "initialization of the hbase directory on HDFS");
      regionServer.overrideHosts = mkOption {
        type = types.bool;
        default = true;
          description = lib.mdDoc ''
        description = mdDoc ''
          Remove /etc/hosts entries for "127.0.0.2" and "::1" defined in nixos/modules/config/networking.nix
          Regionservers must be able to resolve their hostnames to their IP addresses, through PTR records
          or /etc/hosts entries.

        '';
      };

        openFirewall = mkOption {
          type = types.bool;
          default = false;
          description = lib.mdDoc ''
            Open firewall ports for HBase master.
          '';
        };
      };
    };
  };

  config = mkMerge [
    (mkIf cfg.hbase.master.enable {
      services.hadoop.gatewayRole = {
        enable = true;
        enableHbaseCli = mkDefault true;
      thrift = ports 9090 9095;
      rest = ports 8080 8085;
    });
  };

      systemd.services.hbase-master = {
        description = "HBase master";
        wantedBy = [ "multi-user.target" ];

        preStart = mkIf cfg.hbase.master.initHDFS ''
          HADOOP_USER_NAME=hdfs ${cfg.package}/bin/hdfs --config ${hadoopConf} dfsadmin -safemode wait
          HADOOP_USER_NAME=hdfs ${cfg.package}/bin/hdfs --config ${hadoopConf} dfs -mkdir -p ${cfg.hbase.rootdir}
          HADOOP_USER_NAME=hdfs ${cfg.package}/bin/hdfs --config ${hadoopConf} dfs -chown hbase ${cfg.hbase.rootdir}
        '';

        serviceConfig = {
          User = "hbase";
          SyslogIdentifier = "hbase-master";
          ExecStart = "${cfg.hbase.package}/bin/hbase --config ${hadoopConf} " +
                      "master start";
          Restart = "always";
        };
      };

      services.hadoop.hbaseSiteInternal."hbase.rootdir" = cfg.hbase.rootdir;

      networking.firewall.allowedTCPPorts = mkIf cfg.hbase.master.openFirewall [
        16000 16010
      ];

    })

    (mkIf cfg.hbase.regionServer.enable {
      services.hadoop.gatewayRole = {
        enable = true;
        enableHbaseCli = mkDefault true;
      };

      systemd.services.hbase-regionserver = {
        description = "HBase RegionServer";
        wantedBy = [ "multi-user.target" ];
        serviceConfig = {
          User = "hbase";
          SyslogIdentifier = "hbase-regionserver";
          ExecStart = "${cfg.hbase.package}/bin/hbase --config /etc/hadoop-conf/ " +
                      "regionserver start";
          Restart = "always";
        };
      };

      services.hadoop.hbaseSiteInternal."hbase.rootdir" = cfg.hbase.rootdir;

      networking = {
        firewall.allowedTCPPorts = mkIf cfg.hbase.regionServer.openFirewall [
          16020 16030
        ];
        hosts = mkIf cfg.hbase.regionServer.overrideHosts {
          "127.0.0.2" = mkForce [ ];
          "::1" = mkForce [ ];
        };
      };
    })
  config = mkMerge ([

    (mkIf cfg.gatewayRole.enable {

@@ -192,5 +199,10 @@ in
        isSystemUser = true;
      };
    })
  ];
  ] ++ (mapAttrsToList hbaseRoleConfig {
    master = [ 16000 16010 ];
    regionServer = [ 16020 16030 ];
    thrift = with cfg.hbase.thrift; [ port infoPort ];
    rest = with cfg.hbase.rest; [ port infoPort ];
  }));
}
+25 −0
Original line number Diff line number Diff line
@@ -53,6 +53,24 @@ with pkgs.lib;
        };
      };
    };
    thrift = { ... }:{
      services.hadoop = {
        inherit coreSite;
        hbase = {
          inherit zookeeperQuorum;
          thrift = defOpts;
        };
      };
    };
    rest = { ... }:{
      services.hadoop = {
        inherit coreSite;
        hbase = {
          inherit zookeeperQuorum;
          rest = defOpts;
        };
      };
    };
  };

  testScript = ''
@@ -80,5 +98,12 @@ with pkgs.lib;
    assert "1 active master, 0 backup masters, 1 servers" in master.succeed("echo status | HADOOP_USER_NAME=hbase hbase shell -n")
    regionserver.wait_until_succeeds("echo \"create 't1','f1'\" | HADOOP_USER_NAME=hbase hbase shell -n")
    assert "NAME => 'f1'" in regionserver.succeed("echo \"describe 't1'\" | HADOOP_USER_NAME=hbase hbase shell -n")

    rest.wait_for_open_port(8080)
    assert "${hbase.version}" in regionserver.succeed("curl http://rest:8080/version/cluster")

    thrift.wait_for_open_port(9090)
  '';

  meta.maintainers = with maintainers; [ illustris ];
})