diff --git a/weed/command/s3.go b/weed/command/s3.go index 14998f667..995d15f8a 100644 --- a/weed/command/s3.go +++ b/weed/command/s3.go @@ -207,6 +207,7 @@ func (s3opt *S3Options) startS3Server() bool { filerBucketsPath := "/buckets" filerGroup := "" + var masterAddresses []pb.ServerAddress grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.client") @@ -222,8 +223,13 @@ func (s3opt *S3Options) startS3Server() bool { } filerBucketsPath = resp.DirBuckets filerGroup = resp.FilerGroup + // Get master addresses for filer discovery + masterAddresses = pb.ServerAddresses(strings.Join(resp.Masters, ",")).ToAddresses() metricsAddress, metricsIntervalSec = resp.MetricsAddress, int(resp.MetricsIntervalSec) glog.V(0).Infof("S3 read filer buckets dir: %s", filerBucketsPath) + if len(masterAddresses) > 0 { + glog.V(0).Infof("S3 read master addresses for discovery: %v", masterAddresses) + } return nil }) if err != nil { @@ -256,6 +262,7 @@ func (s3opt *S3Options) startS3Server() bool { s3ApiServer, s3ApiServer_err = s3api.NewS3ApiServer(router, &s3api.S3ApiServerOption{ Filers: filerAddresses, + Masters: masterAddresses, Port: *s3opt.port, Config: *s3opt.config, DomainName: *s3opt.domainName, diff --git a/weed/s3api/s3api_server.go b/weed/s3api/s3api_server.go index 1bbddd94f..8730f424e 100644 --- a/weed/s3api/s3api_server.go +++ b/weed/s3api/s3api_server.go @@ -34,6 +34,7 @@ import ( type S3ApiServerOption struct { Filers []pb.ServerAddress + Masters []pb.ServerAddress // For filer discovery Port int Config string DomainName string @@ -100,8 +101,26 @@ func NewS3ApiServerWithStore(router *mux.Router, option *S3ApiServerOption, expl // Initialize FilerClient for volume location caching // Uses the battle-tested vidMap with filer-based lookups // Supports multiple filer addresses with automatic failover for high availability - filerClient := wdclient.NewFilerClient(option.Filers, option.GrpcDialOption, option.DataCenter) - glog.V(0).Infof("S3 API initialized FilerClient with %d filer(s) for volume location caching", len(option.Filers)) + var filerClient *wdclient.FilerClient + if len(option.Masters) > 0 && option.FilerGroup != "" { + // Enable filer discovery via master + masterMap := make(map[string]pb.ServerAddress) + for i, addr := range option.Masters { + masterMap[fmt.Sprintf("master%d", i)] = addr + } + masterClient := wdclient.NewMasterClient(option.GrpcDialOption, option.FilerGroup, "s3", "", "", "", *pb.NewServiceDiscoveryFromMap(masterMap)) + + filerClient = wdclient.NewFilerClient(option.Filers, option.GrpcDialOption, option.DataCenter, &wdclient.FilerClientOption{ + MasterClient: masterClient, + FilerGroup: option.FilerGroup, + DiscoveryInterval: 5 * time.Minute, + }) + glog.V(0).Infof("S3 API initialized FilerClient with %d filer(s) and discovery enabled (group: %s, masters: %v)", + len(option.Filers), option.FilerGroup, option.Masters) + } else { + filerClient = wdclient.NewFilerClient(option.Filers, option.GrpcDialOption, option.DataCenter) + glog.V(0).Infof("S3 API initialized FilerClient with %d filer(s) (no discovery)", len(option.Filers)) + } // Update credential store to use FilerClient's current filer for HA if store := iam.credentialManager.GetStore(); store != nil {