summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create.go15
-rw-r--r--cmd/podman/containers/create.go1
-rw-r--r--cmd/podman/pods/create.go1
-rw-r--r--docs/source/markdown/podman-pod-clone.1.md9
-rw-r--r--docs/source/markdown/podman-pod-create.1.md8
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--libpod/container.go49
-rw-r--r--libpod/container_api.go7
-rw-r--r--libpod/container_exec.go21
-rw-r--r--libpod/container_inspect.go24
-rw-r--r--libpod/define/errors.go3
-rw-r--r--libpod/define/pod_inspect.go2
-rw-r--r--libpod/define/terminal.go7
-rw-r--r--libpod/oci.go11
-rw-r--r--libpod/oci_conmon_attach_linux.go12
-rw-r--r--libpod/oci_conmon_exec_linux.go13
-rw-r--r--libpod/oci_conmon_linux.go6
-rw-r--r--libpod/oci_missing.go9
-rw-r--r--libpod/pod_api.go1
-rw-r--r--pkg/api/handlers/compat/containers.go12
-rw-r--r--pkg/api/handlers/compat/exec.go5
-rw-r--r--pkg/api/handlers/compat/resize.go3
-rw-r--r--pkg/api/handlers/libpod/pods.go37
-rw-r--r--pkg/bindings/containers/attach.go8
-rw-r--r--pkg/domain/infra/abi/terminal/terminal.go10
-rw-r--r--pkg/domain/infra/abi/terminal/terminal_linux.go11
-rw-r--r--pkg/kubeutils/LICENSE201
-rw-r--r--pkg/machine/qemu/machine.go5
-rw-r--r--pkg/specgen/container_validate.go1
-rw-r--r--pkg/specgen/generate/container_create.go6
-rw-r--r--pkg/specgen/generate/namespaces.go9
-rw-r--r--pkg/specgen/generate/pod_create.go1
-rw-r--r--test/apiv2/40-pods.at2
-rw-r--r--test/apiv2/python/rest_api/fixtures/api_testcase.py4
-rw-r--r--test/apiv2/python/rest_api/test_v2_0_0_container.py47
-rwxr-xr-xtest/apiv2/test-apiv226
-rw-r--r--test/e2e/pod_clone_test.go42
-rw-r--r--test/e2e/pod_create_test.go33
-rw-r--r--utils/utils.go52
-rw-r--r--vendor/github.com/containers/common/pkg/resize/resize.go (renamed from pkg/kubeutils/resize.go)14
-rw-r--r--vendor/github.com/containers/common/pkg/util/copy.go57
-rw-r--r--vendor/modules.txt3
43 files changed, 429 insertions, 365 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index f05549a8d..c1a744011 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -544,13 +544,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(userFlagName, AutocompleteUserFlag)
- utsFlagName := "uts"
- createFlags.String(
- utsFlagName, "",
- "UTS namespace to use",
- )
- _ = cmd.RegisterFlagCompletionFunc(utsFlagName, AutocompleteNamespace)
-
mountFlagName := "mount"
createFlags.StringArrayVar(
&cf.Mount,
@@ -684,6 +677,14 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(usernsFlagName, AutocompleteUserNamespace)
+ utsFlagName := "uts"
+ createFlags.StringVar(
+ &cf.UTS,
+ utsFlagName, "",
+ "UTS namespace to use",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(utsFlagName, AutocompleteNamespace)
+
cgroupParentFlagName := "cgroup-parent"
createFlags.StringVar(
&cf.CgroupParent,
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 05a59ce7b..7d0f4d9ae 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -224,7 +224,6 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
return vals, errors.New("--cpu-quota and --cpus cannot be set together")
}
vals.IPC = c.Flag("ipc").Value.String()
- vals.UTS = c.Flag("uts").Value.String()
vals.PID = c.Flag("pid").Value.String()
vals.CgroupNS = c.Flag("cgroupns").Value.String()
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index 45ad2dfd0..aea8a7229 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -277,6 +277,7 @@ func create(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
+
podSpec.Volumes = podSpec.InfraContainerSpec.Volumes
podSpec.ImageVolumes = podSpec.InfraContainerSpec.ImageVolumes
podSpec.OverlayVolumes = podSpec.InfraContainerSpec.OverlayVolumes
diff --git a/docs/source/markdown/podman-pod-clone.1.md b/docs/source/markdown/podman-pod-clone.1.md
index a18f7dbfe..d90d1efb9 100644
--- a/docs/source/markdown/podman-pod-clone.1.md
+++ b/docs/source/markdown/podman-pod-clone.1.md
@@ -211,6 +211,15 @@ Valid _mode_ values are:
- *nomap*: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is ignored for containers created by the root user.
+#### **--uts**=*mode*
+
+Set the UTS namespace mode for the pod. The following values are supported:
+
+- **host**: use the host's UTS namespace inside the pod.
+- **private**: create a new namespace for the pod (default).
+- **ns:[path]**: run the pod in the given existing UTS namespace.
+
+
#### **--volume**, **-v**[=*[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]
Create a bind mount. If ` -v /HOST-DIR:/CONTAINER-DIR` is specified, Podman
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index 75d2bb611..53d1e3327 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -381,6 +381,14 @@ Valid _mode_ values are:
- *nomap*: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is not allowed for containers created by the root user.
+#### **--uts**=*mode*
+
+Set the UTS namespace mode for the pod. The following values are supported:
+
+- **host**: use the host's UTS namespace inside the pod.
+- **private**: create a new namespace for the pod (default).
+- **ns:[path]**: run the pod in the given existing UTS namespace.
+
#### **--volume**, **-v**[=*[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]
Create a bind mount. If you specify, ` -v /HOST-DIR:/CONTAINER-DIR`, Podman
diff --git a/go.mod b/go.mod
index 521521d9a..d3d3feea0 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
github.com/containernetworking/cni v1.1.1
github.com/containernetworking/plugins v1.1.1
github.com/containers/buildah v1.26.1-0.20220609225314-e66309ebde8c
- github.com/containers/common v0.48.1-0.20220630172158-178929cf063e
+ github.com/containers/common v0.48.1-0.20220705175712-dd1c331887b9
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.21.2-0.20220617075545-929f14a56f5c
github.com/containers/ocicrypt v1.1.5
diff --git a/go.sum b/go.sum
index aed64a5c6..13056f853 100644
--- a/go.sum
+++ b/go.sum
@@ -338,8 +338,8 @@ github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19
github.com/containers/buildah v1.26.1-0.20220609225314-e66309ebde8c h1:/fKyiLFFuceBPZGJ0Lig7ElURhfsslAOw1BOcItD+X8=
github.com/containers/buildah v1.26.1-0.20220609225314-e66309ebde8c/go.mod h1:b0L+u2Dam7soWGn5sVTK31L++Xrf80AbGvK5z9D2+lw=
github.com/containers/common v0.48.1-0.20220608111710-dbecabbe82c9/go.mod h1:WBLwq+i7bicCpH54V70HM6s7jqDAESTlYnd05XXp0ac=
-github.com/containers/common v0.48.1-0.20220630172158-178929cf063e h1:Vf5tsGrLC2B2omVBP3AdDA7YlE/VoMdNyQ5yPF8GRoY=
-github.com/containers/common v0.48.1-0.20220630172158-178929cf063e/go.mod h1:Zt3D/IhgFyG1oaBrqsbn9NdH/4fkjsO2Y0ahP12ieu4=
+github.com/containers/common v0.48.1-0.20220705175712-dd1c331887b9 h1:KeGIf6Z1R+16Sq+5/fhkoCCKa7wjQ6Ksnmo0beU1E2U=
+github.com/containers/common v0.48.1-0.20220705175712-dd1c331887b9/go.mod h1:Zt3D/IhgFyG1oaBrqsbn9NdH/4fkjsO2Y0ahP12ieu4=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.21.2-0.20220511203756-fe4fd4ed8be4/go.mod h1:OsX9sFexyGF0FCNAjfcVFv3IwMqDyLyV/WQY/roLPcE=
diff --git a/libpod/container.go b/libpod/container.go
index 786d9c3d4..4e2d93860 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -1335,3 +1335,52 @@ func (c *Container) getNetworkStatus() map[string]types.StatusBlock {
}
return nil
}
+
+func (c *Container) NamespaceMode(ns spec.LinuxNamespaceType, ctrSpec *spec.Spec) string {
+ switch ns {
+ case spec.UTSNamespace:
+ if c.config.UTSNsCtr != "" {
+ return fmt.Sprintf("container:%s", c.config.UTSNsCtr)
+ }
+ case spec.CgroupNamespace:
+ if c.config.CgroupNsCtr != "" {
+ return fmt.Sprintf("container:%s", c.config.CgroupNsCtr)
+ }
+ case spec.IPCNamespace:
+ if c.config.IPCNsCtr != "" {
+ return fmt.Sprintf("container:%s", c.config.IPCNsCtr)
+ }
+ case spec.PIDNamespace:
+ if c.config.PIDNsCtr != "" {
+ return fmt.Sprintf("container:%s", c.config.PIDNsCtr)
+ }
+ case spec.UserNamespace:
+ if c.config.UserNsCtr != "" {
+ return fmt.Sprintf("container:%s", c.config.UserNsCtr)
+ }
+ case spec.NetworkNamespace:
+ if c.config.NetNsCtr != "" {
+ return fmt.Sprintf("container:%s", c.config.NetNsCtr)
+ }
+ case spec.MountNamespace:
+ if c.config.MountNsCtr != "" {
+ return fmt.Sprintf("container:%s", c.config.MountNsCtr)
+ }
+ }
+
+ if ctrSpec.Linux != nil {
+ // Locate the spec's given namespace.
+ // If there is none, it's namespace=host.
+ // If there is one and it has a path, it's "ns:".
+ // If there is no path, it's default - the empty string.
+ for _, availableNS := range ctrSpec.Linux.Namespaces {
+ if availableNS.Type == ns {
+ if availableNS.Path != "" {
+ return fmt.Sprintf("ns:%s", availableNS.Path)
+ }
+ return "private"
+ }
+ }
+ }
+ return "host"
+}
diff --git a/libpod/container_api.go b/libpod/container_api.go
index c96845546..dbd5fc1fb 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -11,6 +11,7 @@ import (
"sync"
"time"
+ "github.com/containers/common/pkg/resize"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/signal"
@@ -103,7 +104,7 @@ func (c *Container) Start(ctx context.Context, recursive bool) error {
// Attach call occurs before Start).
// In overall functionality, it is identical to the Start call, with the added
// side effect that an attach session will also be started.
-func (c *Container) StartAndAttach(ctx context.Context, streams *define.AttachStreams, keys string, resize <-chan define.TerminalSize, recursive bool) (<-chan error, error) {
+func (c *Container) StartAndAttach(ctx context.Context, streams *define.AttachStreams, keys string, resize <-chan resize.TerminalSize, recursive bool) (<-chan error, error) {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
@@ -239,7 +240,7 @@ func (c *Container) Kill(signal uint) error {
// Attach attaches to a container.
// This function returns when the attach finishes. It does not hold the lock for
// the duration of its runtime, only using it at the beginning to verify state.
-func (c *Container) Attach(streams *define.AttachStreams, keys string, resize <-chan define.TerminalSize) error {
+func (c *Container) Attach(streams *define.AttachStreams, keys string, resize <-chan resize.TerminalSize) error {
if c.LogDriver() == define.PassthroughLogging {
return fmt.Errorf("this container is using the 'passthrough' log driver, cannot attach: %w", define.ErrNoLogs)
}
@@ -335,7 +336,7 @@ func (c *Container) HTTPAttach(r *http.Request, w http.ResponseWriter, streams *
// AttachResize resizes the container's terminal, which is displayed by Attach
// and HTTPAttach.
-func (c *Container) AttachResize(newSize define.TerminalSize) error {
+func (c *Container) AttachResize(newSize resize.TerminalSize) error {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index ebc5e59ae..d3c80e896 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -11,6 +11,7 @@ import (
"strconv"
"time"
+ "github.com/containers/common/pkg/resize"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/storage/pkg/stringid"
@@ -278,13 +279,13 @@ func (c *Container) ExecStart(sessionID string) error {
return c.save()
}
-func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachStreams, newSize *define.TerminalSize) error {
+func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachStreams, newSize *resize.TerminalSize) error {
return c.execStartAndAttach(sessionID, streams, newSize, false)
}
// ExecStartAndAttach starts and attaches to an exec session in a container.
// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
-func (c *Container) execStartAndAttach(sessionID string, streams *define.AttachStreams, newSize *define.TerminalSize, isHealthcheck bool) error {
+func (c *Container) execStartAndAttach(sessionID string, streams *define.AttachStreams, newSize *resize.TerminalSize, isHealthcheck bool) error {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
@@ -423,7 +424,7 @@ func (c *Container) execStartAndAttach(sessionID string, streams *define.AttachS
// ExecHTTPStartAndAttach starts and performs an HTTP attach to an exec session.
// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
func (c *Container) ExecHTTPStartAndAttach(sessionID string, r *http.Request, w http.ResponseWriter,
- streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool, newSize *define.TerminalSize) error {
+ streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool, newSize *resize.TerminalSize) error {
// TODO: How do we combine streams with the default streams set in the exec session?
// Ensure that we don't leak a goroutine here
@@ -711,7 +712,7 @@ func (c *Container) ExecRemove(sessionID string, force bool) error {
// ExecResize resizes the TTY of the given exec session. Only available if the
// exec session created a TTY.
-func (c *Container) ExecResize(sessionID string, newSize define.TerminalSize) error {
+func (c *Container) ExecResize(sessionID string, newSize resize.TerminalSize) error {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
@@ -753,14 +754,14 @@ func (c *Container) ExecResize(sessionID string, newSize define.TerminalSize) er
return c.ociRuntime.ExecAttachResize(c, sessionID, newSize)
}
-func (c *Container) Exec(config *ExecConfig, streams *define.AttachStreams, resize <-chan define.TerminalSize) (int, error) {
+func (c *Container) Exec(config *ExecConfig, streams *define.AttachStreams, resize <-chan resize.TerminalSize) (int, error) {
return c.exec(config, streams, resize, false)
}
// Exec emulates the old Libpod exec API, providing a single call to create,
// run, and remove an exec session. Returns exit code and error. Exit code is
// not guaranteed to be set sanely if error is not nil.
-func (c *Container) exec(config *ExecConfig, streams *define.AttachStreams, resize <-chan define.TerminalSize, isHealthcheck bool) (int, error) {
+func (c *Container) exec(config *ExecConfig, streams *define.AttachStreams, resizeChan <-chan resize.TerminalSize, isHealthcheck bool) (int, error) {
sessionID, err := c.ExecCreate(config)
if err != nil {
return -1, err
@@ -773,13 +774,13 @@ func (c *Container) exec(config *ExecConfig, streams *define.AttachStreams, resi
// API there.
// TODO: Refactor so this is closed here, before we remove the exec
// session.
- var size *define.TerminalSize
- if resize != nil {
- s := <-resize
+ var size *resize.TerminalSize
+ if resizeChan != nil {
+ s := <-resizeChan
size = &s
go func() {
logrus.Debugf("Sending resize events to exec session %s", sessionID)
- for resizeRequest := range resize {
+ for resizeRequest := range resizeChan {
if err := c.ExecResize(sessionID, resizeRequest); err != nil {
if errors.Is(err, define.ErrExecSessionStateInvalid) {
// The exec session stopped
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 04233455d..fa2130a28 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -794,28 +794,8 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
hostConfig.PidMode = pidMode
// UTS namespace mode
- utsMode := ""
- if c.config.UTSNsCtr != "" {
- utsMode = fmt.Sprintf("container:%s", c.config.UTSNsCtr)
- } else if ctrSpec.Linux != nil {
- // Locate the spec's UTS namespace.
- // If there is none, it's uts=host.
- // If there is one and it has a path, it's "ns:".
- // If there is no path, it's default - the empty string.
- for _, ns := range ctrSpec.Linux.Namespaces {
- if ns.Type == spec.UTSNamespace {
- if ns.Path != "" {
- utsMode = fmt.Sprintf("ns:%s", ns.Path)
- } else {
- utsMode = "private"
- }
- break
- }
- }
- if utsMode == "" {
- utsMode = "host"
- }
- }
+ utsMode := c.NamespaceMode(spec.UTSNamespace, ctrSpec)
+
hostConfig.UTSMode = utsMode
// User namespace mode
diff --git a/libpod/define/errors.go b/libpod/define/errors.go
index 9757a85b1..b858e1989 100644
--- a/libpod/define/errors.go
+++ b/libpod/define/errors.go
@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/containers/common/libnetwork/types"
+ "github.com/containers/common/pkg/util"
)
var (
@@ -92,7 +93,7 @@ var (
// ErrDetach indicates that an attach session was manually detached by
// the user.
- ErrDetach = errors.New("detached from container")
+ ErrDetach = util.ErrDetach
// ErrWillDeadlock indicates that the requested operation will cause a
// deadlock. This is usually caused by upgrade issues, and is resolved
diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go
index 935e0f5f9..2afef48c4 100644
--- a/libpod/define/pod_inspect.go
+++ b/libpod/define/pod_inspect.go
@@ -122,6 +122,8 @@ type InspectPodInfraConfig struct {
PidNS string `json:"pid_ns,omitempty"`
// UserNS is the usernamespace that all the containers in the pod will join.
UserNS string `json:"userns,omitempty"`
+ // UtsNS is the uts namespace that all containers in the pod will join
+ UtsNS string `json:"uts_ns,omitempty"`
}
// InspectPodContainerInfo contains information on a container in a pod.
diff --git a/libpod/define/terminal.go b/libpod/define/terminal.go
deleted file mode 100644
index ce8955544..000000000
--- a/libpod/define/terminal.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package define
-
-// TerminalSize represents the width and height of a terminal.
-type TerminalSize struct {
- Width uint16
- Height uint16
-}
diff --git a/libpod/oci.go b/libpod/oci.go
index 90862969c..70053db1b 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -3,6 +3,7 @@ package libpod
import (
"net/http"
+ "github.com/containers/common/pkg/resize"
"github.com/containers/podman/v4/libpod/define"
)
@@ -66,7 +67,7 @@ type OCIRuntime interface {
// client.
HTTPAttach(ctr *Container, r *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool, streamAttach, streamLogs bool) error
// AttachResize resizes the terminal in use by the given container.
- AttachResize(ctr *Container, newSize define.TerminalSize) error
+ AttachResize(ctr *Container, newSize resize.TerminalSize) error
// ExecContainer executes a command in a running container.
// Returns an int (PID of exec session), error channel (errors from
@@ -76,7 +77,7 @@ type OCIRuntime interface {
// running, in a goroutine that will return via the chan error in the
// return signature.
// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
- ExecContainer(ctr *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *define.TerminalSize) (int, chan error, error)
+ ExecContainer(ctr *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *resize.TerminalSize) (int, chan error, error)
// ExecContainerHTTP executes a command in a running container and
// attaches its standard streams to a provided hijacked HTTP session.
// Maintains the same invariants as ExecContainer (returns on session
@@ -84,14 +85,14 @@ type OCIRuntime interface {
// The HTTP attach itself maintains the same invariants as HTTPAttach.
// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, r *http.Request, w http.ResponseWriter,
- streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *define.TerminalSize) (int, chan error, error)
+ streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *resize.TerminalSize) (int, chan error, error)
// ExecContainerDetached executes a command in a running container, but
// does not attach to it. Returns the PID of the exec session and an
// error (if starting the exec session failed)
ExecContainerDetached(ctr *Container, sessionID string, options *ExecOptions, stdin bool) (int, error)
// ExecAttachResize resizes the terminal of a running exec session. Only
// allowed with sessions that were created with a TTY.
- ExecAttachResize(ctr *Container, sessionID string, newSize define.TerminalSize) error
+ ExecAttachResize(ctr *Container, sessionID string, newSize resize.TerminalSize) error
// ExecStopContainer stops a given exec session in a running container.
// SIGTERM with be sent initially, then SIGKILL after the given timeout.
// If timeout is 0, SIGKILL will be sent immediately, and SIGTERM will
@@ -161,7 +162,7 @@ type AttachOptions struct {
DetachKeys *string
// InitialSize is the initial size of the terminal. Set before the
// attach begins.
- InitialSize *define.TerminalSize
+ InitialSize *resize.TerminalSize
// AttachReady signals when the attach has successfully completed and
// streaming has begun.
AttachReady chan<- bool
diff --git a/libpod/oci_conmon_attach_linux.go b/libpod/oci_conmon_attach_linux.go
index 61578cb3d..aa55aa6f5 100644
--- a/libpod/oci_conmon_attach_linux.go
+++ b/libpod/oci_conmon_attach_linux.go
@@ -13,10 +13,10 @@ import (
"syscall"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/resize"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/errorhandling"
- "github.com/containers/podman/v4/pkg/kubeutils"
- "github.com/containers/podman/v4/utils"
"github.com/moby/term"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
@@ -130,7 +130,7 @@ func (r *ConmonOCIRuntime) Attach(c *Container, params *AttachOptions) error {
// 4. attachToExec sends on startFd, signalling it has attached to the socket and child is ready to go
// 5. child receives on startFd, runs the runtime exec command
// attachToExec is responsible for closing startFd and attachFd
-func (c *Container) attachToExec(streams *define.AttachStreams, keys *string, sessionID string, startFd, attachFd *os.File, newSize *define.TerminalSize) error {
+func (c *Container) attachToExec(streams *define.AttachStreams, keys *string, sessionID string, startFd, attachFd *os.File, newSize *resize.TerminalSize) error {
if !streams.AttachOutput && !streams.AttachError && !streams.AttachInput {
return fmt.Errorf("must provide at least one stream to attach to: %w", define.ErrInvalidArg)
}
@@ -205,8 +205,8 @@ func processDetachKeys(keys string) ([]byte, error) {
return detachKeys, nil
}
-func registerResizeFunc(resize <-chan define.TerminalSize, bundlePath string) {
- kubeutils.HandleResizing(resize, func(size define.TerminalSize) {
+func registerResizeFunc(r <-chan resize.TerminalSize, bundlePath string) {
+ resize.HandleResizing(r, func(size resize.TerminalSize) {
controlPath := filepath.Join(bundlePath, "ctl")
controlFile, err := os.OpenFile(controlPath, unix.O_WRONLY, 0)
if err != nil {
@@ -232,7 +232,7 @@ func setupStdioChannels(streams *define.AttachStreams, conn *net.UnixConn, detac
go func() {
var err error
if streams.AttachInput {
- _, err = utils.CopyDetachable(conn, streams.InputStream, detachKeys)
+ _, err = util.CopyDetachable(conn, streams.InputStream, detachKeys)
}
stdinDone <- err
}()
diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go
index 88343bee8..16cd7ef9f 100644
--- a/libpod/oci_conmon_exec_linux.go
+++ b/libpod/oci_conmon_exec_linux.go
@@ -14,18 +14,19 @@ import (
"github.com/containers/common/pkg/capabilities"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/resize"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/pkg/lookup"
"github.com/containers/podman/v4/pkg/util"
- "github.com/containers/podman/v4/utils"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
// ExecContainer executes a command in a running container
-func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *define.TerminalSize) (int, chan error, error) {
+func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *resize.TerminalSize) (int, chan error, error) {
if options == nil {
return -1, nil, fmt.Errorf("must provide an ExecOptions struct to ExecContainer: %w", define.ErrInvalidArg)
}
@@ -84,7 +85,7 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options
// ExecContainerHTTP executes a new command in an existing container and
// forwards its standard streams over an attach
func (r *ConmonOCIRuntime) ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, req *http.Request, w http.ResponseWriter,
- streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *define.TerminalSize) (int, chan error, error) {
+ streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *resize.TerminalSize) (int, chan error, error) {
if streams != nil {
if !streams.Stdin && !streams.Stdout && !streams.Stderr {
return -1, nil, fmt.Errorf("must provide at least one stream to attach to: %w", define.ErrInvalidArg)
@@ -196,7 +197,7 @@ func (r *ConmonOCIRuntime) ExecContainerDetached(ctr *Container, sessionID strin
}
// ExecAttachResize resizes the TTY of the given exec session.
-func (r *ConmonOCIRuntime) ExecAttachResize(ctr *Container, sessionID string, newSize define.TerminalSize) error {
+func (r *ConmonOCIRuntime) ExecAttachResize(ctr *Container, sessionID string, newSize resize.TerminalSize) error {
controlFile, err := openControlFile(ctr, ctr.execBundlePath(sessionID))
if err != nil {
return err
@@ -487,7 +488,7 @@ func (r *ConmonOCIRuntime) startExec(c *Container, sessionID string, options *Ex
}
// Attach to a container over HTTP
-func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, pipes *execPipes, detachKeys []byte, isTerminal bool, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, execCmd *exec.Cmd, conmonPipeDataChan chan<- conmonPipeData, ociLog string, newSize *define.TerminalSize, runtimeName string) (deferredErr error) {
+func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, pipes *execPipes, detachKeys []byte, isTerminal bool, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, execCmd *exec.Cmd, conmonPipeDataChan chan<- conmonPipeData, ociLog string, newSize *resize.TerminalSize, runtimeName string) (deferredErr error) {
// NOTE: As you may notice, the attach code is quite complex.
// Many things happen concurrently and yet are interdependent.
// If you ever change this function, make sure to write to the
@@ -607,7 +608,7 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
if attachStdin {
go func() {
logrus.Debugf("Beginning STDIN copy")
- _, err := utils.CopyDetachable(conn, httpBuf, detachKeys)
+ _, err := cutil.CopyDetachable(conn, httpBuf, detachKeys)
logrus.Debugf("STDIN copy completed")
stdinChan <- err
}()
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index caf334a31..0cdfe90e9 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -29,6 +29,8 @@ import (
"github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/resize"
+ cutil "github.com/containers/common/pkg/util"
conmonConfig "github.com/containers/conmon/runner/config"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/logs"
@@ -691,7 +693,7 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
// Next, STDIN. Avoid entirely if attachStdin unset.
if attachStdin {
go func() {
- _, err := utils.CopyDetachable(conn, httpBuf, detach)
+ _, err := cutil.CopyDetachable(conn, httpBuf, detach)
logrus.Debugf("STDIN copy completed")
stdinChan <- err
}()
@@ -746,7 +748,7 @@ func openControlFile(ctr *Container, parentDir string) (*os.File, error) {
}
// AttachResize resizes the terminal used by the given container.
-func (r *ConmonOCIRuntime) AttachResize(ctr *Container, newSize define.TerminalSize) error {
+func (r *ConmonOCIRuntime) AttachResize(ctr *Container, newSize resize.TerminalSize) error {
controlFile, err := openControlFile(ctr, ctr.bundlePath())
if err != nil {
return err
diff --git a/libpod/oci_missing.go b/libpod/oci_missing.go
index 6a756757f..2ab2b4577 100644
--- a/libpod/oci_missing.go
+++ b/libpod/oci_missing.go
@@ -6,6 +6,7 @@ import (
"path/filepath"
"sync"
+ "github.com/containers/common/pkg/resize"
"github.com/containers/podman/v4/libpod/define"
"github.com/sirupsen/logrus"
)
@@ -118,18 +119,18 @@ func (r *MissingRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.Re
}
// AttachResize is not available as the runtime is missing
-func (r *MissingRuntime) AttachResize(ctr *Container, newSize define.TerminalSize) error {
+func (r *MissingRuntime) AttachResize(ctr *Container, newSize resize.TerminalSize) error {
return r.printError()
}
// ExecContainer is not available as the runtime is missing
-func (r *MissingRuntime) ExecContainer(ctr *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *define.TerminalSize) (int, chan error, error) {
+func (r *MissingRuntime) ExecContainer(ctr *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *resize.TerminalSize) (int, chan error, error) {
return -1, nil, r.printError()
}
// ExecContainerHTTP is not available as the runtime is missing
func (r *MissingRuntime) ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, req *http.Request, w http.ResponseWriter,
- streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *define.TerminalSize) (int, chan error, error) {
+ streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *resize.TerminalSize) (int, chan error, error) {
return -1, nil, r.printError()
}
@@ -139,7 +140,7 @@ func (r *MissingRuntime) ExecContainerDetached(ctr *Container, sessionID string,
}
// ExecAttachResize is not available as the runtime is missing.
-func (r *MissingRuntime) ExecAttachResize(ctr *Container, sessionID string, newSize define.TerminalSize) error {
+func (r *MissingRuntime) ExecAttachResize(ctr *Container, sessionID string, newSize resize.TerminalSize) error {
return r.printError()
}
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index e04bb6b05..c1d54d55e 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -676,6 +676,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
infraConfig.CPUSetCPUs = p.ResourceLim().CPU.Cpus
infraConfig.PidNS = p.NamespaceMode(specs.PIDNamespace)
infraConfig.UserNS = p.NamespaceMode(specs.UserNamespace)
+ infraConfig.UtsNS = p.NamespaceMode(specs.UTSNamespace)
namedVolumes, mounts := infra.SortUserVolumes(infra.config.Spec)
inspectMounts, err = infra.GetMounts(namedVolumes, infra.config.ImageVolumes, mounts)
infraSecurity = infra.GetSecurityOptions()
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index 38fe0196a..ae063dc9f 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -397,6 +397,15 @@ func LibpodToContainer(l *libpod.Container, sz bool) (*handlers.Container, error
}, nil
}
+func convertSecondaryIPPrefixLen(input *define.InspectNetworkSettings, output *types.NetworkSettings) {
+ for index, ip := range input.SecondaryIPAddresses {
+ output.SecondaryIPAddresses[index].PrefixLen = ip.PrefixLength
+ }
+ for index, ip := range input.SecondaryIPv6Addresses {
+ output.SecondaryIPv6Addresses[index].PrefixLen = ip.PrefixLength
+ }
+}
+
func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON, error) {
_, imageName := l.Image()
inspect, err := l.Inspect(sz)
@@ -587,6 +596,9 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
if err := json.Unmarshal(n, &networkSettings); err != nil {
return nil, err
}
+
+ convertSecondaryIPPrefixLen(inspect.NetworkSettings, &networkSettings)
+
// do not report null instead use an empty map
if networkSettings.Networks == nil {
networkSettings.Networks = map[string]*network.EndpointSettings{}
diff --git a/pkg/api/handlers/compat/exec.go b/pkg/api/handlers/compat/exec.go
index c7990f6e8..1b4dead8b 100644
--- a/pkg/api/handlers/compat/exec.go
+++ b/pkg/api/handlers/compat/exec.go
@@ -7,6 +7,7 @@ import (
"net/http"
"strings"
+ "github.com/containers/common/pkg/resize"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/api/handlers"
@@ -176,9 +177,9 @@ func ExecStartHandler(w http.ResponseWriter, r *http.Request) {
logrus.Error(fmt.Errorf("error attaching to container %s exec session %s: %w", sessionCtr.ID(), sessionID, e))
}
- var size *define.TerminalSize
+ var size *resize.TerminalSize
if bodyParams.Tty && (bodyParams.Height > 0 || bodyParams.Width > 0) {
- size = &define.TerminalSize{
+ size = &resize.TerminalSize{
Height: bodyParams.Height,
Width: bodyParams.Width,
}
diff --git a/pkg/api/handlers/compat/resize.go b/pkg/api/handlers/compat/resize.go
index f5da306da..a2caf6e35 100644
--- a/pkg/api/handlers/compat/resize.go
+++ b/pkg/api/handlers/compat/resize.go
@@ -6,6 +6,7 @@ import (
"net/http"
"strings"
+ "github.com/containers/common/pkg/resize"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/api/handlers/utils"
@@ -32,7 +33,7 @@ func ResizeTTY(w http.ResponseWriter, r *http.Request) {
return
}
- sz := define.TerminalSize{
+ sz := resize.TerminalSize{
Width: query.Width,
Height: query.Height,
}
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 92fd94390..8b1d456ec 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -530,8 +530,12 @@ func PodStats(w http.ResponseWriter, r *http.Request) {
query := struct {
NamesOrIDs []string `schema:"namesOrIDs"`
All bool `schema:"all"`
+ Stream bool `schema:"stream"`
+ Delay int `schema:"delay"`
}{
// default would go here
+ Delay: 5,
+ Stream: false,
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
@@ -544,6 +548,10 @@ func PodStats(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
}
+ var flush = func() {}
+ if flusher, ok := w.(http.Flusher); ok {
+ flush = flusher.Flush
+ }
// Collect the stats and send them over the wire.
containerEngine := abi.ContainerEngine{Libpod: runtime}
reports, err := containerEngine.PodStats(r.Context(), query.NamesOrIDs, options)
@@ -554,10 +562,35 @@ func PodStats(w http.ResponseWriter, r *http.Request) {
utils.Error(w, http.StatusNotFound, err)
return
}
-
utils.InternalServerError(w, err)
return
}
- utils.WriteResponse(w, http.StatusOK, reports)
+ w.Header().Set("Content-Type", "application/json")
+ coder := json.NewEncoder(w)
+ coder.SetEscapeHTML(true)
+
+ if err := coder.Encode(reports); err != nil {
+ logrus.Infof("Error from %s %q : %v", r.Method, r.URL, err)
+ }
+ flush()
+ if query.Stream {
+ for {
+ select {
+ case <-r.Context().Done():
+ return
+ default:
+ time.Sleep(time.Duration(query.Delay) * time.Second)
+ reports, err = containerEngine.PodStats(r.Context(), query.NamesOrIDs, options)
+ if err != nil {
+ return
+ }
+ if err := coder.Encode(reports); err != nil {
+ logrus.Infof("Error from %s %q : %v", r.Method, r.URL, err)
+ return
+ }
+ flush()
+ }
+ }
+ }
}
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index 303fc65bd..2bfccdd3b 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -14,9 +14,9 @@ import (
"strconv"
"time"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/bindings"
- "github.com/containers/podman/v4/utils"
"github.com/moby/term"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -159,7 +159,7 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri
go func() {
logrus.Debugf("Copying STDIN to socket")
- _, err := utils.CopyDetachable(socket, stdin, detachKeysInBytes)
+ _, err := util.CopyDetachable(socket, stdin, detachKeysInBytes)
if err != nil && err != define.ErrDetach {
logrus.Errorf("Failed to write input to service: %v", err)
}
@@ -497,7 +497,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
if options.GetAttachInput() {
go func() {
logrus.Debugf("Copying STDIN to socket")
- _, err := utils.CopyDetachable(socket, options.InputStream, []byte{})
+ _, err := util.CopyDetachable(socket, options.InputStream, []byte{})
if err != nil {
logrus.Errorf("Failed to write input to service: %v", err)
}
@@ -518,7 +518,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
return fmt.Errorf("exec session %s has a terminal and must have STDOUT enabled", sessionID)
}
// If not multiplex'ed, read from server and write to stdout
- _, err := utils.CopyDetachable(options.GetOutputStream(), socket, []byte{})
+ _, err := util.CopyDetachable(options.GetOutputStream(), socket, []byte{})
if err != nil {
return err
}
diff --git a/pkg/domain/infra/abi/terminal/terminal.go b/pkg/domain/infra/abi/terminal/terminal.go
index 692f8dcd5..45ebded26 100644
--- a/pkg/domain/infra/abi/terminal/terminal.go
+++ b/pkg/domain/infra/abi/terminal/terminal.go
@@ -5,7 +5,7 @@ import (
"os"
"os/signal"
- "github.com/containers/podman/v4/libpod/define"
+ "github.com/containers/common/pkg/resize"
lsignal "github.com/containers/podman/v4/pkg/signal"
"github.com/moby/term"
"github.com/pkg/errors"
@@ -18,20 +18,20 @@ type RawTtyFormatter struct {
// getResize returns a TerminalSize command matching stdin's current
// size on success, and nil on errors.
-func getResize() *define.TerminalSize {
+func getResize() *resize.TerminalSize {
winsize, err := term.GetWinsize(os.Stdin.Fd())
if err != nil {
logrus.Warnf("Could not get terminal size %v", err)
return nil
}
- return &define.TerminalSize{
+ return &resize.TerminalSize{
Width: winsize.Width,
Height: winsize.Height,
}
}
// Helper for prepareAttach - set up a goroutine to generate terminal resize events
-func resizeTty(ctx context.Context, resize chan define.TerminalSize) {
+func resizeTty(ctx context.Context, resize chan resize.TerminalSize) {
sigchan := make(chan os.Signal, 1)
signal.Notify(sigchan, lsignal.SIGWINCH)
go func() {
@@ -78,7 +78,7 @@ func (f *RawTtyFormatter) Format(entry *logrus.Entry) ([]byte, error) {
return bytes, err
}
-func handleTerminalAttach(ctx context.Context, resize chan define.TerminalSize) (context.CancelFunc, *term.State, error) {
+func handleTerminalAttach(ctx context.Context, resize chan resize.TerminalSize) (context.CancelFunc, *term.State, error) {
logrus.Debugf("Handling terminal attach")
subCtx, cancel := context.WithCancel(ctx)
diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go
index 62d36f28d..e8f338418 100644
--- a/pkg/domain/infra/abi/terminal/terminal_linux.go
+++ b/pkg/domain/infra/abi/terminal/terminal_linux.go
@@ -6,6 +6,7 @@ import (
"fmt"
"os"
+ "github.com/containers/common/pkg/resize"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/pkg/errors"
@@ -15,14 +16,14 @@ import (
// ExecAttachCtr execs and attaches to a container
func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (int, error) {
- var resize chan define.TerminalSize
+ var resizechan chan resize.TerminalSize
haveTerminal := term.IsTerminal(int(os.Stdin.Fd()))
// Check if we are attached to a terminal. If we are, generate resize
// events, and set the terminal to raw mode
if haveTerminal && execConfig.Terminal {
- resize = make(chan define.TerminalSize)
- cancel, oldTermState, err := handleTerminalAttach(ctx, resize)
+ resizechan = make(chan resize.TerminalSize)
+ cancel, oldTermState, err := handleTerminalAttach(ctx, resizechan)
if err != nil {
return -1, err
}
@@ -33,14 +34,14 @@ func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpo
}
}()
}
- return ctr.Exec(execConfig, streams, resize)
+ return ctr.Exec(execConfig, streams, resizechan)
}
// StartAttachCtr starts and (if required) attaches to a container
// if you change the signature of this function from os.File to io.Writer, it will trigger a downstream
// error. we may need to just lint disable this one.
func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool) error { //nolint: interfacer
- resize := make(chan define.TerminalSize)
+ resize := make(chan resize.TerminalSize)
haveTerminal := term.IsTerminal(int(os.Stdin.Fd()))
diff --git a/pkg/kubeutils/LICENSE b/pkg/kubeutils/LICENSE
deleted file mode 100644
index 9b259bdfc..000000000
--- a/pkg/kubeutils/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- https://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright {yyyy} {name of copyright owner}
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 879ed5109..ca7947e34 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -1217,7 +1217,10 @@ func (v *MachineVM) startHostNetworking() (string, apiForwardingState, error) {
fmt.Println(cmd)
}
_, err = os.StartProcess(cmd[0], cmd, attr)
- return forwardSock, state, fmt.Errorf("unable to execute: %q: %w", cmd, err)
+ if err != nil {
+ return "", 0, fmt.Errorf("unable to execute: %q: %w", cmd, err)
+ }
+ return forwardSock, state, nil
}
func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwardingState) {
diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go
index 5616a4511..e09757d1d 100644
--- a/pkg/specgen/container_validate.go
+++ b/pkg/specgen/container_validate.go
@@ -59,6 +59,7 @@ func (s *SpecGenerator) Validate() error {
if s.ContainerBasicConfig.UtsNS.IsPod() {
return errors.Wrap(ErrInvalidSpecConfig, "cannot set hostname when joining the pod UTS namespace")
}
+
return errors.Wrap(ErrInvalidSpecConfig, "cannot set hostname when running in the host UTS namespace")
}
// systemd values must be true, false, or always
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 6b2e90b22..f31e46090 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -133,6 +133,12 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
options = append(options, libpod.WithRootFSFromImage(newImage.ID(), resolvedImageName, s.RawImageName))
}
+
+ _, err = rt.LookupPod(s.Hostname)
+ if len(s.Hostname) > 0 && !s.UtsNS.IsPrivate() && err == nil {
+ // ok, we are incorrectly setting the pod as the hostname, lets undo that before validation
+ s.Hostname = ""
+ }
if err := s.Validate(); err != nil {
return nil, nil, nil, errors.Wrap(err, "invalid config provided")
}
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index 4224d16ce..a3719d58e 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -176,7 +176,14 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
if pod == nil || infraCtr == nil {
return nil, errNoInfra
}
- toReturn = append(toReturn, libpod.WithUTSNSFrom(infraCtr))
+ if pod.NamespaceMode(spec.UTSNamespace) == host {
+ // adding infra as a nsCtr is not what we want to do when uts == host
+ // this leads the new ctr to try to add an ns path which is should not in this mode
+ logrus.Debug("pod has host uts, not adding infra as a nsCtr")
+ s.UtsNS = specgen.Namespace{NSMode: specgen.Host}
+ } else {
+ toReturn = append(toReturn, libpod.WithUTSNSFrom(infraCtr))
+ }
case specgen.FromContainer:
utsCtr, err := rt.LookupContainer(s.UtsNS.Value)
if err != nil {
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index 4ac8a0aa2..59936c7a8 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -60,6 +60,7 @@ func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) {
if err != nil {
return nil, err
}
+
spec.Pod = pod.ID()
opts = append(opts, rt.WithPod(pod))
spec.CgroupParent = pod.CgroupParent()
diff --git a/test/apiv2/40-pods.at b/test/apiv2/40-pods.at
index 0a5201213..80724a8d9 100644
--- a/test/apiv2/40-pods.at
+++ b/test/apiv2/40-pods.at
@@ -134,4 +134,6 @@ t GET libpod/pods/json?filters='{"label":["testl' 400 \
t DELETE libpod/pods/foo 200
t DELETE "libpod/pods/foo (pod has already been deleted)" 404
+t_timeout 5 GET "libpod/pods/stats?stream=true&delay=1" 200
+
# vim: filetype=sh
diff --git a/test/apiv2/python/rest_api/fixtures/api_testcase.py b/test/apiv2/python/rest_api/fixtures/api_testcase.py
index 155e93928..f47136555 100644
--- a/test/apiv2/python/rest_api/fixtures/api_testcase.py
+++ b/test/apiv2/python/rest_api/fixtures/api_testcase.py
@@ -64,6 +64,10 @@ class APITestCase(unittest.TestCase):
def uri(path):
return APITestCase.PODMAN_URL + "/v2.0.0/libpod" + path
+ @staticmethod
+ def compat_uri(path):
+ return APITestCase.PODMAN_URL + "/v3.0.0/" + path
+
def resolve_container(self, path):
"""Find 'first' container and return 'Id' formatted into given URI path."""
diff --git a/test/apiv2/python/rest_api/test_v2_0_0_container.py b/test/apiv2/python/rest_api/test_v2_0_0_container.py
index a44786c0d..a6cd93a1a 100644
--- a/test/apiv2/python/rest_api/test_v2_0_0_container.py
+++ b/test/apiv2/python/rest_api/test_v2_0_0_container.py
@@ -1,10 +1,12 @@
import multiprocessing
import queue
import random
+import subprocess
import threading
import unittest
import requests
+import os
import time
from dateutil.parser import parse
@@ -358,5 +360,50 @@ class ContainerTestCase(APITestCase):
self.assertEqual(1000, out["HostConfig"]["Memory"])
+
+def execute_process(cmd):
+ return subprocess.run(
+ cmd,
+ shell=True,
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+
+def create_named_network_ns(network_ns_name):
+ execute_process(f"ip netns add {network_ns_name}")
+ execute_process(f"ip netns exec {network_ns_name} ip link add enp2s0 type veth peer name eth0")
+ execute_process(f"ip netns exec {network_ns_name} ip addr add 10.0.1.0/24 dev eth0")
+ execute_process(f"ip netns exec {network_ns_name} ip link set eth0 up")
+ execute_process(f"ip netns exec {network_ns_name} ip link add enp2s1 type veth peer name eth1")
+ execute_process(f"ip netns exec {network_ns_name} ip addr add 10.0.2.0/24 dev eth1")
+ execute_process(f"ip netns exec {network_ns_name} ip link set eth1 up")
+
+def delete_named_network_ns(network_ns_name):
+ execute_process(f"ip netns delete {network_ns_name}")
+
+class ContainerCompatibleAPITestCase(APITestCase):
+ def test_inspect_network(self):
+ if os.getuid() != 0:
+ self.skipTest("test needs to be executed as root!")
+ try:
+ network_ns_name = "test-compat-api"
+ create_named_network_ns(network_ns_name)
+ self.podman.run("rm", "--all", "--force", check=True)
+ self.podman.run("run", "--net", f"ns:/run/netns/{network_ns_name}", "-d", "alpine", "top", check=True)
+
+ r = requests.post(self.uri(self.resolve_container("/containers/{}/start")))
+ self.assertIn(r.status_code, (204, 304), r.text)
+
+ r = requests.get(self.compat_uri(self.resolve_container("/containers/{}/json")))
+ self.assertEqual(r.status_code, 200, r.text)
+ self.assertId(r.content)
+ out = r.json()
+
+ self.assertEqual("10.0.2.0", out["NetworkSettings"]["SecondaryIPAddresses"][0]["Addr"])
+ self.assertEqual(24, out["NetworkSettings"]["SecondaryIPAddresses"][0]["PrefixLen"])
+ finally:
+ delete_named_network_ns(network_ns_name)
+
if __name__ == "__main__":
unittest.main()
diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2
index 8548d84e5..0fd282854 100755
--- a/test/apiv2/test-apiv2
+++ b/test/apiv2/test-apiv2
@@ -56,6 +56,9 @@ fi
# Path to podman binary
PODMAN_BIN=${PODMAN:-${CONTAINERS_HELPER_BINARY_DIR}/podman}
+# Timeout for streamed responses
+CURL_TIMEOUT=0
+
# Cleanup handlers
clean_up_server() {
if [ -n "$service_pid" ]; then
@@ -217,6 +220,21 @@ function jsonify() {
}
#######
+# t_timeout # Timeout wrapper for test helper
+#######
+function t_timeout() {
+ CURL_TIMEOUT=$1; shift
+ local min_runtime=$((CURL_TIMEOUT - 1))
+ start=`date +%s`
+ t $@
+ local end=`date +%s`
+ local runtime=$((end-start))
+ if ! [[ "$runtime" -ge "$min_runtime" ]]; then
+ die "Error: Streaming time should be greater or equal to '$min_runtime'"
+ fi
+}
+
+#######
# t # Main test helper
#######
function t() {
@@ -226,6 +244,12 @@ function t() {
local content_type="application/json"
local testname="$method $path"
+
+ if [[ $CURL_TIMEOUT != 0 ]]; then
+ local c_timeout=$CURL_TIMEOUT
+ curl_args+=("-m $CURL_TIMEOUT")
+ CURL_TIMEOUT=0 # 'consume' timeout
+ fi
# POST and PUT requests may be followed by one or more key=value pairs.
# Slurp the command line until we see a 3-digit status code.
if [[ $method = "POST" || $method == "PUT" ]]; then
@@ -291,7 +315,7 @@ function t() {
-o $WORKDIR/curl.result.out "$url"); rc=$?; } || :
# Any error from curl is instant bad news, from which we can't recover
- if [[ $rc -ne 0 ]]; then
+ if [[ $rc -ne 0 ]] && [[ $c_timeout -eq 0 ]]; then
die "curl failure ($rc) on $url - cannot continue"
fi
diff --git a/test/e2e/pod_clone_test.go b/test/e2e/pod_clone_test.go
index b90bf10da..0a1d2358c 100644
--- a/test/e2e/pod_clone_test.go
+++ b/test/e2e/pod_clone_test.go
@@ -11,9 +11,10 @@ import (
var _ = Describe("Podman pod clone", func() {
var (
- tempdir string
- err error
- podmanTest *PodmanTestIntegration
+ tempdir string
+ err error
+ podmanTest *PodmanTestIntegration
+ hostname, _ = os.Hostname()
)
BeforeEach(func() {
@@ -155,4 +156,39 @@ var _ = Describe("Podman pod clone", func() {
Expect(strings[0]).Should(ContainSubstring("size=10240k"))
})
+ It("podman pod create --uts test", func() {
+ SkipIfRemote("hostname for the custom NS test is not as expected on the remote client")
+
+ session := podmanTest.Podman([]string{"pod", "create"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"pod", "clone", "--uts", "host", session.OutputToString()})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"run", "-it", "--pod", session.OutputToString(), ALPINE, "printenv", "HOSTNAME"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring(hostname))
+
+ podName := "utsPod"
+ ns := "ns:/proc/self/ns/"
+
+ session = podmanTest.Podman([]string{"pod", "create"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ // just share uts with a custom path
+ podCreate := podmanTest.Podman([]string{"pod", "clone", "--uts", ns, "--name", podName, session.OutputToString()})
+ podCreate.WaitWithDefaultTimeout()
+ Expect(podCreate).Should(Exit(0))
+
+ podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
+ podInspect.WaitWithDefaultTimeout()
+ Expect(podInspect).Should(Exit(0))
+ podJSON := podInspect.InspectPodToJSON()
+ Expect(podJSON.InfraConfig).To(HaveField("UtsNS", ns))
+ })
+
})
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index 0e363c1fb..10a8d52b5 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -23,9 +23,10 @@ import (
var _ = Describe("Podman pod create", func() {
var (
- tempdir string
- err error
- podmanTest *PodmanTestIntegration
+ tempdir string
+ err error
+ podmanTest *PodmanTestIntegration
+ hostname, _ = os.Hostname()
)
BeforeEach(func() {
@@ -1136,4 +1137,30 @@ ENTRYPOINT ["sleep","99999"]
Expect(run).ShouldNot(Exit(0))
})
+ It("podman pod create --uts test", func() {
+ session := podmanTest.Podman([]string{"pod", "create", "--uts", "host"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"run", "-it", "--pod", session.OutputToString(), ALPINE, "printenv", "HOSTNAME"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ if !IsRemote() { // remote hostname will not match os.Hostname()
+ Expect(session.OutputToString()).To(ContainSubstring(hostname))
+ }
+
+ podName := "utsPod"
+ ns := "ns:/proc/self/ns/"
+
+ // just share uts with a custom path
+ podCreate := podmanTest.Podman([]string{"pod", "create", "--uts", ns, "--name", podName, "--share", "uts"})
+ podCreate.WaitWithDefaultTimeout()
+ Expect(podCreate).Should(Exit(0))
+
+ podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
+ podInspect.WaitWithDefaultTimeout()
+ Expect(podInspect).Should(Exit(0))
+ podJSON := podInspect.InspectPodToJSON()
+ Expect(podJSON.InfraConfig).To(HaveField("UtsNS", ns))
+ })
})
diff --git a/utils/utils.go b/utils/utils.go
index a20181b0a..997de150d 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -13,7 +13,6 @@ import (
"sync"
"github.com/containers/common/pkg/cgroups"
- "github.com/containers/podman/v4/libpod/define"
"github.com/containers/storage/pkg/archive"
"github.com/godbus/dbus/v5"
"github.com/sirupsen/logrus"
@@ -52,57 +51,6 @@ func ExecCmdWithStdStreams(stdin io.Reader, stdout, stderr io.Writer, env []stri
return nil
}
-// ErrDetach is an error indicating that the user manually detached from the
-// container.
-var ErrDetach = define.ErrDetach
-
-// CopyDetachable is similar to io.Copy but support a detach key sequence to break out.
-func CopyDetachable(dst io.Writer, src io.Reader, keys []byte) (written int64, err error) {
- buf := make([]byte, 32*1024)
- for {
- nr, er := src.Read(buf)
- if nr > 0 {
- preservBuf := []byte{}
- for i, key := range keys {
- preservBuf = append(preservBuf, buf[0:nr]...)
- if nr != 1 || buf[0] != key {
- break
- }
- if i == len(keys)-1 {
- return 0, ErrDetach
- }
- nr, er = src.Read(buf)
- }
- var nw int
- var ew error
- if len(preservBuf) > 0 {
- nw, ew = dst.Write(preservBuf)
- nr = len(preservBuf)
- } else {
- nw, ew = dst.Write(buf[0:nr])
- }
- if nw > 0 {
- written += int64(nw)
- }
- if ew != nil {
- err = ew
- break
- }
- if nr != nw {
- err = io.ErrShortWrite
- break
- }
- }
- if er != nil {
- if er != io.EOF {
- err = er
- }
- break
- }
- }
- return written, err
-}
-
// UntarToFileSystem untars an os.file of a tarball to a destination in the filesystem
func UntarToFileSystem(dest string, tarball *os.File, options *archive.TarOptions) error {
logrus.Debugf("untarring %s", tarball.Name())
diff --git a/pkg/kubeutils/resize.go b/vendor/github.com/containers/common/pkg/resize/resize.go
index a744c66cc..9a2afcf73 100644
--- a/pkg/kubeutils/resize.go
+++ b/vendor/github.com/containers/common/pkg/resize/resize.go
@@ -14,16 +14,18 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package kubeutils
+package resize
-import (
- "github.com/containers/podman/v4/libpod/define"
-)
+// TerminalSize represents the width and height of a terminal.
+type TerminalSize struct {
+ Width uint16
+ Height uint16
+}
// HandleResizing spawns a goroutine that processes the resize channel, calling resizeFunc for each
-// remotecommand.TerminalSize received from the channel. The resize channel must be closed elsewhere to stop the
+// TerminalSize received from the channel. The resize channel must be closed elsewhere to stop the
// goroutine.
-func HandleResizing(resize <-chan define.TerminalSize, resizeFunc func(size define.TerminalSize)) {
+func HandleResizing(resize <-chan TerminalSize, resizeFunc func(size TerminalSize)) {
if resize == nil {
return
}
diff --git a/vendor/github.com/containers/common/pkg/util/copy.go b/vendor/github.com/containers/common/pkg/util/copy.go
new file mode 100644
index 000000000..a45b82fc9
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/util/copy.go
@@ -0,0 +1,57 @@
+package util
+
+import (
+ "errors"
+ "io"
+)
+
+// ErrDetach indicates that an attach session was manually detached by
+// the user.
+var ErrDetach = errors.New("detached from container")
+
+// CopyDetachable is similar to io.Copy but support a detach key sequence to break out.
+func CopyDetachable(dst io.Writer, src io.Reader, keys []byte) (written int64, err error) {
+ buf := make([]byte, 32*1024)
+ for {
+ nr, er := src.Read(buf)
+ if nr > 0 {
+ preservBuf := []byte{}
+ for i, key := range keys {
+ preservBuf = append(preservBuf, buf[0:nr]...)
+ if nr != 1 || buf[0] != key {
+ break
+ }
+ if i == len(keys)-1 {
+ return 0, ErrDetach
+ }
+ nr, er = src.Read(buf)
+ }
+ var nw int
+ var ew error
+ if len(preservBuf) > 0 {
+ nw, ew = dst.Write(preservBuf)
+ nr = len(preservBuf)
+ } else {
+ nw, ew = dst.Write(buf[0:nr])
+ }
+ if nw > 0 {
+ written += int64(nw)
+ }
+ if ew != nil {
+ err = ew
+ break
+ }
+ if nr != nw {
+ err = io.ErrShortWrite
+ break
+ }
+ }
+ if er != nil {
+ if er != io.EOF {
+ err = er
+ }
+ break
+ }
+ }
+ return written, err
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index aaddcaeb0..fa7a963cd 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -111,7 +111,7 @@ github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/util
-# github.com/containers/common v0.48.1-0.20220630172158-178929cf063e
+# github.com/containers/common v0.48.1-0.20220705175712-dd1c331887b9
## explicit
github.com/containers/common/libimage
github.com/containers/common/libimage/define
@@ -142,6 +142,7 @@ github.com/containers/common/pkg/netns
github.com/containers/common/pkg/parse
github.com/containers/common/pkg/report
github.com/containers/common/pkg/report/camelcase
+github.com/containers/common/pkg/resize
github.com/containers/common/pkg/retry
github.com/containers/common/pkg/seccomp
github.com/containers/common/pkg/secrets