From 5206c82423b3a56068317b47220ae7da1216648e Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Sun, 2 Aug 2026 22:34:19 +0800 Subject: [PATCH] ci: require MinIO interop reader matrix (#5640) --- .github/workflows/minio-interop.yml | 14 +++++++++----- docs/architecture/minio-file-format-compat.md | 4 ++++ docs/operations/kms-backend-security.md | 2 ++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/minio-interop.yml b/.github/workflows/minio-interop.yml index 22d30ee95..3ee33e9bf 100644 --- a/.github/workflows/minio-interop.yml +++ b/.github/workflows/minio-interop.yml @@ -75,6 +75,7 @@ jobs: INTEROP_PACKAGE: rustfs INTEROP_FEATURES: rio-v2 INTEROP_FILTER: "test(minio_generated_read_test::)" + INTEROP_REQUIRED_TESTS: '["reads_minio_generated_sse_s3_multipart_fixture", "reads_minio_generated_sse_kms_multipart_fixture", "rejects_minio_generated_sse_s3_fixture_with_wrong_kms_key", "rejects_minio_generated_sse_s3_fixture_with_truncated_ciphertext"]' steps: - name: Checkout repository uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 @@ -95,20 +96,23 @@ jobs: # is a perfectly valid filterset that matches zero tests, so the next # rename or module move would leave this job selecting nothing and # reporting success without executing a single interop assertion. Count - # the selection and fail with a reason instead. + # the selection and require every core reader test, while allowing new + # reader cases to be added without changing this guard. # # Count only `filter-match.status == "matches"`: the top-level # `test-count` in the JSON is the package total and ignores `-E` entirely. - name: Assert the interop selector still matches tests run: | set -euo pipefail - count="$(cargo nextest list --run-ignored all \ + selection="$(cargo nextest list --run-ignored ignored-only \ -p "$INTEROP_PACKAGE" --features "$INTEROP_FEATURES" \ -E "$INTEROP_FILTER" --message-format json \ - | python3 -c 'import json,sys; d=json.load(sys.stdin); print(sum(1 for s in d.get("rust-suites", {}).values() for t in s.get("testcases", {}).values() if t.get("filter-match", {}).get("status") == "matches"))')" + | python3 -c 'import json,os,sys; d=json.load(sys.stdin); required=json.loads(os.environ["INTEROP_REQUIRED_TESTS"]); matched=[name for suite in d.get("rust-suites", {}).values() for name,test in suite.get("testcases", {}).items() if test.get("filter-match", {}).get("status") == "matches"]; missing=[test for test in required if not any(name.endswith("minio_generated_read_test::" + test) for name in matched)]; print(len(matched)); print(",".join(missing))')" + count="$(printf '%s\n' "$selection" | sed -n '1p')" + missing="$(printf '%s\n' "$selection" | sed -n '2p')" echo "interop tests selected: ${count}" - if [ "${count}" -eq 0 ]; then - echo "::error::Selector '${INTEROP_FILTER}' in package '${INTEROP_PACKAGE}' matched 0 tests. The MinIO interop reader tests have moved or been renamed again; fix the selector instead of letting this job pass without running them. Context: rustfs/backlog#1638." + if [ -n "${missing}" ]; then + echo "::error::Selector '${INTEROP_FILTER}' in package '${INTEROP_PACKAGE}' is missing required tests: ${missing}. The MinIO interop reader tests have moved or been renamed; fix the selector instead of running an incomplete matrix. Context: rustfs/backlog#1638." exit 1 fi diff --git a/docs/architecture/minio-file-format-compat.md b/docs/architecture/minio-file-format-compat.md index fdaabd492..ec17791cc 100644 --- a/docs/architecture/minio-file-format-compat.md +++ b/docs/architecture/minio-file-format-compat.md @@ -226,6 +226,10 @@ missing piece is a source adapter that points the importer at a MinIO Container-format parity does **not** extend to encrypted object payloads. RustFS currently does not support reading objects that MinIO wrote with server-side encryption — SSE-S3, SSE-KMS, or SSE-C. This is true of every released binary and container image. Tracked in rustfs/backlog#1638. +### Scope boundary: KMS wire protocols and the production gate + +This document covers MinIO on-disk metadata and object-encryption seams only. The **AWS KMS wire protocol** and the **MinIO KES wire protocol** are explicit non-targets: RustFS's AWS backend uses the AWS SDK's `awsJson1_1` client path (`crates/kms/src/backends/aws.rs:830`), while KES compatibility is outside this interop work. Those ecosystem evaluations remain separate work in the [#1562 Production Ready exit gate](https://github.com/rustfs/backlog/issues/1562), whose compatibility criterion covers MinIO/RustFS SSE data and rolling upgrades. Closing #1638 does not by itself close that gate. + Note the asymmetry with Parts A and B: the `xl.meta` around a MinIO SSE object parses fine, so such objects list, HEAD, and report plausible sizes. Only the payload is unreadable. ### What can and cannot be migrated diff --git a/docs/operations/kms-backend-security.md b/docs/operations/kms-backend-security.md index f178b0cc3..0b4257d41 100644 --- a/docs/operations/kms-backend-security.md +++ b/docs/operations/kms-backend-security.md @@ -36,6 +36,8 @@ Inventory the source before choosing: bucket default-encryption settings mean ob The same limitation applies in reverse — objects RustFS encrypts are not readable by MinIO. For the code-level breakdown of which seams block each SSE mode, see [MinIO file-format interoperability, Part C](../architecture/minio-file-format-compat.md#part-c--server-side-encryption-sse). +The migration warning is not a wire-protocol promise: the **AWS KMS wire protocol** and **MinIO KES wire protocol** are explicit non-targets for this document. The AWS backend uses the AWS SDK client path (`crates/kms/src/backends/aws.rs:830`), and KES remains outside the MinIO on-disk interop scope. Track those ecosystem evaluations and the MinIO/RustFS SSE compatibility matrix in the [#1562 Production Ready exit gate](https://github.com/rustfs/backlog/issues/1562); #1638 alone does not satisfy that gate. + ## Vault KV2: what the backend does and does not do The Vault KV2 backend uses Vault purely as a **secure storage** service: