Skip to content

feat(storage/opendal): route oss:// URLs through the S3 backend - #2332

Open
plusplusjiajia wants to merge 3 commits into
apache:mainfrom
plusplusjiajia:feat/oss-routes-through-s3
Open

feat(storage/opendal): route oss:// URLs through the S3 backend#2332
plusplusjiajia wants to merge 3 commits into
apache:mainfrom
plusplusjiajia:feat/oss-routes-through-s3

Conversation

@plusplusjiajia

Copy link
Copy Markdown
Member

Which issue does this PR close?

N/A

What changes are included in this PR?

Aliyun OSS exposes an S3-compatible API, and the other two Iceberg implementations already read oss:// tables through their S3 code path with canonical s3.* properties:

iceberg-rust routes oss:// to opendal's native Oss service instead, which reads a separate oss.* namespace and can't be driven by the same credentials. Align with the rest of the ecosystem.

@CTTY CTTY left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @plusplusjiajia thanks for the contribution! Logic wise this makes sense, but I'm concerned that this will confuse users that OSS storage has two modes. Do you think we should just keep one?

Comment thread crates/storage/opendal/src/resolving.rs Outdated
#[cfg(feature = "opendal-oss")]
// OSS is S3-API-compatible; route through S3 so `s3.*` props
// work for OSS-backed tables (mirrors pyiceberg/Java S3FileIO).
#[cfg(feature = "opendal-s3")]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[cfg(feature = "opendal-s3")]
#[cfg(all(feature = "opendal-oss", feature = "opendal-s3"))]

Only having s3 feature flag will introduce oss related code to non-oss users

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CTTY Fixed.

}
// Fallback: builds without `opendal-s3` but with `opendal-oss`
// still use the native OSS service (which consumes `oss.*` keys).
#[cfg(all(feature = "opendal-oss", not(feature = "opendal-s3")))]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very familiar with OSS storage so not sure about it: Is the fallback actually necessary? I'm thinking if using OSS exactly like S3 is the common case, maybe we can just use OpenDalS3Storage directly?

@plusplusjiajia plusplusjiajia May 17, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CTTY Agreed, removed it. OSS is S3-compatible and the Java/Python Iceberg implementations both route OSS through S3FileIO without a native fallback.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been marked as stale due to 30 days of inactivity. It will be closed in 1 week if no further activity occurs. If you think that’s incorrect or this pull request requires a review, please simply write any comment. If closed, you can revive the PR at any time and @mention a reviewer or discuss it on the dev@iceberg.apache.org list. Thank you for your contributions.

@github-actions github-actions Bot added the stale label May 16, 2026
@plusplusjiajia
plusplusjiajia force-pushed the feat/oss-routes-through-s3 branch from db91b0b to 3260943 Compare May 17, 2026 10:08
@Xuanwo

Xuanwo commented May 17, 2026

Copy link
Copy Markdown
Member

iceberg-rust routes oss:// to opendal's native Oss service instead, which reads a separate oss.* namespace and can't be driven by the same credentials. Align with the rest of the ecosystem.

Instead of trying to route OSS to S3, I suggest allowing OSS to parse options from the S3 config.

OpenDAL's OSS support is natively implemented, which means it works with Aliyun OSS's RAM out of the box. Switching to S3 services prevents users from working with Aliyun's OIDC or assume roles.

@plusplusjiajia

plusplusjiajia commented May 17, 2026

Copy link
Copy Markdown
Member Author

Hi @plusplusjiajia thanks for the contribution! Logic wise this makes sense, but I'm concerned that this will confuse users that OSS storage has two modes. Do you think we should just keep one?

Thanks for the feedback! I initially removed it, but @Xuanwo raised a valid concern — routing everything through S3 would prevent users from using Aliyun's native RAM/OIDC/assume-role auth. So I restored the native OSS path as a fallback: when s3.* config is present (e.g. REST catalog vended credentials), we route through S3; otherwise we use the native OSS backend. This keeps both use cases working.

@plusplusjiajia
plusplusjiajia force-pushed the feat/oss-routes-through-s3 branch from 3260943 to b73b446 Compare May 17, 2026 10:46
@github-actions github-actions Bot removed the stale label May 18, 2026
@plusplusjiajia
plusplusjiajia force-pushed the feat/oss-routes-through-s3 branch from b73b446 to c57b1ff Compare May 26, 2026 04:12
@plusplusjiajia

Copy link
Copy Markdown
Member Author

