Fediversity/garage.nix

140 lines
4.5 KiB
Nix
Raw Normal View History

let
# generate one using openssl (somehow)
# XXX: when importing, garage tells you importing is only meant for keys previously generated by garage. is it okay to generate them using openssl?
snakeoil_key = {
id = "GK3515373e4c851ebaad366558";
secret = "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34";
};
in
# TODO: expand to a multi-machine setup
{ config, lib, pkgs, ... }: {
# add in options to ensure creation of buckets and keys
2024-03-27 10:59:50 +01:00
options =
let
inherit (lib) types mkOption;
in {
services.garage = {
ensureBuckets = mkOption {
type = types.attrsOf (types.submodule {
options = {
website = mkOption {
type = types.bool;
default = false;
};
};
});
};
ensureKeys = mkOption {
type = types.attrsOf (types.submodule {
options = {
id = mkOption {
type = types.string;
};
secret = mkOption {
type = types.string;
};
# TODO: assert at least one of these is true
ensureAccess = mkOption {
type = types.attrsOf (types.submodule {
options = {
read = mkOption {
type = types.bool;
default = false;
};
write = mkOption {
type = types.bool;
default = false;
};
owner = mkOption {
type = types.bool;
default = false;
};
};
});
default = [];
};
};
});
};
};
};
config = {
virtualisation.vmVariant = {
virtualisation.diskSize = 2048;
virtualisation.forwardPorts = [
{
from = "host";
host.port = 3901;
guest.port = 3901;
}
{
from = "host";
host.port = 3902;
guest.port = 3902;
}
];
};
environment.systemPackages = [ pkgs.minio-client ];
networking.firewall.allowedTCPPorts = [ 3901 3902 ];
services.garage = {
enable = true;
package = pkgs.garage_0_9;
settings = {
replication_mode = "none";
# TODO: use a secret file
rpc_secret = "d576c4478cc7d0d94cfc127138cbb82018b0155c037d1c827dfb6c36be5f6625";
# TODO: why does this have to be set? is there not a sensible default?
rpc_bind_addr = "[::]:3901";
rpc_public_addr = "[::1]:3901";
s3_api.api_bind_addr = "[::]:3900";
s3_web.bind_addr = "[::]:3902";
s3_web.root_domain = ".web.garage.localhost";
index = "index.html";
s3_api.s3_region = "garage";
s3_api.root_domain = ".s3.garage.localhost";
};
};
systemd.services.ensure-garage = {
after = [ "garage.service" ];
wantedBy = [ "garage.service" ];
path = [ config.services.garage.package pkgs.perl ];
script = ''
set -xeuo pipefail
# give garage time to start up
sleep 3
2024-03-27 10:59:50 +01:00
# XXX: this is very sensitive to being a single instance
# (bare minimum to get garage up and running)
# also, it's crazy that we have to parse command output like this
GARAGE_ID=$(garage node id 2>/dev/null | perl -ne '/(.*)@.*/ && print $1')
garage layout assign -z g1 -c 1G $GARAGE_ID
LAYOUT_VER=$(garage layout show | perl -ne '/Current cluster layout version: (\d*)/ && print $1')
garage layout apply --version $((LAYOUT_VER + 1))
2024-03-27 10:59:50 +01:00
${
lib.concatStringsSep "\n" (lib.mapAttrsToList (bucket: { website }: ''
garage bucket create ${bucket}
# XXX: should this --deny the website if `website` is false?
${lib.optionalString website ''
garage bucket website --allow ${bucket}
''}
'') config.services.garage.ensureBuckets)
}
${
lib.concatStringsSep "\n" (lib.mapAttrsToList (key: {id, secret, ensureAccess}: ''
garage key import --yes -n ${key} ${id} ${secret}
${
lib.concatStringsSep "\n" (lib.mapAttrsToList (bucket: { read, write, owner }: ''
garage bucket allow ${lib.optionalString read "--read"} ${lib.optionalString write "--write"} ${lib.optionalString owner "--owner"} ${bucket} --key ${key}
'') ensureAccess)
}
'') config.services.garage.ensureKeys)
}
'';
};
};
}