From b2e807897173fb5192ec498d0a7ea9f05e610f26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E6=AD=A3=E8=B6=85?= Date: Wed, 11 Mar 2026 21:56:32 +0800 Subject: [PATCH] fix(policy): avoid unicode panic in variable resolver (#2115) --- .github/workflows/docker.yml | 24 ++++-------------------- crates/policy/src/policy/variables.rs | 19 +++++++++++++++---- helm/README.md | 24 +++++++++++++----------- helm/rustfs/templates/configmap.yaml | 11 +++++++++++ helm/rustfs/templates/statefulset.yaml | 4 ++-- helm/rustfs/values.yaml | 7 +++++++ 6 files changed, 52 insertions(+), 37 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c4e2c100..c4d8f381 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -163,14 +163,7 @@ jobs: if [[ "$version" == *"alpha"* ]] || [[ "$version" == *"beta"* ]] || [[ "$version" == *"rc"* ]]; then build_type="prerelease" is_prerelease=true - # TODO: Temporary change - currently allows alpha versions to also create latest tags - # After the version is stable, you need to remove the following line and restore the original logic (latest is created only for stable versions) - if [[ "$version" == *"alpha"* ]]; then - create_latest=true - echo "🧪 Building Docker image for prerelease: $version (temporarily allowing creation of latest tag)" - else - echo "🧪 Building Docker image for prerelease: $version" - fi + echo "🧪 Building Docker image for prerelease: $version" else build_type="release" create_latest=true @@ -216,14 +209,7 @@ jobs: v*alpha*|v*beta*|v*rc*|*alpha*|*beta*|*rc*) build_type="prerelease" is_prerelease=true - # TODO: Temporary change - currently allows alpha versions to also create latest tags - # After the version is stable, you need to remove the if block below and restore the original logic. - if [[ "$input_version" == *"alpha"* ]]; then - create_latest=true - echo "🧪 Building with prerelease version: $input_version (temporarily allowing creation of latest tag)" - else - echo "🧪 Building with prerelease version: $input_version" - fi + echo "🧪 Building with prerelease version: $input_version" ;; # Release versions (match after prereleases, more general) v[0-9]*|[0-9]*.*.*) @@ -450,10 +436,8 @@ jobs: "prerelease") echo "🧪 Prerelease Docker image has been built with ${VERSION} tags" echo "⚠️ This is a prerelease image - use with caution" - # TODO: Temporary change - alpha versions currently create the latest tag - # After the version is stable, you need to restore the following prompt information - if [[ "$VERSION" == *"alpha"* ]] && [[ "$CREATE_LATEST" == "true" ]]; then - echo "🏷️ Latest tag has been created for alpha version (temporary measures)" + if [[ "$CREATE_LATEST" == "true" ]]; then + echo "🏷️ Latest tag has been explicitly created for prerelease" else echo "🚫 Latest tag NOT created for prerelease" fi diff --git a/crates/policy/src/policy/variables.rs b/crates/policy/src/policy/variables.rs index 4c02ae08..ce7d30a5 100644 --- a/crates/policy/src/policy/variables.rs +++ b/crates/policy/src/policy/variables.rs @@ -311,10 +311,11 @@ async fn resolve_single_pass(pattern: &str, resolver: &dyn PolicyVariableResolve let mut brace_count = 1; let mut end_pos = actual_pos + 2; // Start after "${" - while end_pos < results[i].len() && brace_count > 0 { - match results[i].chars().nth(end_pos).unwrap() { - '{' => brace_count += 1, - '}' => brace_count -= 1, + let bytes = results[i].as_bytes(); + while end_pos < bytes.len() && brace_count > 0 { + match bytes[end_pos] { + b'{' => brace_count += 1, + b'}' => brace_count -= 1, _ => {} } if brace_count > 0 { @@ -445,6 +446,16 @@ mod tests { assert_eq!(result, vec!["test-bucket".to_string()]); } + #[tokio::test] + async fn test_resolve_aws_variables_with_unicode_prefix() { + let mut context = VariableContext::new(); + context.username = Some("alice".to_string()); + let resolver = VariableResolver::new(context); + + let result = resolve_aws_variables("中文${aws:username}", &resolver).await; + assert_eq!(result, vec!["中文alice".to_string()]); + } + #[tokio::test] async fn test_cached_aws_variable_resolver_dynamic_variables() { let context = VariableContext::new(); diff --git a/helm/README.md b/helm/README.md index cc67c004..0f1e9ae3 100644 --- a/helm/README.md +++ b/helm/README.md @@ -22,33 +22,35 @@ RustFS helm chart supports **standalone and distributed mode**. For standalone m | config.rustfs.address | string | `":9000"` | | | config.rustfs.console_address | string | `":9001"` | | | config.rustfs.console_enable | string | `"true"` | | -| config.rustfs.log_level | string | `"debug"` | | -| config.rustfs.obs_environment | string | `"develop"` | | +| config.rustfs.log_level | string | `"info"` | | +| config.rustfs.obs_environment | string | `"development"` | | | config.rustfs.obs_log_directory | string | `"/logs"` | | | config.rustfs.region | string | `"us-east-1"` | | -| config.rustfs.rust_log | string | `"debug"` | | | config.rustfs.volumes | string | `""` | | | config.rustfs.log_rotation.size | int | `"100"` | Default log rotation size mb for rustfs. | | config.rustfs.log_rotation.time | string | `"hour"` | Default log rotation time for rustfs. | | config.rustfs.log_rotation.keep_files | int | `"30"` | Default log keep files for rustfs. | -| config.rustfs.metrics.enabled | bool | `true` | Toggle metrics export. | +| config.rustfs.metrics.enabled | bool | `false` | Toggle metrics export. | | config.rustfs.metrics.endpoint | string | `""` | Dedicated metrics endpoint. | +| config.rustfs.scanner.speed | string | `""` | Scanner speed preset: `fastest`, `fast`, `default`, `slow`, `slowest` | +| config.rustfs.scanner.start_delay_secs | string | `""` | Override scanner cycle interval in seconds with `RUSTFS_DATA_SCANNER_START_DELAY_SECS` | +| config.rustfs.scanner.idle_mode | string | `""` | Override scanner idle throttling flag (`RUSTFS_SCANNER_IDLE_MODE`) | | containerSecurityContext.capabilities.drop[0] | string | `"ALL"` | | | containerSecurityContext.readOnlyRootFilesystem | bool | `true` | | | containerSecurityContext.runAsNonRoot | bool | `true` | | | enableServiceLinks | bool | `false` | | | extraManifests | list | `[]` | List of additional k8s manifests. | | fullnameOverride | string | `""` | | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.repository | string | `"rustfs/rustfs"` | RustFS docker image repository. | -| image.tag | string | `"latest"` | The tag for rustfs docker image. | +| image.rustfs.pullPolicy | string | `"IfNotPresent"` | | +| image.rustfs.repository | string | `"rustfs/rustfs"` | RustFS docker image repository. | +| image.rustfs.tag | string | `""` | Chart appVersion default if unset. | | imagePullSecrets | list | `[]` | A List of secrets to pull image from private registry. | | imageRegistryCredentials.email | string | `""` | The email to pull rustfs image from private registry. | | imageRegistryCredentials.enabled | bool | `false` | To indicate whether pull image from private registry. | | imageRegistryCredentials.password | string | `""` | The password to pull rustfs image from private registry. | | imageRegistryCredentials.registry | string | `""` | Private registry url to pull rustfs image. | | imageRegistryCredentials.username | string | `""` | The username to pull rustfs image from private registry. | -| ingress.className | string | `"traefik"` | Specify the ingress class, traefik or nginx. | +| ingress.className | string | `"nginx"` | Specify the ingress class, traefik or nginx. | | ingress.enabled | bool | `true` | | | ingress.hosts[0].host | string | `"example.rustfs.com"` | | | ingress.hosts[0].paths[0].path | string | `"/"` | | @@ -92,7 +94,7 @@ RustFS helm chart supports **standalone and distributed mode**. For standalone m | podSecurityContext.runAsGroup | int | `10001` | | | podSecurityContext.runAsUser | int | `10001` | | | readinessProbe.failureThreshold | int | `3` | | -| readinessProbe.httpGet.path | string | `"/health"` | | +| readinessProbe.httpGet.path | string | `"/health/ready"` | | | readinessProbe.httpGet.port | string | `"endpoint"` | | | readinessProbe.initialDelaySeconds | int | `30` | | | readinessProbe.periodSeconds | int | `5` | | @@ -106,7 +108,7 @@ RustFS helm chart supports **standalone and distributed mode**. For standalone m | secret.existingSecret | string | `""` | Use existing secret with a credentials. | | secret.rustfs.access_key | string | `"rustfsadmin"` | RustFS Access Key ID | | secret.rustfs.secret_key | string | `"rustfsadmin"` | RustFS Secret Key ID | -| service.type | string | `"NodePort"` | | +| service.type | string | `"ClusterIP"` | | | service.console.nodePort | int | `32001` | | | service.console.port | int | `9001` | | | service.endpoint.nodePort | int | `32000` | | @@ -154,7 +156,7 @@ The chart pulls the rustfs image from Docker Hub by default. For private registr Both approaches support pulling from private registries seamlessly and you can also combine them. -- The chart default pull rustfs image from dockerhub, if your rustfs image stores in private registry, you can use either existing image Pull secrets with parameter `imagePullSecrets` or create one setting `imageRegistryCredentials.enabled` to `true`,and then specify the `imageRegistryCredentials.registry/username/password/email` as well as `image.repository`,`image.tag` to pull rustfs image from your private registry. +- The chart default pull rustfs image from dockerhub, if your rustfs image stores in private registry, you can use either existing image Pull secrets with parameter `imagePullSecrets` or create one setting `imageRegistryCredentials.enabled` to `true`,and then specify the `imageRegistryCredentials.registry/username/password/email` as well as `image.rustfs.repository`,`image.rustfs.tag` to pull rustfs image from your private registry. - The default storageclass is [`local-path`](https://github.com/rancher/local-path-provisioner),if you want to specify your own storageclass, try to set parameter `storageclass.name`. diff --git a/helm/rustfs/templates/configmap.yaml b/helm/rustfs/templates/configmap.yaml index 59d52140..0d37cc9f 100644 --- a/helm/rustfs/templates/configmap.yaml +++ b/helm/rustfs/templates/configmap.yaml @@ -47,3 +47,14 @@ data: RUSTFS_OBS_METRIC_ENDPOINT: "" RUSTFS_OBS_METRICS_EXPORT_ENABLED: "false" {{- end }} + {{- with .Values.config.rustfs.scanner }} + {{- if .speed }} + RUSTFS_SCANNER_SPEED: {{ .speed | quote }} + {{- end }} + {{- if .start_delay_secs }} + RUSTFS_DATA_SCANNER_START_DELAY_SECS: {{ .start_delay_secs | quote }} + {{- end }} + {{- if .idle_mode }} + RUSTFS_SCANNER_IDLE_MODE: {{ .idle_mode | quote }} + {{- end }} + {{- end }} diff --git a/helm/rustfs/templates/statefulset.yaml b/helm/rustfs/templates/statefulset.yaml index 12e194ee..d4409c1a 100644 --- a/helm/rustfs/templates/statefulset.yaml +++ b/helm/rustfs/templates/statefulset.yaml @@ -62,9 +62,9 @@ spec: {{- end }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} - {{- if .Values.imagePullSecrets }} + {{- with include "chart.imagePullSecrets" . }} imagePullSecrets: - {{- toYaml .Values.imagePullSecrets | nindent 8 }} + {{- . | nindent 8 }} {{- end }} initContainers: - name: init-step diff --git a/helm/rustfs/values.yaml b/helm/rustfs/values.yaml index b58cfd9f..cd029fbf 100644 --- a/helm/rustfs/values.yaml +++ b/helm/rustfs/values.yaml @@ -72,6 +72,13 @@ config: # size: 100 # Default value: 100 MB # time: hour # Default value: hour, eg: day,hour,minute,second # keep_files: 30 # number of rotated log files to keep + scanner: + # Scanner speed preset: fastest|fast|default|slow|slowest + speed: "" + # Override start delay in seconds (optional) + start_delay_secs: "" + # Enable/disable scanner sleeps for throttling + idle_mode: "" metrics: enabled: false endpoint: "" # If specified, rustfs will export metrics to this OTLP endpoint. e.g. "http://localhost:4318/v1/metrics"