浏览代码

daemon/c8d: Cache SnapshotService

Avoid fetching `SnapshotService` from client every time. Fetch it once
and then store when creating the image service.

This also allows to pass custom snapshotter implementation for unit
testing.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Paweł Gronowski 1 年之前
父节点
当前提交
1b108bdfeb
共有 2 个文件被更改,包括 30 次插入16 次删除
  1. 2 2
      daemon/containerd/image_list.go
  2. 28 14
      daemon/containerd/service.go

+ 2 - 2
daemon/containerd/image_list.go

@@ -78,7 +78,7 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions)
 	}
 
 	// TODO(thaJeztah): do we need to take multiple snapshotters into account? See https://github.com/moby/moby/issues/45273
-	snapshotter := i.client.SnapshotService(i.snapshotter)
+	snapshotter := i.snapshotterService(i.snapshotter)
 	sizeCache := make(map[digest.Digest]int64)
 	snapshotSizeFn := func(d digest.Digest) (int64, error) {
 		if s, ok := sizeCache[d]; ok {
@@ -264,7 +264,7 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con
 	}
 
 	// TODO(thaJeztah): do we need to take multiple snapshotters into account? See https://github.com/moby/moby/issues/45273
-	snapshotter := i.client.SnapshotService(i.snapshotter)
+	snapshotter := i.snapshotterService(i.snapshotter)
 
 	imageSnapshotID := identity.ChainID(diffIDs).String()
 	unpackedUsage, err := calculateSnapshotTotalUsage(ctx, snapshotter, imageSnapshotID)

+ 28 - 14
daemon/containerd/service.go

@@ -27,17 +27,18 @@ import (
 
 // ImageService implements daemon.ImageService
 type ImageService struct {
-	client          *containerd.Client
-	images          images.Store
-	content         content.Store
-	containers      container.Store
-	snapshotter     string
-	registryHosts   docker.RegistryHosts
-	registryService registryResolver
-	eventsService   *daemonevents.Events
-	pruneRunning    atomic.Bool
-	refCountMounter snapshotter.Mounter
-	idMapping       idtools.IdentityMapping
+	client              *containerd.Client
+	images              images.Store
+	content             content.Store
+	containers          container.Store
+	snapshotterServices map[string]snapshots.Snapshotter
+	snapshotter         string
+	registryHosts       docker.RegistryHosts
+	registryService     registryResolver
+	eventsService       *daemonevents.Events
+	pruneRunning        atomic.Bool
+	refCountMounter     snapshotter.Mounter
+	idMapping           idtools.IdentityMapping
 }
 
 type registryResolver interface {
@@ -61,9 +62,12 @@ type ImageServiceConfig struct {
 // NewService creates a new ImageService.
 func NewService(config ImageServiceConfig) *ImageService {
 	return &ImageService{
-		client:          config.Client,
-		images:          config.Client.ImageService(),
-		content:         config.Client.ContentStore(),
+		client:  config.Client,
+		images:  config.Client.ImageService(),
+		content: config.Client.ContentStore(),
+		snapshotterServices: map[string]snapshots.Snapshotter{
+			config.Snapshotter: config.Client.SnapshotService(config.Snapshotter),
+		},
 		containers:      config.Containers,
 		snapshotter:     config.Snapshotter,
 		registryHosts:   config.RegistryHosts,
@@ -74,6 +78,16 @@ func NewService(config ImageServiceConfig) *ImageService {
 	}
 }
 
+func (i *ImageService) snapshotterService(snapshotter string) snapshots.Snapshotter {
+	s, ok := i.snapshotterServices[snapshotter]
+	if !ok {
+		s = i.client.SnapshotService(snapshotter)
+		i.snapshotterServices[snapshotter] = s
+	}
+
+	return s
+}
+
 // DistributionServices return services controlling daemon image storage.
 func (i *ImageService) DistributionServices() dimages.DistributionServices {
 	return dimages.DistributionServices{}