iceberg-rust routes oss:// to opendal's native Oss service instead, which reads a separate oss.* namespace and can't be driven by the same credentials. Align with the rest of the ecosystem.

Instead of trying to route OSS to S3, I suggest allowing OSS to parse options from the S3 config.

OpenDAL's OSS support is natively implemented, which means it works with Aliyun OSS's RAM out of the box. Switching to S3 services prevents users from working with Aliyun's OIDC or assume roles.

Good point! I've added a dual-path approach: has_s3_config() checks for s3.endpoint or s3.access-key-id — if present, routes through S3; otherwise falls back to the native OSS backend so RAM/OIDC/assume-role still works.

@plusplusjiajia
plusplusjiajia force-pushed the feat/oss-routes-through-s3 branch 2 times, most recently from de5442a to 96845f5 Compare May 29, 2026 15:19
@plusplusjiajia

Copy link
Copy Markdown
Member Author

Hi @CTTY @Xuanwo, mind taking another look when you get a chance?

The dual-path resolver should cover both your points: has_s3_config() routes through S3 only when s3.* vended creds are present, else falls back to native OSS (keeps RAM/OIDC working — thanks @Xuanwo). Routing is gated behind all(feature = "opendal-oss", feature = "opendal-s3"), so S3-only builds pull in no OSS code (@CTTY). Thanks!

@plusplusjiajia
plusplusjiajia requested a review from CTTY May 29, 2026 15:29
@plusplusjiajia
plusplusjiajia force-pushed the feat/oss-routes-through-s3 branch 2 times, most recently from 248de21 to 8dcda7d Compare June 16, 2026 09:58
@plusplusjiajia

Copy link
Copy Markdown
Member Author

@CTTY @Xuanwo friendly ping — the dual-path resolver should address both of your points:

  • has_s3_config() routes through S3 only when s3.* vended creds are present, else falls back to the native OSS backend — so Aliyun RAM/OIDC/assume-role still works (@Xuanwo).
  • Gated behind all(feature = "opendal-oss", feature = "opendal-s3"), so S3-only builds pull in no OSS code (@CTTY).

Mind taking another look if it looks good? Thanks!

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been marked as stale due to 30 days of inactivity. It will be closed in 1 week if no further activity occurs. If you think that’s incorrect or this pull request requires a review, please simply write any comment. If closed, you can revive the PR at any time and @mention a reviewer or discuss it on the dev@iceberg.apache.org list. Thank you for your contributions.

@github-actions github-actions Bot added the stale label Jul 17, 2026
@plusplusjiajia
plusplusjiajia force-pushed the feat/oss-routes-through-s3 branch from 8dcda7d to 9fa4fe6 Compare July 24, 2026 06:53
@github-actions github-actions Bot removed the stale label Jul 25, 2026
@plusplusjiajia
plusplusjiajia force-pushed the feat/oss-routes-through-s3 branch from 9fa4fe6 to 68c7948 Compare July 25, 2026 09:58
@plusplusjiajia

plusplusjiajia commented Jul 25, 2026

Copy link
Copy Markdown
Member Author

@Xuanwo — on not breaking native Aliyun auth: the resolver is dual-path. oss:// only routes through S3 when s3.* config is present (REST vended credentials); otherwise it falls back to the native OSS backend, so RAM/OIDC/assume-role keep working. Gated behind all(feature = "opendal-oss", feature = "opendal-s3").

@CTTY — would appreciate another look

@plusplusjiajia
plusplusjiajia force-pushed the feat/oss-routes-through-s3 branch from 68c7948 to 684c323 Compare August 19, 2026 02:22
@plusplusjiajia
plusplusjiajia force-pushed the feat/oss-routes-through-s3 branch from 684c323 to bb34312 Compare August 20, 2026 13:32
@plusplusjiajia

Copy link
Copy Markdown
Member Author

@CTTY @Xuanwo Sorry to ping again — I'd rather check the reasoning than push another revision.
The dual path tries to satisfy both points at once: oss:// goes through S3 only when s3.* config is present, so native RAM/OIDC still works when it isn't (@Xuanwo), and it's feature-gated so S3-only builds pull in no OSS code (@CTTY). The cost I've found since: one props map serves every scheme, so a config carrying both s3.* and oss.* is ambiguous — pyiceberg and Java avoid that by routing oss:// through S3 unconditionally.
Does that tradeoff still look right, or would you rather collapse it to a single path? Happy to implement either.

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.

3 participants