Skip to content

feat: add OpenDAL-backed GooseFS object store support - #9134

Open
XuQianJin-Stars wants to merge 2 commits into
vortex-data:developfrom
XuQianJin-Stars:feat/opendal-goosefs
Open

feat: add OpenDAL-backed GooseFS object store support#9134
XuQianJin-Stars wants to merge 2 commits into
vortex-data:developfrom
XuQianJin-Stars:feat/opendal-goosefs

Conversation

@XuQianJin-Stars

Copy link
Copy Markdown
Contributor

Add goosefs:// scheme support to vortex-cloud, bridging Tencent Cloud GooseFS through OpenDAL's services::GooseFs via object_store_opendal.

Rust changes:

  • vortex-cloud: new goosefs Cargo feature and opendal::goosefs module with GoosefsConfig, make_goosefs_store, and URL-to-config translation (master_addr from properties -> URL authority -> GOOSEFS_MASTER_ADDR env)
  • vortex-cloud/src/registry: extend OpenDAL cfg gates to include goosefs
  • 7 unit tests covering missing master_addr, URL authority, env fallback, property override, HA mode, and explicit config construction

Python bindings:

  • vortex-python: new GoosefsStore pyclass with keyword-only options (root, block_size, chunk_size, write_type, auth_type, auth_username)
  • AnyVortexStore accepts GoosefsStore in read_url / write
  • Python store module vortex.store._goosefs with graceful ImportError fallback when the opendal feature is not enabled
  • Type stub (.pyi) for GoosefsStore constructor

Dependency note: goosefs-sdk v0.1.8 is pulled transitively via opendal-service-goosefs v0.57.0; no direct workspace dependency added.

Rationale for this change

What changes are included in this PR?

This PR introduces a new OpenDAL-backed object store scheme in vortex-cloud:

  • New Cargo feature goosefs (gated under the existing opendal umbrella).
  • New module vortex-cloud/src/opendal/goosefs.rs (~300 lines) containing:
    • GoosefsConfig struct (master_addr, root, block_size, chunk_size, write_type, auth_type, auth_username).
    • make_goosefs_store(config) — strongly-typed entry point returning Arc<dyn ObjectStore>.
    • url_and_properties_to_config(url, properties, env_lookup) — translates a goosefs:// URL plus a property map into a GoosefsConfig, with master_addr resolved as properties["master_addr"] → URL authority (host:port) → GOOSEFS_MASTER_ADDR env var.
    • 7 unit tests covering missing master_addr, URL-authority fallback, env fallback, property-vs-URL precedence, HA mode, and explicit config construction.
  • Wiring in vortex-cloud/src/opendal/mod.rs:
    • New mod goosefs;, pub use ... GOOSEFS_SCHEME / GoosefsConfig / make_goosefs_store.
    • SUPPORTED_SCHEMES and make_opendal_store_with_env match arm extended to dispatch on goosefs://.
    • property_or_env, warn_on_unknown_properties, build_operator cfg gates updated.
    • supports_scheme_tracks_enabled_features and every_supported_scheme_dispatches tests extended to cover the new scheme.
  • Wiring in vortex-cloud/src/registry/mod.rs:
    • EnvSource::lookup and Registry::build_store cfg gates updated so the registry can resolve goosefs:// URLs.
    • Module-level doc comment updated to mention GooseFS.
  • vortex-cloud/src/lib.rs doc comment + opendal feature list updated.
  • Python bindings in vortex-python:
    • New GoosefsStore pyclass in vortex-python/src/opendal_store.rs with the same keyword-only options as GoosefsConfig.
    • AnyVortexStore enum extended with a Goosefs(GoosefsStore) variant, with matching into_inner and FromPyObject arms.
    • New vortex-python/python/vortex/store/_goosefs.py mirroring _cos.py (graceful ImportError placeholder when the opendal feature is disabled).
    • vortex-python/python/vortex/store/__init__.py updated: import GoosefsStore, add to ObjectStore type alias, add to __all__, document goosefs:// URL handling in the from_url docstring.
    • vortex-python/python/vortex/_lib/__init__.pyi updated with the GoosefsStore class stub.

Dependency notes:

  • goosefs-sdk is not added as a direct workspace dependency. It is pulled transitively through opendal-service-goosefs v0.57.0, which currently uses goosefs-sdk v0.1.8. Adding a direct dependency would force an extra upgrade every time the OpenDAL facade bumps.
  • The PR targets develop with opendal = "0.57.0" and object_store = "0.13.2" (compatible with datafusion 54).
  • A separate branch is in progress to bump opendal to 0.58.1; it depends on datafusion moving to object_store 0.14 and is intentionally not folded into this PR.

