218 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, lib, pkgs, ... }:
 | 
						|
 | 
						|
with lib;
 | 
						|
 | 
						|
let
 | 
						|
  cfg = config.services.cockroachdb;
 | 
						|
  crdb = cfg.package;
 | 
						|
 | 
						|
  escape    = builtins.replaceStrings ["%"] ["%%"];
 | 
						|
  ifNotNull = v: s: optionalString (v != null) s;
 | 
						|
 | 
						|
  startupCommand = lib.concatStringsSep " "
 | 
						|
    [ # Basic startup
 | 
						|
      "${crdb}/bin/cockroach start"
 | 
						|
      "--logtostderr"
 | 
						|
      "--store=/var/lib/cockroachdb"
 | 
						|
      (ifNotNull cfg.locality "--locality='${cfg.locality}'")
 | 
						|
 | 
						|
      # WebUI settings
 | 
						|
      "--http-addr='${cfg.http.address}:${toString cfg.http.port}'"
 | 
						|
 | 
						|
      # Cluster listen address
 | 
						|
      "--listen-addr='${cfg.listen.address}:${toString cfg.listen.port}'"
 | 
						|
 | 
						|
      # Cluster configuration
 | 
						|
      (ifNotNull cfg.join "--join=${cfg.join}")
 | 
						|
 | 
						|
      # Cache and memory settings. Must be escaped.
 | 
						|
      "--cache='${escape cfg.cache}'"
 | 
						|
      "--max-sql-memory='${escape cfg.maxSqlMemory}'"
 | 
						|
 | 
						|
      # Certificate/security settings.
 | 
						|
      (if cfg.insecure then "--insecure" else "--certs-dir=${cfg.certsDir}")
 | 
						|
    ];
 | 
						|
 | 
						|
    addressOption = descr: defaultPort: {
 | 
						|
      address = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "localhost";
 | 
						|
        description = "Address to bind to for ${descr}";
 | 
						|
      };
 | 
						|
 | 
						|
      port = mkOption {
 | 
						|
        type = types.port;
 | 
						|
        default = defaultPort;
 | 
						|
        description = "Port to bind to for ${descr}";
 | 
						|
      };
 | 
						|
    };
 | 
						|
