mirror of
https://github.com/containerd/containerd.git
synced 2026-06-24 08:48:48 +00:00
diff/walking: enable mount manager
The default walking applier performs a real temporary mount for unpacking, but the mount manager failed to adapt to the walking differ. This fixes the EROFS snapshotter together with the default walking differ, otherwise it reports: ``` ctr: apply layer error for "[]": failed to extract layer sha256:[]: failed to mount /var/lib/containerd/tmpmounts/containerd-mount3992073457: internal mount option "X-containerd.mkfs.fs=ext4" was not consumed by the mount manager ``` Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
This commit is contained in:
@@ -18,6 +18,8 @@ package apply
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
@@ -25,6 +27,7 @@ import (
|
||||
"github.com/containerd/containerd/v2/core/content"
|
||||
"github.com/containerd/containerd/v2/core/diff"
|
||||
"github.com/containerd/containerd/v2/core/mount"
|
||||
"github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
@@ -33,13 +36,22 @@ import (
|
||||
// NewFileSystemApplier returns an applier which simply mounts
|
||||
// and applies diff onto the mounted filesystem.
|
||||
func NewFileSystemApplier(cs content.Provider) diff.Applier {
|
||||
return NewFileSystemApplierWithMountManager(cs, nil)
|
||||
}
|
||||
|
||||
// NewFileSystemApplierWithMountManager returns an applier which simply mounts and
|
||||
// applies diff onto the mounted filesystem.
|
||||
// An optional mount manager can be specified and it will take effect when applying.
|
||||
func NewFileSystemApplierWithMountManager(cs content.Provider, mm mount.Manager) diff.Applier {
|
||||
return &fsApplier{
|
||||
store: cs,
|
||||
mount: mm,
|
||||
}
|
||||
}
|
||||
|
||||
type fsApplier struct {
|
||||
store content.Provider
|
||||
mount mount.Manager
|
||||
}
|
||||
|
||||
var emptyDesc = ocispec.Descriptor{}
|
||||
@@ -98,6 +110,23 @@ func (s *fsApplier) Apply(ctx context.Context, desc ocispec.Descriptor, mounts [
|
||||
r: io.TeeReader(processor, digester.Hash()),
|
||||
}
|
||||
|
||||
// The number of `mounts` that need to be parsed by the mount manager
|
||||
// will be more than 1 in reality; this is needed to work around some
|
||||
// overlayfs/bind shortcuts in core/diff/apply/apply_linux.go
|
||||
if s.mount != nil && len(mounts) > 1 {
|
||||
var b [3]byte
|
||||
// Ignore read failures, just decreases uniqueness
|
||||
rand.Read(b[:])
|
||||
id := fmt.Sprintf("fs-diffapply-%d-%s", t1.Nanosecond(), base64.URLEncoding.EncodeToString(b[:]))
|
||||
info, err := s.mount.Activate(ctx, id, mounts)
|
||||
if err == nil {
|
||||
defer s.mount.Deactivate(ctx, id)
|
||||
mounts = info.System
|
||||
} else if !errdefs.IsNotImplemented(err) {
|
||||
return emptyDesc, fmt.Errorf("failed to activate mounts: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := apply(ctx, mounts, rc, config.SyncFs); err != nil {
|
||||
return emptyDesc, err
|
||||
}
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/containerd/containerd/v2/core/diff"
|
||||
"github.com/containerd/containerd/v2/core/diff/apply"
|
||||
"github.com/containerd/containerd/v2/core/metadata"
|
||||
"github.com/containerd/containerd/v2/core/mount"
|
||||
"github.com/containerd/containerd/v2/plugins"
|
||||
"github.com/containerd/containerd/v2/plugins/diff/walking"
|
||||
"github.com/containerd/platforms"
|
||||
@@ -33,6 +36,7 @@ func init() {
|
||||
ID: "walking",
|
||||
Requires: []plugin.Type{
|
||||
plugins.MetadataPlugin,
|
||||
plugins.MountManagerPlugin,
|
||||
},
|
||||
InitFn: func(ic *plugin.InitContext) (any, error) {
|
||||
md, err := ic.GetSingle(plugins.MetadataPlugin)
|
||||
@@ -40,12 +44,19 @@ func init() {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var mm mount.Manager
|
||||
if mountsI, err := ic.GetSingle(plugins.MountManagerPlugin); err == nil {
|
||||
mm = mountsI.(mount.Manager)
|
||||
} else if !errors.Is(err, plugin.ErrPluginNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec())
|
||||
cs := md.(*metadata.DB).ContentStore()
|
||||
|
||||
return diffPlugin{
|
||||
Comparer: walking.NewWalkingDiff(cs),
|
||||
Applier: apply.NewFileSystemApplier(cs),
|
||||
Applier: apply.NewFileSystemApplierWithMountManager(cs, mm),
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user