From 97ce11cb6b322d3133fa0cb87d7050cb556b53b6 Mon Sep 17 00:00:00 2001 From: Anis Eleuch Date: Wed, 3 Apr 2024 19:27:05 +0100 Subject: [PATCH] Avoid using a nil transport when the config is not initialized (#19405) Make sure to pass a nil pointer as a Transport to minio-go when the API config is not initialized, this will make sure that we do not pass an interface with a known type but a nil value. This will also fix the update of the API remote_transport_deadline configuration without requiring the cluster restart. --- cmd/batch-expire.go | 2 +- cmd/batch-handlers.go | 10 +++++----- cmd/config-current.go | 6 +----- cmd/object-handlers.go | 23 ++++++++++++++++------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/cmd/batch-expire.go b/cmd/batch-expire.go index 7360a76c071f0..dd171ed13f362 100644 --- a/cmd/batch-expire.go +++ b/cmd/batch-expire.go @@ -321,7 +321,7 @@ func (r BatchJobExpire) Notify(ctx context.Context, body io.Reader) error { req.Header.Set("Authorization", r.NotificationCfg.Token) } - clnt := http.Client{Transport: getRemoteInstanceTransport} + clnt := http.Client{Transport: getRemoteInstanceTransport()} resp, err := clnt.Do(req) if err != nil { return err diff --git a/cmd/batch-handlers.go b/cmd/batch-handlers.go index 68317b7b1f664..25d6b6faf08c0 100644 --- a/cmd/batch-handlers.go +++ b/cmd/batch-handlers.go @@ -92,7 +92,7 @@ func notifyEndpoint(ctx context.Context, ri *batchJobInfo, endpoint, token strin } req.Header.Set("Content-Type", "application/json") - clnt := http.Client{Transport: getRemoteInstanceTransport} + clnt := http.Client{Transport: getRemoteInstanceTransport()} resp, err := clnt.Do(req) if err != nil { return err @@ -351,7 +351,7 @@ func (r *BatchJobReplicateV1) StartFromSource(ctx context.Context, api ObjectLay c, err := miniogo.New(u.Host, &miniogo.Options{ Creds: credentials.NewStaticV4(cred.AccessKey, cred.SecretKey, cred.SessionToken), Secure: u.Scheme == "https", - Transport: getRemoteInstanceTransport, + Transport: getRemoteInstanceTransport(), BucketLookup: lookupStyle(r.Source.Path), }) if err != nil { @@ -1048,7 +1048,7 @@ func (r *BatchJobReplicateV1) Start(ctx context.Context, api ObjectLayer, job Ba c, err := miniogo.NewCore(u.Host, &miniogo.Options{ Creds: credentials.NewStaticV4(cred.AccessKey, cred.SecretKey, cred.SessionToken), Secure: u.Scheme == "https", - Transport: getRemoteInstanceTransport, + Transport: getRemoteInstanceTransport(), BucketLookup: lookupStyle(r.Target.Path), }) if err != nil { @@ -1068,7 +1068,7 @@ func (r *BatchJobReplicateV1) Start(ctx context.Context, api ObjectLayer, job Ba cl, err := miniogo.New(u.Host, &miniogo.Options{ Creds: credentials.NewStaticV4(cred.AccessKey, cred.SecretKey, cred.SessionToken), Secure: u.Scheme == "https", - Transport: getRemoteInstanceTransport, + Transport: getRemoteInstanceTransport(), BucketLookup: lookupStyle(r.Target.Path), }) if err != nil { @@ -1354,7 +1354,7 @@ func (r *BatchJobReplicateV1) Validate(ctx context.Context, job BatchJobRequest, c, err := miniogo.NewCore(u.Host, &miniogo.Options{ Creds: credentials.NewStaticV4(cred.AccessKey, cred.SecretKey, cred.SessionToken), Secure: u.Scheme == "https", - Transport: getRemoteInstanceTransport, + Transport: getRemoteInstanceTransport(), BucketLookup: lookupStyle(pathStyle), }) if err != nil { diff --git a/cmd/config-current.go b/cmd/config-current.go index c344fadbf3725..824951e82b8c4 100644 --- a/cmd/config-current.go +++ b/cmd/config-current.go @@ -576,11 +576,7 @@ func applyDynamicConfigForSubSys(ctx context.Context, objAPI ObjectLayer, s conf globalAPIConfig.init(apiConfig, setDriveCounts) autoGenerateRootCredentials() // Generate the KMS root credentials here since we don't know whether API root access is disabled until now. - - // Initialize remote instance transport once. - getRemoteInstanceTransportOnce.Do(func() { - getRemoteInstanceTransport = NewHTTPTransportWithTimeout(apiConfig.RemoteTransportDeadline) - }) + setRemoteInstanceTransport(NewHTTPTransportWithTimeout(apiConfig.RemoteTransportDeadline)) case config.CompressionSubSys: cmpCfg, err := compress.LookupConfig(s[config.CompressionSubSys][config.Default]) if err != nil { diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 5733acc22392b..d742188655d8d 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -34,7 +34,7 @@ import ( "sort" "strconv" "strings" - "sync" + "sync/atomic" "time" "unicode" @@ -1291,11 +1291,20 @@ func getCpObjMetadataFromHeader(ctx context.Context, r *http.Request, userMeta m return defaultMeta, nil } -// getRemoteInstanceTransport contains a singleton roundtripper. -var ( - getRemoteInstanceTransport *http.Transport - getRemoteInstanceTransportOnce sync.Once -) +// getRemoteInstanceTransport contains a roundtripper for external (not peers) servers +var remoteInstanceTransport atomic.Value + +func setRemoteInstanceTransport(tr http.RoundTripper) { + remoteInstanceTransport.Store(tr) +} + +func getRemoteInstanceTransport() http.RoundTripper { + rt, ok := remoteInstanceTransport.Load().(http.RoundTripper) + if ok { + return rt + } + return nil +} // Returns a minio-go Client configured to access remote host described by destDNSRecord // Applicable only in a federated deployment @@ -1306,7 +1315,7 @@ var getRemoteInstanceClient = func(r *http.Request, host string) (*miniogo.Core, core, err := miniogo.NewCore(host, &miniogo.Options{ Creds: credentials.NewStaticV4(cred.AccessKey, cred.SecretKey, ""), Secure: globalIsTLS, - Transport: getRemoteInstanceTransport, + Transport: getRemoteInstanceTransport(), }) if err != nil { return nil, err