summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--RELEASE_NOTES.md2
-rw-r--r--changelog.txt8
-rw-r--r--contrib/spec/podman.spec.in2
-rw-r--r--test/e2e/play_kube_test.go209
-rw-r--r--test/system/075-exec.bats20
-rw-r--r--test/system/helpers.bash14
-rw-r--r--version/version.go2
8 files changed, 178 insertions, 81 deletions
diff --git a/Makefile b/Makefile
index 413b46fb8..a19d4848f 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ export GOPROXY=https://proxy.golang.org
GO ?= go
DESTDIR ?=
-EPOCH_TEST_COMMIT ?= dc1f8b62b168e0815ed5e7eb7c61a26ec3a0c88c
+EPOCH_TEST_COMMIT ?= 2b0892e757c878cdb087dd22b8986bccef0276ed
HEAD ?= HEAD
CHANGELOG_BASE ?= HEAD~
CHANGELOG_TARGET ?= HEAD
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 0f2e748fa..235871273 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -22,9 +22,11 @@
- Fixed a bug where `podman stats` was broken on systems running CGroups V2 when run rootless ([#4268](https://github.com/containers/libpod/issues/4268))
- Fixed a bug where the `podman start` command would print the short container ID, instead of the full ID
- Fixed a bug where containers created with an OCI runtime that is no longer available (uninstalled or removed from the config file) would not appear in `podman ps` and could not be removed via `podman rm`
+- Fixed a bug where containers restored via `podman container restore --import` would retain the CGroup path of the original container, even if their container ID changed; thus, multiple containers created from the same checkpoint would all share the same CGroup
### Misc
- The default PID limit for containers is now set to 4096. It can be adjusted back to the old default (unlimited) by passing `--pids-limit 0` to `podman create` and `podman run`
+- The `podman start --attach` command now automatically attaches `STDIN` if the container was created with `-i`
- The `podman network create` command now validates network names using the same regular expression as container and pod names
- The `--systemd` flag to `podman run` and `podman create` will now only enable systemd mode when the binary being run inside the container is `/sbin/init`, `/usr/sbin/init`, or ends in `systemd` (previously detected any path ending in `init` or `systemd`)
- Updated vendored Buildah to 1.11.3
diff --git a/changelog.txt b/changelog.txt
index dd3fcec82..615e2a135 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,11 @@
+- Changelog for v1.6.2 (2019-10-17)
+ * Finalize release notes for v1.6.2
+ * rootless: drop dependency on docker
+ * Bump gitvalidation epoch
+ * Bump to v1.6.2-dev
+ * Refactor tests when checking for error exit codes
+ * Attach stdin to container at start if it was created with --interactive
+
- Changelog for v1.6.2-rc1 (2019-10-16)
* Add release notes for Podman 1.6.2
* start: print full container ID
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index bd2cff3f6..d5247f689 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -39,7 +39,7 @@
%global shortcommit_conmon %(c=%{commit_conmon}; echo ${c:0:7})
Name: podman
-Version: 1.6.2
+Version: 1.6.3
Release: #COMMITDATE#.git%{shortcommit0}%{?dist}
Summary: Manage Pods, Containers and Container Images
License: ASL 2.0
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 5d59f0eb0..7069e049d 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -23,7 +23,7 @@ metadata:
spec:
hostname: {{ .Hostname }}
containers:
-{{ with .Containers }}
+{{ with .Ctrs }}
{{ range . }}
- command:
{{ range .Cmd }}
@@ -67,47 +67,128 @@ spec:
status: {}
`
-type Pod struct {
- Name string
- Hostname string
- Containers []Container
-}
-
-type Container struct {
- Cmd []string
- Image string
- Name string
- SecurityContext bool
- Caps bool
- CapAdd []string
- CapDrop []string
-}
+var (
+ defaultCtrName = "testCtr"
+ defaultCtrCmd = []string{"top"}
+ defaultCtrImage = ALPINE
+ defaultPodName = "testPod"
+)
-func generateKubeYaml(name string, hostname string, ctrs []Container, fileName string) error {
+func generateKubeYaml(pod *Pod, fileName string) error {
f, err := os.Create(fileName)
if err != nil {
return err
}
defer f.Close()
- testPod := Pod{name, hostname, ctrs}
t, err := template.New("pod").Parse(yamlTemplate)
if err != nil {
return err
}
- if err := t.Execute(f, testPod); err != nil {
+ if err := t.Execute(f, pod); err != nil {
return err
}
return nil
}
+// Pod describes the options a kube yaml can be configured at pod level
+type Pod struct {
+ Name string
+ Hostname string
+ Ctrs []*Ctr
+}
+
+// getPod takes a list of podOptions and returns a pod with sane defaults
+// and the configured options
+// if no containers are added, it will add the default container
+func getPod(options ...podOption) *Pod {
+ p := Pod{defaultPodName, "", make([]*Ctr, 0)}
+ for _, option := range options {
+ option(&p)
+ }
+ if len(p.Ctrs) == 0 {
+ p.Ctrs = []*Ctr{getCtr()}
+ }
+ return &p
+}
+
+type podOption func(*Pod)
+
+func withHostname(h string) podOption {
+ return func(pod *Pod) {
+ pod.Hostname = h
+ }
+}
+
+func withCtr(c *Ctr) podOption {
+ return func(pod *Pod) {
+ pod.Ctrs = append(pod.Ctrs, c)
+ }
+}
+
+// Ctr describes the options a kube yaml can be configured at container level
+type Ctr struct {
+ Name string
+ Image string
+ Cmd []string
+ SecurityContext bool
+ Caps bool
+ CapAdd []string
+ CapDrop []string
+}
+
+// getCtr takes a list of ctrOptions and returns a Ctr with sane defaults
+// and the configured options
+func getCtr(options ...ctrOption) *Ctr {
+ c := Ctr{defaultCtrName, defaultCtrImage, defaultCtrCmd, true, false, nil, nil}
+ for _, option := range options {
+ option(&c)
+ }
+ return &c
+}
+
+type ctrOption func(*Ctr)
+
+func withCmd(cmd []string) ctrOption {
+ return func(c *Ctr) {
+ c.Cmd = cmd
+ }
+}
+
+func withImage(img string) ctrOption {
+ return func(c *Ctr) {
+ c.Image = img
+ }
+}
+
+func withSecurityContext(sc bool) ctrOption {
+ return func(c *Ctr) {
+ c.SecurityContext = sc
+ }
+}
+
+func withCapAdd(caps []string) ctrOption {
+ return func(c *Ctr) {
+ c.CapAdd = caps
+ c.Caps = true
+ }
+}
+
+func withCapDrop(caps []string) ctrOption {
+ return func(c *Ctr) {
+ c.CapDrop = caps
+ c.Caps = true
+ }
+}
+
var _ = Describe("Podman generate kube", func() {
var (
tempdir string
err error
podmanTest *PodmanTestIntegration
+ kubeYaml string
)
BeforeEach(func() {
@@ -118,6 +199,8 @@ var _ = Describe("Podman generate kube", func() {
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
podmanTest.SeedImages()
+
+ kubeYaml = filepath.Join(podmanTest.TempDir, "kube.yaml")
})
AfterEach(func() {
@@ -127,123 +210,98 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman play kube test correct command", func() {
- ctrName := "testCtr"
- ctrCmd := []string{"top"}
- testContainer := Container{ctrCmd, ALPINE, ctrName, true, false, nil, nil}
- tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml")
-
- err := generateKubeYaml("test", "", []Container{testContainer}, tempFile)
+ err := generateKubeYaml(getPod(), kubeYaml)
Expect(err).To(BeNil())
- kube := podmanTest.Podman([]string{"play", "kube", tempFile})
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
- inspect := podmanTest.Podman([]string{"inspect", ctrName})
+ inspect := podmanTest.Podman([]string{"inspect", defaultCtrName})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
- Expect(inspect.OutputToString()).To(ContainSubstring(ctrCmd[0]))
+ Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0]))
})
It("podman play kube test correct output", func() {
- ctrName := "testCtr"
- ctrCmd := []string{"echo", "hello"}
- testContainer := Container{ctrCmd, ALPINE, ctrName, true, false, nil, nil}
- tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml")
+ p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}))))
- err := generateKubeYaml("test", "", []Container{testContainer}, tempFile)
+ err := generateKubeYaml(p, kubeYaml)
Expect(err).To(BeNil())
- kube := podmanTest.Podman([]string{"play", "kube", tempFile})
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
- logs := podmanTest.Podman([]string{"logs", ctrName})
+ logs := podmanTest.Podman([]string{"logs", defaultCtrName})
logs.WaitWithDefaultTimeout()
Expect(logs.ExitCode()).To(Equal(0))
Expect(logs.OutputToString()).To(ContainSubstring("hello"))
- inspect := podmanTest.Podman([]string{"inspect", ctrName, "--format", "'{{ .Config.Cmd }}'"})
+ inspect := podmanTest.Podman([]string{"inspect", defaultCtrName, "--format", "'{{ .Config.Cmd }}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
Expect(inspect.OutputToString()).To(ContainSubstring("hello"))
})
It("podman play kube test hostname", func() {
- podName := "test"
- ctrName := "testCtr"
- ctrCmd := []string{"top"}
- testContainer := Container{ctrCmd, ALPINE, ctrName, true, false, nil, nil}
- tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml")
-
- err := generateKubeYaml(podName, "", []Container{testContainer}, tempFile)
+ err := generateKubeYaml(getPod(), kubeYaml)
Expect(err).To(BeNil())
- kube := podmanTest.Podman([]string{"play", "kube", tempFile})
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
- inspect := podmanTest.Podman([]string{"inspect", ctrName, "--format", "{{ .Config.Hostname }}"})
+ inspect := podmanTest.Podman([]string{"inspect", defaultCtrName, "--format", "{{ .Config.Hostname }}"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
- Expect(inspect.OutputToString()).To(Equal(podName))
+ Expect(inspect.OutputToString()).To(Equal(defaultPodName))
})
It("podman play kube test with customized hostname", func() {
hostname := "myhostname"
- ctrName := "testCtr"
- ctrCmd := []string{"top"}
- testContainer := Container{ctrCmd, ALPINE, ctrName, true, false, nil, nil}
- tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml")
-
- err := generateKubeYaml("test", hostname, []Container{testContainer}, tempFile)
+ err := generateKubeYaml(getPod(withHostname(hostname)), kubeYaml)
Expect(err).To(BeNil())
- kube := podmanTest.Podman([]string{"play", "kube", tempFile})
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
- inspect := podmanTest.Podman([]string{"inspect", ctrName, "--format", "{{ .Config.Hostname }}"})
+ inspect := podmanTest.Podman([]string{"inspect", defaultCtrName, "--format", "{{ .Config.Hostname }}"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
Expect(inspect.OutputToString()).To(Equal(hostname))
})
It("podman play kube cap add", func() {
- ctrName := "testCtr"
- ctrCmd := []string{"cat", "/proc/self/status"}
capAdd := "CAP_SYS_ADMIN"
- testContainer := Container{ctrCmd, ALPINE, ctrName, true, true, []string{capAdd}, nil}
- tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml")
+ ctr := getCtr(withCapAdd([]string{capAdd}), withCmd([]string{"cat", "/proc/self/status"}))
- err := generateKubeYaml("test", "", []Container{testContainer}, tempFile)
+ err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml)
Expect(err).To(BeNil())
- kube := podmanTest.Podman([]string{"play", "kube", tempFile})
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
- inspect := podmanTest.Podman([]string{"inspect", ctrName})
+ inspect := podmanTest.Podman([]string{"inspect", defaultCtrName})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
Expect(inspect.OutputToString()).To(ContainSubstring(capAdd))
})
- It("podman play kube cap add", func() {
- ctrName := "testCtr"
- ctrCmd := []string{"cat", "/proc/self/status"}
- capDrop := "CAP_SYS_ADMIN"
- testContainer := Container{ctrCmd, ALPINE, ctrName, true, true, []string{capDrop}, nil}
- tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml")
+ It("podman play kube cap drop", func() {
+ capDrop := "CAP_CHOWN"
+ ctr := getCtr(withCapDrop([]string{capDrop}))
- err := generateKubeYaml("test", "", []Container{testContainer}, tempFile)
+ err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml)
Expect(err).To(BeNil())
- kube := podmanTest.Podman([]string{"play", "kube", tempFile})
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
- inspect := podmanTest.Podman([]string{"inspect", ctrName})
+ inspect := podmanTest.Podman([]string{"inspect", defaultCtrName})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
Expect(inspect.OutputToString()).To(ContainSubstring(capDrop))
@@ -251,19 +309,14 @@ var _ = Describe("Podman generate kube", func() {
It("podman play kube no security context", func() {
// expect play kube to not fail if no security context is specified
- ctrName := "testCtr"
- ctrCmd := "ls"
- testContainer := Container{[]string{ctrCmd}, ALPINE, ctrName, false, false, nil, nil}
- tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml")
-
- err := generateKubeYaml("test", "", []Container{testContainer}, tempFile)
+ err := generateKubeYaml(getPod(withCtr(getCtr(withSecurityContext(false)))), kubeYaml)
Expect(err).To(BeNil())
- kube := podmanTest.Podman([]string{"play", "kube", tempFile})
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
- inspect := podmanTest.Podman([]string{"inspect", ctrName})
+ inspect := podmanTest.Podman([]string{"inspect", defaultCtrName})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
})
diff --git a/test/system/075-exec.bats b/test/system/075-exec.bats
index 11cb98269..472fdd1ab 100644
--- a/test/system/075-exec.bats
+++ b/test/system/075-exec.bats
@@ -29,4 +29,24 @@ load helpers
run_podman rm $cid
}
+@test "podman exec - leak check" {
+ skip_if_remote
+
+ # Start a container in the background then run exec command
+ # three times and make sure no any exec pid hash file leak
+ run_podman run -td $IMAGE /bin/sh
+ cid="$output"
+
+ is "$(check_exec_pid)" "" "exec pid hash file indeed doesn't exist"
+
+ for i in {1..3}; do
+ run_podman exec $cid /bin/true
+ done
+
+ is "$(check_exec_pid)" "" "there isn't any exec pid hash file leak"
+
+ run_podman stop --time 1 $cid
+ run_podman rm -f $cid
+}
+
# vim: filetype=sh
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index 3d607f4bd..8c061d2c9 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -373,5 +373,19 @@ function random_string() {
head /dev/urandom | tr -dc a-zA-Z0-9 | head -c$length
}
+
+#########################
+# find_exec_pid_files # Returns nothing or exec_pid hash files
+#########################
+#
+# Return exec_pid hash files if exists, otherwise, return nothing
+#
+function find_exec_pid_files() {
+ run_podman info --format '{{.store.RunRoot}}'
+ local storage_path="$output"
+ if [ -d $storage_path ]; then
+ find $storage_path -type f -iname 'exec_pid_*'
+ fi
+}
# END miscellaneous tools
###############################################################################
diff --git a/version/version.go b/version/version.go
index 2c4d69b78..c0dbeadfe 100644
--- a/version/version.go
+++ b/version/version.go
@@ -4,7 +4,7 @@ package version
// NOTE: remember to bump the version at the top
// of the top-level README.md file when this is
// bumped.
-const Version = "1.6.2-dev"
+const Version = "1.6.3-dev"
// RemoteAPIVersion is the version for the remote
// client API. It is used to determine compatibility