249 lines
7.4 KiB
Nix
249 lines
7.4 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
with lib; let
|
|
cfg = config.services.cockroachdb-bin;
|
|
crdb = cfg.package;
|
|
|
|
escapeSystemdExecArg = arg: let
|
|
s =
|
|
if builtins.isPath arg
|
|
then "${arg}"
|
|
else if builtins.isString arg
|
|
then arg
|
|
else if builtins.isInt arg || builtins.isFloat arg
|
|
then toString arg
|
|
else throw "escapeSystemdExecArg only allows strings, paths and numbers";
|
|
in
|
|
lib.replaceStrings ["%" "$"] ["%%" "$$"] (builtins.toJSON s);
|
|
|
|
# Quotes a list of arguments into a single string for use in a Exec*
|
|
# line.
|
|
escapeSystemdExecArgs = lib.concatMapStringsSep " " escapeSystemdExecArg;
|
|
|
|
startupCommand =
|
|
escapeSystemdExecArgs
|
|
([
|
|
# Basic startup
|
|
"${crdb}/bin/cockroach"
|
|
(
|
|
if (cfg.join != null)
|
|
then "start"
|
|
else "start-single-node"
|
|
)
|
|
"--logtostderr"
|
|
"--store=/var/lib/cockroachdb"
|
|
|
|
# WebUI settings
|
|
"--http-addr=${cfg.http.address}:${toString cfg.http.port}"
|
|
|
|
# Cluster listen address
|
|
"--listen-addr=${cfg.listen.address}:${toString cfg.listen.port}"
|
|
|
|
# Cache and memory settings.
|
|
"--cache=${cfg.cache}"
|
|
"--max-sql-memory=${cfg.maxSqlMemory}"
|
|
|
|
# Certificate/security settings.
|
|
(
|
|
if cfg.insecure
|
|
then "--insecure"
|
|
else "--certs-dir=${cfg.certsDir}"
|
|
)
|
|
]
|
|
++ lib.optional (cfg.join != null) "--join=${cfg.join}"
|
|
++ lib.optional (cfg.locality != null) "--locality=${cfg.locality}"
|
|
++ cfg.extraArgs);
|
|
|
|
addressOption = descr: defaultPort: {
|
|
address = mkOption {
|
|
type = types.str;
|
|
default = "localhost";
|
|
description = lib.mdDoc "Address to bind to for ${descr}";
|
|
};
|
|
|
|
port = mkOption {
|
|
type = types.port;
|
|
default = defaultPort;
|
|
description = lib.mdDoc "Port to bind to for ${descr}";
|
|
};
|
|
};
|
|
in {
|
|
options = {
|
|
services.cockroachdb-bin = {
|
|
enable = mkEnableOption (lib.mdDoc "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 = lib.mdDoc ''
|
|
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:
|
|
|
|
```
|
|
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
|
|
```
|
|
'';
|
|
};
|
|
|
|
join = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = lib.mdDoc "The addresses for connecting the node to a cluster.";
|
|
};
|
|
|
|
insecure = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = lib.mdDoc "Run in insecure mode.";
|
|
};
|
|
|
|
certsDir = mkOption {
|
|
type = types.nullOr types.path;
|
|
default = null;
|
|
description = lib.mdDoc "The path to the certificate directory.";
|
|
};
|
|
|
|
user = mkOption {
|
|
type = types.str;
|
|
default = "cockroachdb";
|
|
description = lib.mdDoc "User account under which CockroachDB runs";
|
|
};
|
|
|
|
group = mkOption {
|
|
type = types.str;
|
|
default = "cockroachdb";
|
|
description = lib.mdDoc "User account under which CockroachDB runs";
|
|
};
|
|
|
|
openPorts = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = lib.mdDoc "Open firewall ports for cluster communication by default";
|
|
};
|
|
|
|
cache = mkOption {
|
|
type = types.str;
|
|
default = "25%";
|
|
description = lib.mdDoc ''
|
|
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,
|
|
`"25%"`, `"0.25"` both represent
|
|
25% of the available system memory. The values
|
|
`"1000000000"` and `"1GB"` both
|
|
represent 1 gigabyte of memory.
|
|
|
|
'';
|
|
};
|
|
|
|
maxSqlMemory = mkOption {
|
|
type = types.str;
|
|
default = "25%";
|
|
description = lib.mdDoc ''
|
|
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,
|
|
`"25%"`, `"0.25"` both represent
|
|
25% of the available system memory. The values
|
|
`"1000000000"` and `"1GB"` both
|
|
represent 1 gigabyte of memory.
|
|
'';
|
|
};
|
|
|
|
package = mkOption {
|
|
type = types.package;
|
|
default = pkgs.cockroachdb-bin;
|
|
defaultText = literalExpression "pkgs.cockroachdb-bin";
|
|
description = lib.mdDoc ''
|
|
The CockroachDB derivation to use for running the service.
|
|
'';
|
|
};
|
|
|
|
extraArgs = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
example = ["--advertise-addr" "[fe80::f6f2:::]"];
|
|
description = lib.mdDoc ''
|
|
Extra CLI arguments passed to {command}`cockroach start`.
|
|
For the full list of supported arguments, check <https://www.cockroachlabs.com/docs/stable/cockroach-start.html#flags>
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkIf config.services.cockroachdb-bin.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];
|
|
}
|