Skip to content

feat(gateway): support If-None-Match wildcard - #7479

Merged
zhijian-pro merged 14 commits into
juicedata:mainfrom
ilcm96:feat/if-none-match-wildcard
Sep 15, 2026
Merged

zhijian-pro merged 14 commits into
juicedata:mainfrom
ilcm96:feat/if-none-match-wildcard

Conversation

@ilcm96

@ilcm96 ilcm96 commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Add S3 conditional-write support for If-None-Match: * to JuiceFS Gateway.

  • enforce create-only semantics for PutObject, CopyObject, and multipart completion
  • publish new directory markers through a fully prepared temporary inode and RenameNoReplace
  • preserve the target state when a conditional directory-marker request fails
  • atomically create markers on implicit directories with --head-dir=false; return 412 Precondition Failed for existing explicit markers or directories exposed by --head-dir=true
  • clean up temporary directory-marker inodes on every failed publish path
  • add unit, race, and S3 integration coverage, including repeated If-None-Match header fields

Fixes #6460.

MinIO dependency

This PR depends on juicedata/minio#84.

The current go.mod replacement intentionally points to the pushed feature commit in my MinIO fork so this PR and its CI can be tested before the MinIO PR is merged. After #84 is merged, I will update the replacement to the corresponding github.com/juicedata/minio commit before this PR is merged.

Verification

All verification was run in Docker:

go test ./pkg/gateway -count=1
go test ./cmd -run IfNoneMatch -count=1  # in the MinIO repository
bash -n integration/s3gateway_test.sh

The live JuiceFS Gateway checks also verified:

  • conditional zero-byte PUT and CopyObject against an implicit directory return 200 with --head-dir=false, preserving the directory inode and child data; with --head-dir=true, they return 412
  • a new directory marker is created successfully and a duplicate conditional write returns 412
  • repeated raw If-None-Match fields are combined correctly: an empty field followed by * returns 412, while * followed by an ETag returns 400
  • the existing object content remains unchanged after failed conditional requests

@CLAassistant

CLAassistant commented Aug 29, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Comment thread pkg/gateway/gateway.go Outdated
Comment thread pkg/gateway/gateway.go Outdated
@myangitzh

Copy link
Copy Markdown
Contributor

Hi,Could we add destination If-Match: support alongside If-None-Match: *? AWS supports it for PutObject, CopyObject, and CompleteMultipartUpload.
If this is too large for the current PR, could we open a follow-up PR and track it?

S3 User Guide: https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-requests.html

@ilcm96
ilcm96 force-pushed the feat/if-none-match-wildcard branch from f193215 to 31853dd Compare September 5, 2026 13:29
@ilcm96
ilcm96 requested a review from CaitinChen as a code owner September 5, 2026 13:29
@ilcm96

ilcm96 commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

@myangitzh

Could we add destination If-Match: support alongside If-None-Match: *?

Thanks for the suggestion. I'd prefer to keep this PR focused on If-None-Match: * and track destination If-Match: <ETag> support separately.

The current implementation atomically checks that the destination does not exist. If-Match would also need to compare the destination's ETag and commit the replacement atomically, so a concurrent write cannot invalidate the comparison. That needs additional gateway and metadata work, along with tests for PUT, CopyObject, and multipart completion. I think a separate follow-up would make that easier to review and validate.

Point the temporary fork replacement at the squashed, pushed MinIO feature commit used by the upstream pull request.
Replace NotImplemented with atomic directory marker creation when
If-None-Match: * targets an implicit directory with HeadDir disabled.

Add transactional marker updates across Redis, SQL, and KV metadata
engines, preserving the directory inode, children, and unrelated xattrs.
Keep PreconditionFailed for existing markers and HeadDir-enabled directories.

Handle PostgreSQL-compatible transaction retry SQLSTATEs for CockroachDB.
Add concurrency and rollback tests and document the new marker operation.
@ilcm96
ilcm96 force-pushed the feat/if-none-match-wildcard branch from 31853dd to 8164c6c Compare September 10, 2026 11:03
@ilcm96

ilcm96 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

MinIO PR juicedata/minio#84 has been merged. I rebased this PR onto the latest main and updated the MinIO pin from my temporary fork to the merged upstream commit (f2266df40f17).

@codecov

codecov Bot commented Sep 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 39.66480% with 108 lines in your changes missing coverage. Please review.
✅ Project coverage is 22.22%. Comparing base (4e99198) to head (8164c6c).

Files with missing lines Patch % Lines
pkg/meta/sql.go 0.00% 46 Missing ⚠️
pkg/meta/redis.go 0.00% 41 Missing ⚠️
pkg/meta/base.go 73.68% 10 Missing and 5 partials ⚠️
pkg/meta/tkv.go 82.85% 4 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #7479       +/-   ##
===========================================
- Coverage   57.18%   22.22%   -34.96%     
===========================================
  Files         181       31      -150     
  Lines       60100    25143    -34957     
===========================================
- Hits        34370     5589    -28781     
+ Misses      22111    18950     -3161     
+ Partials     3619      604     -3015     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread pkg/gateway/gateway.go Outdated
@zhijian-pro
zhijian-pro merged commit 5b34838 into juicedata:main Sep 15, 2026
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

s3 gateway does not support CONDITIONAL WRITE

4 participants