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