at 25.11-pre 4.6 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.dragonflydb; 9 dragonflydb = pkgs.dragonflydb; 10 11 settings = 12 { 13 port = cfg.port; 14 dir = "/var/lib/dragonflydb"; 15 keys_output_limit = cfg.keysOutputLimit; 16 } 17 // (lib.optionalAttrs (cfg.bind != null) { bind = cfg.bind; }) 18 // (lib.optionalAttrs (cfg.requirePass != null) { requirepass = cfg.requirePass; }) 19 // (lib.optionalAttrs (cfg.maxMemory != null) { maxmemory = cfg.maxMemory; }) 20 // (lib.optionalAttrs (cfg.memcachePort != null) { memcache_port = cfg.memcachePort; }) 21 // (lib.optionalAttrs (cfg.dbNum != null) { dbnum = cfg.dbNum; }) 22 // (lib.optionalAttrs (cfg.cacheMode != null) { cache_mode = cfg.cacheMode; }); 23in 24{ 25 26 ###### interface 27 28 options = { 29 services.dragonflydb = { 30 enable = lib.mkEnableOption "DragonflyDB"; 31 32 user = lib.mkOption { 33 type = lib.types.str; 34 default = "dragonfly"; 35 description = "The user to run DragonflyDB as"; 36 }; 37 38 port = lib.mkOption { 39 type = lib.types.port; 40 default = 6379; 41 description = "The TCP port to accept connections."; 42 }; 43 44 bind = lib.mkOption { 45 type = with lib.types; nullOr str; 46 default = "127.0.0.1"; 47 description = '' 48 The IP interface to bind to. 49 `null` means "all interfaces". 50 ''; 51 }; 52 53 requirePass = lib.mkOption { 54 type = with lib.types; nullOr str; 55 default = null; 56 description = "Password for database"; 57 example = "letmein!"; 58 }; 59 60 maxMemory = lib.mkOption { 61 type = with lib.types; nullOr ints.unsigned; 62 default = null; 63 description = '' 64 The maximum amount of memory to use for storage (in bytes). 65 `null` means this will be automatically set. 66 ''; 67 }; 68 69 memcachePort = lib.mkOption { 70 type = with lib.types; nullOr port; 71 default = null; 72 description = '' 73 To enable memcached compatible API on this port. 74 `null` means disabled. 75 ''; 76 }; 77 78 keysOutputLimit = lib.mkOption { 79 type = lib.types.ints.unsigned; 80 default = 8192; 81 description = '' 82 Maximum number of returned keys in keys command. 83 `keys` is a dangerous command. 84 We truncate its result to avoid blowup in memory when fetching too many keys. 85 ''; 86 }; 87 88 dbNum = lib.mkOption { 89 type = with lib.types; nullOr ints.unsigned; 90 default = null; 91 description = "Maximum number of supported databases for `select`"; 92 }; 93 94 cacheMode = lib.mkOption { 95 type = with lib.types; nullOr bool; 96 default = null; 97 description = '' 98 Once this mode is on, Dragonfly will evict items least likely to be stumbled 99 upon in the future but only when it is near maxmemory limit. 100 ''; 101 }; 102 }; 103 }; 104 105 ###### implementation 106 107 config = lib.mkIf config.services.dragonflydb.enable { 108 109 users.users = lib.optionalAttrs (cfg.user == "dragonfly") { 110 dragonfly.description = "DragonflyDB server user"; 111 dragonfly.isSystemUser = true; 112 dragonfly.group = "dragonfly"; 113 }; 114 users.groups = lib.optionalAttrs (cfg.user == "dragonfly") { dragonfly = { }; }; 115 116 environment.systemPackages = [ dragonflydb ]; 117 118 systemd.services.dragonflydb = { 119 description = "DragonflyDB server"; 120 121 wantedBy = [ "multi-user.target" ]; 122 after = [ "network.target" ]; 123 124 serviceConfig = { 125 ExecStart = "${dragonflydb}/bin/dragonfly --alsologtostderr ${ 126 lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "--${n} ${lib.escapeShellArg v}") settings) 127 }"; 128 129 User = cfg.user; 130 131 # Filesystem access 132 ReadWritePaths = [ settings.dir ]; 133 StateDirectory = "dragonflydb"; 134 StateDirectoryMode = "0700"; 135 # Process Properties 136 LimitMEMLOCK = "infinity"; 137 # Caps 138 CapabilityBoundingSet = ""; 139 NoNewPrivileges = true; 140 # Sandboxing 141 ProtectSystem = "strict"; 142 ProtectHome = true; 143 PrivateTmp = true; 144 PrivateDevices = true; 145 ProtectKernelTunables = true; 146 ProtectKernelModules = true; 147 ProtectControlGroups = true; 148 LockPersonality = true; 149 RestrictAddressFamilies = [ 150 "AF_INET" 151 "AF_INET6" 152 ]; 153 RestrictRealtime = true; 154 PrivateMounts = true; 155 MemoryDenyWriteExecute = true; 156 }; 157 }; 158 }; 159}