metadata.go 2.2 KB

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