What APIs are changed? Are there any user-facing changes?

Yes — this PR adds new public APIs and a new URL scheme. It does not modify or break any existing public API.

New public Rust API (gated on the new goosefs feature)

In vortex-cloud::opendal:

  • pub const GOOSEFS_SCHEME: &str = "goosefs";
  • pub struct GoosefsConfig { pub master_addr: String, pub root: Option<String>, pub block_size: Option<u64>, pub chunk_size: Option<u64>, pub write_type: Option<String>, pub auth_type: Option<String>, pub auth_username: Option<String> }
  • pub fn make_goosefs_store(config: GoosefsConfig) -> Result<Arc<dyn object_store::ObjectStore>, OpenDALStoreError>

The existing make_opendal_store_with_env URL dispatcher now also accepts the goosefs scheme, returning a store rooted at the URL path. supports_scheme("goosefs") returns true when the goosefs feature is enabled (and the corresponding Cargo features are turned on via the opendal umbrella).

New public Cargo features

  • vortex-cloud/goosefs — opt-in. When enabled, opendal, object_store_opendal, tracing, and opendal/services-goosefs are pulled in.
  • vortex-cloud/opendal now also enables the new goosefs feature (alongside the existing cos and oss).

New Python API (gated on the opendal feature)

In vortex._lib:

  • class GoosefsStore(master_addr: str, *, root: str | None = None, block_size: int | None = None, chunk_size: int | None = None, write_type: str | None = None, auth_type: str | None = None, auth_username: str | None = None) — a pyo3-backed store class.

In vortex.store:

  • GoosefsStore re-exported with the same constructor signature.
  • vortex.store.ObjectStore union type extended to include GoosefsStore.
  • vortex.store.from_url(...) recognises goosefs://master-addr:port/path URLs (when the opendal feature is enabled).
  • vortex.io.read_url(url, store=...) and vortex.io.write(..., store=...) accept a GoosefsStore instance.

New environment variable

  • GOOSEFS_MASTER_ADDR — read by GoosefsConfig::from_properties_auto() (the OpenDAL builder) and by vortex-cloud's url_and_properties_to_config as the final fallback for master_addr when the URL has no authority and the property map is empty.

Backwards compatibility

  • All existing public APIs are unchanged. Existing features (cos, oss, registry, etc.) are unaffected.
  • The new goosefs feature is opt-in; existing consumers that don't enable it will see no new code or dependencies pulled in.
  • The new goosefs scheme is recognised by vortex-cloud/src/registry::Registry only when the goosefs feature is enabled, so existing deployments won't accidentally treat goosefs:// URLs as a different scheme.

Add `goosefs://` scheme support to `vortex-cloud`, bridging Tencent Cloud
GooseFS through OpenDAL's `services::GooseFs` via `object_store_opendal`.

Rust changes:
- `vortex-cloud`: new `goosefs` Cargo feature and `opendal::goosefs` module
  with `GoosefsConfig`, `make_goosefs_store`, and URL-to-config translation
  (master_addr from properties -> URL authority -> GOOSEFS_MASTER_ADDR env)
- `vortex-cloud/src/registry`: extend OpenDAL cfg gates to include `goosefs`
- 7 unit tests covering missing master_addr, URL authority, env fallback,
  property override, HA mode, and explicit config construction

Python bindings:
- `vortex-python`: new `GoosefsStore` pyclass with keyword-only options
  (root, block_size, chunk_size, write_type, auth_type, auth_username)
- `AnyVortexStore` accepts `GoosefsStore` in `read_url` / `write`
- Python store module `vortex.store._goosefs` with graceful ImportError
  fallback when the `opendal` feature is not enabled
- Type stub (`.pyi`) for `GoosefsStore` constructor

Dependency note: goosefs-sdk v0.1.8 is pulled transitively via
opendal-service-goosefs v0.57.0; no direct workspace dependency added.

Signed-off-by: forwardxu <forwardxu@apache.org>
@XuQianJin-Stars

Copy link
Copy Markdown
Contributor Author

Hi @robert3005, could you please help review this PR when you have a moment? Thanks!

The test_opendal_schemes_reach_the_opendal_builder test assumed all
OpenDAL-backed schemes fail to build without an endpoint. GooseFS is
different: its master_addr is derived from the URL authority, so
goosefs://bucket/key.vortex builds successfully. Update the test to
accept Ok (proof the OpenDAL builder ran, since parse_url_opts rejects
goosefs://) in addition to an OpenDAL error, and add goosefs to the
cfg gate.

Signed-off-by: forwardxu <forwardxu@apache.org>
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.

feat: Add OpenDAL-backed GooseFS object store support

1 participant