diff options
Diffstat (limited to 'nixos/modules/services/databases/tigerbeetle.nix')
-rw-r--r-- | nixos/modules/services/databases/tigerbeetle.nix | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/nixos/modules/services/databases/tigerbeetle.nix b/nixos/modules/services/databases/tigerbeetle.nix new file mode 100644 index 000000000000..b90a0703175f --- /dev/null +++ b/nixos/modules/services/databases/tigerbeetle.nix @@ -0,0 +1,115 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.tigerbeetle; +in +{ + meta = { + maintainers = with lib.maintainers; [ danielsidhion ]; + doc = ./tigerbeetle.md; + buildDocsInSandbox = true; + }; + + options = { + services.tigerbeetle = with lib; { + enable = mkEnableOption (mdDoc "TigerBeetle server"); + + package = mkPackageOption pkgs "tigerbeetle" { }; + + clusterId = mkOption { + type = types.either types.ints.unsigned (types.strMatching "[0-9]+"); + default = 0; + description = lib.mdDoc '' + The 128-bit cluster ID used to create the replica data file (if needed). + Since Nix only supports integers up to 64 bits, you need to pass a string to this if the cluster ID can't fit in 64 bits. + Otherwise, you can pass the cluster ID as either an integer or a string. + ''; + }; + + replicaIndex = mkOption { + type = types.ints.unsigned; + default = 0; + description = lib.mdDoc '' + The index (starting at 0) of the replica in the cluster. + ''; + }; + + replicaCount = mkOption { + type = types.ints.unsigned; + default = 1; + description = lib.mdDoc '' + The number of replicas participating in replication of the cluster. + ''; + }; + + cacheGridSize = mkOption { + type = types.strMatching "[0-9]+(K|M|G)B"; + default = "1GB"; + description = lib.mdDoc '' + The grid cache size. + The grid cache acts like a page cache for TigerBeetle. + It is recommended to set this as large as possible. + ''; + }; + + addresses = mkOption { + type = types.listOf types.nonEmptyStr; + default = [ "3001" ]; + description = lib.mdDoc '' + The addresses of all replicas in the cluster. + This should be a list of IPv4/IPv6 addresses with port numbers. + Either the address or port number (but not both) may be omitted, in which case a default of 127.0.0.1 or 3001 will be used. + The first address in the list corresponds to the address for replica 0, the second address for replica 1, and so on. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = + let + numAddresses = builtins.length cfg.addresses; + in + [ + { + assertion = cfg.replicaIndex < cfg.replicaCount; + message = "the TigerBeetle replica index must fit the configured replica count"; + } + { + assertion = cfg.replicaCount == numAddresses; + message = if cfg.replicaCount < numAddresses then "TigerBeetle must not have more addresses than the configured number of replicas" else "TigerBeetle must be configured with the addresses of all replicas"; + } + ]; + + systemd.services.tigerbeetle = + let + replicaDataPath = "/var/lib/tigerbeetle/${builtins.toString cfg.clusterId}_${builtins.toString cfg.replicaIndex}.tigerbeetle"; + in + { + description = "TigerBeetle server"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + preStart = '' + if ! test -e "${replicaDataPath}"; then + ${lib.getExe cfg.package} format --cluster="${builtins.toString cfg.clusterId}" --replica="${builtins.toString cfg.replicaIndex}" --replica-count="${builtins.toString cfg.replicaCount}" "${replicaDataPath}" + fi + ''; + + serviceConfig = { + Type = "exec"; + + DynamicUser = true; + ProtectHome = true; + DevicePolicy = "closed"; + + StateDirectory = "tigerbeetle"; + StateDirectoryMode = 700; + + ExecStart = "${lib.getExe cfg.package} start --cache-grid=${cfg.cacheGridSize} --addresses=${lib.escapeShellArg (builtins.concatStringsSep "," cfg.addresses)} ${replicaDataPath}"; + }; + }; + + environment.systemPackages = [ cfg.package ]; + }; +} |