mirror of https://github.com/containers/podman.git
Merge pull request #17522 from giuseppe/relative-idmapping
libpod: support relative positions for idmaps
This commit is contained in:
commit
b8b386b7ea
|
|
@ -40,7 +40,8 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
|
|||
The idmap option supports a custom mapping that can be different than the user namespace used by the container.
|
||||
The mapping can be specified after the idmap option like: `idmap=uids=0-1-10#10-11-10;gids=0-100-10`. For each triplet, the first value is the
|
||||
start of the backing file system IDs that are mapped to the second value on the host. The length of this mapping is given in the third value.
|
||||
Multiple ranges are separated with #.
|
||||
Multiple ranges are separated with #. If the specified mapping is prepended with a '@' then the mapping is considered relative to the container
|
||||
user namespace. The host ID for the mapping is changed to account for the relative position of the container user in the container user namespace.
|
||||
|
||||
Options specific to image:
|
||||
|
||||
|
|
|
|||
|
|
@ -57,11 +57,17 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func parseOptionIDs(option string) ([]idtools.IDMap, error) {
|
||||
func parseOptionIDs(ctrMappings []idtools.IDMap, option string) ([]idtools.IDMap, error) {
|
||||
ranges := strings.Split(option, "#")
|
||||
ret := make([]idtools.IDMap, len(ranges))
|
||||
for i, m := range ranges {
|
||||
var v idtools.IDMap
|
||||
|
||||
relative := false
|
||||
if m[0] == '@' {
|
||||
relative = true
|
||||
m = m[1:]
|
||||
}
|
||||
_, err := fmt.Sscanf(m, "%d-%d-%d", &v.ContainerID, &v.HostID, &v.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -69,6 +75,20 @@ func parseOptionIDs(option string) ([]idtools.IDMap, error) {
|
|||
if v.ContainerID < 0 || v.HostID < 0 || v.Size < 1 {
|
||||
return nil, fmt.Errorf("invalid value for %q", option)
|
||||
}
|
||||
|
||||
if relative {
|
||||
found := false
|
||||
for _, m := range ctrMappings {
|
||||
if v.ContainerID >= m.ContainerID && v.ContainerID < m.ContainerID+m.Size {
|
||||
v.HostID += m.HostID - m.ContainerID
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return nil, fmt.Errorf("could not find a user namespace mapping for the relative mapping %q", option)
|
||||
}
|
||||
}
|
||||
ret[i] = v
|
||||
}
|
||||
return ret, nil
|
||||
|
|
@ -83,12 +103,12 @@ func parseIDMapMountOption(idMappings stypes.IDMappingOptions, option string, in
|
|||
for _, i := range options {
|
||||
switch {
|
||||
case strings.HasPrefix(i, "uids="):
|
||||
uidMap, err = parseOptionIDs(strings.Replace(i, "uids=", "", 1))
|
||||
uidMap, err = parseOptionIDs(idMappings.UIDMap, strings.Replace(i, "uids=", "", 1))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
case strings.HasPrefix(i, "gids="):
|
||||
gidMap, err = parseOptionIDs(strings.Replace(i, "gids=", "", 1))
|
||||
gidMap, err = parseOptionIDs(idMappings.GIDMap, strings.Replace(i, "gids=", "", 1))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,18 @@ import (
|
|||
var hookPath string
|
||||
|
||||
func TestParseOptionIDs(t *testing.T) {
|
||||
_, err := parseOptionIDs("uids=100-200-2")
|
||||
idMap := []idtools.IDMap{
|
||||
{
|
||||
ContainerID: 0,
|
||||
HostID: 1,
|
||||
Size: 10000,
|
||||
},
|
||||
}
|
||||
|
||||
_, err := parseOptionIDs(idMap, "uids=100-200-2")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mappings, err := parseOptionIDs("100-200-2")
|
||||
mappings, err := parseOptionIDs(idMap, "100-200-2")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, mappings)
|
||||
|
||||
|
|
@ -31,7 +39,7 @@ func TestParseOptionIDs(t *testing.T) {
|
|||
assert.Equal(t, mappings[0].HostID, 200)
|
||||
assert.Equal(t, mappings[0].Size, 2)
|
||||
|
||||
mappings, err = parseOptionIDs("100-200-2#300-400-5")
|
||||
mappings, err = parseOptionIDs(idMap, "100-200-2#300-400-5")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, mappings)
|
||||
|
||||
|
|
@ -44,6 +52,23 @@ func TestParseOptionIDs(t *testing.T) {
|
|||
assert.Equal(t, mappings[1].ContainerID, 300)
|
||||
assert.Equal(t, mappings[1].HostID, 400)
|
||||
assert.Equal(t, mappings[1].Size, 5)
|
||||
|
||||
mappings, err = parseOptionIDs(idMap, "@100-200-2#@300-400-5")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, mappings)
|
||||
|
||||
assert.Equal(t, len(mappings), 2)
|
||||
|
||||
assert.Equal(t, mappings[0].ContainerID, 100)
|
||||
assert.Equal(t, mappings[0].HostID, 201)
|
||||
assert.Equal(t, mappings[0].Size, 2)
|
||||
|
||||
assert.Equal(t, mappings[1].ContainerID, 300)
|
||||
assert.Equal(t, mappings[1].HostID, 401)
|
||||
assert.Equal(t, mappings[1].Size, 5)
|
||||
|
||||
_, err = parseOptionIDs(idMap, "@10000-20000-2")
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestParseIDMapMountOption(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue