service.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package images // import "github.com/docker/docker/daemon/images"
  2. import (
  3. "context"
  4. "os"
  5. "github.com/containerd/containerd/content"
  6. "github.com/containerd/containerd/leases"
  7. "github.com/docker/docker/container"
  8. daemonevents "github.com/docker/docker/daemon/events"
  9. "github.com/docker/docker/distribution"
  10. "github.com/docker/docker/distribution/metadata"
  11. "github.com/docker/docker/distribution/xfer"
  12. "github.com/docker/docker/image"
  13. "github.com/docker/docker/layer"
  14. dockerreference "github.com/docker/docker/reference"
  15. "github.com/opencontainers/go-digest"
  16. "github.com/pkg/errors"
  17. )
  18. type containerStore interface {
  19. // First is used by image delete
  20. First(container.StoreFilter) *container.Container
  21. // List is used by image prune, and image list
  22. List() []*container.Container
  23. // Get is used by CommitBuildStep
  24. // TODO: remove, only used for CommitBuildStep
  25. Get(string) *container.Container
  26. }
  27. // ImageServiceConfig is the configuration used to create a new ImageService
  28. type ImageServiceConfig struct {
  29. ContainerStore containerStore
  30. DistributionMetadataStore metadata.Store
  31. EventsService *daemonevents.Events
  32. ImageStore image.Store
  33. LayerStore layer.Store
  34. MaxConcurrentDownloads int
  35. MaxConcurrentUploads int
  36. MaxDownloadAttempts int
  37. ReferenceStore dockerreference.Store
  38. RegistryService distribution.RegistryResolver
  39. ContentStore content.Store
  40. Leases leases.Manager
  41. ContentNamespace string
  42. }
  43. // NewImageService returns a new ImageService from a configuration
  44. func NewImageService(config ImageServiceConfig) *ImageService {
  45. return &ImageService{
  46. containers: config.ContainerStore,
  47. distributionMetadataStore: config.DistributionMetadataStore,
  48. downloadManager: xfer.NewLayerDownloadManager(config.LayerStore, config.MaxConcurrentDownloads, xfer.WithMaxDownloadAttempts(config.MaxDownloadAttempts)),
  49. eventsService: config.EventsService,
  50. imageStore: &imageStoreWithLease{Store: config.ImageStore, leases: config.Leases, ns: config.ContentNamespace},
  51. layerStore: config.LayerStore,
  52. referenceStore: config.ReferenceStore,
  53. registryService: config.RegistryService,
  54. uploadManager: xfer.NewLayerUploadManager(config.MaxConcurrentUploads),
  55. leases: config.Leases,
  56. content: config.ContentStore,
  57. contentNamespace: config.ContentNamespace,
  58. }
  59. }
  60. // ImageService provides a backend for image management
  61. type ImageService struct {
  62. containers containerStore
  63. distributionMetadataStore metadata.Store
  64. downloadManager *xfer.LayerDownloadManager
  65. eventsService *daemonevents.Events
  66. imageStore image.Store
  67. layerStore layer.Store
  68. pruneRunning int32
  69. referenceStore dockerreference.Store
  70. registryService distribution.RegistryResolver
  71. uploadManager *xfer.LayerUploadManager
  72. leases leases.Manager
  73. content content.Store
  74. contentNamespace string
  75. }
  76. // DistributionServices provides daemon image storage services
  77. type DistributionServices struct {
  78. DownloadManager *xfer.LayerDownloadManager
  79. V2MetadataService metadata.V2MetadataService
  80. LayerStore layer.Store
  81. ImageStore image.Store
  82. ReferenceStore dockerreference.Store
  83. }
  84. // DistributionServices return services controlling daemon image storage
  85. func (i *ImageService) DistributionServices() DistributionServices {
  86. return DistributionServices{
  87. DownloadManager: i.downloadManager,
  88. V2MetadataService: metadata.NewV2MetadataService(i.distributionMetadataStore),
  89. LayerStore: i.layerStore,
  90. ImageStore: i.imageStore,
  91. ReferenceStore: i.referenceStore,
  92. }
  93. }
  94. // CountImages returns the number of images stored by ImageService
  95. // called from info.go
  96. func (i *ImageService) CountImages(ctx context.Context) int {
  97. return i.imageStore.Len()
  98. }
  99. // Children returns the children image.IDs for a parent image.
  100. // called from list.go to filter containers
  101. // TODO: refactor to expose an ancestry for image.ID?
  102. func (i *ImageService) Children(_ context.Context, id image.ID) ([]image.ID, error) {
  103. return i.imageStore.Children(id), nil
  104. }
  105. // CreateLayer creates a filesystem layer for a container.
  106. // called from create.go
  107. // TODO: accept an opt struct instead of container?
  108. func (i *ImageService) CreateLayer(container *container.Container, initFunc layer.MountInit) (layer.RWLayer, error) {
  109. var layerID layer.ChainID
  110. if container.ImageID != "" {
  111. img, err := i.imageStore.Get(container.ImageID)
  112. if err != nil {
  113. return nil, err
  114. }
  115. layerID = img.RootFS.ChainID()
  116. }
  117. rwLayerOpts := &layer.CreateRWLayerOpts{
  118. MountLabel: container.MountLabel,
  119. InitFunc: initFunc,
  120. StorageOpt: container.HostConfig.StorageOpt,
  121. }
  122. return i.layerStore.CreateRWLayer(container.ID, layerID, rwLayerOpts)
  123. }
  124. // GetLayerByID returns a layer by ID
  125. // called from daemon.go Daemon.restore().
  126. func (i *ImageService) GetLayerByID(cid string) (layer.RWLayer, error) {
  127. return i.layerStore.GetRWLayer(cid)
  128. }
  129. // LayerStoreStatus returns the status for each layer store
  130. // called from info.go
  131. func (i *ImageService) LayerStoreStatus() [][2]string {
  132. return i.layerStore.DriverStatus()
  133. }
  134. // GetLayerMountID returns the mount ID for a layer
  135. // called from daemon.go Daemon.Shutdown(), and Daemon.Cleanup() (cleanup is actually continerCleanup)
  136. // TODO: needs to be refactored to Unmount (see callers), or removed and replaced with GetLayerByID
  137. func (i *ImageService) GetLayerMountID(cid string) (string, error) {
  138. return i.layerStore.GetMountID(cid)
  139. }
  140. // Cleanup resources before the process is shutdown.
  141. // called from daemon.go Daemon.Shutdown()
  142. func (i *ImageService) Cleanup() error {
  143. if err := i.layerStore.Cleanup(); err != nil {
  144. return errors.Wrap(err, "error during layerStore.Cleanup()")
  145. }
  146. return nil
  147. }
  148. // StorageDriver returns the name of the storage driver used by the ImageService.
  149. func (i *ImageService) StorageDriver() string {
  150. return i.layerStore.DriverName()
  151. }
  152. // ReleaseLayer releases a layer allowing it to be removed
  153. // called from delete.go Daemon.cleanupContainer().
  154. func (i *ImageService) ReleaseLayer(rwlayer layer.RWLayer) error {
  155. metaData, err := i.layerStore.ReleaseRWLayer(rwlayer)
  156. layer.LogReleaseMetadata(metaData)
  157. if err != nil && !errors.Is(err, layer.ErrMountDoesNotExist) && !errors.Is(err, os.ErrNotExist) {
  158. return errors.Wrapf(err, "driver %q failed to remove root filesystem",
  159. i.layerStore.DriverName())
  160. }
  161. return nil
  162. }
  163. // LayerDiskUsage returns the number of bytes used by layer stores
  164. // called from disk_usage.go
  165. func (i *ImageService) LayerDiskUsage(ctx context.Context) (int64, error) {
  166. var allLayersSize int64
  167. layerRefs := i.getLayerRefs()
  168. allLayers := i.layerStore.Map()
  169. for _, l := range allLayers {
  170. select {
  171. case <-ctx.Done():
  172. return allLayersSize, ctx.Err()
  173. default:
  174. size := l.DiffSize()
  175. if _, ok := layerRefs[l.ChainID()]; ok {
  176. allLayersSize += size
  177. }
  178. }
  179. }
  180. return allLayersSize, nil
  181. }
  182. func (i *ImageService) getLayerRefs() map[layer.ChainID]int {
  183. tmpImages := i.imageStore.Map()
  184. layerRefs := map[layer.ChainID]int{}
  185. for id, img := range tmpImages {
  186. dgst := digest.Digest(id)
  187. if len(i.referenceStore.References(dgst)) == 0 && len(i.imageStore.Children(id)) != 0 {
  188. continue
  189. }
  190. rootFS := *img.RootFS
  191. rootFS.DiffIDs = nil
  192. for _, id := range img.RootFS.DiffIDs {
  193. rootFS.Append(id)
  194. chid := rootFS.ChainID()
  195. layerRefs[chid]++
  196. }
  197. }
  198. return layerRefs
  199. }
  200. // UpdateConfig values
  201. //
  202. // called from reload.go
  203. func (i *ImageService) UpdateConfig(maxDownloads, maxUploads int) {
  204. if i.downloadManager != nil && maxDownloads != 0 {
  205. i.downloadManager.SetConcurrency(maxDownloads)
  206. }
  207. if i.uploadManager != nil && maxUploads != 0 {
  208. i.uploadManager.SetConcurrency(maxUploads)
  209. }
  210. }