summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/stats.go6
-rw-r--r--docs/podman-stats.1.md20
-rw-r--r--libpod/container_api.go5
-rw-r--r--libpod/runtime_pod_linux.go6
-rw-r--r--pkg/cgroups/cgroups.go8
-rw-r--r--test/e2e/exec_test.go19
6 files changed, 51 insertions, 13 deletions
diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go
index 2f696445e..25514ec75 100644
--- a/cmd/podman/stats.go
+++ b/cmd/podman/stats.go
@@ -134,9 +134,13 @@ func statsCmd(c *cliconfig.StatsValues) error {
initialStats, err := ctr.GetContainerStats(&libpod.ContainerStats{})
if err != nil {
// when doing "all", dont worry about containers that are not running
- if c.All && errors.Cause(err) == define.ErrCtrRemoved || errors.Cause(err) == define.ErrNoSuchCtr || errors.Cause(err) == define.ErrCtrStateInvalid {
+ cause := errors.Cause(err)
+ if c.All && (cause == define.ErrCtrRemoved || cause == define.ErrNoSuchCtr || cause == define.ErrCtrStateInvalid) {
continue
}
+ if cause == cgroups.ErrCgroupV1Rootless {
+ err = cause
+ }
return err
}
containerStats[ctr.ID()] = initialStats
diff --git a/docs/podman-stats.1.md b/docs/podman-stats.1.md
index c1a87f210..2f604644f 100644
--- a/docs/podman-stats.1.md
+++ b/docs/podman-stats.1.md
@@ -9,6 +9,10 @@ podman\-stats - Display a live stream of 1 or more containers' resource usage st
## DESCRIPTION
Display a live stream of one or more containers' resource usage statistics
+Note: Podman stats will not work in rootless environments that use CGroups V1.
+Podman stats relies on CGroup information for statistics, and CGroup v1 is not
+supported for rootless use cases.
+
## OPTIONS
**--all**, **-a**
@@ -69,14 +73,14 @@ a9f807ffaacd frosty_hodgkin -- 3.092MB / 16.7GB 0.02% -- / -- --
# podman stats --no-stream --format=json a9f80
[
{
- "id": "a9f807ffaacd",
- "name": "frosty_hodgkin",
- "cpu_percent": "--",
- "mem_usage": "3.092MB / 16.7GB",
- "mem_percent": "0.02%",
- "netio": "-- / --",
- "blocki": "-- / --",
- "pids": "2"
+ "id": "a9f807ffaacd",
+ "name": "frosty_hodgkin",
+ "cpu_percent": "--",
+ "mem_usage": "3.092MB / 16.7GB",
+ "mem_percent": "0.02%",
+ "netio": "-- / --",
+ "blocki": "-- / --",
+ "pids": "2"
}
]
```
diff --git a/libpod/container_api.go b/libpod/container_api.go
index abcfcb271..9e59104cc 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -274,6 +274,11 @@ func (c *Container) Exec(tty, privileged bool, env, cmd []string, user, workDir
}
}()
+ // if the user is empty, we should inherit the user that the container is currently running with
+ if user == "" {
+ user = c.config.User
+ }
+
pid, attachChan, err := c.ociRuntime.execContainer(c, cmd, capList, env, tty, workDir, user, sessionID, streams, preserveFDs, resize, detachKeys)
if err != nil {
ec := define.ExecErrorCodeGeneric
diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go
index 073c5054d..05866d05a 100644
--- a/libpod/runtime_pod_linux.go
+++ b/libpod/runtime_pod_linux.go
@@ -204,7 +204,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool)
// Get the conmon CGroup
conmonCgroupPath := filepath.Join(p.state.CgroupPath, "conmon")
conmonCgroup, err := cgroups.Load(conmonCgroupPath)
- if err != nil && err != cgroups.ErrCgroupDeleted {
+ if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
removalErr = errors.Wrapf(err, "error retrieving pod %s conmon cgroup %s", p.ID(), conmonCgroupPath)
}
@@ -266,7 +266,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool)
// hard - instead, just log errors.
conmonCgroupPath := filepath.Join(p.state.CgroupPath, "conmon")
conmonCgroup, err := cgroups.Load(conmonCgroupPath)
- if err != nil && err != cgroups.ErrCgroupDeleted {
+ if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
if removalErr == nil {
removalErr = errors.Wrapf(err, "error retrieving pod %s conmon cgroup", p.ID())
} else {
@@ -283,7 +283,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool)
}
}
cgroup, err := cgroups.Load(p.state.CgroupPath)
- if err != nil && err != cgroups.ErrCgroupDeleted {
+ if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
if removalErr == nil {
removalErr = errors.Wrapf(err, "error retrieving pod %s cgroup", p.ID())
} else {
diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go
index 085718855..9711e8120 100644
--- a/pkg/cgroups/cgroups.go
+++ b/pkg/cgroups/cgroups.go
@@ -10,6 +10,7 @@ import (
"strconv"
"strings"
+ "github.com/containers/libpod/pkg/rootless"
systemdDbus "github.com/coreos/go-systemd/dbus"
"github.com/godbus/dbus"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -19,7 +20,9 @@ import (
var (
// ErrCgroupDeleted means the cgroup was deleted
- ErrCgroupDeleted = errors.New("cgroups: cgroup deleted")
+ ErrCgroupDeleted = errors.New("cgroup deleted")
+ // ErrCgroupV1Rootless means the cgroup v1 were attempted to be used in rootless environmen
+ ErrCgroupV1Rootless = errors.New("no support for CGroups V1 in rootless environments")
)
// CgroupControl controls a cgroup hierarchy
@@ -339,6 +342,9 @@ func Load(path string) (*CgroupControl, error) {
p := control.getCgroupv1Path(name)
if _, err := os.Stat(p); err != nil {
if os.IsNotExist(err) {
+ if rootless.IsRootless() {
+ return nil, ErrCgroupV1Rootless
+ }
// compatible with the error code
// used by containerd/cgroups
return nil, ErrCgroupDeleted
diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go
index ac727f9bc..f3190978c 100644
--- a/test/e2e/exec_test.go
+++ b/test/e2e/exec_test.go
@@ -146,6 +146,25 @@ var _ = Describe("Podman exec", func() {
Expect(session2.OutputToString()).To(Equal(testUser))
})
+ It("podman exec with user from run", func() {
+ testUser := "guest"
+ setup := podmanTest.Podman([]string{"run", "--user", testUser, "-d", ALPINE, "top"})
+ setup.WaitWithDefaultTimeout()
+ Expect(setup.ExitCode()).To(Equal(0))
+ ctrID := setup.OutputToString()
+
+ session := podmanTest.Podman([]string{"exec", ctrID, "whoami"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring(testUser))
+
+ overrideUser := "root"
+ session = podmanTest.Podman([]string{"exec", "--user", overrideUser, ctrID, "whoami"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring(overrideUser))
+ })
+
It("podman exec simple working directory test", func() {
setup := podmanTest.RunTopContainer("test1")
setup.WaitWithDefaultTimeout()