From d9154e97ebad33ead3d7f0d6aa8dea2bc4374ac2 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Wed, 2 Dec 2020 10:40:35 -0500 Subject: Add containerenv information to /run/.containerenv We have been asked to leak some information into the container to indicate: * The name and id of the container * The version of podman used to launch the container * The image name and ID the container is based on. * Whether the container engine is running in rootless mode. Fixes: https://github.com/containers/podman/issues/6192 Signed-off-by: Daniel J Walsh --- docs/source/markdown/podman-run.1.md | 9 ++++++--- libpod/container_internal_linux.go | 24 ++++++++++++++++++++---- test/system/030-run.bats | 24 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 1038906c0..53c5b2d4b 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -26,9 +26,12 @@ Several files will be automatically created within the container. These include _/etc/hosts_, _/etc/hostname_, and _/etc/resolv.conf_ to manage networking. These will be based on the host's version of the files, though they can be customized with options (for example, **--dns** will override the host's DNS -servers in the created _resolv.conf_). Additionally, an empty file is created in -each container to indicate to programs they are running in a container. This file -is located at _/run/.containerenv_. +servers in the created _resolv.conf_). Additionally, a container environment +file is created in each container to indicate to programs they are running in a +container. This file is located at _/run/.containerenv_. When using the +--privileged flag the .containerenv contains name/value pairs indicating the +container engine version, whether the engine is running in rootless mode, the +container name and id, as well as the image name and id that the container is based on. When running from a user defined network namespace, the _/etc/netns/NSNAME/resolv.conf_ will be used if it exists, otherwise _/etc/resolv.conf_ will be used. diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 56575c195..fb30192f1 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -35,6 +35,7 @@ import ( "github.com/containers/podman/v2/pkg/rootless" "github.com/containers/podman/v2/pkg/util" "github.com/containers/podman/v2/utils" + "github.com/containers/podman/v2/version" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/idtools" securejoin "github.com/cyphar/filepath-securejoin" @@ -1423,11 +1424,26 @@ func (c *Container) makeBindMounts() error { } } - // Make .containerenv - // Empty file, so no need to recreate if it exists + // Make .containerenv if it does not exist if _, ok := c.state.BindMounts["/run/.containerenv"]; !ok { - // Empty string for now, but we may consider populating this later - containerenvPath, err := c.writeStringToRundir(".containerenv", "") + var containerenv string + isRootless := 0 + if rootless.IsRootless() { + isRootless = 1 + } + imageID, imageName := c.Image() + + if c.Privileged() { + // Populate the .containerenv with container information + containerenv = fmt.Sprintf(`engine="podman-%s" +name=%q +id=%q +image=%q +imageid=%q +rootless=%d +`, version.Version.String(), c.Name(), c.ID(), imageName, imageID, isRootless) + } + containerenvPath, err := c.writeStringToRundir(".containerenv", containerenv) if err != nil { return errors.Wrapf(err, "error creating containerenv file for container %s", c.ID()) } diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 37695f205..6db6b76f1 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -536,6 +536,30 @@ json-file | f run_podman untag $IMAGE $newtag $newtag2 } +@test "Verify /run/.containerenv exist" { + run_podman run --rm $IMAGE ls -1 /run/.containerenv + is "$output" "/run/.containerenv" + + run_podman run --privileged --rm $IMAGE sh -c '. /run/.containerenv; echo $engine' + is "$output" ".*podman.*" "failed to identify engine" + + run_podman run --privileged --name "testcontainerenv" --rm $IMAGE sh -c '. /run/.containerenv; echo $name' + is "$output" ".*testcontainerenv.*" + + run_podman run --privileged --rm $IMAGE sh -c '. /run/.containerenv; echo $image' + is "$output" ".*$IMAGE.*" "failed to idenitfy image" + + run_podman run --privileged --rm $IMAGE sh -c '. /run/.containerenv; echo $rootless' + # FIXME: on some CI systems, 'run --privileged' emits a spurious + # warning line about dup devices. Ignore it. + remove_same_dev_warning + if is_rootless; then + is "$output" "1" + else + is "$output" "0" + fi +} + @test "podman run with --net=host and --port prints warning" { rand=$(random_string 10) -- cgit v1.2.3-54-g00ecf