Repository navigation
Conversation
…ach object Versioning is not implemented, so every bucket behaves like an AWS S3 bucket that never had versioning enabled. ListObjectVersions now lists each object with VersionId "null" instead of returning NotImplemented, and "null" is accepted as the version ID of the current object in DeleteObjects, DeleteObject, PutObjectTagging and DeleteObjectTagging. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Before we have proper versioning implementation, we could have this. Thoughts, @fmorg-git ? |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
ListObjectVersions must reject version-id-marker when key-marker is absent.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Adds unversioned ListObjectVersions compatibility to S3 Gateway and permits operations targeting the current object via version ID null.
Changes:
- Returns each object as its latest null version with pagination support.
- Accepts null versions for deletion and tagging while rejecting unsupported versions.
- Adds unit, SDK integration, and interface documentation coverage.
| File | Description |
|---|---|
TestObjectTaggingPut.java |
Tests tagging the null version. |
TestObjectTaggingDelete.java |
Tests removing null-version tags. |
TestObjectNotImplemented.java |
Tests null-version object deletion. |
TestObjectMultiDelete.java |
Tests null-version bulk deletion responses. |
TestBucketNotImplemented.java |
Allows GET on ?versions. |
TestBucketList.java |
Tests version listing and pagination. |
S3Consts.java |
Defines version constants and parameters. |
ObjectTaggingHandler.java |
Accepts null-version tagging requests. |
ObjectOperationNotImplementedHandler.java |
Allows null-version deletion. |
MultiDeleteResponse.java |
Serializes response version IDs. |
ListVersionsResult.java |
Models ListObjectVersions responses. |
EndpointBase.java |
Adds version-ID validation helper. |
BucketOperationNotImplementedHandler.java |
Routes version listings to the endpoint. |
BucketEndpoint.java |
Implements listing and null-version bulk deletion. |
KeyMetadata.java |
Adds version metadata fields. |
AbstractS3SDKV2Tests.java |
Adds end-to-end SDK coverage. |
S3.md |
Documents ListObjectVersions support. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
hi @smengcl, yeah I was actually working on something very similar, but you got the PR up before me. FYI @Gargi-jais11 |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| | ✅ [DeleteObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) | Deletes multiple objects in one request. | Bulk delete operation with aggregated error reporting. | | ||
| | ✅ [CopyObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) | Copies an object (intra- or inter-bucket). | Supports metadata directives (COPY/REPLACE). **Non-compliant behavior:** Self-copying for metadata updates may differ slightly from AWS S3. | | ||
| | ✅ [ListObjectsV2](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) | Lists objects in a bucket with filtering and pagination. | Supports prefix, delimiter, and continuation tokens. | | ||
| | ✅ [ListObjectVersions](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectVersions.html) | Lists the versions of the objects in a bucket. | Bucket versioning is not supported, so each object is listed with a single version whose `VersionId` is `null`, same as in an AWS S3 bucket that never had versioning enabled. `DeleteObject`, `DeleteObjects` and the object tagging operations accept `null` as the version ID and operate on the current object. | |
There was a problem hiding this comment.
@adoroszlai mentioned not to update this S3.md anymore because it is being transitioned to ozone-site.
|
hi @smengcl - fyi the change is bigger than this because the actions for STS differ between ListObjectVersions and ListObjects. Maybe I can handle the STS portions after this PR goes in? |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sounds good! Thx |

Generated-by: Claude Code (Fable 5.1, Opus 5.5)
What changes were proposed in this pull request?
Since HDDS-16591,
GET /bucket?versions(ListObjectVersions) returns 501 NotImplemented. Before that, the request fell through to ListObjects and clients parsed the response as an empty version list. Bucket cleanup tools commonly call ListObjectVersions and then delete by the returned version IDs. The ceph/s3-tests cleanup fixture does so before and after each test, so the nightly S3 compatibility report dropped from 37.0% to 0.4% for s3-tests.Ozone does not support bucket versioning yet, so every bucket behaves like an AWS S3 bucket that never had versioning enabled. This PR makes S3 Gateway respond the way AWS S3 does for such a bucket:
VersionwithVersionIdnullandIsLatesttrue, with noDeleteMarkerentries. It reuses the existing key listing inBucketEndpointand paginates withkey-marker,NextKeyMarkerandNextVersionIdMarker.PUTandDELETEon?versionsare still rejected.nullis accepted as the version ID of the current object in DeleteObjects, DeleteObject, PutObjectTagging and DeleteObjectTagging. Any other version ID is still rejected with NotImplemented.VersionIdinDeletedandErrorentries when the request specified it.Not changed: the request is still audited and authorized as a bucket listing (
GET_BUCKET), GetBucketVersioning still returns NotImplemented, and GetObject and HeadObject still ignoreversionId.This is the unversioned subset of the ListObjectVersions work planned in HDDS-15728, which can extend it with the merged listing for versioned buckets.
What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-16739
How was this patch tested?
TestBucketList,TestObjectMultiDelete,TestObjectNotImplemented,TestObjectTaggingPutandTestObjectTaggingDelete.TestBucketNotImplementednow expects onlyPUTandDELETEon?versionsto be rejected.testDeleteObjectsListedByListObjectVersions, which paginates ListObjectVersions, deletes the returned versions with DeleteObjects and checks that the bucket is empty.TestS3SDKlocally.🤖 Generated with Claude Code