2022-10-30 15:09:59 +00:00
{ config , lib , pkgs , . . . }:
with lib ;
let
cfg = config . services . garage ;
2023-10-19 13:55:26 +00:00
toml = pkgs . formats . toml { } ;
2022-10-30 15:09:59 +00:00
configFile = toml . generate " g a r a g e . t o m l " cfg . settings ;
in
{
2023-01-11 07:51:40 +00:00
meta = {
2023-02-02 18:25:31 +00:00
doc = ./garage.md ;
2024-06-05 15:53:02 +00:00
maintainers = [ ] ;
2023-01-11 07:51:40 +00:00
} ;
2022-10-30 15:09:59 +00:00
options . services . garage = {
2024-04-21 15:54:59 +00:00
enable = mkEnableOption " G a r a g e O b j e c t S t o r a g e ( S 3 c o m p a t i b l e ) " ;
2022-10-30 15:09:59 +00:00
extraEnvironment = mkOption {
type = types . attrsOf types . str ;
2024-04-21 15:54:59 +00:00
description = " E x t r a e n v i r o n m e n t v a r i a b l e s t o p a s s t o t h e G a r a g e s e r v e r . " ;
2023-10-19 13:55:26 +00:00
default = { } ;
example = { RUST_BACKTRACE = " y e s " ; } ;
2022-10-30 15:09:59 +00:00
} ;
2023-10-09 19:29:22 +00:00
environmentFile = mkOption {
type = types . nullOr types . path ;
2024-04-21 15:54:59 +00:00
description = " F i l e c o n t a i n i n g e n v i r o n m e n t v a r i a b l e s t o b e p a s s e d t o t h e G a r a g e s e r v e r . " ;
2023-10-09 19:29:22 +00:00
default = null ;
} ;
2022-10-30 15:09:59 +00:00
logLevel = mkOption {
2024-02-29 20:09:43 +00:00
type = types . enum ( [ " e r r o r " " w a r n " " i n f o " " d e b u g " " t r a c e " ] ) ;
2022-10-30 15:09:59 +00:00
default = " i n f o " ;
example = " d e b u g " ;
2024-04-21 15:54:59 +00:00
description = " G a r a g e l o g l e v e l , s e e < h t t p s : / / g a r a g e h q . d e u x f l e u r s . f r / d o c u m e n t a t i o n / q u i c k - s t a r t / # l a u n c h i n g - t h e - g a r a g e - s e r v e r > f o r e x a m p l e s . " ;
2022-10-30 15:09:59 +00:00
} ;
settings = mkOption {
type = types . submodule {
freeformType = toml . type ;
options = {
metadata_dir = mkOption {
default = " / v a r / l i b / g a r a g e / m e t a " ;
type = types . path ;
2024-04-21 15:54:59 +00:00
description = " T h e m e t a d a t a d i r e c t o r y , p u t t h i s o n a f a s t d i s k ( e . g . S S D ) i f p o s s i b l e . " ;
2022-10-30 15:09:59 +00:00
} ;
data_dir = mkOption {
default = " / v a r / l i b / g a r a g e / d a t a " ;
2024-06-05 15:53:02 +00:00
example = [ {
path = " / v a r / l i b / g a r a g e / d a t a " ;
capacity = " 2 T " ;
} ] ;
type = with types ; either path ( listOf attrs ) ;
description = ''
The directory in which Garage will store the data blocks of objects . This folder can be placed on an HDD .
Since v0 .9 .0 , Garage supports multiple data directories , refer to https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/ #data_dir for the exact format.
'' ;
2022-10-30 15:09:59 +00:00
} ;
} ;
} ;
2024-04-21 15:54:59 +00:00
description = " G a r a g e c o n f i g u r a t i o n , s e e < h t t p s : / / g a r a g e h q . d e u x f l e u r s . f r / d o c u m e n t a t i o n / r e f e r e n c e - m a n u a l / c o n f i g u r a t i o n / > f o r r e f e r e n c e . " ;
2022-10-30 15:09:59 +00:00
} ;
package = mkOption {
type = types . package ;
2024-04-21 15:54:59 +00:00
description = " G a r a g e p a c k a g e t o u s e , n e e d s t o b e s e t e x p l i c i t l y . I f y o u a r e u p g r a d i n g f r o m a m a j o r v e r s i o n , p l e a s e r e a d N i x O S a n d G a r a g e r e l e a s e n o t e s f o r u p g r a d e i n s t r u c t i o n s . " ;
2022-10-30 15:09:59 +00:00
} ;
} ;
config = mkIf cfg . enable {
2024-05-15 15:35:15 +00:00
assertions = [
# We removed our module-level default for replication_mode. If a user upgraded
# to garage 1.0.0 while relying on the module-level default, they would be left
# with a config which evaluates and builds, but then garage refuses to start
# because either replication_factor or replication_mode is required.
# The replication_factor option also was `toString`'ed before, which is
# now not possible anymore, so we prompt the user to change it to a string
# if present.
# These assertions can be removed in NixOS 24.11, when all users have been
# warned once.
{
2024-06-05 15:53:02 +00:00
assertion = ( cfg . settings ? replication_factor || cfg . settings ? replication_mode ) || lib . versionOlder cfg . package . version " 1 . 0 . 0 " ;
2024-05-15 15:35:15 +00:00
message = ''
Garage 1 .0 .0 requires an explicit replication factor to be set .
Please set replication_factor to 1 explicitly to preserve the previous behavior .
https://git.deuxfleurs.fr/Deuxfleurs/garage/src/tag/v1.0.0/doc/book/reference-manual/configuration.md #replication_factor
'' ;
}
{
assertion = lib . isString ( cfg . settings . replication_mode or " " ) ;
message = ''
The explicit ` replication_mode ` option in ` services . garage . settings `
has been removed and is now handled by the freeform settings in order
to allow it being completely absent ( for Garage 1 . x ) .
That module option previously ` toString ` ' ed the value it's configured
with , which is now no longer possible .
You're still using a non-string here , please manually set it to
a string , or migrate to the separate setting keys introduced in 1 . x .
Refer to https://garagehq.deuxfleurs.fr/documentation/working-documents/migration-1/
for the migration guide .
'' ;
}
] ;
2022-10-30 15:09:59 +00:00
environment . etc . " g a r a g e . t o m l " = {
source = configFile ;
} ;
2024-04-21 15:54:59 +00:00
# For administration
environment . systemPackages = [
( pkgs . writeScriptBin " g a r a g e " ''
# make it so all future variables set are automatically exported as environment variables
set - a
# source the set environmentFile (since systemd EnvironmentFile is supposed to be a minor subset of posix sh parsing) (with shell arg escaping to avoid quoting issues)
[ - f $ { lib . escapeShellArg cfg . environmentFile } ] && . $ { lib . escapeShellArg cfg . environmentFile }
# exec the program with quoted args (also with shell arg escaping for the program path to avoid quoting issues there)
exec $ { lib . escapeShellArg ( lib . getExe cfg . package ) } " $ @ "
'' )
] ;
2022-10-30 15:09:59 +00:00
systemd . services . garage = {
description = " G a r a g e O b j e c t S t o r a g e ( S 3 c o m p a t i b l e ) " ;
after = [ " n e t w o r k . t a r g e t " " n e t w o r k - o n l i n e . t a r g e t " ] ;
wants = [ " n e t w o r k . t a r g e t " " n e t w o r k - o n l i n e . t a r g e t " ] ;
wantedBy = [ " m u l t i - u s e r . t a r g e t " ] ;
2023-10-09 19:29:22 +00:00
restartTriggers = [ configFile ] ++ ( lib . optional ( cfg . environmentFile != null ) cfg . environmentFile ) ;
2022-10-30 15:09:59 +00:00
serviceConfig = {
ExecStart = " ${ cfg . package } / b i n / g a r a g e s e r v e r " ;
2023-11-16 04:20:00 +00:00
StateDirectory = mkIf ( hasPrefix " / v a r / l i b / g a r a g e " cfg . settings . data_dir || hasPrefix " / v a r / l i b / g a r a g e " cfg . settings . metadata_dir ) " g a r a g e " ;
2022-10-30 15:09:59 +00:00
DynamicUser = lib . mkDefault true ;
ProtectHome = true ;
NoNewPrivileges = true ;
2023-10-09 19:29:22 +00:00
EnvironmentFile = lib . optional ( cfg . environmentFile != null ) cfg . environmentFile ;
2022-10-30 15:09:59 +00:00
} ;
environment = {
RUST_LOG = lib . mkDefault " g a r a g e = ${ cfg . logLevel } " ;
} // cfg . extraEnvironment ;
} ;
} ;
}