mirror of https://github.com/minio/minio.git
Avoid ListBuckets() call instead rely on simple HTTP GET (#8475)
This is to avoid making calls to backend and requiring gateways to allow permissions for ListBuckets() operation just for Liveness checks, we can avoid this and make our liveness checks to be more performant.
This commit is contained in:
parent
d28bcb4f84
commit
07a556a10b
|
@ -17,8 +17,10 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio/cmd/config"
|
||||
xhttp "github.com/minio/minio/cmd/http"
|
||||
|
@ -286,6 +288,28 @@ func ToMinioClientCompleteParts(parts []CompletePart) []minio.CompletePart {
|
|||
return mparts
|
||||
}
|
||||
|
||||
// IsBackendOnline - verifies if the backend is reachable
|
||||
// by performing a GET request on the URL. returns 'true'
|
||||
// if backend is reachable.
|
||||
func IsBackendOnline(ctx context.Context, clnt *http.Client, urlStr string) bool {
|
||||
ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// never follow redirects
|
||||
clnt.CheckRedirect = func(*http.Request, []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, urlStr, nil)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if _, err = clnt.Do(req); err != nil {
|
||||
return !xnet.IsNetworkOrHostDown(err)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ErrorRespToObjectError converts MinIO errors to minio object layer errors.
|
||||
func ErrorRespToObjectError(err error, params ...string) error {
|
||||
if err == nil {
|
||||
|
|
|
@ -185,7 +185,9 @@ func (g *Azure) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, erro
|
|||
c.HTTPClient = &http.Client{Transport: minio.NewCustomHTTPTransport()}
|
||||
|
||||
return &azureObjects{
|
||||
client: c.GetBlobService(),
|
||||
endpoint: fmt.Sprintf("https://%s.blob.core.windows.net", creds.AccessKey),
|
||||
httpClient: c.HTTPClient,
|
||||
client: c.GetBlobService(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -343,7 +345,9 @@ func azurePropertiesToS3Meta(meta storage.BlobMetadata, props storage.BlobProper
|
|||
// azureObjects - Implements Object layer for Azure blob storage.
|
||||
type azureObjects struct {
|
||||
minio.GatewayUnsupported
|
||||
client storage.BlobStorageClient // Azure sdk client
|
||||
endpoint string
|
||||
httpClient *http.Client
|
||||
client storage.BlobStorageClient // Azure sdk client
|
||||
}
|
||||
|
||||
// Convert azure errors to minio object layer errors.
|
||||
|
@ -447,6 +451,8 @@ func (a *azureObjects) Shutdown(ctx context.Context) error {
|
|||
|
||||
// StorageInfo - Not relevant to Azure backend.
|
||||
func (a *azureObjects) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, a.httpClient, a.endpoint)
|
||||
return si
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,10 @@ func (g *B2) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error)
|
|||
return &b2Objects{
|
||||
creds: creds,
|
||||
b2Client: client,
|
||||
ctx: ctx,
|
||||
httpClient: &http.Client{
|
||||
Transport: minio.NewCustomHTTPTransport(),
|
||||
},
|
||||
ctx: ctx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -135,10 +138,11 @@ func (g *B2) Production() bool {
|
|||
// b2Object implements gateway for MinIO and BackBlaze B2 compatible object storage servers.
|
||||
type b2Objects struct {
|
||||
minio.GatewayUnsupported
|
||||
mu sync.Mutex
|
||||
creds auth.Credentials
|
||||
b2Client *b2.B2
|
||||
ctx context.Context
|
||||
mu sync.Mutex
|
||||
creds auth.Credentials
|
||||
b2Client *b2.B2
|
||||
httpClient *http.Client
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// Convert B2 errors to minio object layer errors.
|
||||
|
@ -225,12 +229,13 @@ func b2MsgCodeToObjectError(code int, msgCode string, msg string, params ...stri
|
|||
// Shutdown saves any gateway metadata to disk
|
||||
// if necessary and reload upon next restart.
|
||||
func (l *b2Objects) Shutdown(ctx context.Context) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
// StorageInfo is not relevant to B2 backend.
|
||||
func (l *b2Objects) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, l.httpClient, "https://api.backblazeb2.com/b2api/v1")
|
||||
return si
|
||||
}
|
||||
|
||||
|
|
|
@ -208,6 +208,9 @@ func (g *GCS) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error)
|
|||
gcs := &gcsGateway{
|
||||
client: client,
|
||||
projectID: g.projectID,
|
||||
httpClient: &http.Client{
|
||||
Transport: minio.NewCustomHTTPTransport(),
|
||||
},
|
||||
}
|
||||
|
||||
// Start background process to cleanup old files in minio.sys.tmp
|
||||
|
@ -346,8 +349,9 @@ func isValidGCSProjectIDFormat(projectID string) bool {
|
|||
// gcsGateway - Implements gateway for MinIO and GCS compatible object storage servers.
|
||||
type gcsGateway struct {
|
||||
minio.GatewayUnsupported
|
||||
client *storage.Client
|
||||
projectID string
|
||||
client *storage.Client
|
||||
httpClient *http.Client
|
||||
projectID string
|
||||
}
|
||||
|
||||
// Returns projectID from the GOOGLE_APPLICATION_CREDENTIALS file.
|
||||
|
@ -412,8 +416,10 @@ func (l *gcsGateway) Shutdown(ctx context.Context) error {
|
|||
}
|
||||
|
||||
// StorageInfo - Not relevant to GCS backend.
|
||||
func (l *gcsGateway) StorageInfo(ctx context.Context) minio.StorageInfo {
|
||||
return minio.StorageInfo{}
|
||||
func (l *gcsGateway) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, l.httpClient, "https://storage.googleapis.com")
|
||||
return si
|
||||
}
|
||||
|
||||
// MakeBucketWithLocation - Create a new container on GCS backend.
|
||||
|
|
|
@ -227,7 +227,8 @@ func (n *hdfsObjects) StorageInfo(ctx context.Context) minio.StorageInfo {
|
|||
}
|
||||
sinfo := minio.StorageInfo{}
|
||||
sinfo.Used = []uint64{fsInfo.Used}
|
||||
sinfo.Backend.Type = minio.Unknown
|
||||
sinfo.Backend.Type = minio.BackendGateway
|
||||
sinfo.Backend.GatewayOnline = true
|
||||
return sinfo
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,8 @@ func (n *nasObjects) IsListenBucketSupported() bool {
|
|||
|
||||
func (n *nasObjects) StorageInfo(ctx context.Context) minio.StorageInfo {
|
||||
sinfo := n.ObjectLayer.StorageInfo(ctx)
|
||||
sinfo.Backend.Type = minio.Unknown
|
||||
sinfo.Backend.GatewayOnline = sinfo.Backend.Type == minio.BackendFS
|
||||
sinfo.Backend.Type = minio.BackendGateway
|
||||
return sinfo
|
||||
}
|
||||
|
||||
|
|
|
@ -145,7 +145,9 @@ func (g *OSS) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error)
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client.HTTPClient = &http.Client{
|
||||
Transport: minio.NewCustomHTTPTransport(),
|
||||
}
|
||||
return &ossObjects{
|
||||
Client: client,
|
||||
}, nil
|
||||
|
@ -341,7 +343,9 @@ func (l *ossObjects) Shutdown(ctx context.Context) error {
|
|||
|
||||
// StorageInfo is not relevant to OSS backend.
|
||||
func (l *ossObjects) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
return
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, l.Client.HTTPClient, l.Client.Config.Endpoint)
|
||||
return si
|
||||
}
|
||||
|
||||
// ossIsValidBucketName verifies whether a bucket name is valid.
|
||||
|
|
|
@ -261,7 +261,11 @@ func (g *S3) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error)
|
|||
|
||||
s := s3Objects{
|
||||
Client: clnt,
|
||||
HTTPClient: &http.Client{
|
||||
Transport: minio.NewCustomHTTPTransport(),
|
||||
},
|
||||
}
|
||||
|
||||
// Enables single encryption of KMS is configured.
|
||||
if minio.GlobalKMS != nil {
|
||||
encS := s3EncObjects{s}
|
||||
|
@ -283,7 +287,8 @@ func (g *S3) Production() bool {
|
|||
// s3Objects implements gateway for MinIO and S3 compatible object storage servers.
|
||||
type s3Objects struct {
|
||||
minio.GatewayUnsupported
|
||||
Client *miniogo.Core
|
||||
Client *miniogo.Core
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
// Shutdown saves any gateway metadata to disk
|
||||
|
@ -294,6 +299,8 @@ func (l *s3Objects) Shutdown(ctx context.Context) error {
|
|||
|
||||
// StorageInfo is not relevant to S3 backend.
|
||||
func (l *s3Objects) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, l.HTTPClient, l.Client.EndpointURL().String())
|
||||
return si
|
||||
}
|
||||
|
||||
|
|
|
@ -59,18 +59,15 @@ func LivenessCheckHandler(w http.ResponseWriter, r *http.Request) {
|
|||
// is able to start on orchestration platforms like Docker Swarm.
|
||||
// Refer https://github.com/minio/minio/issues/8140 for more details.
|
||||
// Make sure to add server not initialized status in header
|
||||
w.Header().Set(xhttp.MinIOServerStatus, "Server-not-initialized")
|
||||
w.Header().Set(xhttp.MinIOServerStatus, "server-not-initialized")
|
||||
writeSuccessResponseHeadersOnly(w)
|
||||
return
|
||||
}
|
||||
|
||||
if !globalIsXL && !globalIsDistXL {
|
||||
s := objLayer.StorageInfo(ctx)
|
||||
// Gateways don't provide disk info.
|
||||
if s.Backend.Type == Unknown {
|
||||
// ListBuckets to confirm gateway backend is up
|
||||
if _, err := objLayer.ListBuckets(ctx); err != nil {
|
||||
logger.LogOnceIf(ctx, err, struct{}{})
|
||||
if s.Backend.Type == BackendGateway {
|
||||
if !s.Backend.GatewayOnline {
|
||||
writeResponse(w, http.StatusServiceUnavailable, nil, mimeNone)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ const (
|
|||
BackendFS
|
||||
// Multi disk BackendErasure (single, distributed) backend.
|
||||
BackendErasure
|
||||
// Gateway backend.
|
||||
BackendGateway
|
||||
// Add your own backend.
|
||||
)
|
||||
|
||||
|
@ -49,9 +51,12 @@ type StorageInfo struct {
|
|||
|
||||
// Backend type.
|
||||
Backend struct {
|
||||
// Represents various backend types, currently on FS and Erasure.
|
||||
// Represents various backend types, currently on FS, Erasure and Gateway
|
||||
Type BackendType
|
||||
|
||||
// Following fields are only meaningful if BackendType is Gateway.
|
||||
GatewayOnline bool
|
||||
|
||||
// Following fields are only meaningful if BackendType is Erasure.
|
||||
OnlineDisks madmin.BackendDisks // Online disks during server startup.
|
||||
OfflineDisks madmin.BackendDisks // Offline disks during server startup.
|
||||
|
|
Loading…
Reference in New Issue