github.com/demonoid81/containerd@v1.3.4/metadata/boltutil/helpers.go (about) 1 /* 2 Copyright The containerd Authors. 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 boltutil 18 19 import ( 20 "time" 21 22 "github.com/pkg/errors" 23 bolt "go.etcd.io/bbolt" 24 ) 25 26 var ( 27 bucketKeyAnnotations = []byte("annotations") 28 bucketKeyLabels = []byte("labels") 29 bucketKeyCreatedAt = []byte("createdat") 30 bucketKeyUpdatedAt = []byte("updatedat") 31 ) 32 33 // ReadLabels reads the labels key from the bucket 34 // Uses the key "labels" 35 func ReadLabels(bkt *bolt.Bucket) (map[string]string, error) { 36 return readMap(bkt, bucketKeyLabels) 37 } 38 39 // ReadAnnotations reads the OCI Descriptor Annotations key from the bucket 40 // Uses the key "annotations" 41 func ReadAnnotations(bkt *bolt.Bucket) (map[string]string, error) { 42 return readMap(bkt, bucketKeyAnnotations) 43 } 44 45 func readMap(bkt *bolt.Bucket, bucketName []byte) (map[string]string, error) { 46 lbkt := bkt.Bucket(bucketName) 47 if lbkt == nil { 48 return nil, nil 49 } 50 labels := map[string]string{} 51 if err := lbkt.ForEach(func(k, v []byte) error { 52 labels[string(k)] = string(v) 53 return nil 54 }); err != nil { 55 return nil, err 56 } 57 return labels, nil 58 } 59 60 // WriteLabels will write a new labels bucket to the provided bucket at key 61 // bucketKeyLabels, replacing the contents of the bucket with the provided map. 62 // 63 // The provide map labels will be modified to have the final contents of the 64 // bucket. Typically, this removes zero-value entries. 65 // Uses the key "labels" 66 func WriteLabels(bkt *bolt.Bucket, labels map[string]string) error { 67 return writeMap(bkt, bucketKeyLabels, labels) 68 } 69 70 // WriteAnnotations writes the OCI Descriptor Annotations 71 func WriteAnnotations(bkt *bolt.Bucket, labels map[string]string) error { 72 return writeMap(bkt, bucketKeyAnnotations, labels) 73 } 74 75 func writeMap(bkt *bolt.Bucket, bucketName []byte, labels map[string]string) error { 76 // Remove existing labels to keep from merging 77 if lbkt := bkt.Bucket(bucketName); lbkt != nil { 78 if err := bkt.DeleteBucket(bucketName); err != nil { 79 return err 80 } 81 } 82 83 if len(labels) == 0 { 84 return nil 85 } 86 87 lbkt, err := bkt.CreateBucket(bucketName) 88 if err != nil { 89 return err 90 } 91 92 for k, v := range labels { 93 if v == "" { 94 delete(labels, k) // remove since we don't actually set it 95 continue 96 } 97 98 if err := lbkt.Put([]byte(k), []byte(v)); err != nil { 99 return errors.Wrapf(err, "failed to set label %q=%q", k, v) 100 } 101 } 102 103 return nil 104 } 105 106 // ReadTimestamps reads created and updated timestamps from a bucket. 107 // Uses keys "createdat" and "updatedat" 108 func ReadTimestamps(bkt *bolt.Bucket, created, updated *time.Time) error { 109 for _, f := range []struct { 110 b []byte 111 t *time.Time 112 }{ 113 {bucketKeyCreatedAt, created}, 114 {bucketKeyUpdatedAt, updated}, 115 } { 116 v := bkt.Get(f.b) 117 if v != nil { 118 if err := f.t.UnmarshalBinary(v); err != nil { 119 return err 120 } 121 } 122 } 123 return nil 124 } 125 126 // WriteTimestamps writes created and updated timestamps to a bucket. 127 // Uses keys "createdat" and "updatedat" 128 func WriteTimestamps(bkt *bolt.Bucket, created, updated time.Time) error { 129 createdAt, err := created.MarshalBinary() 130 if err != nil { 131 return err 132 } 133 updatedAt, err := updated.MarshalBinary() 134 if err != nil { 135 return err 136 } 137 for _, v := range [][2][]byte{ 138 {bucketKeyCreatedAt, createdAt}, 139 {bucketKeyUpdatedAt, updatedAt}, 140 } { 141 if err := bkt.Put(v[0], v[1]); err != nil { 142 return err 143 } 144 } 145 146 return nil 147 }