1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.garage;
7 toml = pkgs.formats.toml {};
8 configFile = toml.generate "garage.toml" cfg.settings;
9in
10{
11 meta = {
12 doc = ./garage.md;
13 maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
14 };
15
16 options.services.garage = {
17 enable = mkEnableOption (lib.mdDoc "Garage Object Storage (S3 compatible)");
18
19 extraEnvironment = mkOption {
20 type = types.attrsOf types.str;
21 description = lib.mdDoc "Extra environment variables to pass to the Garage server.";
22 default = {};
23 example = { RUST_BACKTRACE="yes"; };
24 };
25
26 logLevel = mkOption {
27 type = types.enum (["info" "debug" "trace"]);
28 default = "info";
29 example = "debug";
30 description = lib.mdDoc "Garage log level, see <https://garagehq.deuxfleurs.fr/documentation/quick-start/#launching-the-garage-server> for examples.";
31 };
32
33 settings = mkOption {
34 type = types.submodule {
35 freeformType = toml.type;
36
37 options = {
38 metadata_dir = mkOption {
39 default = "/var/lib/garage/meta";
40 type = types.path;
41 description = lib.mdDoc "The metadata directory, put this on a fast disk (e.g. SSD) if possible.";
42 };
43
44 data_dir = mkOption {
45 default = "/var/lib/garage/data";
46 type = types.path;
47 description = lib.mdDoc "The main data storage, put this on your large storage (e.g. high capacity HDD)";
48 };
49
50 replication_mode = mkOption {
51 default = "none";
52 type = types.enum ([ "none" "1" "2" "3" 1 2 3 ]);
53 apply = v: toString v;
54 description = lib.mdDoc "Garage replication mode, defaults to none, see: <https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#replication-mode> for reference.";
55 };
56 };
57 };
58 description = lib.mdDoc "Garage configuration, see <https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/> for reference.";
59 };
60
61 package = mkOption {
62 # TODO: when 23.05 is released and if Garage 0.9 is the default, put a stateVersion check.
63 default = if versionAtLeast config.system.stateVersion "23.05" then pkgs.garage_0_8
64 else pkgs.garage_0_7;
65 defaultText = literalExpression "pkgs.garage_0_7";
66 type = types.package;
67 description = lib.mdDoc "Garage package to use, if you are upgrading from a major version, please read NixOS and Garage release notes for upgrade instructions.";
68 };
69 };
70
71 config = mkIf cfg.enable {
72 environment.etc."garage.toml" = {
73 source = configFile;
74 };
75
76 environment.systemPackages = [ cfg.package ]; # For administration
77
78 systemd.services.garage = {
79 description = "Garage Object Storage (S3 compatible)";
80 after = [ "network.target" "network-online.target" ];
81 wants = [ "network.target" "network-online.target" ];
82 wantedBy = [ "multi-user.target" ];
83 serviceConfig = {
84 ExecStart = "${cfg.package}/bin/garage server";
85
86 StateDirectory = mkIf (hasPrefix "/var/lib/garage" cfg.settings.data_dir && hasPrefix "/var/lib/garage" cfg.settings.metadata_dir) "garage";
87 DynamicUser = lib.mkDefault true;
88 ProtectHome = true;
89 NoNewPrivileges = true;
90 };
91 environment = {
92 RUST_LOG = lib.mkDefault "garage=${cfg.logLevel}";
93 } // cfg.extraEnvironment;
94 };
95 };
96}