diff --git a/machines/prattle/default.nix b/machines/prattle/default.nix index 36ac165..cf2a031 100644 --- a/machines/prattle/default.nix +++ b/machines/prattle/default.nix @@ -105,6 +105,11 @@ protonvpn-wg = { file = ../../secrets/protonvpn-wg.age; }; + garage-env = { + file = ../../secrets/garage-env.age; + owner = "garage"; + group = "garage"; + }; }; programs.nh = { @@ -304,7 +309,7 @@ "d /storage/torrents 2775 root media -" "d /storage/torrents/.incomplete 2775 root media -" "d /storage/.trash 2775 root media -" - "d /storage/s3 0750 root root -" + "d /storage/s3 0750 garage garage -" "d /storage/s3/meta 0750 garage garage -" "d /storage/s3/data 0750 garage garage -" ]; @@ -492,7 +497,7 @@ data_dir = "/storage/s3/data"; db_engine = "lmdb"; replication_factor = 1; - consistency_mode = "none"; + consistency_mode = "consistent"; rpc_bind_addr = "[::]:3901"; rpc_public_addr = "127.0.0.1:3901"; s3_api = { @@ -511,12 +516,19 @@ }; # Custom paths need a static user; disable DynamicUser so tmpfiles ownership works - systemd.services.garage.serviceConfig = { - DynamicUser = lib.mkForce false; - User = "garage"; - Group = "garage"; + systemd.services.garage = { + serviceConfig = { + DynamicUser = lib.mkForce false; + User = "garage"; + Group = "garage"; + ExecStartPre = "!${pkgs.bash}/bin/bash -c 'mkdir -p /storage/s3/meta /storage/s3/data && chown garage:garage /storage/s3 && chown -R garage:garage /storage/s3/meta /storage/s3/data'"; + }; + after = [ "storage.mount" ]; + requires = [ "storage.mount" ]; }; + services.garage.environmentFile = config.age.secrets.garage-env.path; + # Bootstrap garage: generate RPC secret, assign layout, create default key/bucket systemd.services.garage-bootstrap = { description = "Bootstrap Garage cluster (one-time setup)"; @@ -528,10 +540,11 @@ RemainAfterExit = true; EnvironmentFile = config.services.garage.environmentFile or null; }; + path = [ config.services.garage.package pkgs.coreutils ]; script = '' set -euo pipefail GARAGE="${config.services.garage.package}/bin/garage" - MARKER="/var/lib/garage/.bootstrapped" + MARKER="/storage/s3/.bootstrapped" if [ -f "$MARKER" ]; then echo "Garage already bootstrapped" @@ -544,13 +557,14 @@ sleep 1 done - # Get or generate node ID - NODE_ID=$($GARAGE node id 2>/dev/null | head -1 || true) + # Get node ID (first field only) + NODE_ID=$($GARAGE node id 2>/dev/null | cut -d' ' -f1 | head -1) if [ -z "$NODE_ID" ]; then echo "Waiting for node ID..." sleep 2 - NODE_ID=$($GARAGE node id 2>/dev/null | head -1) + NODE_ID=$($GARAGE node id 2>/dev/null | cut -d' ' -f1 | head -1) fi + echo "Node ID: $NODE_ID" # Assign layout $GARAGE layout assign -z dc1 -c 1G "$NODE_ID" || true diff --git a/secrets/garage-env.age b/secrets/garage-env.age new file mode 100644 index 0000000..3d491d6 --- /dev/null +++ b/secrets/garage-env.age @@ -0,0 +1,13 @@ +age-encryption.org/v1 +-> ssh-rsa DqcG0Q +btqY5wDM2A7iEUcOK+GHGKnM5re3kbZxTAdL8vNlJQaQ4vqiZlrtdQA7radATjsR +AmriN3Tb2zhZWYdN1UtwKCgYYgKJ7JHizf5DuizavF86buu/7iDb6pjDTidumhdP +3VhG+P4YV24/7fkx+9rR/Nqubqs4Mf12NGH/TgR2zFTv2fosX6k1CvCxGiXpUyel +XuPfi2h0FHI3LlmOFbxFJ2ddbRPUeROq79kM29iWIQiXcidTIpRAKIHyyDxZsUuQ +jDGDwkaG+dOEVxRgTuqpz9YFS94+j9i9zQGcYbHaTiaTGRi7+I2GDSSD2Uf1A1/G +mm7Twbs66KTUKaSw/lDJuYIe2ablmOdBNg6OKelM7wiZ1V5CzVYHQjrBJyBR2qjK +fe/HpzEPlpKjX1upjTK787VbJLLUe8jYWrjUx6GKxnSFHRvftAz0PWzO6Ld7qGOe +K4ppJuDHkOhVxgOCgJOVGVE6V8SywuKfuEtN8pNhRHji+FPzrzRLgXXTnXOEB3XG + +--- lazR9E5zSfi20UjTdYhL4YAR3avfrtgI6yZrywh4LC8 +�U�P��t������j���}9�y)�� �j�n�zcYC����E�����{��j1�).?&نG��p�h�UJy�'A�j�a���{���k��^�=�IB�e�tC� |��?�� \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 5a33a20..3dbad33 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -99,4 +99,7 @@ in "minio.age".publicKeys = [ kierank ]; + "garage-env.age".publicKeys = [ + kierank + ]; }