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  }