Update commit id unmap to directly use active mounts
Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
parent
cf5a3bc531
commit
f74ca4ed36
3 changed files with 93 additions and 15 deletions
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/rootfs"
|
||||
"github.com/containerd/containerd/pkg/cleanup"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
|
@ -251,35 +251,77 @@ func writeContentsForImage(ctx context.Context, snName string, cs content.Store,
|
|||
// createDiff creates a layer diff into containerd's content store.
|
||||
// If the diff is empty it returns nil empty digest and no error.
|
||||
func (i *ImageService) createDiff(ctx context.Context, name string, sn snapshots.Snapshotter, cs content.Store, comparer diff.Comparer) (*ocispec.Descriptor, digest.Digest, error) {
|
||||
info, err := sn.Stat(ctx, name)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
var upper []mount.Mount
|
||||
if !i.idMapping.Empty() {
|
||||
// The rootfs of the container is remapped if an id mapping exists, we
|
||||
// need to "unremap" it before committing the snapshot
|
||||
rootPair := i.idMapping.RootPair()
|
||||
usernsID := fmt.Sprintf("%s-%d-%d", name, rootPair.UID, rootPair.GID)
|
||||
usernsID := fmt.Sprintf("%s-%d-%d-%s", name, rootPair.UID, rootPair.GID, uniquePart())
|
||||
remappedID := usernsID + remapSuffix
|
||||
baseName := name
|
||||
|
||||
err := sn.Commit(ctx, name+"-pre", name)
|
||||
if err != nil && !cerrdefs.IsAlreadyExists(err) {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if !cerrdefs.IsAlreadyExists(err) {
|
||||
mounts, err := sn.Prepare(ctx, remappedID, name+"-pre")
|
||||
if info.Kind == snapshots.KindActive {
|
||||
source, err := sn.Mounts(ctx, name)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if err := i.unremapRootFS(ctx, mounts); err != nil {
|
||||
// No need to use parent since the whole snapshot is copied.
|
||||
// Using parent would require doing diff/apply while starting
|
||||
// from empty can just copy the whole snapshot.
|
||||
// TODO: Optimize this for overlay mounts, can use parent
|
||||
// and just copy upper directories without mounting
|
||||
upper, err = sn.Prepare(ctx, remappedID, "")
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if err := sn.Commit(ctx, name, remappedID); err != nil {
|
||||
if err := i.copyAndUnremapRootFS(ctx, upper, source); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
} else {
|
||||
upper, err = sn.Prepare(ctx, remappedID, baseName)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if err := i.unremapRootFS(ctx, upper); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if info.Kind == snapshots.KindActive {
|
||||
upper, err = sn.Mounts(ctx, name)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
} else {
|
||||
upperKey := fmt.Sprintf("%s-view-%s", name, uniquePart())
|
||||
upper, err = sn.View(ctx, upperKey, name)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
defer cleanup.Do(ctx, func(ctx context.Context) {
|
||||
sn.Remove(ctx, upperKey)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
newDesc, err := rootfs.CreateDiff(ctx, name, sn, comparer)
|
||||
lowerKey := fmt.Sprintf("%s-parent-view-%s", info.Parent, uniquePart())
|
||||
lower, err := sn.View(ctx, lowerKey, info.Parent)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
defer cleanup.Do(ctx, func(ctx context.Context) {
|
||||
sn.Remove(ctx, lowerKey)
|
||||
})
|
||||
|
||||
newDesc, err := comparer.Compare(ctx, lower, upper)
|
||||
if err != nil {
|
||||
return nil, "", errors.Wrap(err, "CreateDiff")
|
||||
}
|
||||
|
@ -298,12 +340,12 @@ func (i *ImageService) createDiff(ctx context.Context, name string, sn snapshots
|
|||
return nil, "", nil
|
||||
}
|
||||
|
||||
info, err := cs.Info(ctx, newDesc.Digest)
|
||||
cinfo, err := cs.Info(ctx, newDesc.Digest)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("failed to get content info: %w", err)
|
||||
}
|
||||
|
||||
diffIDStr, ok := info.Labels["containerd.io/uncompressed"]
|
||||
diffIDStr, ok := cinfo.Labels["containerd.io/uncompressed"]
|
||||
if !ok {
|
||||
return nil, "", fmt.Errorf("invalid differ response with no diffID")
|
||||
}
|
||||
|
@ -316,7 +358,7 @@ func (i *ImageService) createDiff(ctx context.Context, name string, sn snapshots
|
|||
return &ocispec.Descriptor{
|
||||
MediaType: ocispec.MediaTypeImageLayerGzip,
|
||||
Digest: newDesc.Digest,
|
||||
Size: info.Size,
|
||||
Size: cinfo.Size,
|
||||
}, diffID, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/containerd/continuity/sysx"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
)
|
||||
|
@ -63,6 +64,35 @@ func (i *ImageService) remapRootFS(ctx context.Context, mounts []mount.Mount) er
|
|||
})
|
||||
}
|
||||
|
||||
func (i *ImageService) copyAndUnremapRootFS(ctx context.Context, dst, src []mount.Mount) error {
|
||||
return mount.WithTempMount(ctx, src, func(source string) error {
|
||||
return mount.WithTempMount(ctx, dst, func(root string) error {
|
||||
// TODO: Update CopyDir to support remap directly
|
||||
if err := fs.CopyDir(root, source); err != nil {
|
||||
return fmt.Errorf("failed to copy: %w", err)
|
||||
}
|
||||
|
||||
return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stat := info.Sys().(*syscall.Stat_t)
|
||||
if stat == nil {
|
||||
return fmt.Errorf("cannot get underlying data for %s", path)
|
||||
}
|
||||
|
||||
uid, gid, err := i.idMapping.ToContainer(idtools.Identity{UID: int(stat.Uid), GID: int(stat.Gid)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return chownWithCaps(path, uid, gid)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (i *ImageService) unremapRootFS(ctx context.Context, mounts []mount.Mount) error {
|
||||
return mount.WithTempMount(ctx, mounts, func(root string) error {
|
||||
return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
|
|
|
@ -7,6 +7,12 @@ import (
|
|||
"github.com/containerd/containerd/snapshots"
|
||||
)
|
||||
|
||||
const remapSuffix = "-remap"
|
||||
|
||||
func (i *ImageService) copyAndUnremapRootFS(ctx context.Context, dst, src []mount.Mount) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ImageService) remapSnapshot(ctx context.Context, snapshotter snapshots.Snapshotter, id string, parentSnapshot string) error {
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue