at 25.11-pre 3.6 kB view raw
1{ 2 lib, 3 pkgs, 4 config, 5 ... 6}: 7let 8 settingsFormat = pkgs.formats.yaml { }; 9 10 # gemstash uses a yaml config where the keys are ruby symbols, 11 # which means they start with ':'. This would be annoying to use 12 # on the nix side, so we rewrite plain names instead. 13 prefixColon = 14 s: 15 lib.listToAttrs ( 16 map (attrName: { 17 name = ":${attrName}"; 18 value = if lib.isAttrs s.${attrName} then prefixColon s."${attrName}" else s."${attrName}"; 19 }) (lib.attrNames s) 20 ); 21 22 # parse the port number out of the tcp://ip:port bind setting string 23 parseBindPort = bind: lib.strings.toInt (lib.last (lib.strings.splitString ":" bind)); 24 25 cfg = config.services.gemstash; 26in 27{ 28 options.services.gemstash = { 29 enable = lib.mkEnableOption "gemstash, a cache for rubygems.org and a private gem server"; 30 31 openFirewall = lib.mkOption { 32 type = lib.types.bool; 33 default = false; 34 description = '' 35 Whether to open the firewall for the port in {option}`services.gemstash.bind`. 36 ''; 37 }; 38 39 settings = lib.mkOption { 40 default = { }; 41 description = '' 42 Configuration for Gemstash. The details can be found at in 43 [gemstash documentation](https://github.com/rubygems/gemstash/blob/master/man/gemstash-configuration.5.md). 44 Each key set here is automatically prefixed with ":" to match the gemstash expectations. 45 ''; 46 type = lib.types.submodule { 47 freeformType = settingsFormat.type; 48 options = { 49 base_path = lib.mkOption { 50 type = lib.types.path; 51 default = "/var/lib/gemstash"; 52 description = "Path to store the gem files and the sqlite database. If left unchanged, the directory will be created."; 53 }; 54 bind = lib.mkOption { 55 type = lib.types.str; 56 default = "tcp://0.0.0.0:9292"; 57 description = "Host and port combination for the server to listen on."; 58 }; 59 db_adapter = lib.mkOption { 60 type = lib.types.nullOr ( 61 lib.types.enum [ 62 "sqlite3" 63 "postgres" 64 "mysql" 65 "mysql2" 66 ] 67 ); 68 default = null; 69 description = "Which database type to use. For choices other than sqlite3, the dbUrl has to be specified as well."; 70 }; 71 db_url = lib.mkOption { 72 type = lib.types.nullOr lib.types.str; 73 default = null; 74 description = "The database to connect to when using postgres, mysql, or mysql2."; 75 }; 76 }; 77 }; 78 }; 79 }; 80 81 config = lib.mkIf cfg.enable { 82 users = { 83 users.gemstash = { 84 group = "gemstash"; 85 isSystemUser = true; 86 }; 87 groups.gemstash = { }; 88 }; 89 90 networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 91 (parseBindPort cfg.settings.bind) 92 ]; 93 94 systemd.services.gemstash = { 95 wantedBy = [ "multi-user.target" ]; 96 after = [ "network.target" ]; 97 serviceConfig = lib.mkMerge [ 98 { 99 ExecStart = "${pkgs.gemstash}/bin/gemstash start --no-daemonize --config-file ${settingsFormat.generate "gemstash.yaml" (prefixColon cfg.settings)}"; 100 NoNewPrivileges = true; 101 User = "gemstash"; 102 Group = "gemstash"; 103 PrivateTmp = true; 104 RestrictSUIDSGID = true; 105 LockPersonality = true; 106 } 107 (lib.mkIf (cfg.settings.base_path == "/var/lib/gemstash") { 108 StateDirectory = "gemstash"; 109 }) 110 ]; 111 }; 112 }; 113}