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 environmentFile = mkOption {
27 type = types.nullOr types.path;
28 description = lib.mdDoc "File containing environment variables to be passed to the Garage server.";
29 default = null;
30 };
31
32 logLevel = mkOption {
33 type = types.enum ([ "info" "debug" "trace" ]);
34 default = "info";
35 example = "debug";
36 description = lib.mdDoc "Garage log level, see <https://garagehq.deuxfleurs.fr/documentation/quick-start/#launching-the-garage-server> for examples.";
37 };
38
39 settings = mkOption {
40 type = types.submodule {
41 freeformType = toml.type;
42
43 options = {
44 metadata_dir = mkOption {
45 default = "/var/lib/garage/meta";
46 type = types.path;
47 description = lib.mdDoc "The metadata directory, put this on a fast disk (e.g. SSD) if possible.";
48 };
49
50 data_dir = mkOption {
51 default = "/var/lib/garage/data";
52 type = types.path;
53 description = lib.mdDoc "The main data storage, put this on your large storage (e.g. high capacity HDD)";
54 };
55
56 replication_mode = mkOption {
57 default = "none";
58 type = types.enum ([ "none" "1" "2" "3" "2-dangerous" "3-dangerous" "3-degraded" 1 2 3 ]);
59 apply = v: toString v;
60 description = lib.mdDoc "Garage replication mode, defaults to none, see: <https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#replication-mode> for reference.";
61 };
62 };
63 };
64 description = lib.mdDoc "Garage configuration, see <https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/> for reference.";
65 };
66
67 package = mkOption {
68 type = types.package;
69 description = lib.mdDoc "Garage package to use, needs to be set explicitly. If you are upgrading from a major version, please read NixOS and Garage release notes for upgrade instructions.";
70 };
71 };
72
73 config = mkIf cfg.enable {
74 environment.etc."garage.toml" = {
75 source = configFile;
76 };
77
78 environment.systemPackages = [ cfg.package ]; # For administration
79
80 systemd.services.garage = {
81 description = "Garage Object Storage (S3 compatible)";
82 after = [ "network.target" "network-online.target" ];
83 wants = [ "network.target" "network-online.target" ];
84 wantedBy = [ "multi-user.target" ];
85 restartTriggers = [ configFile ] ++ (lib.optional (cfg.environmentFile != null) cfg.environmentFile);
86 serviceConfig = {
87 ExecStart = "${cfg.package}/bin/garage server";
88
89 StateDirectory = mkIf (hasPrefix "/var/lib/garage" cfg.settings.data_dir || hasPrefix "/var/lib/garage" cfg.settings.metadata_dir) "garage";
90 DynamicUser = lib.mkDefault true;
91 ProtectHome = true;
92 NoNewPrivileges = true;
93 EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile;
94 };
95 environment = {
96 RUST_LOG = lib.mkDefault "garage=${cfg.logLevel}";
97 } // cfg.extraEnvironment;
98 };
99 };
100}