github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/storage/tsdb/bucketindex/storage.go (about) 1 package bucketindex 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "context" 7 "encoding/json" 8 9 "github.com/go-kit/log" 10 "github.com/grafana/dskit/runutil" 11 "github.com/pkg/errors" 12 "github.com/thanos-io/thanos/pkg/objstore" 13 14 "github.com/cortexproject/cortex/pkg/storage/bucket" 15 ) 16 17 var ( 18 ErrIndexNotFound = errors.New("bucket index not found") 19 ErrIndexCorrupted = errors.New("bucket index corrupted") 20 ) 21 22 // ReadIndex reads, parses and returns a bucket index from the bucket. 23 func ReadIndex(ctx context.Context, bkt objstore.Bucket, userID string, cfgProvider bucket.TenantConfigProvider, logger log.Logger) (*Index, error) { 24 userBkt := bucket.NewUserBucketClient(userID, bkt, cfgProvider) 25 26 // Get the bucket index. 27 reader, err := userBkt.WithExpectedErrs(userBkt.IsObjNotFoundErr).Get(ctx, IndexCompressedFilename) 28 if err != nil { 29 if userBkt.IsObjNotFoundErr(err) { 30 return nil, ErrIndexNotFound 31 } 32 return nil, errors.Wrap(err, "read bucket index") 33 } 34 defer runutil.CloseWithLogOnErr(logger, reader, "close bucket index reader") 35 36 // Read all the content. 37 gzipReader, err := gzip.NewReader(reader) 38 if err != nil { 39 return nil, ErrIndexCorrupted 40 } 41 defer runutil.CloseWithLogOnErr(logger, gzipReader, "close bucket index gzip reader") 42 43 // Deserialize it. 44 index := &Index{} 45 d := json.NewDecoder(gzipReader) 46 if err := d.Decode(index); err != nil { 47 return nil, ErrIndexCorrupted 48 } 49 50 return index, nil 51 } 52 53 // WriteIndex uploads the provided index to the storage. 54 func WriteIndex(ctx context.Context, bkt objstore.Bucket, userID string, cfgProvider bucket.TenantConfigProvider, idx *Index) error { 55 bkt = bucket.NewUserBucketClient(userID, bkt, cfgProvider) 56 57 // Marshal the index. 58 content, err := json.Marshal(idx) 59 if err != nil { 60 return errors.Wrap(err, "marshal bucket index") 61 } 62 63 // Compress it. 64 var gzipContent bytes.Buffer 65 gzip := gzip.NewWriter(&gzipContent) 66 gzip.Name = IndexFilename 67 68 if _, err := gzip.Write(content); err != nil { 69 return errors.Wrap(err, "gzip bucket index") 70 } 71 if err := gzip.Close(); err != nil { 72 return errors.Wrap(err, "close gzip bucket index") 73 } 74 75 // Upload the index to the storage. 76 if err := bkt.Upload(ctx, IndexCompressedFilename, &gzipContent); err != nil { 77 return errors.Wrap(err, "upload bucket index") 78 } 79 80 return nil 81 } 82 83 // DeleteIndex deletes the bucket index from the storage. No error is returned if the index 84 // does not exist. 85 func DeleteIndex(ctx context.Context, bkt objstore.Bucket, userID string, cfgProvider bucket.TenantConfigProvider) error { 86 bkt = bucket.NewUserBucketClient(userID, bkt, cfgProvider) 87 88 err := bkt.Delete(ctx, IndexCompressedFilename) 89 if err != nil && !bkt.IsObjNotFoundErr(err) { 90 return errors.Wrap(err, "delete bucket index") 91 } 92 return nil 93 }