summaryrefslogtreecommitdiffstats
path: root/nixos/modules/services/databases/tigerbeetle.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/databases/tigerbeetle.nix')
-rw-r--r--nixos/modules/services/databases/tigerbeetle.nix115
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 ];
+ };
+}