Skip to content

Commit

Permalink
Merge pull request #23240 from mheon/backports_512
Browse files Browse the repository at this point in the history
[v5.1] Backports for v5.1.2
  • Loading branch information
openshift-merge-bot[bot] authored Jul 10, 2024
2 parents a5ba0a9 + 2bcdb32 commit 6114aaa
Show file tree
Hide file tree
Showing 28 changed files with 314 additions and 241 deletions.
12 changes: 12 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Release Notes

## 5.1.2
### Bugfixes
- Fixed a bug that would sometimes prevent the mount of some `podman machine` volumes into the virtual machine when using the Apple hypervisor ([#22569](https://github.com/containers/podman/issues/22569)).
- Fixed a bug where `podman top` would show the incorrect UID for processes in containers run in a user namespace ([#22293](https://github.com/containers/podman/issues/22293)).
- Fixed a bug where the `/etc/hosts` and `/etc/resolv.conf` files in a container would be empty after restoring from a checkpoint ([#22901](https://github.com/containers/podman/issues/22901)).
- Fixed a bug where the `--pod-id-file` argument to `podman run` and `podman create` did not respect the pod's user namespace ([#22931](https://github.com/containers/podman/issues/22931)).
- Fixed a bug in the Podman remote client where specifying a invalid connection in the `CONTAINER_CONNECTION` environment variable would lead to a panic.

### Misc
- Virtual machines run by `podman machine` using the Apple hypervisor now wait 90 seconds before forcibly stopping the VM, matching the standard systemd shutdown timeout ([#22515](https://github.com/containers/podman/issues/22515)).
- Updates the containers/image library to v5.31.1

## 5.1.1
### Bugfixes
- Fixed a bug where systemd timers associated with startup healthchecks would not be properly deleted after transitioning to the regular healthcheck ([#22884](https://github.com/containers/podman/issues/22884)).
Expand Down
4 changes: 1 addition & 3 deletions cmd/podman/common/create.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package common

import (
"os"

"github.com/containers/common/pkg/auth"
"github.com/containers/common/pkg/completion"
commonFlag "github.com/containers/common/pkg/flag"
Expand Down Expand Up @@ -723,7 +721,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,

usernsFlagName := "userns"
createFlags.String(
usernsFlagName, os.Getenv("PODMAN_USERNS"),
usernsFlagName, "",
"User namespace to use",
)
_ = cmd.RegisterFlagCompletionFunc(usernsFlagName, AutocompleteUserNamespace)
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/kube/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func playFlags(cmd *cobra.Command) {
_ = cmd.RegisterFlagCompletionFunc(logOptFlagName, common.AutocompleteLogOpt)

usernsFlagName := "userns"
flags.StringVar(&playOptions.Userns, usernsFlagName, os.Getenv("PODMAN_USERNS"),
flags.StringVar(&playOptions.Userns, usernsFlagName, "",
"User namespace to use",
)
_ = cmd.RegisterFlagCompletionFunc(usernsFlagName, common.AutocompleteUserNamespace)
Expand Down
26 changes: 17 additions & 9 deletions cmd/podman/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ func readRemoteCliFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig)
}
case host.Changed:
podmanConfig.URI = host.Value.String()
default:
// No cli options set, in case CONTAINER_CONNECTION was set to something
// invalid this contains the error, see setupRemoteConnection().
// Important so that we can show a proper useful error message but still
// allow the cli overwrites (https://github.com/containers/podman/pull/22997).
return podmanConfig.ConnectionError
}
return nil
}
Expand All @@ -185,19 +191,22 @@ func readRemoteCliFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig)
// 2. Env variables (CONTAINER_HOST and CONTAINER_CONNECTION);
// 3. ActiveService from containers.conf;
// 4. RemoteURI;
func setupRemoteConnection(podmanConfig *entities.PodmanConfig) error {
// Returns the name of the default connection if any.
func setupRemoteConnection(podmanConfig *entities.PodmanConfig) string {
conf := podmanConfig.ContainersConfDefaultsRO
connEnv, hostEnv, sshkeyEnv := os.Getenv("CONTAINER_CONNECTION"), os.Getenv("CONTAINER_HOST"), os.Getenv("CONTAINER_SSHKEY")

switch {
case connEnv != "":
con, err := conf.GetConnection(connEnv, false)
if err != nil {
return err
podmanConfig.ConnectionError = err
return connEnv
}
podmanConfig.URI = con.URI
podmanConfig.Identity = con.Identity
podmanConfig.MachineMode = con.IsMachine
return con.Name
case hostEnv != "":
if sshkeyEnv != "" {
podmanConfig.Identity = sshkeyEnv
Expand All @@ -209,11 +218,11 @@ func setupRemoteConnection(podmanConfig *entities.PodmanConfig) error {
podmanConfig.URI = con.URI
podmanConfig.Identity = con.Identity
podmanConfig.MachineMode = con.IsMachine
} else {
podmanConfig.URI = registry.DefaultAPIAddress()
return con.Name
}
podmanConfig.URI = registry.DefaultAPIAddress()
}
return nil
return ""
}

func persistentPreRunE(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -459,17 +468,16 @@ func stdOutHook() {
}

func rootFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig) {
if err := setupRemoteConnection(podmanConfig); err != nil {
return
}
connectionName := setupRemoteConnection(podmanConfig)

lFlags := cmd.Flags()

sshFlagName := "ssh"
lFlags.StringVar(&podmanConfig.SSHMode, sshFlagName, string(ssh.GolangMode), "define the ssh mode")
_ = cmd.RegisterFlagCompletionFunc(sshFlagName, common.AutocompleteSSH)

connectionFlagName := "connection"
lFlags.StringP(connectionFlagName, "c", podmanConfig.ContainersConfDefaultsRO.Engine.ActiveService, "Connection to use for remote Podman service")
lFlags.StringP(connectionFlagName, "c", connectionName, "Connection to use for remote Podman service (CONTAINER_CONNECTION)")
_ = cmd.RegisterFlagCompletionFunc(connectionFlagName, common.AutocompleteSystemConnections)

urlFlagName := "url"
Expand Down
2 changes: 0 additions & 2 deletions contrib/cirrus/setup_environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,6 @@ case "$TEST_FLAVOR" in
remove_packaged_podman_files
showrun make install PREFIX=/usr ETCDIR=/etc

msg "Installing previously downloaded/cached packages"
showrun dnf install -y $PACKAGE_DOWNLOAD_DIR/python3*.rpm
virtualenv .venv/docker-py
source .venv/docker-py/bin/activate
showrun pip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/containers/common v0.59.1
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/gvisor-tap-vsock v0.7.4-0.20240408151405-d744d71db363
github.com/containers/image/v5 v5.31.0
github.com/containers/image/v5 v5.31.1
github.com/containers/libhvee v0.7.1
github.com/containers/ocicrypt v1.1.10
github.com/containers/psgo v1.9.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6J
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/gvisor-tap-vsock v0.7.4-0.20240408151405-d744d71db363 h1:EqWMZeFa08y2c1GniaFkfjlO5AjegoG2foWo6NlDfUY=
github.com/containers/gvisor-tap-vsock v0.7.4-0.20240408151405-d744d71db363/go.mod h1:KN4qqZfwVBzvqlN1Ytbhf84sOzftw+R8YL9bixQlr2Y=
github.com/containers/image/v5 v5.31.0 h1:eDFVlz5XaYICxe9dXpf23htEKvyosgkl62mJlIATXE4=
github.com/containers/image/v5 v5.31.0/go.mod h1:5QfOqSackPkSbF7Qxc1DnVNnPJKQ+KWLkfEfDpK590Q=
github.com/containers/image/v5 v5.31.1 h1:3x9soI6Biml/GiDLpkSmKrkRSwVGctxu/vONpoUdklA=
github.com/containers/image/v5 v5.31.1/go.mod h1:5QfOqSackPkSbF7Qxc1DnVNnPJKQ+KWLkfEfDpK590Q=
github.com/containers/libhvee v0.7.1 h1:dWGF5GLq9DZvXo3P8aDp3cNieL5eCaSell4UmeA/jY4=
github.com/containers/libhvee v0.7.1/go.mod h1:fRKB3AyIqHMvq6xaeYhTpckM2cdoq0oecolyoiuLP7M=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
Expand Down
9 changes: 9 additions & 0 deletions libpod/container_internal_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -1712,6 +1712,15 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
}
}

// setup hosts/resolv.conf files
// Note this should normally be called after the container is created in the runtime but before it is started.
// However restore starts the container right away. This means that if we do the call afterwards there is a
// short interval where the file is still empty. Thus I decided to call it before which makes it not working
// with PostConfigureNetNS (userns) but as this does not work anyway today so I don't see it as problem.
if err := c.completeNetworkSetup(); err != nil {
return nil, 0, fmt.Errorf("complete network setup: %w", err)
}

runtimeRestoreDuration, err = c.ociRuntime.CreateContainer(c, &options)
if err != nil {
return nil, 0, err
Expand Down
26 changes: 26 additions & 0 deletions libpod/container_top_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mount.h>
Expand All @@ -11,6 +13,7 @@

/* keep special_exit_code in sync with container_top_linux.go */
int special_exit_code = 255;
int join_userns = 0;
char **argv = NULL;

void
Expand All @@ -33,6 +36,12 @@ set_argv (int pos, char *arg)
argv[pos] = arg;
}

void
set_userns ()
{
join_userns = 1;
}

/*
We use cgo code here so we can fork then exec separately,
this is done so we can mount proc after the fork because the pid namespace is
Expand Down Expand Up @@ -64,6 +73,23 @@ fork_exec_ps ()
fprintf (stderr, "mount proc: %m");
exit (special_exit_code);
}
if (join_userns)
{
// join the userns to make sure uid mapping match
// we are already part of the pidns so so pid 1 is the main container process
r = open ("/proc/1/ns/user", O_CLOEXEC | O_RDONLY);
if (r < 0)
{
fprintf (stderr, "open /proc/1/ns/user: %m");
exit (special_exit_code);
}
if ((status = setns (r, CLONE_NEWUSER)) < 0)
{
fprintf (stderr, "setns NEWUSER: %m");
exit (special_exit_code);
}
}

/* use execve to unset all env vars, we do not want to leak anything into the container */
execve (argv[0], argv, NULL);
fprintf (stderr, "execve: %m");
Expand Down
25 changes: 19 additions & 6 deletions libpod/container_top_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
void fork_exec_ps();
void create_argv(int len);
void set_argv(int pos, char *arg);
void set_userns();
*/
import "C"

Expand All @@ -56,13 +57,13 @@ func podmanTopMain() {
os.Exit(0)
}

// podmanTopInner os.Args = {command name} {pid} {psPath} [args...]
// podmanTopInner os.Args = {command name} {pid} {userns(1/0)} {psPath} [args...]
// We are rexxec'd in a new mountns, then we need to set some security settings in order
// to safely execute ps in the container pid namespace. Most notably make sure podman and
// ps are read only to prevent a process from overwriting it.
func podmanTopInner() error {
if len(os.Args) < 3 {
return fmt.Errorf("internal error, need at least two arguments")
if len(os.Args) < 4 {
return fmt.Errorf("internal error, need at least three arguments")
}

// We have to lock the thread as we a) switch namespace below and b) use PR_SET_PDEATHSIG
Expand All @@ -84,7 +85,7 @@ func podmanTopInner() error {
return fmt.Errorf("make / mount private: %w", err)
}

psPath := os.Args[2]
psPath := os.Args[3]

// try to mount everything read only
if err := unix.MountSetattr(0, "/", unix.AT_RECURSIVE, &unix.MountAttr{
Expand Down Expand Up @@ -122,8 +123,13 @@ func podmanTopInner() error {
}
pidFD.Close()

userns := os.Args[2]
if userns == "1" {
C.set_userns()
}

args := []string{psPath}
args = append(args, os.Args[3:]...)
args = append(args, os.Args[4:]...)

C.create_argv(C.int(len(args)))
for i, arg := range args {
Expand Down Expand Up @@ -317,7 +323,14 @@ func (c *Container) execPS(psArgs []string) ([]string, bool, error) {
wPipe.Close()
return nil, true, err
}
args := append([]string{podmanTopCommand, strconv.Itoa(c.state.PID), psPath}, psArgs...)

// see podmanTopInner()
userns := "0"
if len(c.config.IDMappings.UIDMap) > 0 {
userns = "1"
}

args := append([]string{podmanTopCommand, strconv.Itoa(c.state.PID), userns, psPath}, psArgs...)

cmd := reexec.Command(args...)
cmd.SysProcAttr = &syscall.SysProcAttr{
Expand Down
21 changes: 14 additions & 7 deletions pkg/api/handlers/libpod/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,12 +400,8 @@ func PodTop(w http.ResponseWriter, r *http.Request) {
return
}

// We are committed now - all errors logged but not reported to client, ship has sailed
w.WriteHeader(http.StatusOK)
wroteContent := false
w.Header().Set("Content-Type", "application/json")
if f, ok := w.(http.Flusher); ok {
f.Flush()
}

encoder := json.NewEncoder(w)

Expand All @@ -417,11 +413,22 @@ loop: // break out of for/select infinite` loop
default:
output, err := pod.GetPodPidInformation([]string{query.PsArgs})
if err != nil {
logrus.Infof("Error from %s %q : %v", r.Method, r.URL, err)
break loop
if !wroteContent {
utils.InternalServerError(w, err)
} else {
// ship has sailed, client already got a 200 response and expects valid
// PodTopOKBody json format so we no longer can send the error.
logrus.Infof("Error from %s %q : %v", r.Method, r.URL, err)
}
return
}

if len(output) > 0 {
if !wroteContent {
// Write header only first time around
w.WriteHeader(http.StatusOK)
wroteContent = true
}
body := handlers.PodTopOKBody{}
body.Titles = utils.PSTitles(output[0])
for i := range body.Titles {
Expand Down
1 change: 1 addition & 0 deletions pkg/domain/entities/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type PodmanConfig struct {
Trace bool // Hidden: Trace execution
URI string // URI to RESTful API Service
FarmNodeName string // Name of farm node
ConnectionError error // Error when looking up the connection in setupRemoteConnection()

Runroot string
ImageStore string
Expand Down
Loading

0 comments on commit 6114aaa

Please sign in to comment.