зеркало из https://github.com/microsoft/docker.git
66 строки
1.9 KiB
Go
66 строки
1.9 KiB
Go
package metadata
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
)
|
|
|
|
// Store implements a K/V store for mapping distribution-related IDs
|
|
// to on-disk layer IDs and image IDs. The namespace identifies the type of
|
|
// mapping (i.e. "v1ids" or "artifacts"). MetadataStore is goroutine-safe.
|
|
type Store interface {
|
|
// Get retrieves data by namespace and key.
|
|
Get(namespace string, key string) ([]byte, error)
|
|
// Set writes data indexed by namespace and key.
|
|
Set(namespace, key string, value []byte) error
|
|
}
|
|
|
|
// FSMetadataStore uses the filesystem to associate metadata with layer and
|
|
// image IDs.
|
|
type FSMetadataStore struct {
|
|
sync.RWMutex
|
|
basePath string
|
|
}
|
|
|
|
// NewFSMetadataStore creates a new filesystem-based metadata store.
|
|
func NewFSMetadataStore(basePath string) (*FSMetadataStore, error) {
|
|
if err := os.MkdirAll(basePath, 0700); err != nil {
|
|
return nil, err
|
|
}
|
|
return &FSMetadataStore{
|
|
basePath: basePath,
|
|
}, nil
|
|
}
|
|
|
|
func (store *FSMetadataStore) path(namespace, key string) string {
|
|
return filepath.Join(store.basePath, namespace, key)
|
|
}
|
|
|
|
// Get retrieves data by namespace and key. The data is read from a file named
|
|
// after the key, stored in the namespace's directory.
|
|
func (store *FSMetadataStore) Get(namespace string, key string) ([]byte, error) {
|
|
store.RLock()
|
|
defer store.RUnlock()
|
|
|
|
return ioutil.ReadFile(store.path(namespace, key))
|
|
}
|
|
|
|
// Set writes data indexed by namespace and key. The data is written to a file
|
|
// named after the key, stored in the namespace's directory.
|
|
func (store *FSMetadataStore) Set(namespace, key string, value []byte) error {
|
|
store.Lock()
|
|
defer store.Unlock()
|
|
|
|
path := store.path(namespace, key)
|
|
tempFilePath := path + ".tmp"
|
|
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
|
return err
|
|
}
|
|
if err := ioutil.WriteFile(tempFilePath, value, 0644); err != nil {
|
|
return err
|
|
}
|
|
return os.Rename(tempFilePath, path)
|
|
}
|