Files
zeekayandHanzo Dev 69ddc9947a s3-csi: ZAP-native CSI driver for the Hanzo filer
Fork of seaweedfs/seaweedfs-csi-driver, renamed seaweedfs -> s3 throughout and
ported off protobuf entirely.

WHY a fork was unavoidable: hanzoai/s3 serves HanzoFiler over the native ZAP
transport on the port still named "grpc" (18888) — s3/command/filer.go binds it
with transport.ListenStream and says it "replaces the legacy gRPC HanzoFiler
server: the whole filer (28 unary + 5 streaming RPCs) now answers over ZAP, no
gRPC". RegisterHanzoFilerServer exists nowhere in that tree. So the upstream
driver's gRPC client cannot connect at all; it fails as
`Unimplemented: unknown service filer_pb.SeaweedFiler`, which LOOKS like a
service-name mismatch but is a gRPC client hitting a non-gRPC port. Renaming the
service in the client would not have helped.

pkg/filer is the only place this driver touches storage, and it speaks ZAP:
  Mkdir  -> CreateEntry           (CreateVolume)
  Remove -> DeleteEntry           (DeleteVolume)
  Exists -> LookupDirectoryEntry  (ValidateVolumeCapabilities)
One shared, concurrency-safe client multiplexes over a single ZAP connection,
dials lazily so controller start does not depend on filer readiness, and redials
exactly once on a transport fault (covers a filer restart closing an idle conn
without becoming a retry storm against a struggling backend).

pkg/driver/volume.go Quota() likewise moves to s3/wire/mount — the fork generates
no mount_pb at all. Dead gRPC plumbing (WithFilerClient, AdjustedUrl,
grpcDialOption) is deleted rather than left inert.

The kubelet-facing side stays CSI gRPC: that is the Kubernetes contract between
kubelet and any CSI driver, not a Hanzo choice.

Zero protobuf call sites remain. Whole module compiles clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 16:42:29 -07:00

42 lines
973 B
Go

package driver
import (
"slices"
"testing"
)
func TestBuildMountArgsIncludesInitialCollectionQuota(t *testing.T) {
mounter := &mountServiceMounter{
driver: &S3Driver{},
volumeID: "/buckets/pvc-1234",
volContext: map[string]string{
volumeCapacityKey: "5368709120",
},
}
args, err := mounter.buildMountArgs(
"/staging",
"/cache",
"/socket",
[]string{"filer:8888"},
)
if err != nil {
t.Fatalf("buildMountArgs: %v", err)
}
if !slices.Contains(args, "-collectionQuotaMB=5120") {
t.Fatalf("mount args do not contain initial quota: %v", args)
}
}
func TestInitialCollectionQuotaMBRoundsUp(t *testing.T) {
if got, want := initialCollectionQuotaMB("1048577"), "2"; got != want {
t.Fatalf("initialCollectionQuotaMB = %q, want %q", got, want)
}
}
func TestInitialCollectionQuotaMBDisablesOneByteSentinel(t *testing.T) {
if got := initialCollectionQuotaMB("1"); got != "" {
t.Fatalf("initialCollectionQuotaMB = %q, want empty", got)
}
}