@@ -29,6 +29,7 @@ import (
2929 "github.com/containerd/containerd/v2/core/mount"
3030 "github.com/containerd/containerd/v2/core/snapshots"
3131 "github.com/containerd/containerd/v2/core/snapshots/storage"
32+ "github.com/containerd/containerd/v2/internal/userns"
3233 "github.com/containerd/containerd/v2/plugins/snapshots/overlay/overlayutils"
3334 "github.com/containerd/continuity/fs"
3435 "github.com/containerd/log"
@@ -424,41 +425,6 @@ func (o *snapshotter) getCleanupDirectories(ctx context.Context) ([]string, erro
424425 return cleanup , nil
425426}
426427
427- func validateIDMapping (mapping string ) error {
428- var (
429- hostID int
430- ctrID int
431- length int
432- )
433-
434- if _ , err := fmt .Sscanf (mapping , "%d:%d:%d" , & ctrID , & hostID , & length ); err != nil {
435- return err
436- }
437- // Almost impossible, but snapshots.WithLabels doesn't check it
438- if ctrID < 0 || hostID < 0 || length < 0 {
439- return fmt .Errorf ("invalid mapping \" %d:%d:%d\" " , ctrID , hostID , length )
440- }
441- if ctrID != 0 {
442- return fmt .Errorf ("container mapping of 0 is only supported" )
443- }
444- return nil
445- }
446-
447- func hostID (mapping string ) (int , error ) {
448- var (
449- hostID int
450- ctrID int
451- length int
452- )
453- if err := validateIDMapping (mapping ); err != nil {
454- return - 1 , fmt .Errorf ("invalid mapping: %w" , err )
455- }
456- if _ , err := fmt .Sscanf (mapping , "%d:%d:%d" , & ctrID , & hostID , & length ); err != nil {
457- return - 1 , err
458- }
459- return hostID , nil
460- }
461-
462428func (o * snapshotter ) createSnapshot (ctx context.Context , kind snapshots.Kind , key , parent string , opts []snapshots.Opt ) (_ []mount.Mount , err error ) {
463429 var (
464430 s storage.Snapshot
@@ -499,22 +465,35 @@ func (o *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
499465 return fmt .Errorf ("failed to get snapshot info: %w" , err )
500466 }
501467
502- mappedUID := - 1
503- mappedGID := - 1
468+ var (
469+ mappedUID , mappedGID = - 1 , - 1
470+ uidmapLabel , gidmapLabel string
471+ needsRemap = false
472+ )
504473 // NOTE: if idmapped mounts' supported by hosted kernel there may be
505474 // no parents at all, so overlayfs will not work and snapshotter
506475 // will use bind mount. To be able to create file objects inside the
507476 // rootfs -- just chown this only bound directory according to provided
508477 // {uid,gid}map. In case of one/multiple parents -- chown upperdir.
509478 if v , ok := info .Labels [snapshots .LabelSnapshotUIDMapping ]; ok {
510- if mappedUID , err = hostID (v ); err != nil {
511- return fmt .Errorf ("failed to parse UID mapping: %w" , err )
512- }
479+ uidmapLabel = v
480+ needsRemap = true
513481 }
514482 if v , ok := info .Labels [snapshots .LabelSnapshotGIDMapping ]; ok {
515- if mappedGID , err = hostID (v ); err != nil {
516- return fmt .Errorf ("failed to parse GID mapping: %w" , err )
483+ gidmapLabel = v
484+ needsRemap = true
485+ }
486+
487+ if needsRemap {
488+ var idMap userns.IDMap
489+ if err = idMap .Unmarshal (uidmapLabel , gidmapLabel ); err != nil {
490+ return fmt .Errorf ("failed to unmarshal snapshot ID mapped labels: %w" , err )
491+ }
492+ root , err := idMap .RootPair ()
493+ if err != nil {
494+ return fmt .Errorf ("failed to find root pair: %w" , err )
517495 }
496+ mappedUID , mappedGID = int (root .Uid ), int (root .Gid )
518497 }
519498
520499 if mappedUID == - 1 || mappedGID == - 1 {
0 commit comments