head-vps/rustfs/init.sh

38 lines
2.2 KiB
Shell
Executable file

#!/bin/sh
# post_start hook of the server: brings RustFS to buckets.conf on every start (idempotent): each bucket exists, its
# public prefixes (and only those) are anonymously readable, and its app user exists with a policy
# limited to that bucket. Credentials come from fnox.toml; none is printed.
set -eu
cd /head
K="$(cat /run/secrets/age_key)"
get() { FNOX_AGE_KEY="$K" fnox get "$1"; }
ROOT="$(get RUSTFS_ROOT_ACCESS_KEY):$(get RUSTFS_ROOT_SECRET_KEY)"
S=http://127.0.0.1:9000
s3() { curl -fsS --aws-sigv4 "aws:amz:us-east-1:s3" --user "$ROOT" "$@"; }
# /health answers before IAM is loaded (503 meanwhile): wait for an authenticated call to succeed.
ready=""
for _ in $(seq 1 120); do s3 -o /dev/null "$S/" 2>/dev/null && { ready=1; break; }; sleep 1; done
[ -n "$ready" ] || { echo "RustFS not ready after 120s" >&2; exit 1; }
grep -v '^\s*\(#\|$\)' buckets.conf | while read -r bucket user prefixes; do
if ! s3 -o /dev/null -I "$S/$bucket" 2>/dev/null; then
s3 -X PUT "$S/$bucket" >/dev/null
echo "bucket $bucket: created"
fi
resources=""
for p in $prefixes; do resources="$resources${resources:+,}\"arn:aws:s3:::$bucket/$p*\""; done
s3 -X PUT "$S/$bucket?policy" -H 'Content-Type: application/json' --data-binary \
"{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\"],\"Resource\":[$resources]}]}" >/dev/null
U="$(echo "$user" | tr 'a-z-' 'A-Z_')"
ak="$(get "S3_${U}_ACCESS_KEY")"
sk="$(get "S3_${U}_SECRET_KEY")"
s3 -X PUT "$S/rustfs/admin/v3/add-canned-policy?name=app-$user" -H 'Content-Type: application/json' --data-binary \
"{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"s3:*\"],\"Resource\":[\"arn:aws:s3:::$bucket\",\"arn:aws:s3:::$bucket/*\"]}]}" >/dev/null
s3 -X PUT "$S/rustfs/admin/v3/add-user?accessKey=$ak" -H 'Content-Type: application/json' --data-binary \
"{\"secretKey\":\"$sk\",\"status\":\"enabled\"}" >/dev/null
s3 -X PUT "$S/rustfs/admin/v3/set-user-or-group-policy?policyName=app-$user&userOrGroup=$ak&isGroup=false" >/dev/null
echo "bucket $bucket: public ${prefixes:-none}; user $user limited to it"
done
echo "initialised"