Skip to content

Commit

Permalink
Merge pull request #18344 from Luap99/container-ns
Browse files Browse the repository at this point in the history
rootless: support joining containers that use host ns
  • Loading branch information
openshift-merge-robot authored Apr 26, 2023
2 parents 25b026d + d222a39 commit 931447b
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 7 deletions.
45 changes: 38 additions & 7 deletions pkg/specgen/generate/namespaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,13 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
if err != nil {
return nil, fmt.Errorf("looking up container to share pid namespace with: %w", err)
}
toReturn = append(toReturn, libpod.WithPIDNSFrom(pidCtr))
if rootless.IsRootless() && pidCtr.NamespaceMode(spec.PIDNamespace, pidCtr.ConfigNoCopy().Spec) == host {
// Treat this the same as host, the problem is the runtime tries to do a
// setns call and this will fail when it is the host ns as rootless user.
s.PidNS.NSMode = specgen.Host
} else {
toReturn = append(toReturn, libpod.WithPIDNSFrom(pidCtr))
}
}

// IPC
Expand All @@ -158,9 +164,16 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
if ipcCtr.ConfigNoCopy().NoShmShare {
return nil, fmt.Errorf("joining IPC of container %s is not allowed: non-shareable IPC (hint: use IpcMode:shareable for the donor container)", ipcCtr.ID())
}
toReturn = append(toReturn, libpod.WithIPCNSFrom(ipcCtr))
if !ipcCtr.ConfigNoCopy().NoShm {
toReturn = append(toReturn, libpod.WithShmDir(ipcCtr.ShmDir()))
if rootless.IsRootless() && ipcCtr.NamespaceMode(spec.IPCNamespace, ipcCtr.ConfigNoCopy().Spec) == host {
// Treat this the same as host, the problem is the runtime tries to do a
// setns call and this will fail when it is the host ns as rootless user.
s.IpcNS.NSMode = specgen.Host
toReturn = append(toReturn, libpod.WithShmDir("/dev/shm"))
} else {
toReturn = append(toReturn, libpod.WithIPCNSFrom(ipcCtr))
if !ipcCtr.ConfigNoCopy().NoShm {
toReturn = append(toReturn, libpod.WithShmDir(ipcCtr.ShmDir()))
}
}
case specgen.None:
toReturn = append(toReturn, libpod.WithNoShm(true))
Expand All @@ -187,7 +200,13 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
if err != nil {
return nil, fmt.Errorf("looking up container to share uts namespace with: %w", err)
}
toReturn = append(toReturn, libpod.WithUTSNSFrom(utsCtr))
if rootless.IsRootless() && utsCtr.NamespaceMode(spec.UTSNamespace, utsCtr.ConfigNoCopy().Spec) == host {
// Treat this the same as host, the problem is the runtime tries to do a
// setns call and this will fail when it is the host ns as rootless user.
s.UtsNS.NSMode = specgen.Host
} else {
toReturn = append(toReturn, libpod.WithUTSNSFrom(utsCtr))
}
}

// User
Expand Down Expand Up @@ -257,7 +276,13 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
if err != nil {
return nil, fmt.Errorf("looking up container to share cgroup namespace with: %w", err)
}
toReturn = append(toReturn, libpod.WithCgroupNSFrom(cgroupCtr))
if rootless.IsRootless() && cgroupCtr.NamespaceMode(spec.CgroupNamespace, cgroupCtr.ConfigNoCopy().Spec) == host {
// Treat this the same as host, the problem is the runtime tries to do a
// setns call and this will fail when it is the host ns as rootless user.
s.CgroupNS.NSMode = specgen.Host
} else {
toReturn = append(toReturn, libpod.WithCgroupNSFrom(cgroupCtr))
}
}

if s.CgroupParent != "" {
Expand Down Expand Up @@ -285,7 +310,13 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
if err != nil {
return nil, fmt.Errorf("looking up container to share net namespace with: %w", err)
}
toReturn = append(toReturn, libpod.WithNetNSFrom(netCtr))
if rootless.IsRootless() && netCtr.NamespaceMode(spec.NetworkNamespace, netCtr.ConfigNoCopy().Spec) == host {
// Treat this the same as host, the problem is the runtime tries to do a
// setns call and this will fail when it is the host ns as rootless user.
s.NetNS.NSMode = specgen.Host
} else {
toReturn = append(toReturn, libpod.WithNetNSFrom(netCtr))
}
case specgen.Slirp:
portMappings, expose, err := createPortMappings(s, imageData)
if err != nil {
Expand Down
52 changes: 52 additions & 0 deletions test/system/195-run-namesapces.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env bats -*- bats -*-
#
# Tests for the namespace options
#

load helpers

@test "podman test all namespaces" {
# format is nsname | option name
tests="
cgroup | cgroupns
ipc | ipc
net | network
pid | pid
uts | uts
"

for nstype in private host; do
while read name option; do
local cname="c_${name}_$(random_string)"
# ipc is special, private does not allow joining from another container.
# Instead we must use "shareable".
local type=$nstype
if [ "$name" = "ipc" ] && [ "$type" = "private" ]; then
type="shareable"
fi

run_podman run --name $cname --$option $type -d $IMAGE sh -c \
"readlink /proc/self/ns/$name; sleep inf"

run_podman run --rm --$option container:$cname $IMAGE readlink /proc/self/ns/$name
con2_ns="$output"

run readlink /proc/self/ns/$name
host_ns="$output"

run_podman logs $cname
con1_ns="$output"

assert "$con1_ns" == "$con2_ns" "($name) namespace matches (type: $type)"
local matcher="=="
if [[ "$type" != "host" ]]; then
matcher="!="
fi
assert "$con1_ns" $matcher "$host_ns" "expected host namespace to ($matcher) (type: $type)"

run_podman rm -f -t0 $cname
done < <(parse_table "$tests")
done
}

# vim: filetype=sh

0 comments on commit 931447b

Please sign in to comment.