github.com/lazyboychen7/engine@v17.12.1-ce-rc2+incompatible/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 platform string 30 } 31 32 // NewFSMetadataStore creates a new filesystem-based metadata store. 33 func NewFSMetadataStore(basePath, platform string) (*FSMetadataStore, error) { 34 if err := os.MkdirAll(basePath, 0700); err != nil { 35 return nil, err 36 } 37 return &FSMetadataStore{ 38 basePath: basePath, 39 platform: platform, 40 }, nil 41 } 42 43 func (store *FSMetadataStore) path(namespace, key string) string { 44 return filepath.Join(store.basePath, namespace, key) 45 } 46 47 // Get retrieves data by namespace and key. The data is read from a file named 48 // after the key, stored in the namespace's directory. 49 func (store *FSMetadataStore) Get(namespace string, key string) ([]byte, error) { 50 store.RLock() 51 defer store.RUnlock() 52 53 return ioutil.ReadFile(store.path(namespace, key)) 54 } 55 56 // Set writes data indexed by namespace and key. The data is written to a file 57 // named after the key, stored in the namespace's directory. 58 func (store *FSMetadataStore) Set(namespace, key string, value []byte) error { 59 store.Lock() 60 defer store.Unlock() 61 62 path := store.path(namespace, key) 63 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { 64 return err 65 } 66 return ioutils.AtomicWriteFile(path, value, 0644) 67 } 68 69 // Delete removes data indexed by namespace and key. The data file named after 70 // the key, stored in the namespace's directory is deleted. 71 func (store *FSMetadataStore) Delete(namespace, key string) error { 72 store.Lock() 73 defer store.Unlock() 74 75 path := store.path(namespace, key) 76 return os.Remove(path) 77 }