layers.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package fs
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/dotcloud/docker/future"
  6. "io/ioutil"
  7. "os"
  8. "path"
  9. "path/filepath"
  10. )
  11. type LayerStore struct {
  12. Root string
  13. }
  14. func NewLayerStore(root string) (*LayerStore, error) {
  15. abspath, err := filepath.Abs(root)
  16. if err != nil {
  17. return nil, err
  18. }
  19. // Create the root directory if it doesn't exists
  20. if err := os.Mkdir(root, 0700); err != nil && !os.IsExist(err) {
  21. return nil, err
  22. }
  23. return &LayerStore{
  24. Root: abspath,
  25. }, nil
  26. }
  27. func (store *LayerStore) List() []string {
  28. files, err := ioutil.ReadDir(store.Root)
  29. if err != nil {
  30. return []string{}
  31. }
  32. var layers []string
  33. for _, st := range files {
  34. if st.IsDir() {
  35. layers = append(layers, path.Join(store.Root, st.Name()))
  36. }
  37. }
  38. return layers
  39. }
  40. func (store *LayerStore) Get(id string) string {
  41. if !store.Exists(id) {
  42. return ""
  43. }
  44. return store.layerPath(id)
  45. }
  46. func (store *LayerStore) rootExists() (bool, error) {
  47. if stat, err := os.Stat(store.Root); err != nil {
  48. if os.IsNotExist(err) {
  49. return false, nil
  50. }
  51. return false, err
  52. } else if !stat.IsDir() {
  53. return false, errors.New("Not a directory: " + store.Root)
  54. }
  55. return true, nil
  56. }
  57. func (store *LayerStore) Init() error {
  58. if exists, err := store.rootExists(); err != nil {
  59. return err
  60. } else if exists {
  61. return nil
  62. }
  63. return os.Mkdir(store.Root, 0700)
  64. }
  65. func (store *LayerStore) Mktemp() (string, error) {
  66. tmpName := future.RandomId()
  67. tmpPath := path.Join(store.Root, "tmp-"+tmpName)
  68. if err := os.Mkdir(tmpPath, 0700); err != nil {
  69. return "", err
  70. }
  71. return tmpPath, nil
  72. }
  73. func (store *LayerStore) layerPath(id string) string {
  74. return path.Join(store.Root, id)
  75. }
  76. func (store *LayerStore) AddLayer(id string, archive Archive) (string, error) {
  77. if _, err := os.Stat(store.layerPath(id)); err == nil {
  78. return "", fmt.Errorf("Layer already exists: %v", id)
  79. }
  80. tmp, err := store.Mktemp()
  81. defer os.RemoveAll(tmp)
  82. if err != nil {
  83. return "", fmt.Errorf("Mktemp failed: %s", err)
  84. }
  85. if err := Untar(archive, tmp); err != nil {
  86. return "", err
  87. }
  88. layer := store.layerPath(id)
  89. if !store.Exists(id) {
  90. if err := os.Rename(tmp, layer); err != nil {
  91. return "", fmt.Errorf("Could not rename temp dir to layer %s: %s", layer, err)
  92. }
  93. }
  94. return layer, nil
  95. }
  96. func (store *LayerStore) Exists(id string) bool {
  97. st, err := os.Stat(store.layerPath(id))
  98. if err != nil {
  99. return false
  100. }
  101. return st.IsDir()
  102. }