store.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package image
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "sync"
  7. "github.com/Sirupsen/logrus"
  8. "github.com/docker/distribution/digest"
  9. "github.com/docker/docker/layer"
  10. )
  11. // Store is an interface for creating and accessing images
  12. type Store interface {
  13. Create(config []byte) (ID, error)
  14. Get(id ID) (*Image, error)
  15. Delete(id ID) ([]layer.Metadata, error)
  16. Search(partialID string) (ID, error)
  17. SetParent(id ID, parent ID) error
  18. GetParent(id ID) (ID, error)
  19. Children(id ID) []ID
  20. Map() map[ID]*Image
  21. Heads() map[ID]*Image
  22. }
  23. // LayerGetReleaser is a minimal interface for getting and releasing images.
  24. type LayerGetReleaser interface {
  25. Get(layer.ChainID) (layer.Layer, error)
  26. Release(layer.Layer) ([]layer.Metadata, error)
  27. }
  28. type imageMeta struct {
  29. layer layer.Layer
  30. children map[ID]struct{}
  31. }
  32. type store struct {
  33. sync.Mutex
  34. ls LayerGetReleaser
  35. images map[ID]*imageMeta
  36. fs StoreBackend
  37. digestSet *digest.Set
  38. }
  39. // NewImageStore returns new store object for given layer store
  40. func NewImageStore(fs StoreBackend, ls LayerGetReleaser) (Store, error) {
  41. is := &store{
  42. ls: ls,
  43. images: make(map[ID]*imageMeta),
  44. fs: fs,
  45. digestSet: digest.NewSet(),
  46. }
  47. // load all current images and retain layers
  48. if err := is.restore(); err != nil {
  49. return nil, err
  50. }
  51. return is, nil
  52. }
  53. func (is *store) restore() error {
  54. err := is.fs.Walk(func(id ID) error {
  55. img, err := is.Get(id)
  56. if err != nil {
  57. logrus.Errorf("invalid image %v, %v", id, err)
  58. return nil
  59. }
  60. var l layer.Layer
  61. if chainID := img.RootFS.ChainID(); chainID != "" {
  62. l, err = is.ls.Get(chainID)
  63. if err != nil {
  64. return err
  65. }
  66. }
  67. if err := is.digestSet.Add(digest.Digest(id)); err != nil {
  68. return err
  69. }
  70. imageMeta := &imageMeta{
  71. layer: l,
  72. children: make(map[ID]struct{}),
  73. }
  74. is.images[ID(id)] = imageMeta
  75. return nil
  76. })
  77. if err != nil {
  78. return err
  79. }
  80. // Second pass to fill in children maps
  81. for id := range is.images {
  82. if parent, err := is.GetParent(id); err == nil {
  83. if parentMeta := is.images[parent]; parentMeta != nil {
  84. parentMeta.children[id] = struct{}{}
  85. }
  86. }
  87. }
  88. return nil
  89. }
  90. func (is *store) Create(config []byte) (ID, error) {
  91. var img Image
  92. err := json.Unmarshal(config, &img)
  93. if err != nil {
  94. return "", err
  95. }
  96. // Must reject any config that references diffIDs from the history
  97. // which aren't among the rootfs layers.
  98. rootFSLayers := make(map[layer.DiffID]struct{})
  99. for _, diffID := range img.RootFS.DiffIDs {
  100. rootFSLayers[diffID] = struct{}{}
  101. }
  102. layerCounter := 0
  103. for _, h := range img.History {
  104. if !h.EmptyLayer {
  105. layerCounter++
  106. }
  107. }
  108. if layerCounter > len(img.RootFS.DiffIDs) {
  109. return "", errors.New("too many non-empty layers in History section")
  110. }
  111. dgst, err := is.fs.Set(config)
  112. if err != nil {
  113. return "", err
  114. }
  115. imageID := ID(dgst)
  116. is.Lock()
  117. defer is.Unlock()
  118. if _, exists := is.images[imageID]; exists {
  119. return imageID, nil
  120. }
  121. layerID := img.RootFS.ChainID()
  122. var l layer.Layer
  123. if layerID != "" {
  124. l, err = is.ls.Get(layerID)
  125. if err != nil {
  126. return "", err
  127. }
  128. }
  129. imageMeta := &imageMeta{
  130. layer: l,
  131. children: make(map[ID]struct{}),
  132. }
  133. is.images[imageID] = imageMeta
  134. if err := is.digestSet.Add(digest.Digest(imageID)); err != nil {
  135. delete(is.images, imageID)
  136. return "", err
  137. }
  138. return imageID, nil
  139. }
  140. func (is *store) Search(term string) (ID, error) {
  141. is.Lock()
  142. defer is.Unlock()
  143. dgst, err := is.digestSet.Lookup(term)
  144. if err != nil {
  145. if err == digest.ErrDigestNotFound {
  146. err = fmt.Errorf("No such image: %s", term)
  147. }
  148. return "", err
  149. }
  150. return ID(dgst), nil
  151. }
  152. func (is *store) Get(id ID) (*Image, error) {
  153. // todo: Check if image is in images
  154. // todo: Detect manual insertions and start using them
  155. config, err := is.fs.Get(id)
  156. if err != nil {
  157. return nil, err
  158. }
  159. img, err := NewFromJSON(config)
  160. if err != nil {
  161. return nil, err
  162. }
  163. img.computedID = id
  164. img.Parent, err = is.GetParent(id)
  165. if err != nil {
  166. img.Parent = ""
  167. }
  168. return img, nil
  169. }
  170. func (is *store) Delete(id ID) ([]layer.Metadata, error) {
  171. is.Lock()
  172. defer is.Unlock()
  173. imageMeta := is.images[id]
  174. if imageMeta == nil {
  175. return nil, fmt.Errorf("unrecognized image ID %s", id.String())
  176. }
  177. for id := range imageMeta.children {
  178. is.fs.DeleteMetadata(id, "parent")
  179. }
  180. if parent, err := is.GetParent(id); err == nil && is.images[parent] != nil {
  181. delete(is.images[parent].children, id)
  182. }
  183. if err := is.digestSet.Remove(digest.Digest(id)); err != nil {
  184. logrus.Errorf("error removing %s from digest set: %q", id, err)
  185. }
  186. delete(is.images, id)
  187. is.fs.Delete(id)
  188. if imageMeta.layer != nil {
  189. return is.ls.Release(imageMeta.layer)
  190. }
  191. return nil, nil
  192. }
  193. func (is *store) SetParent(id, parent ID) error {
  194. is.Lock()
  195. defer is.Unlock()
  196. parentMeta := is.images[parent]
  197. if parentMeta == nil {
  198. return fmt.Errorf("unknown parent image ID %s", parent.String())
  199. }
  200. if parent, err := is.GetParent(id); err == nil && is.images[parent] != nil {
  201. delete(is.images[parent].children, id)
  202. }
  203. parentMeta.children[id] = struct{}{}
  204. return is.fs.SetMetadata(id, "parent", []byte(parent))
  205. }
  206. func (is *store) GetParent(id ID) (ID, error) {
  207. d, err := is.fs.GetMetadata(id, "parent")
  208. if err != nil {
  209. return "", err
  210. }
  211. return ID(d), nil // todo: validate?
  212. }
  213. func (is *store) Children(id ID) []ID {
  214. is.Lock()
  215. defer is.Unlock()
  216. return is.children(id)
  217. }
  218. func (is *store) children(id ID) []ID {
  219. var ids []ID
  220. if is.images[id] != nil {
  221. for id := range is.images[id].children {
  222. ids = append(ids, id)
  223. }
  224. }
  225. return ids
  226. }
  227. func (is *store) Heads() map[ID]*Image {
  228. return is.imagesMap(false)
  229. }
  230. func (is *store) Map() map[ID]*Image {
  231. return is.imagesMap(true)
  232. }
  233. func (is *store) imagesMap(all bool) map[ID]*Image {
  234. is.Lock()
  235. defer is.Unlock()
  236. images := make(map[ID]*Image)
  237. for id := range is.images {
  238. if !all && len(is.children(id)) > 0 {
  239. continue
  240. }
  241. img, err := is.Get(id)
  242. if err != nil {
  243. logrus.Errorf("invalid image access: %q, error: %q", id, err)
  244. continue
  245. }
  246. images[id] = img
  247. }
  248. return images
  249. }