Files
zooqueen dd74d3e6d6 Replace AGPL MinIO fork with Apache-2.0 SeaweedFS fork; rebrand CLI weed->s3
hanzoai/s3 was an AGPL-3.0 MinIO fork whose network-copyleft blocks embedding
and reselling as a managed service. Replace it wholesale with a fork of
SeaweedFS (github.com/seaweedfs/seaweedfs, Apache-2.0, Go) which ships a
built-in S3 gateway + Filer.

- License: AGPL-3.0 -> Apache-2.0 (upstream LICENSE kept verbatim, incl.
  "Copyright 2025 Chris Lu"); NOTICE added crediting SeaweedFS. No AGPL/BUSL/
  SSPL/GPL or enterprise ("ee") files remain.
- Module: go.mod path set to github.com/hanzoai/s3 with a self-replace
  (replace github.com/seaweedfs/seaweedfs => ./) so the ~1800 internal Go files
  keep their upstream import paths with zero churn. Internal identifiers and
  import paths are intentionally NOT renamed.
- CLI rebrand: the binary is built as `s3` (was `weed`); root usage, per-command
  help/usage/flag strings, shell autocomplete program name, and the product name
  in CLI output now read "Hanzo S3" / `s3`. Users never see `weed`.
  (e.g. `s3 server`, `s3 filer`, `s3 master`, `s3 volume`, `s3 s3`, `s3 mount`.)
- Build: `make` (or `go build -o s3 ./weed`) builds the `s3` binary green;
  `cmd/weed-db` and `cmd/weed-sql` also build; `go vet ./weed/command/` clean.
- README/LLM.md rewritten for Hanzo S3; AGENTS.md/CLAUDE.md symlinks preserved.
- Dropped a 33MB prebuilt Mach-O `stress` binary upstream had committed; `.gitignore`
  updated to ignore the `s3` build output.
2026-06-18 23:41:25 -07:00
..

Unity Catalog OSS integration tests

These tests run Unity Catalog OSS in Docker against an embedded SeaweedFS S3 endpoint. The server.properties mirrors the upstream playground at mds-in-a-box/unitycatalog-playground.

Test Variant Status
TestUnityCatalogDeltaIntegration static keys, aws.masterRoleArn= empty passes; covers catalog/schema/EXTERNAL Delta CRUD against SeaweedFS-backed warehouse and asserts that UC's /temporary-table-credentials cannot vend usable creds with this configuration -- exactly the gap the playground reports.
TestUnityCatalogMasterRoleIntegration aws.masterRoleArn=arn:aws:iam::000000000000:role/UnityCatalogVendedRole passes; proves SeaweedFS' STS endpoint accepts sts:AssumeRole for the role UC would use (Go SDK round-trip), and that UC starts and accepts CRUD when wired with the master-role config. UC's own StsClient still talks to real AWS regardless of aws.endpoint / AWS_ENDPOINT_URL_STS (UC bug, see below); that hop is logged via t.Logf rather than asserted.
TestUnityCatalogDeltaRsRoundTrip static keys + delta-rs Python client passes; resolves table metadata through UC and writes/reads a real Delta table at the registered storage_location using python:3.11-slim + deltalake with the SeaweedFS test credentials.

Prerequisites

  • Docker available locally (the tests call docker run / docker build directly).
  • A weed binary at the repo root (weed/weed) or on $PATH.

Run

go test -timeout 15m \
    -run 'TestUnityCatalog' \
    ./test/s3tables/unity_catalog/...

Pin a specific Unity Catalog image (defaults to unitycatalog/unitycatalog:v0.4.0):

UC_IMAGE=unitycatalog/unitycatalog:main \
    go test -timeout 15m -run TestUnityCatalogDeltaIntegration \
    ./test/s3tables/unity_catalog/...

The tests self-skip when Docker is unavailable or no weed binary is on the path; running under -short also skips them.

Why the static-key path can't vend usable creds

UC OSS' AwsCredentialVendor.createPerBucketCredentialGenerator:

if (config.getSessionToken() != null && !config.getSessionToken().isEmpty()) {
    return new AwsCredentialGenerator.StaticAwsCredentialGenerator(config);
}
return createStsCredentialGenerator(config);

With aws.masterRoleArn= empty and s3.sessionToken.0= empty (this test's configuration), /temporary-table-credentials short-circuits with "S3 bucket configuration not found." before UC fires any STS call. Setting a stub s3.sessionToken.0 switches UC to StaticAwsCredentialGenerator and the endpoint returns the static keys, but the response carries that stub session token -- SeaweedFS won't recognize it on the next S3 call, so the vended creds aren't usable for table I/O. Clients have to fall back to the static keys directly.

With aws.masterRoleArn set, UC's AwsCredentialGenerator.StsAwsCredentialGenerator builds the StsClient with only .region(...) and .credentialsProvider(...) -- no .endpointOverride(). The SDK's generic env-var resolution doesn't kick in for that builder shape, so even with AWS_ENDPOINT_URL_STS=... (or the matching aws.endpointUrlSts Java property, or the catch-all AWS_ENDPOINT_URL=...) the StsClient still targets real AWS and gets back InvalidClientTokenId. Verified by pointing the env var at port 1: UC reports the same AWS-issued 403 that it reports against SeaweedFS, and a sniffer in front of SeaweedFS' STS port records zero traffic. SeaweedFS' STS handler itself works -- the Go SDK round-trip in assumeRoleViaSeaweedFS proves that against the same SeaweedFS instance.

UC's own AWS credential-vending tests don't catch this because they mock StsClient away entirely -- BaseCRUDTestWithMockCredentials injects a custom stsClientBuilderSupplier returning an EchoAwsStsClient that synthesizes credentials in-process, and CloudCredentialVendorTest uses Mockito.mockStatic(StsClient.class). No test ever exercises the wire path between UC's Java SDK and a real STS endpoint, so the missing endpointOverride slipped through.

Fix is upstream in unitycatalog/unitycatalog#1532, which adds an aws.endpoint property and applies it to both the StsClient and the S3Client builders. Until that lands, the master-role test logs the failure but does not assert it.

What the tests actually validate today

  • Unity Catalog accepts a SeaweedFS-backed server.properties and starts.
  • Catalog / schema / EXTERNAL Delta table CRUD all work against the SeaweedFS warehouse via the UC REST API.
  • SeaweedFS' STS endpoint correctly issues sts:AssumeRole credentials for the UnityCatalogVendedRole and those credentials are accepted on S3 round-trips (Go AWS SDK).
  • Delta-RS resolves a UC table's storage_location and can write/read Delta data through the SeaweedFS S3 endpoint with the test credentials.

What is still pending

Nothing on the SeaweedFS side. The remaining gap (UC's StsClient ignoring endpoint config) needs a UC OSS patch upstream.

MANAGED tables

Not exercised. UC OSS gates them behind server.managed-table.enabled=true and a two-step staging flow (POST /staging-tables then POST /tables); EXTERNAL Delta is the simpler path and what these tests cover.