summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/container_internal_linux.go34
-rw-r--r--pkg/namespaces/namespaces.go87
-rw-r--r--pkg/spec/spec.go37
-rw-r--r--test/e2e/pod_infra_container_test.go20
-rw-r--r--test/system/200-pod-top.bats5
5 files changed, 103 insertions, 80 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 047b73d65..5aa4ee9a9 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -471,9 +471,9 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
return err
}
- g.RemoveMount("/sys/fs/cgroup")
-
if unified {
+ g.RemoveMount("/sys/fs/cgroup")
+
sourcePath := filepath.Join("/sys/fs/cgroup")
systemdMnt := spec.Mount{
Destination: "/sys/fs/cgroup",
@@ -483,31 +483,13 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
}
g.AddMount(systemdMnt)
} else {
- // rootless containers have no write access to /sys/fs/cgroup, so don't
- // add any mount into the container.
- if !rootless.IsRootless() {
- cgroupPath, err := c.CGroupPath()
- if err != nil {
- return err
- }
- sourcePath := filepath.Join("/sys/fs/cgroup", cgroupPath)
-
- systemdMnt := spec.Mount{
- Destination: "/sys/fs/cgroup",
- Type: "bind",
- Source: sourcePath,
- Options: []string{"bind", "private"},
- }
- g.AddMount(systemdMnt)
- } else {
- systemdMnt := spec.Mount{
- Destination: "/sys/fs/cgroup",
- Type: "bind",
- Source: "/sys/fs/cgroup",
- Options: []string{"bind", "nodev", "noexec", "nosuid"},
- }
- g.AddMount(systemdMnt)
+ systemdMnt := spec.Mount{
+ Destination: "/sys/fs/cgroup/systemd",
+ Type: "bind",
+ Source: "/sys/fs/cgroup/systemd",
+ Options: []string{"bind", "nodev", "noexec", "nosuid"},
}
+ g.AddMount(systemdMnt)
}
return nil
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go
index 35298796f..9d1033b93 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -4,17 +4,30 @@ import (
"strings"
)
+const (
+ bridgeType = "bridge"
+ containerType = "container"
+ defaultType = "default"
+ hostType = "host"
+ noneType = "none"
+ nsType = "ns"
+ podType = "pod"
+ privateType = "private"
+ shareableType = "shareable"
+ slirpType = "slirp4netns"
+)
+
// CgroupMode represents cgroup mode in the container.
type CgroupMode string
// IsHost indicates whether the container uses the host's cgroup.
func (n CgroupMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsNS indicates a cgroup namespace passed in by path (ns:<path>)
func (n CgroupMode) IsNS() bool {
- return strings.HasPrefix(string(n), "ns:")
+ return strings.HasPrefix(string(n), nsType)
}
// NS gets the path associated with a ns:<path> cgroup ns
@@ -29,13 +42,13 @@ func (n CgroupMode) NS() string {
// IsContainer indicates whether the container uses a new cgroup namespace.
func (n CgroupMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Container returns the name of the container whose cgroup namespace is going to be used.
func (n CgroupMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -43,15 +56,15 @@ func (n CgroupMode) Container() string {
// IsPrivate indicates whether the container uses the a private cgroup.
func (n CgroupMode) IsPrivate() bool {
- return n == "private"
+ return n == privateType
}
// Valid indicates whether the Cgroup namespace is valid.
func (n CgroupMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
- case "", "host", "private", "ns":
- case "container":
+ case "", hostType, privateType, nsType:
+ case containerType:
if len(parts) != 2 || parts[1] == "" {
return false
}
@@ -66,7 +79,7 @@ type UsernsMode string
// IsHost indicates whether the container uses the host's userns.
func (n UsernsMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsKeepID indicates whether container uses a mapping where the (uid, gid) on the host is lept inside of the namespace.
@@ -83,8 +96,8 @@ func (n UsernsMode) IsPrivate() bool {
func (n UsernsMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
- case "", "host", "keep-id", "ns":
- case "container":
+ case "", hostType, "keep-id", nsType:
+ case containerType:
if len(parts) != 2 || parts[1] == "" {
return false
}
@@ -111,13 +124,13 @@ func (n UsernsMode) NS() string {
// IsContainer indicates whether container uses a container userns.
func (n UsernsMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Container is the id of the container which network this container is connected to.
func (n UsernsMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -133,19 +146,19 @@ func (n UTSMode) IsPrivate() bool {
// IsHost indicates whether the container uses the host's UTS namespace.
func (n UTSMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsContainer indicates whether the container uses a container's UTS namespace.
func (n UTSMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Container returns the name of the container whose uts namespace is going to be used.
func (n UTSMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -155,8 +168,8 @@ func (n UTSMode) Container() string {
func (n UTSMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
- case "", "host":
- case "container":
+ case "", hostType:
+ case containerType:
if len(parts) != 2 || parts[1] == "" {
return false
}
@@ -171,28 +184,28 @@ type IpcMode string
// IsPrivate indicates whether the container uses its own private ipc namespace which cannot be shared.
func (n IpcMode) IsPrivate() bool {
- return n == "private"
+ return n == privateType
}
// IsHost indicates whether the container shares the host's ipc namespace.
func (n IpcMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsShareable indicates whether the container's ipc namespace can be shared with another container.
func (n IpcMode) IsShareable() bool {
- return n == "shareable"
+ return n == shareableType
}
// IsContainer indicates whether the container uses another container's ipc namespace.
func (n IpcMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// IsNone indicates whether container IpcMode is set to "none".
func (n IpcMode) IsNone() bool {
- return n == "none"
+ return n == noneType
}
// IsEmpty indicates whether container IpcMode is empty
@@ -208,7 +221,7 @@ func (n IpcMode) Valid() bool {
// Container returns the name of the container ipc stack is going to be used.
func (n IpcMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 && parts[0] == "container" {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -224,21 +237,21 @@ func (n PidMode) IsPrivate() bool {
// IsHost indicates whether the container uses the host's pid namespace.
func (n PidMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsContainer indicates whether the container uses a container's pid namespace.
func (n PidMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Valid indicates whether the pid namespace is valid.
func (n PidMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
- case "", "host":
- case "container":
+ case "", hostType:
+ case containerType:
if len(parts) != 2 || parts[1] == "" {
return false
}
@@ -251,7 +264,7 @@ func (n PidMode) Valid() bool {
// Container returns the name of the container whose pid namespace is going to be used.
func (n PidMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -262,17 +275,17 @@ type NetworkMode string
// IsNone indicates whether container isn't using a network stack.
func (n NetworkMode) IsNone() bool {
- return n == "none"
+ return n == noneType
}
// IsHost indicates whether the container uses the host's network stack.
func (n NetworkMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsDefault indicates whether container uses the default network stack.
func (n NetworkMode) IsDefault() bool {
- return n == "default"
+ return n == defaultType
}
// IsPrivate indicates whether container uses its private network stack.
@@ -283,13 +296,13 @@ func (n NetworkMode) IsPrivate() bool {
// IsContainer indicates whether container uses a container network stack.
func (n NetworkMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Container is the id of the container which network this container is connected to.
func (n NetworkMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -305,17 +318,17 @@ func (n NetworkMode) UserDefined() string {
// IsBridge indicates whether container uses the bridge network stack
func (n NetworkMode) IsBridge() bool {
- return n == "bridge"
+ return n == bridgeType
}
// IsSlirp4netns indicates if we are running a rootless network stack
func (n NetworkMode) IsSlirp4netns() bool {
- return n == "slirp4netns"
+ return n == slirpType
}
// IsNS indicates a network namespace passed in by path (ns:<path>)
func (n NetworkMode) IsNS() bool {
- return strings.HasPrefix(string(n), "ns:")
+ return strings.HasPrefix(string(n), nsType)
}
// NS gets the path associated with a ns:<path> network ns
@@ -329,7 +342,7 @@ func (n NetworkMode) NS() string {
// IsPod returns whether the network refers to pod networking
func (n NetworkMode) IsPod() bool {
- return n == "pod"
+ return n == podType
}
// IsUserDefined indicates user-created network
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index c94746767..156d6849d 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -174,10 +174,20 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
}
hostname := config.Hostname
- if hostname == "" && (config.NetMode.IsHost() || config.UtsMode.IsHost()) {
- hostname, err = os.Hostname()
- if err != nil {
- return nil, errors.Wrap(err, "unable to retrieve hostname")
+ if hostname == "" {
+ if utsCtrID := config.UtsMode.Container(); utsCtrID != "" {
+ utsCtr, err := runtime.GetContainer(utsCtrID)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to retrieve hostname from dependency container %s", utsCtrID)
+ }
+ hostname = utsCtr.Hostname()
+ } else if config.NetMode.IsHost() || config.UtsMode.IsHost() {
+ hostname, err = os.Hostname()
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to retrieve hostname of the host")
+ }
+ } else {
+ logrus.Debug("No hostname set; container's hostname will default to runtime default")
}
}
g.RemoveHostname()
@@ -541,8 +551,8 @@ func addPidNS(config *CreateConfig, g *generate.Generator) error {
if pidMode.IsHost() {
return g.RemoveLinuxNamespace(string(spec.PIDNamespace))
}
- if pidMode.IsContainer() {
- logrus.Debug("using container pidmode")
+ if pidCtr := pidMode.Container(); pidCtr != "" {
+ logrus.Debugf("using container %s pidmode", pidCtr)
}
if IsPod(string(pidMode)) {
logrus.Debug("using pod pidmode")
@@ -579,8 +589,8 @@ func addNetNS(config *CreateConfig, g *generate.Generator) error {
} else if netMode.IsBridge() {
logrus.Debug("Using bridge netmode")
return nil
- } else if netMode.IsContainer() {
- logrus.Debug("Using container netmode")
+ } else if netCtr := netMode.Container(); netCtr != "" {
+ logrus.Debugf("using container %s netmode", netCtr)
return nil
} else if IsNS(string(netMode)) {
logrus.Debug("Using ns netmode")
@@ -606,6 +616,9 @@ func addUTSNS(config *CreateConfig, g *generate.Generator) error {
if utsMode.IsHost() {
return g.RemoveLinuxNamespace(string(spec.UTSNamespace))
}
+ if utsCtr := utsMode.Container(); utsCtr != "" {
+ logrus.Debugf("using container %s utsmode", utsCtr)
+ }
return nil
}
@@ -617,8 +630,8 @@ func addIpcNS(config *CreateConfig, g *generate.Generator) error {
if ipcMode.IsHost() {
return g.RemoveLinuxNamespace(string(spec.IPCNamespace))
}
- if ipcMode.IsContainer() {
- logrus.Debug("Using container ipcmode")
+ if ipcCtr := ipcMode.Container(); ipcCtr != "" {
+ logrus.Debugf("Using container %s ipcmode", ipcCtr)
}
return nil
@@ -635,8 +648,8 @@ func addCgroupNS(config *CreateConfig, g *generate.Generator) error {
if cgroupMode.IsPrivate() {
return g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), "")
}
- if cgroupMode.IsContainer() {
- logrus.Debug("Using container cgroup mode")
+ if cgCtr := cgroupMode.Container(); cgCtr != "" {
+ logrus.Debugf("Using container %s cgroup mode", cgCtr)
}
return nil
}
diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go
index c8763de9f..3897aa851 100644
--- a/test/e2e/pod_infra_container_test.go
+++ b/test/e2e/pod_infra_container_test.go
@@ -383,4 +383,24 @@ var _ = Describe("Podman pod create", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
+
+ It("podman run hostname is shared", func() {
+ session := podmanTest.Podman([]string{"pod", "create"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ podID := session.OutputToString()
+
+ // verify we can add a host to the infra's /etc/hosts
+ session = podmanTest.Podman([]string{"run", "--pod", podID, ALPINE, "hostname"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ hostname := session.OutputToString()
+
+ infraName := podID[:12] + "-infra"
+ // verify we can see the other hosts of infra's /etc/hosts
+ session = podmanTest.Podman([]string{"inspect", infraName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring(hostname))
+ })
})
diff --git a/test/system/200-pod-top.bats b/test/system/200-pod-top.bats
index 08f495fb1..10808ddb2 100644
--- a/test/system/200-pod-top.bats
+++ b/test/system/200-pod-top.bats
@@ -3,8 +3,6 @@
load helpers
@test "podman pod top - containers in different PID namespaces" {
- skip "this test is not reliable. Reenable once pod-top is fixed."
-
# With infra=false, we don't get a /pause container (we also
# don't pull k8s.gcr.io/pause )
no_infra='--infra=false'
@@ -28,9 +26,6 @@ load helpers
# By default (podman pod create w/ default --infra) there should be
# a /pause container.
- # FIXME: sometimes there is, sometimes there isn't. If anyone ever
- # actually figures this out, please either reenable this line or
- # remove it entirely.
if [ -z "$no_infra" ]; then
is "$output" ".*0 \+1 \+0 \+[0-9. ?s]\+/pause" "there is a /pause container"
fi