@@ -633,13 +633,39 @@ type AutoUserNsOptions = types.AutoUserNsOptions
633633
634634type IDMappingOptions = types.IDMappingOptions
635635
636+ // LayerIDMappingOptions are the on-disk ID mappings for a layer.
637+ //
638+ // Unlike the caller-facing IDMappingOptions (which expresses what mapping
639+ // the caller wants), these record how files are actually stored. The two
640+ // may differ: when the graph driver supports shifting, no chown
641+ // occurs so HostUIDMapping/HostGIDMapping are true and UIDMap/GIDMap
642+ // are empty, even though the caller requested a non-trivial mapping.
643+ // The caller's requested mapping is still honored at mount time via
644+ // the Container's UIDMap/GIDMap.
645+ type LayerIDMappingOptions struct {
646+ // HostUIDMapping is true when files in this layer are stored with host
647+ // UIDs.
648+ HostUIDMapping bool
649+ // HostGIDMapping is true when files in this layer are stored with host
650+ // GIDs. See HostUIDMapping for details.
651+ HostGIDMapping bool
652+ // UIDMap is the on-disk UID mapping: it records the chown that was
653+ // applied to the layer's files at creation time. Empty when
654+ // HostUIDMapping is true.
655+ UIDMap []idtools.IDMap
656+ // GIDMap is the on-disk GID mapping: it records the chown that was
657+ // applied to the layer's files at creation time. Empty when
658+ // HostGIDMapping is true.
659+ GIDMap []idtools.IDMap
660+ }
661+
636662// LayerOptions is used for passing options to a Store's CreateLayer() and PutLayer() methods.
637663type LayerOptions struct {
638664 // IDMappingOptions specifies the type of ID mapping which should be
639665 // used for this layer. If nothing is specified, the layer will
640666 // inherit settings from its parent layer or, if it has no parent
641667 // layer, the Store object.
642- types. IDMappingOptions
668+ IDMappingOptions LayerIDMappingOptions
643669 // TemplateLayer is the ID of a layer whose contents will be used to
644670 // initialize this layer. If set, it should be a child of the layer
645671 // which we want to use as the parent of the new layer.
@@ -708,10 +734,18 @@ type ImageBigDataOption struct {
708734
709735// ContainerOptions is used for passing options to a Store's CreateContainer() method.
710736type ContainerOptions struct {
711- // IDMappingOptions specifies the type of ID mapping which should be
712- // used for this container's layer. If nothing is specified, the
713- // container's layer will inherit settings from the image's top layer
714- // or, if it is not being created based on an image, the Store object.
737+ // IDMappingOptions specifies the caller's desired ID mapping for the
738+ // container's user namespace.
739+ //
740+ // These express what the caller wants, not what ends up on disk.
741+ // The store records them in the Container and uses them at mount
742+ // time. How the layer's files are stored depends on whether the
743+ // driver supports shifting: if it does, no chown occurs and the
744+ // mapping is applied at mount time; otherwise files are chowned at
745+ // layer creation time.
746+ //
747+ // If nothing is specified, mappings are inherited from the image's top
748+ // layer or, if no image, from the Store's defaults.
715749 types.IDMappingOptions
716750 LabelOpts []string
717751 // Flags is a set of named flags and their values to store with the container.
@@ -1518,14 +1552,14 @@ func populateLayerOptions(s *store, rlstore rwLayerStore, rlstores []roLayerStor
15181552 options .BigData = slices .Clone (lOptions .BigData )
15191553 options .Flags = copyMapPreferringNil (lOptions .Flags )
15201554 }
1521- if options .HostUIDMapping {
1522- options .UIDMap = nil
1555+ if options .IDMappingOptions . HostUIDMapping {
1556+ options .IDMappingOptions . UIDMap = nil
15231557 }
1524- if options .HostGIDMapping {
1525- options .GIDMap = nil
1558+ if options .IDMappingOptions . HostGIDMapping {
1559+ options .IDMappingOptions . GIDMap = nil
15261560 }
1527- uidMap := options .UIDMap
1528- gidMap := options .GIDMap
1561+ uidMap := options .IDMappingOptions . UIDMap
1562+ gidMap := options .IDMappingOptions . GIDMap
15291563 if parent != "" {
15301564 var err error
15311565 parentLayer , unlock , err = getParentLayer (rlstore , rlstores , parent )
@@ -1546,26 +1580,26 @@ func populateLayerOptions(s *store, rlstore rwLayerStore, rlstores []roLayerStor
15461580 return nil , nil , unlock , ErrParentIsContainer
15471581 }
15481582 }
1549- if ! options .HostUIDMapping && len (options .UIDMap ) == 0 {
1583+ if ! options .IDMappingOptions . HostUIDMapping && len (options . IDMappingOptions .UIDMap ) == 0 {
15501584 uidMap = parentLayer .UIDMap
15511585 }
1552- if ! options .HostGIDMapping && len (options .GIDMap ) == 0 {
1586+ if ! options .IDMappingOptions . HostGIDMapping && len (options . IDMappingOptions .GIDMap ) == 0 {
15531587 gidMap = parentLayer .GIDMap
15541588 }
15551589 } else {
1556- if ! options .HostUIDMapping && len (options .UIDMap ) == 0 {
1590+ if ! options .IDMappingOptions . HostUIDMapping && len (options . IDMappingOptions .UIDMap ) == 0 {
15571591 uidMap = s .uidMap
15581592 }
1559- if ! options .HostGIDMapping && len (options .GIDMap ) == 0 {
1593+ if ! options .IDMappingOptions . HostGIDMapping && len (options . IDMappingOptions .GIDMap ) == 0 {
15601594 gidMap = s .gidMap
15611595 }
15621596 }
15631597 if s .canUseShifting (uidMap , gidMap ) {
1564- options .IDMappingOptions = types. IDMappingOptions {HostUIDMapping : true , HostGIDMapping : true , UIDMap : nil , GIDMap : nil }
1598+ options .IDMappingOptions = LayerIDMappingOptions {HostUIDMapping : true , HostGIDMapping : true , UIDMap : nil , GIDMap : nil }
15651599 } else {
1566- options .IDMappingOptions = types. IDMappingOptions {
1567- HostUIDMapping : options .HostUIDMapping ,
1568- HostGIDMapping : options .HostGIDMapping ,
1600+ options .IDMappingOptions = LayerIDMappingOptions {
1601+ HostUIDMapping : options .IDMappingOptions . HostUIDMapping ,
1602+ HostGIDMapping : options .IDMappingOptions . HostGIDMapping ,
15691603 UIDMap : copySlicePreferringNil (uidMap ),
15701604 GIDMap : copySlicePreferringNil (gidMap ),
15711605 }
@@ -1856,14 +1890,14 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore roImageStore, rlst
18561890 // mappings, and register it as an alternate top layer in the image.
18571891 var layerOptions LayerOptions
18581892 if s .canUseShifting (options .UIDMap , options .GIDMap ) {
1859- layerOptions .IDMappingOptions = types. IDMappingOptions {
1893+ layerOptions .IDMappingOptions = LayerIDMappingOptions {
18601894 HostUIDMapping : true ,
18611895 HostGIDMapping : true ,
18621896 UIDMap : nil ,
18631897 GIDMap : nil ,
18641898 }
18651899 } else {
1866- layerOptions .IDMappingOptions = types. IDMappingOptions {
1900+ layerOptions .IDMappingOptions = LayerIDMappingOptions {
18671901 HostUIDMapping : options .HostUIDMapping ,
18681902 HostGIDMapping : options .HostGIDMapping ,
18691903 UIDMap : copySlicePreferringNil (options .UIDMap ),
@@ -2008,20 +2042,12 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
20082042 // But in transient store mode, all container layers are volatile.
20092043 Volatile : options .Volatile || s .transientStore ,
20102044 }
2011- if s .canUseShifting (uidMap , gidMap ) {
2012- layerOptions .IDMappingOptions = types.IDMappingOptions {
2013- HostUIDMapping : true ,
2014- HostGIDMapping : true ,
2015- UIDMap : nil ,
2016- GIDMap : nil ,
2017- }
2018- } else {
2019- layerOptions .IDMappingOptions = types.IDMappingOptions {
2020- HostUIDMapping : idMappingsOptions .HostUIDMapping ,
2021- HostGIDMapping : idMappingsOptions .HostGIDMapping ,
2022- UIDMap : copySlicePreferringNil (uidMap ),
2023- GIDMap : copySlicePreferringNil (gidMap ),
2024- }
2045+ useHostMapping := idMappingsOptions .HostUIDMapping || s .canUseShifting (uidMap , gidMap )
2046+ layerOptions .IDMappingOptions = LayerIDMappingOptions {
2047+ HostUIDMapping : useHostMapping ,
2048+ HostGIDMapping : useHostMapping ,
2049+ UIDMap : copySlicePreferringNil (uidMap ),
2050+ GIDMap : copySlicePreferringNil (gidMap ),
20252051 }
20262052 if options .Flags == nil {
20272053 options .Flags = make (map [string ]any )
@@ -3074,10 +3100,6 @@ func (s *store) Mount(id, mountLabel string) (string, error) {
30743100 if err != nil {
30753101 return "" , err
30763102 }
3077- if options .UidMaps != nil || options .GidMaps != nil {
3078- options .DisableShifting = ! s .canUseShifting (options .UidMaps , options .GidMaps )
3079- }
3080-
30813103 if err := rlstore .startWriting (); err != nil {
30823104 return "" , err
30833105 }
0 commit comments