// Copyright (c) 2015-2021 MinIO, Inc. // // This file is part of MinIO Object Storage stack // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . package cmd import ( "bytes" "context" "errors" "io" "net/http" "github.com/minio/minio/internal/hash" ) var errConfigNotFound = errors.New("config file not found") func readConfigWithMetadata(ctx context.Context, store objectIO, configFile string, opts ObjectOptions) ([]byte, ObjectInfo, error) { r, err := store.GetObjectNInfo(ctx, minioMetaBucket, configFile, nil, http.Header{}, opts) if err != nil { if isErrObjectNotFound(err) { return nil, ObjectInfo{}, errConfigNotFound } return nil, ObjectInfo{}, err } defer r.Close() buf, err := io.ReadAll(r) if err != nil { return nil, ObjectInfo{}, err } if len(buf) == 0 { return nil, ObjectInfo{}, errConfigNotFound } return buf, r.ObjInfo, nil } func readConfig(ctx context.Context, store objectIO, configFile string) ([]byte, error) { buf, _, err := readConfigWithMetadata(ctx, store, configFile, ObjectOptions{}) return buf, err } type objectDeleter interface { DeleteObject(ctx context.Context, bucket, object string, opts ObjectOptions) (ObjectInfo, error) } func deleteConfig(ctx context.Context, objAPI objectDeleter, configFile string) error { _, err := objAPI.DeleteObject(ctx, minioMetaBucket, configFile, ObjectOptions{ DeletePrefix: true, DeletePrefixObject: true, // use prefix delete on exact object (this is an optimization to avoid fan-out calls) }) if err != nil && isErrObjectNotFound(err) { return errConfigNotFound } return err } func saveConfigWithOpts(ctx context.Context, store objectIO, configFile string, data []byte, opts ObjectOptions) error { hashReader, err := hash.NewReader(ctx, bytes.NewReader(data), int64(len(data)), "", getSHA256Hash(data), int64(len(data))) if err != nil { return err } _, err = store.PutObject(ctx, minioMetaBucket, configFile, NewPutObjReader(hashReader), opts) return err } func saveConfig(ctx context.Context, store objectIO, configFile string, data []byte) error { return saveConfigWithOpts(ctx, store, configFile, data, ObjectOptions{MaxParity: true}) } func checkConfig(ctx context.Context, objAPI ObjectLayer, configFile string) error { if _, err := objAPI.GetObjectInfo(ctx, minioMetaBucket, configFile, ObjectOptions{}); err != nil { // Treat object not found as config not found. if isErrObjectNotFound(err) { return errConfigNotFound } return err } return nil }