Commit Graph

4925 Commits

Author SHA1 Message Date
马登山 4d8088ddbd Merge remote-tracking branch 'origin/main' into cxymds/fix-1358-opaque-transition-metadata
# Conflicts:
#	crates/ecstore/src/set_disk/ops/object.rs
2026-07-28 17:49:18 +08:00
cxymds 7f146fc5de feat(tiering): model provider version capabilities (#5372) 2026-07-28 17:42:08 +08:00
cxymds 5426237a49 fix(filemeta): preserve canonical version order (#5353) 2026-07-28 17:38:59 +08:00
cxymds d7afa4e38e fix(heal): report partial rename failures (#5355)
* fix(heal): report partial rename failures

* fix(log-analyzer): track partial heal rename failures
2026-07-28 17:37:02 +08:00
cxymds a3f5a8eaf9 fix(ecstore): fence object tagging updates (#5360)
* fix(ecstore): fence object tagging updates

* test(ecstore): stabilize tagging lock regressions

* test(ecstore): restore setup type on current-thread runtime
2026-07-28 17:36:00 +08:00
cxymds 547c678eed fix(filemeta): reject positive size without parts (#5354)
* fix(filemeta): reject positive size without parts

* test(ecstore): keep optimized read fixture valid

* test(ecstore): keep listing fixtures valid
2026-07-28 17:35:53 +08:00
cxymds df945b275a fix(lifecycle): recover saturated scanner tasks (#5369) 2026-07-28 17:30:52 +08:00
cxymds 2e78a49c95 fix(lifecycle): reject invalid modification times (#5370) 2026-07-28 17:23:21 +08:00
cxymds 7ad0e726db fix(ecstore): use set read quorum for version reads (#5365)
* fix(ecstore): use set read quorum for version reads

* fix(ecstore): convert optimized read batch errors
2026-07-28 17:23:15 +08:00
cxymds 45c3386b68 fix(bitrot): reject trailing shard data (#5358)
* fix(bitrot): reject trailing shard data

* test(ecstore): align bitrot disk fixture type
2026-07-28 17:23:08 +08:00
cxymds 7af92b4f54 fix(ecstore): handle pre-epoch disk health clocks (#5383) 2026-07-28 17:22:26 +08:00
cxymds daa627ee0e fix(auth): enforce presigned URL expiry limit (#5368)
* fix(auth): enforce presigned URL expiry limit

* ci(deny): allow presigned expiry s3s fork

* chore(deps): update presigned expiry validation
2026-07-28 17:11:30 +08:00
cxymds 5c3d3a8220 fix(ecstore): handle mutex poisoning explicitly (#5379)
* fix(ecstore): handle mutex poisoning explicitly

* test(ecstore): satisfy poison assertion lint
2026-07-28 17:09:09 +08:00
cxymds 6bc5fc77b5 fix(notify): emit noop event for missing deletes (#5381) 2026-07-28 17:05:10 +08:00
cxymds e822fc1552 fix(swift): enforce cumulative container quotas (#5378) 2026-07-28 17:05:04 +08:00
cxymds 2f6115e058 fix(swift): enforce TempURL IP restrictions (#5377) 2026-07-28 17:04:58 +08:00
cxymds 882e1a71b1 fix(tiering): abort failed multipart restores (#5367)
* fix(tiering): abort failed multipart restores

* fix(tiering): compile restore abort regressions

* test(tiering): assert restored multipart metadata

* test(tiering): parse completed restore status
2026-07-28 17:04:52 +08:00
cxymds b432f31c2c fix(multipart): preserve retried parts on quorum failure (#5363)
* fix(multipart): preserve retried parts on quorum failure

* style(multipart): format transaction rollback

* fix(proto): regenerate multipart transaction RPCs

* fix(multipart): import rollback marker constant

* fix(multipart): export transaction action

* fix: import multipart transaction test requests
2026-07-28 17:04:46 +08:00
cxymds 6e0640444e fix(multipart): list uploads across all sets (#5362) 2026-07-28 17:04:40 +08:00
cxymds 4fb9b0dc7f fix(authz): fail closed on policy load errors (#5359)
* fix(authz): fail closed on policy load errors

* test(authz): cover policy failure precedence

* test: align policy failure expectations

* test: align upload part copy fail-closed expectation
2026-07-28 17:04:35 +08:00
唐小鸭 2216f00cfd fix(kms): unify persisted SSE data key envelopes (#5343)
* feat(kms): implement secure handling of static KMS secret keys and enhance encryption context validation

* feat: enhance local SSE DEK handling with JSON envelope format and versioning
2026-07-28 17:02:18 +08:00
cxymds fd2a87d47e fix(s3): reject empty multipart completions (#5352)
Co-authored-by: houseme <housemecn@gmail.com>
2026-07-28 08:35:50 +00:00
马登山 821e056f70 fix(tiering): gate remote version state safely 2026-07-28 15:10:53 +08:00
马登山 a6695f6d30 merge: stack provider version semantics 2026-07-28 14:10:56 +08:00
马登山 837286f959 feat(tiering): persist opaque remote versions 2026-07-28 13:37:43 +08:00
马登山 f65ac198dc feat(tiering): model provider version capabilities 2026-07-28 13:20:36 +08:00
houseme 1e10d752b9 test(e2e): stabilize inline full gate checks (#5351)
Align inline fast path cluster tests with the current tier mutation and manual transition contracts while keeping msgpack compat assertions focused on observed traffic.

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-28 04:31:19 +00:00
houseme 362f6026ac chore(build): pin Rust toolchain configs to 1.97.1 (#5350)
Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-28 03:53:32 +00:00
GatewayJ 5cedab09ab fix(sts): return Query API-compatible responses (#5282)
* fix(sts): return Query API-compatible responses

* fix(sts): resolve review and CI failures

* fix(sts): harden query response conversion

* test(e2e): stabilize transition conflict coverage

* fix(ilm): retry vanished transition admission CAS

* test(e2e): narrow transition overlap coverage

---------

Co-authored-by: houseme <housemecn@gmail.com>
2026-07-28 10:39:17 +08:00
houseme d385cea7c6 test(lifecycle): add manual transition rollout harnesses (#5346)
* test(lifecycle): add manual transition rollout harnesses

Add a dedicated #1508 ignored E2E harness for non-empty manual transition rollout readback and a reusable Docker mixed-version harness entrypoint.

Co-Authored-By: heihutu <heihutu@gmail.com>

* test(lifecycle): satisfy rollout harness clippy

Use unwrap_or_default for the optional transition_failed report field while preserving the zero-default status readback behavior.

Co-Authored-By: heihutu <heihutu@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-28 00:04:47 +00:00
Henry Guo d5df66ac4f fix(scanner): require authoritative usage snapshots (#5333) 2026-07-28 07:29:57 +08:00
Zhengchao An 5a768d3a44 perf(s3): resolve bucket versioning once per DeleteObjects request (#5340)
DeleteObjects rebuilt ObjectOptions inside its per-key phase-1 loop, and
del_opts re-fetched the bucket versioning configuration on every call: a
1000-key request paid 1001 identical metadata-sys lookups, each taking the
global bucket-metadata read lock and cloning a VersioningConfiguration.

Split del_opts into the existing async entry point plus a synchronous
del_opts_with_versioning that takes an already-resolved configuration, and
reuse the request-level version_cfg the handler had already fetched.

This also removes a snapshot inconsistency. The skip-stat decision
(can_skip_delete_objects_pre_stat) and the post-delete accounting already
derived from the request-level snapshot while del_opts re-read the config
per key, so a PutBucketVersioning committing mid-request could give a key
opts.versioned=true while the batch delete still ran with versioned=false:
the object was deleted outright with replication state attached to a delete
marker that was never created, and the advisory object-lock pre-check was
skipped on a false premise. All three now derive from one snapshot.

GET, HEAD and DeleteObject additionally establish bucket existence before
building ObjectOptions, so a request naming a nonexistent bucket no longer
performs bucket-metadata work first. GET keeps its cheap request-shape
validations (key, range, partNumber) ahead of the existence check so
InvalidArgument still wins over NoSuchBucket for malformed requests.

Bucket validation moves to validate_bucket_exists, which takes an explicit
store and shares the existing 5s-TTL cache. GET, PUT, HEAD and DeleteObject
now resolve the store through the request-bound server context
(backlog#1052 S6) instead of the process-global handle: get_validated_store
resolves the first-published global AppContext, so in an embedded
multi-instance process a request to the second server operated on the first
server's store. Remaining global-handle call sites in bucket_usecase and
select_object are left for a follow-up.
2026-07-28 06:33:17 +08:00
houseme 6d3ce90c0f fix(lifecycle): harden manual transition rollout checks (#5344)
Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 17:29:06 +00:00
houseme 0e42a3d1d9 fix(audit): load env-only targets at startup (#5342)
Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 16:41:38 +00:00
abdullahnah92 c3aac2279f fix(site-replication): keep reverse direction after config broadcast (#5292)
* fix(site-replication): keep reverse direction after config broadcast

`site-repl-*` rules encode the sender's outbound direction: their
destination ARN names the receiver. `apply_bucket_meta_item` wrote an
incoming rule set verbatim over the receiver's, leaving the receiver with
a rule whose ARN is its own deployment ID. `reconcile_site_replication_bucket_targets`
skips the local peer, so no bucket target can back that ARN and every
object was dropped; the follow-up call reconciled targets only, so
nothing rebuilt the lost reverse rule. Replication went one-directional
after any PutBucketReplication broadcast — the console's Save button,
`mc replicate import`, a metadata import, or `/site-replication/repair`.

Only operator-authored rules now travel between sites; each site owns its
`site-repl-*` rules and rebuilds them from the current peer set.

Four defects kept that invisible or unrecoverable:

- `update_all_targets` discarded target-client build errors silently, and
  `replicate_object` logged the resulting missing-target drop at debug
  while every other failure there logs at error. Both now report.
- `site_replication_rule_complete` never checked that a rule's
  destination named a remote site, so two sites holding identical
  configs — the post-clobber state — passed as in sync.
- `update_service_account` cannot rewrite `parent_user`, and IAM records
  encrypted with a previous root secret decode as "no such account".
  Startup now reconciles the account, reseeding from the secret every
  site-replication bucket target already stores, and refuses the
  delete-then-create sequence when the parent cannot back an account.
  Bucket rules are reconciled too, so an already-broken site heals on
  upgrade.
- A joined site never verified it could reach the initiator, whose
  endpoint is derived from the Host header of the admin request that
  created the topology. The join now probes each peer and reports through
  `initial_sync_error_message`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(site-replication): report unreachable targets and reconcile on a timer

Rule-shape checking cannot see an unreachable peer. A `site-repl-*` rule
can be perfectly formed while the endpoint recorded for its peer is one
this site cannot reach: `update_all_targets` then builds no client and
`replicate_object` drops every object against that ARN, yet the rule set
still reads as correct and the bucket reports in sync.

Each site now reports whether all of its `site-repl-*` rules resolve to a
live target (`SRBucketInfo.replicationTargetsOnline`, read from the
already-resolved client map so the status path stays cheap), and the
status aggregation treats an offline report as a mismatch. The field is
additive and optional: peers that omit it are "unknown", never a fault,
so a mixed-version topology does not flip every bucket to out of sync.

The reconcilers also run on a 10-minute timer instead of at startup only,
so drift is repaired without waiting for a restart. Both are no-ops when
the wiring already matches — the bucket pass compares serialized targets
and the rule set before writing. The tick takes the site-replication
lifecycle lock with a non-blocking try_acquire and skips the round when
an add/remove/endpoint-refresh holds it: those run in phases, and
rebuilding rules between two of them would resurrect what the operation
just tore down.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* refactor(site-replication): invert reconcile dependency to satisfy layers

`startup_services.rs` sits in the infra layer and was calling the
reconcilers in `admin::handlers::site_replication`, which is interface —
a reverse dependency that check_layer_dependencies.sh rejects.

Moving the reconcilers down is not viable in this change: they rest on
the site-replication state core (`SiteReplicationState` alone has 107
in-file uses, `load_site_replication_state` 38, the state lock 33), so
relocating it would move ~2000 lines and ~200 call sites through a
bug-fix PR.

Invert the direction instead. A new infra module owns the contract and
the schedule; the admin layer registers its reconciler from
`register_site_replication_route`, which runs while the admin router is
built — `init_startup_http_servers` awaits that before
`init_startup_runtime_services` reconciles, so the hook is always
installed in time. No logic moves and no baseline entry is added: the
dependency genuinely reverses.

The lifecycle guard now wraps both reconcilers in one round rather than
each separately, closing the window between them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(site-replication): harden reconcile per review feedback

Addresses the automated review on #5292.

Security: secret recovery from bucket targets accepted any target carrying
the `site-replicator-0` access key. Bucket targets are writable by anyone
holding `admin:SetBucketTarget`, so such a principal could plant a secret
and have reconciliation recreate the broadly privileged replication
account with it. A target must now name a peer in the persisted state and
point at that peer's recorded endpoint, disagreeing targets abort the
recovery, and only missing/unreadable-account errors may trigger it at
all — a transient store failure no longer rewrites a live account.

Durability: the repair no longer deletes before creating. A readable
account is rebound in place through a new `parent_user` field on
`UpdateServiceAccountOpts`, gated to `site-replicator-0` under
`allow_site_replicator_account` exactly as the account itself is. The
parent also lives in the session-token claims, and
`prepare_service_account_auth` denies the account when the two disagree,
so both move together.

Availability: the reconcile scheduler no longer requires an inline IAM
bootstrap. Deferred IAM recovers in the background with no callback into
the scheduler, which left a recovered node with self-pointing rules until
the next restart. It now starts unconditionally and returns early while
IAM or the object store are unavailable. Its first pass runs inside the
task, so walking every bucket no longer delays startup.

Correctness: an endpoint refresh commits bucket targets and peer state in
separate steps without holding the lifecycle lock, so a tick landing
between them rewrote targets from the stale endpoint; the reconciler now
also skips while any pending marker is set. Rule repair preserves an
operator-authored `role` and clears only sender-owned site-replication
ARNs, matching the merge path.

Hot path: the per-object missing-target message returns to debug. The
condition is reported once per bucket per reconcile pass instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: houseme <housemecn@gmail.com>
2026-07-27 22:39:23 +08:00
houseme 300beff970 fix: classify manual transition tier failures (#5335)
Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 12:49:08 +00:00
houseme 0a2370c024 docs: clarify outbound allowlist scope (#5336) 2026-07-27 19:57:22 +08:00
Heracles 0c9d721910 docs: document RUSTFS_OUTBOUND_ALLOW_ORIGINS outbound policy (#5334) 2026-07-27 19:50:47 +08:00
houseme f6c227628f test(scripts): capture manual transition failure samples (#5331)
Add a reusable evidence collector for manual transition tier-failure attribution samples and wire the runbook tests to cover its dry-run and argument guards.

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 18:49:48 +08:00
houseme 0cbfa1ac90 test(internode): pin JSON fallback compatibility (#5330)
Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 09:49:24 +00:00
houseme ab5aa54035 fix(ecstore): replay manual transition task journal (#5329)
Recover accepted manual-transition tasks from the durable task journal when worker-result markers are missing after a restart.

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 17:36:40 +08:00
houseme 464bf45e15 chore(scripts): add manual transition follow-up monitor (#5328)
* test(scripts): cover manual transition runbooks

Add a script-test entry for the manual transition rollout and soak runbook generators. The test covers ratio fail-fast behavior, generated status/metrics/journal checks, and runnable dry-run artifacts.

Verification:

- ./scripts/test_manual_transition_runbooks.sh

- make script-tests

Co-Authored-By: heihutu <heihutu@gmail.com>

* test(scripts): assert nightly stress snapshot hooks

Co-Authored-By: heihutu <heihutu@gmail.com>

* feat(scripts): add transition CI follow-up monitor

Co-Authored-By: heihutu <heihutu@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 16:36:41 +08:00
houseme bc2d8e0c60 test(scripts): cover manual transition runbooks (#5327)
Add a script-test entry for the manual transition rollout and soak runbook generators. The test covers ratio fail-fast behavior, generated status/metrics/journal checks, and runnable dry-run artifacts.

Verification:

- ./scripts/test_manual_transition_runbooks.sh

- make script-tests

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 07:56:58 +00:00
GatewayJ 24cf2cdb78 fix(iam): align OIDC parent IDs with MinIO (#5290)
* fix(iam): align OIDC parent IDs with MinIO

* test(iam): cover OIDC STS binding policy lookup

* test(admin): use runtime facade for AppContext setup

* test(ilm): wait for lifecycle backfill before manual failure

* test(ilm): make overlapping admission check concurrent
2026-07-27 07:16:22 +00:00
houseme e076e8cc6e feat(scripts): add runbook entrypoints for #1508 #1510 (#5326)
* feat(ecstore): attribute manual transition worker failures

Add manual transition worker failure reason tracking and persistence recovery compatibility for checksum validation.

Co-Authored-By: heihutu <heihutu@gmail.com>

* chore(ilm): add manual transition diagnostics scripts

Co-Authored-By: heihutu <heihutu@gmail.com>

* style(ecstore): format manual transition attribution

Co-Authored-By: heihutu <heihutu@gmail.com>

* fix(ecstore): avoid copying failure reasons via clone

Co-Authored-By: heihutu <heihutu@gmail.com>

* fix(manual-transition): improve matrix verification scripts

- Add strict mixed rollout phase ratio validation.
- Add strict read/write ratio validation for soak mix.
- Inline generated admin-check command blocks into mixed-rollout run script.

Co-Authored-By: heihutu <heihutu@gmail.com>

* feat(scripts): add runbook entrypoints for #1508 #1510

---------

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 06:47:28 +00:00
houseme 9d84056d7b feat(ecstore): attribute manual transition worker failures (#5324)
* feat(ecstore): attribute manual transition worker failures

Add manual transition worker failure reason tracking and persistence recovery compatibility for checksum validation.

Co-Authored-By: heihutu <heihutu@gmail.com>

* chore(ilm): add manual transition diagnostics scripts

Co-Authored-By: heihutu <heihutu@gmail.com>

* style(ecstore): format manual transition attribution

Co-Authored-By: heihutu <heihutu@gmail.com>

* fix(ecstore): avoid copying failure reasons via clone

Co-Authored-By: heihutu <heihutu@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 06:06:12 +00:00
houseme f566b382a0 fix(bench): formalize paired ABBA corrected artifacts (#5322)
Add a reusable offline rebuild path for pinned paired ABBA benchmark evidence so corrected summaries can be regenerated from raw warp logs after parser fixes.

Record ACK-contract comparability explicitly in the rebuilt product comparison output, preventing relaxed RustFS ACK results from being treated as direct strict MinIO comparisons.

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-27 04:06:51 +00:00
dependabot[bot] a909f2f27b chore(deps): bump the dependencies group with 3 updates (#5321)
Bumps the dependencies group with 3 updates: [jiff](https://github.com/BurntSushi/jiff), [serial_test](https://github.com/palfrey/serial_test) and [hotpath](https://github.com/pawurb/hotpath-rs).


Updates `jiff` from 0.2.34 to 0.2.35
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.34...jiff-static-0.2.35)

Updates `serial_test` from 3.5.0 to 4.0.1
- [Release notes](https://github.com/palfrey/serial_test/releases)
- [Commits](https://github.com/palfrey/serial_test/compare/v3.5.0...v4.0.1)

Updates `hotpath` from 0.21.5 to 0.22.0
- [Release notes](https://github.com/pawurb/hotpath-rs/releases)
- [Changelog](https://github.com/pawurb/hotpath-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pawurb/hotpath-rs/compare/v0.21.5...v0.22.0)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.35
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: serial_test
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: dependencies
- dependency-name: hotpath
  dependency-version: 0.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 02:42:07 +00:00
houseme 5af997ce5f test(ilm): cover manual transition e2e stress (#5320)
* test(e2e): cover distributed manual transition admission

Co-Authored-By: heihutu <heihutu@gmail.com>

* test: cover manual transition restart recovery

Co-Authored-By: heihutu <heihutu@gmail.com>

* test(ilm): cover queue pressure status readback

Co-Authored-By: heihutu <heihutu@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-26 18:46:15 +00:00
houseme 4bd8cc1369 fix(bench): parse final warp report metrics (#5308)
Co-authored-by: heihutu <heihutu@gmail.com>
2026-07-26 17:49:00 +00:00