diff --git a/.github/workflows/helm_ci.yml b/.github/workflows/helm_ci.yml index 98e993405e..10be17ac09 100644 --- a/.github/workflows/helm_ci.yml +++ b/.github/workflows/helm_ci.yml @@ -1328,6 +1328,67 @@ jobs: echo "$BOOL_FALSE" | grep -q -- '-status Suspended' || { echo "FAIL: bool false versioning did not Suspend the bucket"; exit 1; } echo "Bucket versioning: YAML bool false suspends consistently with string \"false\"" + echo "=== Testing bucket ttl, replication and disk in one fs.configure ===" + FS_CONFIGURE=$(helm template test $CHART_DIR \ + --set s3.enabled=true \ + --set s3.createBuckets[0].name=cfgbucket \ + --set s3.createBuckets[0].ttl=7d \ + --set-string s3.createBuckets[0].replication=001 \ + --set s3.createBuckets[0].disk=ssd | grep 'fs.configure -locationPrefix=/buckets/cfgbucket/' || true) + echo "$FS_CONFIGURE" | grep -q -- '-ttl=7d -replication=001 -disk=ssd -apply' || { echo "FAIL: bucket fs.configure missing ttl/replication/disk: $FS_CONFIGURE"; exit 1; } + echo "Bucket fs.configure: ttl, replication and disk render together" + + FS_CONFIGURE=$(helm template test $CHART_DIR \ + --set s3.enabled=true \ + --set s3.createBuckets[0].name=replbucket \ + --set-string s3.createBuckets[0].replication=002 | grep 'fs.configure -locationPrefix=/buckets/replbucket/' || true) + echo "$FS_CONFIGURE" | grep -q -- '/buckets/replbucket/ -replication=002 -apply' || { echo "FAIL: replication-only bucket did not render fs.configure: $FS_CONFIGURE"; exit 1; } + echo "Bucket fs.configure: replication without ttl" + + FS_CONFIGURE=$(helm template test $CHART_DIR \ + --set s3.enabled=true \ + --set s3.createBuckets[0].name=diskbucket \ + --set s3.createBuckets[0].disk=ssd | grep 'fs.configure -locationPrefix=/buckets/diskbucket/' || true) + echo "$FS_CONFIGURE" | grep -q -- '/buckets/diskbucket/ -disk=ssd -apply' || { echo "FAIL: disk-only bucket did not render fs.configure: $FS_CONFIGURE"; exit 1; } + echo "Bucket fs.configure: disk without ttl" + + if helm template test $CHART_DIR \ + --set s3.enabled=true \ + --set s3.createBuckets[0].name=numbucket \ + --set s3.createBuckets[0].replication=0 >/dev/null 2>&1; then + echo "FAIL: a numeric replication should fail to render"; exit 1 + fi + echo "Bucket fs.configure: numeric replication is rejected" + + if helm template test $CHART_DIR \ + --set s3.enabled=true \ + --set s3.createBuckets[0].name=badbucket \ + --set-string s3.createBuckets[0].replication=00O >/dev/null 2>&1; then + echo "FAIL: a non-digit replication should fail to render"; exit 1 + fi + echo "Bucket fs.configure: non-digit replication is rejected" + + if helm template test $CHART_DIR \ + --set s3.enabled=true \ + --set s3.createBuckets[0].name=bigbucket \ + --set-string s3.createBuckets[0].replication=256 >/dev/null 2>&1; then + echo "FAIL: a replication above 255 should fail to render"; exit 1 + fi + FS_CONFIGURE=$(helm template test $CHART_DIR \ + --set s3.enabled=true \ + --set s3.createBuckets[0].name=maxbucket \ + --set-string s3.createBuckets[0].replication=255 | grep 'fs.configure -locationPrefix=/buckets/maxbucket/' || true) + echo "$FS_CONFIGURE" | grep -q -- '/buckets/maxbucket/ -replication=255 -apply' || { echo "FAIL: replication 255 should render: $FS_CONFIGURE"; exit 1; } + echo "Bucket fs.configure: replication is limited to 000-255" + + FS_CONFIGURE=$(helm template test $CHART_DIR \ + --set s3.enabled=true \ + --set s3.createBuckets[0].name=nullbucket \ + --set s3.createBuckets[0].ttl=7d \ + --set s3.createBuckets[0].replication=null | grep 'fs.configure -locationPrefix=/buckets/nullbucket/' || true) + echo "$FS_CONFIGURE" | grep -q -- '/buckets/nullbucket/ -ttl=7d -apply' || { echo "FAIL: null replication should be treated as unset: $FS_CONFIGURE"; exit 1; } + echo "Bucket fs.configure: null replication is unset" + echo "" echo "=== Testing hook Job labels ===" # The hook Jobs were the only pods in the chart without the standard diff --git a/k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml b/k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml index 2a88b6018d..6a4bc2535c 100644 --- a/k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml +++ b/k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml @@ -215,8 +215,11 @@ spec: {{- end }} {{- end }} {{- range $createBuckets }} - {{- if .ttl }} - /bin/echo 'fs.configure -locationPrefix={{ $bucketsFolder }}/{{ .name }}/ -ttl={{ .ttl }} -apply' | /usr/bin/weed shell + {{- if not (or (kindIs "invalid" .replication) (and (kindIs "string" .replication) (or (eq .replication "") (regexMatch "^([01][0-9]{2}|2[0-4][0-9]|25[0-5])$" .replication)))) }} + {{- fail (printf "createBuckets %s: replication must be a quoted three-digit string from 000 to 255 such as \"001\" (use --set-string)" .name) }} + {{- end }} + {{- if or .ttl .replication .disk }} + /bin/echo 'fs.configure -locationPrefix={{ $bucketsFolder }}/{{ .name }}/{{- with .ttl }} -ttl={{ . }}{{- end }}{{- with .replication }} -replication={{ . }}{{- end }}{{- with .disk }} -disk={{ . }}{{- end }} -apply' | /usr/bin/weed shell {{- end }} {{- end }} {{- range $createBuckets }} diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index 0ba8072314..9f7e31be5f 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -1083,12 +1083,16 @@ filer: # You may specify buckets to be created during the install or upgrade process. # Buckets may be exposed publicly by setting `anonymousRead` to `true` # ttl format: [1-255][m|h|d|w|M|y] (e.g., 7d) + # replication (e.g., 001) and disk (e.g., ssd) apply to writes into the bucket + # removing ttl, replication or disk later keeps the stored rule; set a new value instead # objectLock enables S3 Object Lock (irreversible, forces versioning) # versioning: Enabled or Suspended (or bool true/false) # createBuckets: # - name: bucket-a # anonymousRead: true # ttl: 7d + # replication: "001" + # disk: ssd # objectLock: true # versioning: Enabled # - name: bucket-b @@ -1165,12 +1169,16 @@ s3: # You may specify buckets to be created during the install or upgrade process. # Buckets may be exposed publicly by setting `anonymousRead` to `true` # ttl format: [1-255][m|h|d|w|M|y] (e.g., 7d) + # replication (e.g., 001) and disk (e.g., ssd) apply to writes into the bucket + # removing ttl, replication or disk later keeps the stored rule; set a new value instead # objectLock enables S3 Object Lock (irreversible, forces versioning) # versioning: Enabled or Suspended (or bool true/false) # createBuckets: # - name: bucket-a # anonymousRead: true # ttl: 7d + # replication: "001" + # disk: ssd # objectLock: true # versioning: Enabled # - name: bucket-b @@ -2007,12 +2015,16 @@ allInOne: # You may specify buckets to be created during the install process. # Buckets may be exposed publicly by setting `anonymousRead` to `true` # ttl format: [1-255][m|h|d|w|M|y] (e.g., 7d) + # replication (e.g., 001) and disk (e.g., ssd) apply to writes into the bucket + # removing ttl, replication or disk later keeps the stored rule; set a new value instead # objectLock enables S3 Object Lock (irreversible, forces versioning) # versioning: Enabled or Suspended (or bool true/false) # createBuckets: # - name: bucket-a # anonymousRead: true # ttl: 7d + # replication: "001" + # disk: ssd # objectLock: true # versioning: Enabled # - name: bucket-b