Implement GetLayerFolders for the containerd image store

The existing API ImageService.GetLayerFolders didn't have access to the
ID of the container, and once we have that, the snapshotter Mounts API
provides all the information we need here.

Signed-off-by: Paul "TBBle" Hampson <Paul.Hampson@Pobox.com>
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
Paul "TBBle" Hampson 2023-09-23 20:06:20 +09:00 committed by Paweł Gronowski
parent 0dc07ccc3a
commit 66325f7271
No known key found for this signature in database
GPG key ID: B85EFCFE26DEF92A
7 changed files with 51 additions and 11 deletions

View file

@ -19,7 +19,6 @@ import (
dimages "github.com/docker/docker/daemon/images"
"github.com/docker/docker/daemon/snapshotter"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/registry"
@ -156,11 +155,6 @@ func (i *ImageService) UpdateConfig(maxDownloads, maxUploads int) {
log.G(context.TODO()).Warn("max downloads and uploads is not yet implemented with the containerd store")
}
// GetLayerFolders returns the layer folders from an image RootFS.
func (i *ImageService) GetLayerFolders(img *image.Image, rwLayer layer.RWLayer) ([]string, error) {
return nil, errdefs.NotImplemented(errors.New("not implemented"))
}
// GetContainerLayerSize returns the real size & virtual size of the container.
func (i *ImageService) GetContainerLayerSize(ctx context.Context, containerID string) (int64, int64, error) {
ctr := i.containers.Get(containerID)

View file

@ -0,0 +1,15 @@
//go:build linux || freebsd
package containerd
import (
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/pkg/errors"
)
// GetLayerFolders returns the layer folders from an image RootFS.
func (i *ImageService) GetLayerFolders(img *image.Image, rwLayer layer.RWLayer, containerID string) ([]string, error) {
return nil, errdefs.NotImplemented(errors.New("not implemented"))
}

View file

@ -0,0 +1,31 @@
package containerd
import (
"context"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/pkg/errors"
)
// GetLayerFolders returns the layer folders from an image RootFS.
func (i *ImageService) GetLayerFolders(img *image.Image, rwLayer layer.RWLayer, containerID string) ([]string, error) {
if rwLayer != nil {
return nil, errors.New("RWLayer is unexpectedly not nil")
}
snapshotter := i.client.SnapshotService(i.StorageDriver())
mounts, err := snapshotter.Mounts(context.TODO(), containerID)
if err != nil {
return nil, errors.Wrapf(err, "snapshotter.Mounts failed: container %s", containerID)
}
// This is the same logic used by the hcsshim containerd runtime shim's createInternal
// to convert an array of Mounts into windows layers.
// See https://github.com/microsoft/hcsshim/blob/release/0.11/cmd/containerd-shim-runhcs-v1/service_internal.go
parentPaths, err := mounts[0].GetParentPaths()
if err != nil {
return nil, errors.Wrapf(err, "GetParentPaths failed: container %s", containerID)
}
return append(parentPaths, mounts[0].Source), nil
}

View file

@ -65,7 +65,7 @@ type ImageService interface {
// Windows specific
GetLayerFolders(img *image.Image, rwLayer layer.RWLayer) ([]string, error)
GetLayerFolders(img *image.Image, rwLayer layer.RWLayer, containerID string) ([]string, error)
// Build

View file

@ -11,7 +11,7 @@ import (
)
// GetLayerFolders returns the layer folders from an image RootFS
func (i *ImageService) GetLayerFolders(img *image.Image, rwLayer layer.RWLayer) ([]string, error) {
func (i *ImageService) GetLayerFolders(img *image.Image, rwLayer layer.RWLayer, containerID string) ([]string, error) {
// Windows specific
panic("not implemented")
}

View file

@ -15,7 +15,7 @@ func (i *ImageService) GetContainerLayerSize(ctx context.Context, containerID st
}
// GetLayerFolders returns the layer folders from an image RootFS
func (i *ImageService) GetLayerFolders(img *image.Image, rwLayer layer.RWLayer) ([]string, error) {
func (i *ImageService) GetLayerFolders(img *image.Image, rwLayer layer.RWLayer, containerID string) ([]string, error) {
folders := []string{}
rd := len(img.RootFS.DiffIDs)
for index := 1; index <= rd; index++ {

View file

@ -138,9 +138,9 @@ func (daemon *Daemon) createSpec(ctx context.Context, daemonCfg *configStore, c
}
}
s.Process.User.Username = c.Config.User
s.Windows.LayerFolders, err = daemon.imageService.GetLayerFolders(img, c.RWLayer)
s.Windows.LayerFolders, err = daemon.imageService.GetLayerFolders(img, c.RWLayer, c.ID)
if err != nil {
return nil, errors.Wrapf(err, "container %s", c.ID)
return nil, errors.Wrapf(err, "GetLayerFolders failed: container %s", c.ID)
}
// Get endpoints for the libnetwork allocated networks to the container