in
 | 
						|
 | 
						|
{
 | 
						|
  options = {
 | 
						|
    services.cockroachdb = {
 | 
						|
      enable = mkEnableOption "CockroachDB Server";
 | 
						|
 | 
						|
      listen = addressOption "intra-cluster communication" 26257;
 | 
						|
 | 
						|
      http = addressOption "http-based Admin UI" 8080;
 | 
						|
 | 
						|
      locality = mkOption {
 | 
						|
        type = types.nullOr types.str;
 | 
						|
        default = null;
 | 
						|
        description = ''
 | 
						|
          An ordered, comma-separated list of key-value pairs that describe the
 | 
						|
          topography of the machine. Topography might include country,
 | 
						|
          datacenter or rack designations. Data is automatically replicated to
 | 
						|
          maximize diversities of each tier. The order of tiers is used to
 | 
						|
          determine the priority of the diversity, so the more inclusive
 | 
						|
          localities like country should come before less inclusive localities
 | 
						|
          like datacenter.  The tiers and order must be the same on all nodes.
 | 
						|
          Including more tiers is better than including fewer. For example:
 | 
						|
 | 
						|
          <literal>
 | 
						|
              country=us,region=us-west,datacenter=us-west-1b,rack=12
 | 
						|
              country=ca,region=ca-east,datacenter=ca-east-2,rack=4
 | 
						|
 | 
						|
              planet=earth,province=manitoba,colo=secondary,power=3
 | 
						|
          </literal>
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      join = mkOption {
 | 
						|
        type = types.nullOr types.str;
 | 
						|
        default = null;
 | 
						|
        description = "The addresses for connecting the node to a cluster.";
 | 
						|
      };
 | 
						|
 | 
						|
      insecure = mkOption {
 | 
						|
        type = types.bool;
 | 
						|
        default = false;
 | 
						|
        description = "Run in insecure mode.";
 | 
						|
      };
 | 
						|
 | 
						|
      certsDir = mkOption {
 | 
						|
        type = types.nullOr types.path;
 | 
						|
        default = null;
 | 
						|
        description = "The path to the certificate directory.";
 | 
						|
      };
 | 
						|
 | 
						|
      user = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "cockroachdb";
 | 
						|
        description = "User account under which CockroachDB runs";
 | 
						|
      };
 | 
						|
 | 
						|
      group = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "cockroachdb";
 | 
						|
        description = "User account under which CockroachDB runs";
 | 
						|
      };
 | 
						|
 | 
						|
      openPorts = mkOption {
 | 
						|
        type = types.bool;
 | 
						|
        default = false;
 | 
						|
        description = "Open firewall ports for cluster communication by default";
 | 
						|
      };
 | 
						|
 | 
						|
      cache = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "25%";
 | 
						|
        description = ''
 | 
						|
          The total size for caches.
 | 
						|
 | 
						|
          This can be a percentage, expressed with a fraction sign or as a
 | 
						|
          decimal-point number, or any bytes-based unit. For example,
 | 
						|
          <literal>"25%"</literal>, <literal>"0.25"</literal> both represent
 | 
						|
          25% of the available system memory. The values
 | 
						|
          <literal>"1000000000"</literal> and <literal>"1GB"</literal> both
 | 
						|
          represent 1 gigabyte of memory.
 | 
						|
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      maxSqlMemory = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "25%";
 | 
						|
        description = ''
 | 
						|
          The maximum in-memory storage capacity available to store temporary
 | 
						|
          data for SQL queries.
 | 
						|
 | 
						|
          This can be a percentage, expressed with a fraction sign or as a
 | 
						|
          decimal-point number, or any bytes-based unit. For example,
 | 
						|
          <literal>"25%"</literal>, <literal>"0.25"</literal> both represent
 | 
						|
          25% of the available system memory. The values
 | 
						|
          <literal>"1000000000"</literal> and <literal>"1GB"</literal> both
 | 
						|
          represent 1 gigabyte of memory.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      package = mkOption {
 | 
						|
        type = types.package;
 | 
						|
        default = pkgs.cockroachdb;
 | 
						|
        defaultText = "pkgs.cockroachdb";
 | 
						|
        description = ''
 | 
						|
          The CockroachDB derivation to use for running the service.
 | 
						|
          
 | 
						|
          This would primarily be useful to enable Enterprise Edition features
 | 
						|
          in your own custom CockroachDB build (Nixpkgs CockroachDB binaries
 | 
						|
          only contain open source features and open source code).
 | 
						|
        '';
 | 
						|
      };
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  config = mkIf config.services.cockroachdb.enable {
 | 
						|
    assertions = [
 | 
						|
      { assertion = !cfg.insecure -> cfg.certsDir != null;
 | 
						|
        message = "CockroachDB must have a set of SSL certificates (.certsDir), or run in Insecure Mode (.insecure = true)";
 | 
						|
      }
 | 
						|
    ];
 | 
						|
 | 
						|
    environment.systemPackages = [ crdb ];
 | 
						|
 | 
						|
    users.users = optionalAttrs (cfg.user == "cockroachdb") {
 | 
						|
      cockroachdb = {
 | 
						|
        description = "CockroachDB Server User";
 | 
						|
        uid         = config.ids.uids.cockroachdb;
 | 
						|
        group       = cfg.group;
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    users.groups = optionalAttrs (cfg.group == "cockroachdb") {
 | 
						|
      cockroachdb.gid = config.ids.gids.cockroachdb;
 | 
						|
    };
 | 
						|
 | 
						|
    networking.firewall.allowedTCPPorts = lib.optionals cfg.openPorts
 | 
						|
      [ cfg.http.port cfg.listen.port ];
 | 
						|
 | 
						|
    systemd.services.cockroachdb =
 | 
						|
      { description   = "CockroachDB Server";
 | 
						|
        documentation = [ "man:cockroach(1)" "https://www.cockroachlabs.com" ];
 | 
						|
 | 
						|
        after    = [ "network.target" "time-sync.target" ];
 | 
						|
        requires = [ "time-sync.target" ];
 | 
						|
        wantedBy = [ "multi-user.target" ];
 | 
						|
 | 
						|
        unitConfig.RequiresMountsFor = "/var/lib/cockroachdb";
 | 
						|
 | 
						|
        serviceConfig =
 | 
						|
          { ExecStart = startupCommand;
 | 
						|
            Type = "notify";
 | 
						|
            User = cfg.user;
 | 
						|
            StateDirectory = "cockroachdb";
 | 
						|
            StateDirectoryMode = "0700";
 | 
						|
 | 
						|
            Restart = "always";
 | 
						|
 | 
						|
            # A conservative-ish timeout is alright here, because for Type=notify
 | 
						|
            # cockroach will send systemd pings during startup to keep it alive
 | 
						|
            TimeoutStopSec = 60;
 | 
						|
            RestartSec = 10;
 | 
						|
          };
 | 
						|
      };
 | 
						|
  };
 | 
						|
 | 
						|
  meta.maintainers = with lib.maintainers; [ thoughtpolice ];
 | 
						|
}
 |