storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/data-usage.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2019 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package cmd 18 19 import ( 20 "bytes" 21 "context" 22 "encoding/json" 23 "net/http" 24 25 jsoniter "github.com/json-iterator/go" 26 27 "storj.io/minio/cmd/logger" 28 "storj.io/minio/pkg/hash" 29 "storj.io/minio/pkg/madmin" 30 ) 31 32 const ( 33 dataUsageRoot = SlashSeparator 34 dataUsageBucket = minioMetaBucket + SlashSeparator + bucketMetaPrefix 35 36 dataUsageObjName = ".usage.json" 37 dataUsageCacheName = ".usage-cache.bin" 38 dataUsageBloomName = ".bloomcycle.bin" 39 ) 40 41 // storeDataUsageInBackend will store all objects sent on the gui channel until closed. 42 func storeDataUsageInBackend(ctx context.Context, objAPI ObjectLayer, dui <-chan madmin.DataUsageInfo) { 43 for dataUsageInfo := range dui { 44 dataUsageJSON, err := json.Marshal(dataUsageInfo) 45 if err != nil { 46 logger.LogIf(ctx, err) 47 continue 48 } 49 size := int64(len(dataUsageJSON)) 50 r, err := hash.NewReader(bytes.NewReader(dataUsageJSON), size, "", "", size) 51 if err != nil { 52 logger.LogIf(ctx, err) 53 continue 54 } 55 _, err = objAPI.PutObject(ctx, dataUsageBucket, dataUsageObjName, NewPutObjReader(r), ObjectOptions{}) 56 if !isErrBucketNotFound(err) { 57 logger.LogIf(ctx, err) 58 } 59 } 60 } 61 62 func loadDataUsageFromBackend(ctx context.Context, objAPI ObjectLayer) (madmin.DataUsageInfo, error) { 63 r, err := objAPI.GetObjectNInfo(ctx, dataUsageBucket, dataUsageObjName, nil, http.Header{}, readLock, ObjectOptions{}) 64 if err != nil { 65 if isErrObjectNotFound(err) || isErrBucketNotFound(err) { 66 return madmin.DataUsageInfo{}, nil 67 } 68 return madmin.DataUsageInfo{}, toObjectErr(err, dataUsageBucket, dataUsageObjName) 69 } 70 defer r.Close() 71 72 var dataUsageInfo madmin.DataUsageInfo 73 var json = jsoniter.ConfigCompatibleWithStandardLibrary 74 if err = json.NewDecoder(r).Decode(&dataUsageInfo); err != nil { 75 return madmin.DataUsageInfo{}, err 76 } 77 78 // For forward compatibility reasons, we need to add this code. 79 if len(dataUsageInfo.BucketsUsage) == 0 { 80 dataUsageInfo.BucketsUsage = make(map[string]madmin.BucketUsageInfo, len(dataUsageInfo.BucketSizes)) 81 for bucket, size := range dataUsageInfo.BucketSizes { 82 dataUsageInfo.BucketsUsage[bucket] = madmin.BucketUsageInfo{Size: size} 83 } 84 } 85 86 // For backward compatibility reasons, we need to add this code. 87 if len(dataUsageInfo.BucketSizes) == 0 { 88 dataUsageInfo.BucketSizes = make(map[string]uint64, len(dataUsageInfo.BucketsUsage)) 89 for bucket, bui := range dataUsageInfo.BucketsUsage { 90 dataUsageInfo.BucketSizes[bucket] = bui.Size 91 } 92 } 93 94 return dataUsageInfo, nil 95 }