github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/daemon/containerd/service.go (about) 1 package containerd 2 3 import ( 4 "context" 5 "fmt" 6 "sync/atomic" 7 8 "github.com/containerd/containerd" 9 cerrdefs "github.com/containerd/containerd/errdefs" 10 "github.com/containerd/containerd/plugin" 11 "github.com/containerd/containerd/remotes/docker" 12 "github.com/containerd/containerd/snapshots" 13 "github.com/containerd/log" 14 "github.com/distribution/reference" 15 "github.com/Prakhar-Agarwal-byte/moby/container" 16 daemonevents "github.com/Prakhar-Agarwal-byte/moby/daemon/events" 17 "github.com/Prakhar-Agarwal-byte/moby/daemon/images" 18 "github.com/Prakhar-Agarwal-byte/moby/daemon/snapshotter" 19 "github.com/Prakhar-Agarwal-byte/moby/errdefs" 20 "github.com/Prakhar-Agarwal-byte/moby/image" 21 "github.com/Prakhar-Agarwal-byte/moby/layer" 22 "github.com/Prakhar-Agarwal-byte/moby/pkg/idtools" 23 "github.com/Prakhar-Agarwal-byte/moby/registry" 24 "github.com/pkg/errors" 25 ) 26 27 // ImageService implements daemon.ImageService 28 type ImageService struct { 29 client *containerd.Client 30 containers container.Store 31 snapshotter string 32 registryHosts docker.RegistryHosts 33 registryService RegistryConfigProvider 34 eventsService *daemonevents.Events 35 pruneRunning atomic.Bool 36 refCountMounter snapshotter.Mounter 37 idMapping idtools.IdentityMapping 38 } 39 40 type RegistryConfigProvider interface { 41 IsInsecureRegistry(host string) bool 42 ResolveRepository(name reference.Named) (*registry.RepositoryInfo, error) 43 } 44 45 type ImageServiceConfig struct { 46 Client *containerd.Client 47 Containers container.Store 48 Snapshotter string 49 RegistryHosts docker.RegistryHosts 50 Registry RegistryConfigProvider 51 EventsService *daemonevents.Events 52 RefCountMounter snapshotter.Mounter 53 IDMapping idtools.IdentityMapping 54 } 55 56 // NewService creates a new ImageService. 57 func NewService(config ImageServiceConfig) *ImageService { 58 return &ImageService{ 59 client: config.Client, 60 containers: config.Containers, 61 snapshotter: config.Snapshotter, 62 registryHosts: config.RegistryHosts, 63 registryService: config.Registry, 64 eventsService: config.EventsService, 65 refCountMounter: config.RefCountMounter, 66 idMapping: config.IDMapping, 67 } 68 } 69 70 // DistributionServices return services controlling daemon image storage. 71 func (i *ImageService) DistributionServices() images.DistributionServices { 72 return images.DistributionServices{} 73 } 74 75 // CountImages returns the number of images stored by ImageService 76 // called from info.go 77 func (i *ImageService) CountImages() int { 78 imgs, err := i.client.ListImages(context.TODO()) 79 if err != nil { 80 return 0 81 } 82 83 return len(imgs) 84 } 85 86 // CreateLayer creates a filesystem layer for a container. 87 // called from create.go 88 // TODO: accept an opt struct instead of container? 89 func (i *ImageService) CreateLayer(container *container.Container, initFunc layer.MountInit) (layer.RWLayer, error) { 90 return nil, errdefs.NotImplemented(errdefs.NotImplemented(errors.New("not implemented"))) 91 } 92 93 // LayerStoreStatus returns the status for each layer store 94 // called from info.go 95 func (i *ImageService) LayerStoreStatus() [][2]string { 96 // TODO(thaJeztah) do we want to add more details about the driver here? 97 return [][2]string{ 98 {"driver-type", string(plugin.SnapshotPlugin)}, 99 } 100 } 101 102 // GetLayerMountID returns the mount ID for a layer 103 // called from daemon.go Daemon.Shutdown(), and Daemon.Cleanup() (cleanup is actually continerCleanup) 104 // TODO: needs to be refactored to Unmount (see callers), or removed and replaced with GetLayerByID 105 func (i *ImageService) GetLayerMountID(cid string) (string, error) { 106 return "", errdefs.NotImplemented(errors.New("not implemented")) 107 } 108 109 // Cleanup resources before the process is shutdown. 110 // called from daemon.go Daemon.Shutdown() 111 func (i *ImageService) Cleanup() error { 112 return nil 113 } 114 115 // StorageDriver returns the name of the default storage-driver (snapshotter) 116 // used by the ImageService. 117 func (i *ImageService) StorageDriver() string { 118 return i.snapshotter 119 } 120 121 // ReleaseLayer releases a layer allowing it to be removed 122 // called from delete.go Daemon.cleanupContainer(), and Daemon.containerExport() 123 func (i *ImageService) ReleaseLayer(rwlayer layer.RWLayer) error { 124 return errdefs.NotImplemented(errors.New("not implemented")) 125 } 126 127 // LayerDiskUsage returns the number of bytes used by layer stores 128 // called from disk_usage.go 129 func (i *ImageService) LayerDiskUsage(ctx context.Context) (int64, error) { 130 var allLayersSize int64 131 // TODO(thaJeztah): do we need to take multiple snapshotters into account? See https://github.com/moby/moby/issues/45273 132 snapshotter := i.client.SnapshotService(i.snapshotter) 133 snapshotter.Walk(ctx, func(ctx context.Context, info snapshots.Info) error { 134 usage, err := snapshotter.Usage(ctx, info.Name) 135 if err != nil { 136 return err 137 } 138 allLayersSize += usage.Size 139 return nil 140 }) 141 return allLayersSize, nil 142 } 143 144 // UpdateConfig values 145 // 146 // called from reload.go 147 func (i *ImageService) UpdateConfig(maxDownloads, maxUploads int) { 148 log.G(context.TODO()).Warn("max downloads and uploads is not yet implemented with the containerd store") 149 } 150 151 // GetLayerFolders returns the layer folders from an image RootFS. 152 func (i *ImageService) GetLayerFolders(img *image.Image, rwLayer layer.RWLayer) ([]string, error) { 153 return nil, errdefs.NotImplemented(errors.New("not implemented")) 154 } 155 156 // GetContainerLayerSize returns the real size & virtual size of the container. 157 func (i *ImageService) GetContainerLayerSize(ctx context.Context, containerID string) (int64, int64, error) { 158 ctr := i.containers.Get(containerID) 159 if ctr == nil { 160 return 0, 0, nil 161 } 162 163 snapshotter := i.client.SnapshotService(ctr.Driver) 164 rwLayerUsage, err := snapshotter.Usage(ctx, containerID) 165 if err != nil { 166 if cerrdefs.IsNotFound(err) { 167 return 0, 0, errdefs.NotFound(fmt.Errorf("rw layer snapshot not found for container %s", containerID)) 168 } 169 return 0, 0, errdefs.System(errors.Wrapf(err, "snapshotter.Usage failed for %s", containerID)) 170 } 171 172 unpackedUsage, err := calculateSnapshotParentUsage(ctx, snapshotter, containerID) 173 if err != nil { 174 if cerrdefs.IsNotFound(err) { 175 log.G(ctx).WithField("ctr", containerID).Warn("parent of container snapshot no longer present") 176 } else { 177 log.G(ctx).WithError(err).WithField("ctr", containerID).Warn("unexpected error when calculating usage of the parent snapshots") 178 } 179 } 180 log.G(ctx).WithFields(log.Fields{ 181 "rwLayerUsage": rwLayerUsage.Size, 182 "unpacked": unpackedUsage.Size, 183 }).Debug("GetContainerLayerSize") 184 185 // TODO(thaJeztah): include content-store size for the image (similar to "GET /images/json") 186 return rwLayerUsage.Size, rwLayerUsage.Size + unpackedUsage.Size, nil 187 }