github.com/skf/moby@v1.13.1/distribution/metadata/metadata.go (about) 1 package metadata 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "sync" 8 9 "github.com/docker/docker/pkg/ioutils" 10 ) 11 12 // Store implements a K/V store for mapping distribution-related IDs 13 // to on-disk layer IDs and image IDs. The namespace identifies the type of 14 // mapping (i.e. "v1ids" or "artifacts"). MetadataStore is goroutine-safe. 15 type Store interface { 16 // Get retrieves data by namespace and key. 17 Get(namespace string, key string) ([]byte, error) 18 // Set writes data indexed by namespace and key. 19 Set(namespace, key string, value []byte) error 20 // Delete removes data indexed by namespace and key. 21 Delete(namespace, key string) error 22 } 23 24 // FSMetadataStore uses the filesystem to associate metadata with layer and 25 // image IDs. 26 type FSMetadataStore struct { 27 sync.RWMutex 28 basePath string 29 } 30 31 // NewFSMetadataStore creates a new filesystem-based metadata store. 32 func NewFSMetadataStore(basePath string) (*FSMetadataStore, error) { 33 if err := os.MkdirAll(basePath, 0700); err != nil { 34 return nil, err 35 } 36 return &FSMetadataStore{ 37 basePath: basePath, 38 }, nil 39 } 40 41 func (store *FSMetadataStore) path(namespace, key string) string { 42 return filepath.Join(store.basePath, namespace, key) 43 } 44 45 // Get retrieves data by namespace and key. The data is read from a file named 46 // after the key, stored in the namespace's directory. 47 func (store *FSMetadataStore) Get(namespace string, key string) ([]byte, error) { 48 store.RLock() 49 defer store.RUnlock() 50 51 return ioutil.ReadFile(store.path(namespace, key)) 52 } 53 54 // Set writes data indexed by namespace and key. The data is written to a file 55 // named after the key, stored in the namespace's directory. 56 func (store *FSMetadataStore) Set(namespace, key string, value []byte) error { 57 store.Lock() 58 defer store.Unlock() 59 60 path := store.path(namespace, key) 61 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { 62 return err 63 } 64 return ioutils.AtomicWriteFile(path, value, 0644) 65 } 66 67 // Delete removes data indexed by namespace and key. The data file named after 68 // the key, stored in the namespace's directory is deleted. 69 func (store *FSMetadataStore) Delete(namespace, key string) error { 70 store.Lock() 71 defer store.Unlock() 72 73 path := store.path(namespace, key) 74 return os.Remove(path) 75 }