From c3bdae5cf924078c3a1447260babaa8e2843d6c6 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Mon, 24 May 2021 17:12:20 -0400 Subject: [PATCH] Pass Systemd LISTEN_* environment to the container If a container is running within a systemd service and it is socket activated, we need to leak the LISTEN_* environment variables into the container. Fixes: https://github.com/containers/podman/issues/10443 Signed-off-by: Daniel J Walsh --- libpod/container_internal_linux.go | 12 +++++++++ libpod/oci_conmon_linux.go | 10 ++++++++ test/system/250-systemd.bats | 39 ++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 25db3cff01..df44a574eb 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -648,6 +648,18 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { g.AddProcessEnv("HOSTNAME", hostname) } + for _, lEnv := range []string{"LISTEN_PID", "LISTEN_FDS", "LISTEN_FDNAMES"} { + if val, ok := os.LookupEnv(lEnv); ok { + // The primary process within the container will be PID=1, so this + // value needs to be reset + if lEnv == "LISTEN_PID" { + g.AddProcessEnv(lEnv, "1") + continue + } + g.AddProcessEnv(lEnv, val) + } + } + if c.config.UTSNsCtr != "" { if err := c.addNamespaceContainer(&g, UTSNS, c.config.UTSNsCtr, spec.UTSNamespace); err != nil { return nil, err diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index 2914bd1a19..99c612ed71 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -1055,6 +1055,16 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co } } + if l, ok := os.LookupEnv("LISTEN_FDS"); ok { + listenFds, err := strconv.ParseUint(l, 10, 64) + if err != nil { + logrus.Warnf("Error LISTEN_FDS environment variable for %s not an int %v", ctr.ID(), err) + } + + if uint(listenFds) > ctr.config.PreserveFDs { + ctr.config.PreserveFDs = uint(listenFds) + } + } if ctr.config.PreserveFDs > 0 { args = append(args, formatRuntimeOpts("--preserve-fds", fmt.Sprintf("%d", ctr.config.PreserveFDs))...) } diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index 4ea1920098..6657785025 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -148,4 +148,43 @@ function service_cleanup() { service_cleanup } +@test "podman pass run LISTEN environment " { + tmpdir=$PODMAN_TMPDIR/build-test + subdir=$tmpdir/subdir + run_podman run --hostname=host1 --rm $IMAGE printenv + std_output=$output + + export LISTEN_PID="100" LISTEN_FDS="1" LISTEN_FDNAMES="listen_fdnames" + run_podman run --hostname=host1 --rm $IMAGE printenv + if is_remote; then + is "$output" "$std_output" "LISTEN Environment did not pass" + else + is "$output" "$std_output +LISTEN_PID=1 +LISTEN_FDS=1 +LISTEN_FDNAMES=listen_fdnames" "LISTEN Environment passed" + fi + unset LISTEN_PID LISTEN_FDS LISTEN_FDNAMES +} + +@test "podman pass start LISTEN environment " { + tmpdir=$PODMAN_TMPDIR/build-test + subdir=$tmpdir/subdir + run_podman run --hostname=host1 --rm $IMAGE printenv + std_output=$output + + run_podman create --name=test --hostname=host1 --rm $IMAGE printenv + export LISTEN_PID="100" LISTEN_FDS="1" LISTEN_FDNAMES="listen_fdnames" + run_podman start --attach test + if is_remote; then + is "$output" "$std_output" "LISTEN Environment did not pass" + else + is "$output" "$std_output +LISTEN_PID=1 +LISTEN_FDS=1 +LISTEN_FDNAMES=listen_fdnames" "LISTEN Environment passed" + fi + unset LISTEN_PID LISTEN_FDS LISTEN_FDNAMES +} + # vim: filetype=sh