aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create.go3
-rw-r--r--cmd/podman/common/create_opts.go4
-rw-r--r--cmd/podman/containers/start.go3
-rw-r--r--cmd/podman/system/connection/list.go8
-rw-r--r--contrib/systemd/system/podman-restart.service.in3
-rw-r--r--docs/source/markdown/podman-create.1.md17
-rw-r--r--docs/source/markdown/podman-pod-rm.1.md2
-rw-r--r--docs/source/markdown/podman-run.1.md19
-rw-r--r--docs/source/markdown/podman-system-connection-list.1.md8
-rw-r--r--docs/source/markdown/podman-system-connection.1.md4
-rw-r--r--libpod/container_internal.go25
-rw-r--r--libpod/container_log_linux.go6
-rw-r--r--libpod/runtime_pod_linux.go12
-rw-r--r--pkg/api/handlers/compat/images_tag.go5
-rw-r--r--pkg/domain/infra/abi/images.go4
-rw-r--r--pkg/specgenutil/specgen.go12
-rw-r--r--test/e2e/manifest_test.go19
-rw-r--r--test/e2e/pod_rm_test.go17
-rw-r--r--test/e2e/run_test.go12
-rw-r--r--test/e2e/system_connection_test.go4
-rw-r--r--test/system/001-basic.bats21
-rw-r--r--test/system/015-help.bats6
-rw-r--r--test/system/030-run.bats5
-rw-r--r--test/system/045-start.bats4
-rw-r--r--test/system/272-system-connection.bats159
25 files changed, 317 insertions, 65 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index a3ff37c19..6270bad16 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -319,6 +319,9 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
"Kernel memory limit "+sizeWithUnitFormat,
)
_ = cmd.RegisterFlagCompletionFunc(kernelMemoryFlagName, completion.AutocompleteNone)
+ // kernel-memory is deprecated in the runtime spec.
+ _ = createFlags.MarkHidden("kernel-memory")
+
logDriverFlagName := "log-driver"
createFlags.StringVar(
&cf.LogDriver,
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 50d7c446d..223a91331 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -18,6 +18,7 @@ import (
"github.com/containers/podman/v3/pkg/specgen"
"github.com/docker/docker/api/types/mount"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
func stringMaptoArray(m map[string]string) []string {
@@ -383,6 +384,9 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
if cc.HostConfig.Memory > 0 {
cliOpts.Memory = strconv.Itoa(int(cc.HostConfig.Memory))
}
+ if cc.HostConfig.KernelMemory > 0 {
+ logrus.Warnf("The --kernel-memory flag has been deprecated. May not work properly on your system.")
+ }
if cc.HostConfig.MemoryReservation > 0 {
cliOpts.MemoryReservation = strconv.Itoa(int(cc.HostConfig.MemoryReservation))
diff --git a/cmd/podman/containers/start.go b/cmd/podman/containers/start.go
index 1163b9093..8813fc273 100644
--- a/cmd/podman/containers/start.go
+++ b/cmd/podman/containers/start.go
@@ -87,6 +87,9 @@ func validateStart(cmd *cobra.Command, args []string) error {
if len(args) == 0 && !startOptions.Latest && !startOptions.All {
return errors.New("start requires at least one argument")
}
+ if startOptions.All && startOptions.Latest {
+ return errors.Errorf("--all and --latest cannot be used together")
+ }
if len(args) > 0 && startOptions.Latest {
return errors.Errorf("--latest and containers cannot be used together")
}
diff --git a/cmd/podman/system/connection/list.go b/cmd/podman/system/connection/list.go
index de85ce3fa..a3290e3d6 100644
--- a/cmd/podman/system/connection/list.go
+++ b/cmd/podman/system/connection/list.go
@@ -44,6 +44,7 @@ func init() {
type namedDestination struct {
Name string
config.Destination
+ Default bool
}
func list(cmd *cobra.Command, _ []string) error {
@@ -60,12 +61,14 @@ func list(cmd *cobra.Command, _ []string) error {
"Identity": "Identity",
"Name": "Name",
"URI": "URI",
+ "Default": "Default",
}}
rows := make([]namedDestination, 0)
for k, v := range cfg.Engine.ServiceDestinations {
+ def := false
if k == cfg.Engine.ActiveService {
- k += "*"
+ def = true
}
r := namedDestination{
@@ -74,6 +77,7 @@ func list(cmd *cobra.Command, _ []string) error {
Identity: v.Identity,
URI: v.URI,
},
+ Default: def,
}
rows = append(rows, r)
}
@@ -82,7 +86,7 @@ func list(cmd *cobra.Command, _ []string) error {
return rows[i].Name < rows[j].Name
})
- format := "{{.Name}}\t{{.Identity}}\t{{.URI}}\n"
+ format := "{{.Name}}\t{{.URI}}\t{{.Identity}}\t{{.Default}}\n"
switch {
case report.IsJSON(cmd.Flag("format").Value.String()):
buf, err := registry.JSONLibrary().MarshalIndent(rows, "", " ")
diff --git a/contrib/systemd/system/podman-restart.service.in b/contrib/systemd/system/podman-restart.service.in
index a2951e111..46193e2c6 100644
--- a/contrib/systemd/system/podman-restart.service.in
+++ b/contrib/systemd/system/podman-restart.service.in
@@ -5,8 +5,9 @@ StartLimitIntervalSec=0
[Service]
Type=oneshot
+RemainAfterExit=true
Environment=LOGGING="--log-level=info"
ExecStart=@@PODMAN@@ $LOGGING start --all --filter restart-policy=always
[Install]
-WantedBy=multi-user.target
+WantedBy=multi-user.target default.target
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index ee52bfd13..ca104cb4e 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -487,18 +487,6 @@ Default is to create a private IPC namespace (POSIX SysV IPC) for the container
`host`: use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.
`ns:<path>` path to an IPC namespace to join.
-#### **--kernel-memory**=*number[unit]*
-
-Kernel memory limit (format: `<number>[<unit>]`, where unit = b (bytes), k (kilobytes), m (megabytes), or g (gigabytes))
-
-Constrains the kernel memory available to a container. If a limit of 0
-is specified (not using `--kernel-memory`), the container's kernel memory
-is not limited. If you specify a limit, it may be rounded up to a multiple
-of the operating system's page size and the value can be very large,
-millions of trillions.
-
-This flag is not supported on cgroups V2 systems.
-
#### **--label**, **-l**=*label*
Add metadata to a container (e.g., --label com.example.key=value)
@@ -515,6 +503,11 @@ Not implemented
Logging driver for the container. Currently available options are *k8s-file*, *journald*, *none* and *passthrough*, with *json-file* aliased to *k8s-file* for scripting compatibility.
+The podman info command below will display the default log-driver for the system.
+```
+$ podman info --format '{{ .Host.LogDriver }}'
+journald
+```
The *passthrough* driver passes down the standard streams (stdin, stdout, stderr) to the
container. It is not allowed with the remote Podman client and on a tty, since it is
vulnerable to attacks via TIOCSTI.
diff --git a/docs/source/markdown/podman-pod-rm.1.md b/docs/source/markdown/podman-pod-rm.1.md
index eac40ef62..fc834a69c 100644
--- a/docs/source/markdown/podman-pod-rm.1.md
+++ b/docs/source/markdown/podman-pod-rm.1.md
@@ -7,7 +7,7 @@ podman\-pod\-rm - Remove one or more stopped pods and containers
**podman pod rm** [*options*] *pod*
## DESCRIPTION
-**podman pod rm** will remove one or more stopped pods and their containers from the host. The pod name or ID can be used. The \-f option stops all containers and then removes them before removing the pod.
+**podman pod rm** will remove one or more stopped pods and their containers from the host. The pod name or ID can be used. The \-f option stops all containers and then removes them before removing the pod. If all containers added by the user are in an exited state, the pod will be removed.
## OPTIONS
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 5cc17f470..d0b111037 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -512,18 +512,6 @@ a private IPC namespace.
- **host**: use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.
- **ns:**_path_: path to an IPC namespace to join.
-#### **--kernel-memory**=_number_[_unit_]
-
-Kernel memory limit. A _unit_ can be **b** (bytes), **k** (kilobytes), **m** (megabytes), or **g** (gigabytes).
-
-Constrains the kernel memory available to a container. If a limit of 0
-is specified (not using *--kernel-memory*), the container's kernel memory
-is not limited. If you specify a limit, it may be rounded up to a multiple
-of the operating system's page size and the value can be very large,
-millions of trillions.
-
-This flag is not supported on cgroups V2 systems.
-
#### **--label**, **-l**=*key*=*value*
Add metadata to a container.
@@ -538,8 +526,13 @@ Not implemented.
#### **--log-driver**="*driver*"
-Logging driver for the container. Currently available options are **k8s-file**, **journald**, **none** and **passthrough**, with **json-file** aliased to **k8s-file** for scripting compatibility.
+Logging driver for the container. Currently available options are **k8s-file**, **journald**, **none** and **passthrough**, with **json-file** aliased to **k8s-file** for scripting compatibility. (Default journald)
+The podman info command below will display the default log-driver for the system.
+```
+$ podman info --format '{{ .Host.LogDriver }}'
+journald
+```
The **passthrough** driver passes down the standard streams (stdin, stdout, stderr) to the
container. It is not allowed with the remote Podman client and on a tty, since it is
vulnerable to attacks via TIOCSTI.
diff --git a/docs/source/markdown/podman-system-connection-list.1.md b/docs/source/markdown/podman-system-connection-list.1.md
index 6b25a045d..4dc85dd98 100644
--- a/docs/source/markdown/podman-system-connection-list.1.md
+++ b/docs/source/markdown/podman-system-connection-list.1.md
@@ -23,14 +23,14 @@ Valid placeholders for the Go template listed below:
| *.Name* | Connection Name/Identifier |
| *.Identity* | Path to file containing SSH identity |
| *.URI* | URI to podman service. Valid schemes are ssh://[user@]*host*[:port]*Unix domain socket*[?secure=True], unix://*Unix domain socket*, and tcp://localhost[:*port*] |
-
-An asterisk is appended to the default connection.
+| *.Default* | Indicates whether connection is the default |
## EXAMPLE
```
$ podman system connection list
-Name URI Identity
-devl ssh://root@example.com/run/podman/podman.sock ~/.ssh/id_rsa
+Name URI Identity Default
+devl ssh://root@example.com:/run/podman/podman.sock ~/.ssh/id_rsa True
+devl ssh://user@example.com:/run/user/1000/podman/podman.sock ~/.ssh/id_rsa False
```
## SEE ALSO
podman-system(1) , containers.conf(5)
diff --git a/docs/source/markdown/podman-system-connection.1.md b/docs/source/markdown/podman-system-connection.1.md
index 6cd4a5fa8..b00a2aec3 100644
--- a/docs/source/markdown/podman-system-connection.1.md
+++ b/docs/source/markdown/podman-system-connection.1.md
@@ -24,8 +24,8 @@ The user will be prompted for the ssh login password or key file pass phrase as
## EXAMPLE
```
$ podman system connection list
-Name URI Identity
-devl ssh://root@example.com/run/podman/podman.sock ~/.ssh/id_rsa
+Name URI Identity Default
+devl ssh://root@example.com/run/podman/podman.sock ~/.ssh/id_rsa true
```
## SEE ALSO
podman-system(1) , containers.conf(5)
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 4e8074840..43f5398a2 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -17,12 +17,14 @@ import (
"github.com/containers/buildah/copier"
"github.com/containers/buildah/pkg/overlay"
butil "github.com/containers/buildah/util"
+ "github.com/containers/common/pkg/chown"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/events"
"github.com/containers/podman/v3/pkg/cgroups"
"github.com/containers/podman/v3/pkg/ctime"
"github.com/containers/podman/v3/pkg/hooks"
"github.com/containers/podman/v3/pkg/hooks/exec"
+ "github.com/containers/podman/v3/pkg/lookup"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/selinux"
"github.com/containers/podman/v3/pkg/util"
@@ -485,8 +487,12 @@ func (c *Container) setupStorage(ctx context.Context) error {
return errors.Wrapf(err, "error creating container storage")
}
- c.config.IDMappings.UIDMap = containerInfo.UIDMap
- c.config.IDMappings.GIDMap = containerInfo.GIDMap
+ // only reconfig IDMappings if layer was mounted from storage
+ // if its a external overlay do not reset IDmappings
+ if !c.config.RootfsOverlay {
+ c.config.IDMappings.UIDMap = containerInfo.UIDMap
+ c.config.IDMappings.GIDMap = containerInfo.GIDMap
+ }
processLabel, err := c.processLabel(containerInfo.ProcessLabel)
if err != nil {
@@ -1515,6 +1521,19 @@ func (c *Container) mountStorage() (_ string, deferredErr error) {
}
mountPoint = overlayMount.Source
+ execUser, err := lookup.GetUserGroupInfo(mountPoint, c.config.User, nil)
+ if err != nil {
+ return "", err
+ }
+ hostUID, hostGID, err := butil.GetHostIDs(util.IDtoolsToRuntimeSpec(c.config.IDMappings.UIDMap), util.IDtoolsToRuntimeSpec(c.config.IDMappings.GIDMap), uint32(execUser.Uid), uint32(execUser.Gid))
+ if err != nil {
+ return "", errors.Wrap(err, "unable to get host UID and host GID")
+ }
+
+ //note: this should not be recursive, if using external rootfs users should be responsible on configuring ownership.
+ if err := chown.ChangeHostPathOwnership(mountPoint, false, int(hostUID), int(hostGID)); err != nil {
+ return "", err
+ }
}
if mountPoint == "" {
@@ -2084,7 +2103,7 @@ func (c *Container) checkReadyForRemoval() error {
return errors.Wrapf(define.ErrCtrStateInvalid, "container %s is in invalid state", c.ID())
}
- if c.ensureState(define.ContainerStateRunning, define.ContainerStatePaused) {
+ if c.ensureState(define.ContainerStateRunning, define.ContainerStatePaused) && !c.IsInfra() {
return errors.Wrapf(define.ErrCtrStateInvalid, "cannot remove container %s as it is %s - running or paused containers cannot be removed without force", c.ID(), c.state.State.String())
}
diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index ca1e11ef5..562169ce2 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -91,8 +91,12 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
var cursorError error
for i := 1; i <= 3; i++ {
cursor, cursorError = journal.GetCursor()
+ hundreds := 1
+ for j := 1; j < i; j++ {
+ hundreds *= 2
+ }
if cursorError != nil {
- time.Sleep(time.Duration(i*100) * time.Millisecond)
+ time.Sleep(time.Duration(hundreds*100) * time.Millisecond)
continue
}
break
diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go
index 9c6f1539f..7d7fef4d1 100644
--- a/libpod/runtime_pod_linux.go
+++ b/libpod/runtime_pod_linux.go
@@ -177,10 +177,9 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
if err != nil {
return err
}
-
numCtrs := len(ctrs)
- // If the only container in the pod is the pause container, remove the pod and container unconditionally.
+ // If the only running container in the pod is the pause container, remove the pod and container unconditionally.
pauseCtrID := p.state.InfraContainerID
if numCtrs == 1 && ctrs[0].ID() == pauseCtrID {
removeCtrs = true
@@ -264,6 +263,15 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
}
}
+ // Clear infra container ID before we remove the infra container.
+ // There is a potential issue if we don't do that, and removal is
+ // interrupted between RemoveAllContainers() below and the pod's removal
+ // later - we end up with a reference to a nonexistent infra container.
+ p.state.InfraContainerID = ""
+ if err := p.save(); err != nil {
+ return err
+ }
+
// Remove all containers in the pod from the state.
if err := r.state.RemovePodContainers(p); err != nil {
// If this fails, there isn't much more we can do.
diff --git a/pkg/api/handlers/compat/images_tag.go b/pkg/api/handlers/compat/images_tag.go
index 7858298be..5d413a821 100644
--- a/pkg/api/handlers/compat/images_tag.go
+++ b/pkg/api/handlers/compat/images_tag.go
@@ -4,6 +4,7 @@ import (
"fmt"
"net/http"
+ "github.com/containers/common/libimage"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
api "github.com/containers/podman/v3/pkg/api/types"
@@ -16,7 +17,9 @@ func TagImage(w http.ResponseWriter, r *http.Request) {
// /v1.xx/images/(name)/tag
name := utils.GetName(r)
- newImage, _, err := runtime.LibimageRuntime().LookupImage(name, nil)
+ // Allow tagging manifest list instead of resolving instances from manifest
+ lookupOptions := &libimage.LookupImageOptions{ManifestList: true}
+ newImage, _, err := runtime.LibimageRuntime().LookupImage(name, lookupOptions)
if err != nil {
utils.ImageNotFound(w, name, errors.Wrapf(err, "failed to find image %s", name))
return
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index d2222c017..8878bf128 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -331,7 +331,9 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri
}
func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, options entities.ImageTagOptions) error {
- image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, nil)
+ // Allow tagging manifest list instead of resolving instances from manifest
+ lookupOptions := &libimage.LookupImageOptions{ManifestList: true}
+ image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, lookupOptions)
if err != nil {
return err
}
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 6a6397257..8007e5d8e 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -133,12 +133,14 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOption
if err != nil {
return nil, errors.Wrapf(err, "invalid value for memory")
}
- memory.Limit = &ml
- if c.MemorySwap == "" {
- limit := 2 * ml
- memory.Swap = &(limit)
+ if ml > 0 {
+ memory.Limit = &ml
+ if c.MemorySwap == "" {
+ limit := 2 * ml
+ memory.Swap = &(limit)
+ }
+ hasLimits = true
}
- hasLimits = true
}
if m := c.MemoryReservation; len(m) > 0 {
mr, err := units.RAMInBytes(m)
diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go
index 27aaaba48..5978214ff 100644
--- a/test/e2e/manifest_test.go
+++ b/test/e2e/manifest_test.go
@@ -93,6 +93,25 @@ var _ = Describe("Podman manifest", func() {
Expect(session.OutputToString()).To(ContainSubstring(imageListARM64InstanceDigest))
})
+ It("podman manifest tag", func() {
+ session := podmanTest.Podman([]string{"manifest", "create", "foobar"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ session = podmanTest.Podman([]string{"manifest", "add", "foobar", "quay.io/libpod/busybox"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ session = podmanTest.Podman([]string{"tag", "foobar", "foobar2"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ session = podmanTest.Podman([]string{"manifest", "inspect", "foobar"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ session2 := podmanTest.Podman([]string{"manifest", "inspect", "foobar2"})
+ session2.WaitWithDefaultTimeout()
+ Expect(session2).Should(Exit(0))
+ Expect(session2.OutputToString()).To(Equal(session.OutputToString()))
+ })
+
It("podman manifest add --all", func() {
session := podmanTest.Podman([]string{"manifest", "create", "foo"})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go
index 6a8ac72fb..7dc3dfa7f 100644
--- a/test/e2e/pod_rm_test.go
+++ b/test/e2e/pod_rm_test.go
@@ -301,4 +301,21 @@ var _ = Describe("Podman pod rm", func() {
Expect(session).Should(Exit(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
})
+
+ It("podman pod rm with exited containers", func() {
+ _, ec, podid := podmanTest.CreatePod(nil)
+ Expect(ec).To(Equal(0))
+
+ session := podmanTest.Podman([]string{"run", "--pod", podid, ALPINE})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"run", "--pod", podid, ALPINE})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ result := podmanTest.Podman([]string{"pod", "rm", podid})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(0))
+ })
})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index f40d4a749..8502879ff 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -259,6 +259,18 @@ var _ = Describe("Podman run", func() {
startsession.WaitWithDefaultTimeout()
Expect(startsession).Should(Exit(0))
Expect(startsession.OutputToString()).To(Equal("hello"))
+
+ // remove container for above test overlay-foo
+ osession = podmanTest.Podman([]string{"rm", "overlay-foo"})
+ osession.WaitWithDefaultTimeout()
+ Expect(osession).Should(Exit(0))
+
+ // Test --rootfs with an external overlay with --uidmap
+ osession = podmanTest.Podman([]string{"run", "--uidmap", "0:1000:1000", "--rm", "--security-opt", "label=disable",
+ "--rootfs", rootfs + ":O", "echo", "hello"})
+ osession.WaitWithDefaultTimeout()
+ Expect(osession).Should(Exit(0))
+ Expect(osession.OutputToString()).To(Equal("hello"))
})
It("podman run a container with --init", func() {
diff --git a/test/e2e/system_connection_test.go b/test/e2e/system_connection_test.go
index 6cdb78c5e..842ae8df6 100644
--- a/test/e2e/system_connection_test.go
+++ b/test/e2e/system_connection_test.go
@@ -208,13 +208,13 @@ var _ = Describe("podman system connection", func() {
session = podmanTest.Podman(cmd)
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- Expect(session.Out).Should(Say("Name *Identity *URI"))
+ Expect(session.Out).Should(Say("Name *URI *Identity *Default"))
cmd = []string{"system", "connection", "list", "--format", "{{.Name}}"}
session = podmanTest.Podman(cmd)
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- Expect(session.OutputToString()).Should(Equal("devl* qe"))
+ Expect(session.OutputToString()).Should(Equal("devl qe"))
})
It("failed default", func() {
diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats
index 50735f576..78b8ecdfd 100644
--- a/test/system/001-basic.bats
+++ b/test/system/001-basic.bats
@@ -94,22 +94,21 @@ function setup() {
}
@test "podman-remote: defaults" {
- if is_remote; then
- skip "only applicable on a local run"
- fi
+ skip_if_remote "only applicable on a local run"
+
+ # By default, podman should include '--remote' in its help output
+ run_podman --help
+ is "$output" ".* --remote " "podman --help includes the --remote option"
+ # When it detects CONTAINER_HOST or _CONNECTION, --remote is not an option
CONTAINER_HOST=foobar run_podman --help
- # Should not have --remote flag
- echo $output | grep -v -qw -- "--remote"
- if [ $? -ne 0 ]; then
- die "Should not have --remote flag"
+ if grep -- " --remote " <<<"$output"; then
+ die "podman --help, with CONTAINER_HOST set, is showing --remote"
fi
CONTAINER_CONNECTION=foobar run_podman --help
- # Should not have --remote flag
- echo $output | grep -v -qw -- "--remote"
- if [ $? -ne 0 ]; then
- die "Should not have --remote flag"
+ if grep -- " --remote " <<<"$output"; then
+ die "podman --help, with CONTAINER_CONNECTION set, is showing --remote"
fi
}
diff --git a/test/system/015-help.bats b/test/system/015-help.bats
index 5f38c34a1..b0795b524 100644
--- a/test/system/015-help.bats
+++ b/test/system/015-help.bats
@@ -86,6 +86,12 @@ function check_help() {
run_podman 125 "$@" $cmd -l nonexistent-container
is "$output" "Error: .*--latest and \(containers\|pods\|arguments\) cannot be used together" \
"'$command_string' with both -l and container"
+
+ # Combine -l and -a, too (but spell it as --all, because "-a"
+ # means "attach" in podman container start)
+ run_podman 125 "$@" $cmd --all --latest
+ is "$output" "Error: \(--all and --latest cannot be used together\|--all, --latest and containers cannot be used together\|--all, --latest and arguments cannot be used together\|unknown flag\)" \
+ "'$command_string' with both --all and --latest"
fi
fi
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index 44c2ee509..2c8d08b99 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -67,6 +67,11 @@ echo $rand | 0 | $rand
is "$output" ".*invalidflag" "failed when passing undefined flags to the runtime"
}
+@test "podman run --memory=0 runtime option" {
+ run_podman run --memory=0 --rm $IMAGE echo hello
+ is "$output" "hello" "failed to run when --memory is set to 0"
+}
+
# 'run --preserve-fds' passes a number of additional file descriptors into the container
@test "podman run --preserve-fds" {
skip_if_remote "preserve-fds is meaningless over remote"
diff --git a/test/system/045-start.bats b/test/system/045-start.bats
index 7e4bbde8d..2ea057cd3 100644
--- a/test/system/045-start.bats
+++ b/test/system/045-start.bats
@@ -36,10 +36,6 @@ load helpers
expected="Error: either start all containers or the container(s) provided in the arguments"
run_podman 125 start --all 12333
is "$output" "$expected" "start --all, with args, throws error"
- if ! is_remote; then
- run_podman 125 start --all --latest
- is "$output" "$expected" "podman start --all --latest"
- fi
}
@test "podman start --filter - start only containers that match the filter" {
diff --git a/test/system/272-system-connection.bats b/test/system/272-system-connection.bats
new file mode 100644
index 000000000..5a90d9398
--- /dev/null
+++ b/test/system/272-system-connection.bats
@@ -0,0 +1,159 @@
+#!/usr/bin/env bats -*- bats -*-
+#
+# tests for podman system connection
+#
+
+load helpers
+
+# This will be set if we start a local service
+_SERVICE_PID=
+
+function setup() {
+ if ! is_remote; then
+ skip "only applicable when running remote"
+ fi
+
+ basic_setup
+}
+
+function teardown() {
+ if ! is_remote; then
+ return
+ fi
+
+ # In case test function failed to clean up
+ if [[ -n $_SERVICE_PID ]]; then
+ run kill $_SERVICE_PID
+ fi
+
+ # Aaaaargh! When running as root, 'system service' creates a tmpfs
+ # mount on $root/overlay. This in turn causes cleanup to fail.
+ mount \
+ | grep $PODMAN_TMPDIR \
+ | awk '{print $3}' \
+ | xargs -l1 --no-run-if-empty umount
+
+ # Remove all system connections
+ run_podman system connection ls --format json
+ while read name; do
+ run_podman system connection rm "$name"
+ done < <(jq -r '.[].Name' <<<"$output")
+
+ basic_teardown
+}
+
+# Helper function: invokes $PODMAN (which is podman-remote) _without_ --url opt
+#
+# Needed because, in CI, PODMAN="/path/to/podman-remote --url /path/to/socket"
+# which of course overrides podman's detection and use of a connection.
+function _run_podman_remote() {
+ PODMAN=${PODMAN%%--url*} run_podman "$@"
+}
+
+# Very basic test, does not actually connect at any time
+@test "podman system connection - basic add / ls / remove" {
+ run_podman system connection ls
+ is "$output" "" "system connection ls: no connections"
+
+ c1="c1_$(random_string 15)"
+ c2="c2_$(random_string 15)"
+
+ run_podman system connection add $c1 tcp://localhost:12345
+ run_podman system connection add --default $c2 tcp://localhost:54321
+ run_podman system connection ls
+ is "$output" \
+ ".*$c1[ ]\+tcp://localhost:12345[ ]\+false
+$c2[ ]\+tcp://localhost:54321[ ]\+true" \
+ "system connection ls"
+
+ # Remove default connection; the remaining one should still not be default
+ run_podman system connection rm $c2
+ run_podman system connection ls
+ is "$output" ".*$c1[ ]\+tcp://localhost:12345[ ]\+false" \
+ "system connection ls (after removing default connection)"
+
+ run_podman system connection rm $c1
+}
+
+# Test tcp socket; requires starting a local server
+@test "podman system connection - tcp" {
+ # Start server
+ _SERVICE_PORT=$(random_free_port 63000-64999)
+
+ # Add the connection, and run podman info *before* starting the service.
+ # This should fail.
+ run_podman system connection add myconnect tcp://localhost:$_SERVICE_PORT
+ # IMPORTANT NOTE: in CI, podman-remote is tested by setting PODMAN
+ # to "podman-remote --url sdfsdf". This of course overrides the default
+ # podman-remote action. Our solution: strip off the "--url xyz" part
+ # when invoking podman.
+ _run_podman_remote 125 info
+ is "$output" \
+ "Cannot connect to Podman. Please verify.*dial tcp.*connection refused" \
+ "podman info, without active service"
+
+ # Start service. Now podman info should work fine. The %%-remote*
+ # converts "podman-remote --opts" to just "podman", which is what
+ # we need for the server.
+ ${PODMAN%%-remote*} --root ${PODMAN_TMPDIR}/root \
+ --runroot ${PODMAN_TMPDIR}/runroot \
+ system service -t 99 tcp:localhost:$_SERVICE_PORT &
+ _SERVICE_PID=$!
+ wait_for_port localhost $_SERVICE_PORT
+
+ # FIXME: #12023, RemoteSocket is always /run/something
+# run_podman info --format '{{.Host.RemoteSocket.Path}}'
+# is "$output" "tcp:localhost:$_SERVICE_PORT" \
+# "podman info works, and talks to the correct server"
+
+ _run_podman_remote info --format '{{.Store.GraphRoot}}'
+ is "$output" "${PODMAN_TMPDIR}/root" \
+ "podman info, talks to the right service"
+
+ # Add another connection; make sure it does not get set as default
+ _run_podman_remote system connection add fakeconnect tcp://localhost:$(( _SERVICE_PORT + 1))
+ _run_podman_remote info --format '{{.Store.GraphRoot}}'
+ # (Don't bother checking output; we just care about exit status)
+
+ # Stop server. Use 'run' to avoid failing on nonzero exit status
+ run kill $_SERVICE_PID
+ run wait $_SERVICE_PID
+ _SERVICE_PID=
+
+ run_podman system connection rm fakeconnect
+ run_podman system connection rm myconnect
+}
+
+# If we have ssh access to localhost (unlikely in CI), test that.
+@test "podman system connection - ssh" {
+ rand=$(random_string 20)
+ echo $rand >$PODMAN_TMPDIR/testfile
+
+ # Can we actually ssh to localhost?
+ run ssh -q -o BatchMode=yes \
+ -o UserKnownHostsFile=/dev/null \
+ -o StrictHostKeyChecking=no \
+ -o CheckHostIP=no \
+ localhost \
+ cat $PODMAN_TMPDIR/testfile
+ test "$status" -eq 0 || skip "cannot ssh to localhost"
+ is "$output" "$rand" "weird! ssh worked, but could not cat local file"
+
+ # OK, ssh works.
+ # Create a new connection, over ssh, but using existing socket file
+ # (Remember, we're already podman-remote, there's a service running)
+ run_podman info --format '{{.Host.RemoteSocket.Path}}'
+ local socketpath="$output"
+ run_podman system connection add --socket-path "$socketpath" \
+ mysshcon ssh://localhost
+ is "$output" "" "output from system connection add"
+
+ # debug logs will confirm that we use ssh connection
+ _run_podman_remote --log-level=debug info --format '{{.Host.RemoteSocket.Path}}'
+ is "$output" ".*msg=\"SSH Agent Key .*" "we are truly using ssh"
+
+ # Clean up
+ run_podman system connection rm mysshconn
+}
+
+# vim: filetype=sh