summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/util.go13
-rw-r--r--cmd/podman/common/volumes.go44
-rw-r--r--cmd/podman/containers/start.go11
-rw-r--r--docs/source/markdown/podman-create.1.md7
-rw-r--r--docs/source/markdown/podman-run.1.md6
-rw-r--r--pkg/api/handlers/compat/images_build.go9
-rw-r--r--pkg/api/handlers/libpod/containers.go1
-rw-r--r--pkg/rootless/rootless_linux.c2
-rw-r--r--test/e2e/run_networking_test.go12
-rw-r--r--test/e2e/run_test.go8
-rw-r--r--test/e2e/start_test.go12
11 files changed, 112 insertions, 13 deletions
diff --git a/cmd/podman/common/util.go b/cmd/podman/common/util.go
index 41432c6f0..17e779c86 100644
--- a/cmd/podman/common/util.go
+++ b/cmd/podman/common/util.go
@@ -175,12 +175,15 @@ func parseSplitPort(hostIP, hostPort *string, ctrPort string, protocol *string)
if hostIP != nil {
if *hostIP == "" {
return newPort, errors.Errorf("must provide a non-empty container host IP to publish")
+ } else if *hostIP != "0.0.0.0" {
+ // If hostIP is 0.0.0.0, leave it unset - CNI treats
+ // 0.0.0.0 and empty differently, Docker does not.
+ testIP := net.ParseIP(*hostIP)
+ if testIP == nil {
+ return newPort, errors.Errorf("cannot parse %q as an IP address", *hostIP)
+ }
+ newPort.HostIP = testIP.String()
}
- testIP := net.ParseIP(*hostIP)
- if testIP == nil {
- return newPort, errors.Errorf("cannot parse %q as an IP address", *hostIP)
- }
- newPort.HostIP = testIP.String()
}
if hostPort != nil {
if *hostPort == "" {
diff --git a/cmd/podman/common/volumes.go b/cmd/podman/common/volumes.go
index 3b8f7ec6e..20c31bd81 100644
--- a/cmd/podman/common/volumes.go
+++ b/cmd/podman/common/volumes.go
@@ -20,6 +20,8 @@ const (
TypeVolume = "volume"
// TypeTmpfs is the type for mounting tmpfs
TypeTmpfs = "tmpfs"
+ // TypeDevpts is the type for creating a devpts
+ TypeDevpts = "devpts"
)
var (
@@ -197,6 +199,15 @@ func getMounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.N
return nil, nil, errors.Wrapf(errDuplicateDest, mount.Destination)
}
finalMounts[mount.Destination] = mount
+ case TypeDevpts:
+ mount, err := getDevptsMount(tokens)
+ if err != nil {
+ return nil, nil, err
+ }
+ if _, ok := finalMounts[mount.Destination]; ok {
+ return nil, nil, errors.Wrapf(errDuplicateDest, mount.Destination)
+ }
+ finalMounts[mount.Destination] = mount
case "volume":
volume, err := getNamedVolume(tokens)
if err != nil {
@@ -416,6 +427,39 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
return newMount, nil
}
+// Parse a single devpts mount entry from the --mount flag
+func getDevptsMount(args []string) (spec.Mount, error) {
+ newMount := spec.Mount{
+ Type: TypeDevpts,
+ Source: TypeDevpts,
+ }
+
+ var setDest bool
+
+ for _, val := range args {
+ kv := strings.Split(val, "=")
+ switch kv[0] {
+ case "target", "dst", "destination":
+ if len(kv) == 1 {
+ return newMount, errors.Wrapf(optionArgError, kv[0])
+ }
+ if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
+ return newMount, err
+ }
+ newMount.Destination = filepath.Clean(kv[1])
+ setDest = true
+ default:
+ return newMount, errors.Wrapf(util.ErrBadMntOption, kv[0])
+ }
+ }
+
+ if !setDest {
+ return newMount, noDestError
+ }
+
+ return newMount, nil
+}
+
// Parse a single volume mount entry from the --mount flag.
// Note that the volume-label option for named volumes is currently NOT supported.
// TODO: add support for --volume-label
diff --git a/cmd/podman/containers/start.go b/cmd/podman/containers/start.go
index 05fdfc780..ccbe80317 100644
--- a/cmd/podman/containers/start.go
+++ b/cmd/podman/containers/start.go
@@ -99,12 +99,17 @@ func start(cmd *cobra.Command, args []string) error {
}
for _, r := range responses {
- if r.Err == nil && !startOptions.Attach {
- fmt.Println(r.RawInput)
+ if r.Err == nil {
+ if startOptions.Attach {
+ // Implement the exitcode when the only one container is enabled attach
+ registry.SetExitCode(r.ExitCode)
+ } else {
+ fmt.Println(r.RawInput)
+ }
} else {
errs = append(errs, r.Err)
}
}
- // TODO need to understand an implement exitcodes
+
return errs.PrintErrors()
}
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index b4456225e..9267e5729 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -494,7 +494,7 @@ Tune a container's memory swappiness behavior. Accepts an integer between 0 and
Attach a filesystem mount to the container
-Current supported mount TYPES are `bind`, `volume`, and `tmpfs`. <sup>[[1]](#Footnote1)</sup>
+Current supported mount TYPES are `bind`, `volume`, `tmpfs` and `devpts`. <sup>[[1]](#Footnote1)</sup>
e.g.
@@ -506,6 +506,8 @@ Current supported mount TYPES are `bind`, `volume`, and `tmpfs`. <sup>[[1]](#Foo
type=tmpfs,tmpfs-size=512M,destination=/path/in/container
+ type=devpts,destination=/dev/pts
+
Common Options:
· src, source: mount source spec for bind and volume. Mandatory for bind.
@@ -634,7 +636,8 @@ Both hostPort and containerPort can be specified as a range of ports.
When specifying ranges for both, the number of container ports in the range must match the number of host ports in the range.
(e.g., `podman run -p 1234-1236:1222-1224 --name thisWorks -t busybox`
but not `podman run -p 1230-1236:1230-1240 --name RangeContainerPortsBiggerThanRangeHostPorts -t busybox`)
-With ip: `podman run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage`
+With host IP: `podman run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage`
+If host IP is set to 0.0.0.0 or not set at all, the port will be bound on all IPs on the host.
Host port does not have to be specified (e.g. `podman run -p 127.0.0.1::80`).
If it is not, the container port will be randomly assigned a port on the host.
Use `podman port` to see the actual mapping: `podman port CONTAINER $CONTAINERPORT`
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 4fdb7f81b..e47d1fa83 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -501,7 +501,7 @@ Tune a container's memory swappiness behavior. Accepts an integer between *0* an
Attach a filesystem mount to the container
-Current supported mount TYPEs are **bind**, **volume**, and **tmpfs**. <sup>[[1]](#Footnote1)</sup>
+Current supported mount TYPEs are **bind**, **volume**, **tmpfs** and **devpts**. <sup>[[1]](#Footnote1)</sup>
e.g.
@@ -513,6 +513,8 @@ Current supported mount TYPEs are **bind**, **volume**, and **tmpfs**. <sup>[[1]
type=tmpfs,tmpfs-size=512M,destination=/path/in/container
+ type=devpts,destination=/dev/pts
+
Common Options:
· src, source: mount source spec for bind and volume. Mandatory for bind.
@@ -647,6 +649,8 @@ Both hostPort and containerPort can be specified as a range of ports.
When specifying ranges for both, the number of container ports in the range must match the number of host ports in the range.
+If host IP is set to 0.0.0.0 or not set at all, the port will be bound on all IPs on the host.
+
Host port does not have to be specified (e.g. `podman run -p 127.0.0.1::80`).
If it is not, the container port will be randomly assigned a port on the host.
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index 3005063a7..9601f5e18 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -20,6 +20,7 @@ import (
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/storage/pkg/archive"
"github.com/gorilla/schema"
+ "github.com/sirupsen/logrus"
)
func BuildImage(w http.ResponseWriter, r *http.Request) {
@@ -33,7 +34,13 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
}
if hdr, found := r.Header["Content-Type"]; found && len(hdr) > 0 {
- if hdr[0] != "application/x-tar" {
+ contentType := hdr[0]
+ switch contentType {
+ case "application/tar":
+ logrus.Warnf("tar file content type is %s, should use \"application/x-tar\" content type", contentType)
+ case "application/x-tar":
+ break
+ default:
utils.BadRequest(w, "Content-Type", hdr[0],
fmt.Errorf("Content-Type: %s is not supported. Should be \"application/x-tar\"", hdr[0]))
return
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 864775fe4..47ea6c40d 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -24,6 +24,7 @@ func ContainerExists(w http.ResponseWriter, r *http.Request) {
if err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
utils.ContainerNotFound(w, name, err)
+ return
}
utils.InternalServerError(w, err)
return
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index eaf2d4551..0223c35ee 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -205,7 +205,7 @@ can_use_shortcut ()
if (strcmp (argv[argc], "mount") == 0
|| strcmp (argv[argc], "search") == 0
- || strcmp (argv[argc], "system") == 0)
+ || (strcmp (argv[argc], "system") == 0 && argv[argc+1] && strcmp (argv[argc+1], "service") != 0))
{
ret = false;
break;
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index 87b74052a..0353db9a6 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -236,6 +236,18 @@ var _ = Describe("Podman run networking", func() {
Expect((hp1 == "4000" && hp2 == "8000") || (hp1 == "8000" && hp2 == "4000")).To(BeTrue())
})
+ It("podman run -p 0.0.0.0:8080:80", func() {
+ name := "testctr"
+ session := podmanTest.Podman([]string{"create", "-t", "-p", "0.0.0.0:8080:80", "--name", name, ALPINE, "/bin/sh"})
+ session.WaitWithDefaultTimeout()
+ inspectOut := podmanTest.InspectContainer(name)
+ Expect(len(inspectOut)).To(Equal(1))
+ Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1))
+ Expect(len(inspectOut[0].NetworkSettings.Ports["80/tcp"])).To(Equal(1))
+ Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0].HostPort).To(Equal("8080"))
+ Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0].HostIP).To(Equal(""))
+ })
+
It("podman run network expose host port 80 to container port 8000", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "-dt", "-p", "80:8000", ALPINE, "/bin/sh"})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 6bb12b54a..f2a6d14eb 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -811,6 +811,14 @@ USER mail`
Expect(len(session.OutputToStringArray())).To(Equal(1))
})
+ It("podman run --mount type=devpts,target=/foo/bar", func() {
+ SkipIfRootless()
+ session := podmanTest.Podman([]string{"run", "--mount", "type=devpts,target=/foo/bar", fedoraMinimal, "stat", "-f", "-c%T", "/foo/bar"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("devpts"))
+ })
+
It("podman run --pod automatically", func() {
session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:foobar", ALPINE, "nc", "-l", "-p", "8080"})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go
index 78410c9cf..aef5ca001 100644
--- a/test/e2e/start_test.go
+++ b/test/e2e/start_test.go
@@ -86,6 +86,18 @@ var _ = Describe("Podman start", func() {
Expect(session.OutputToString()).To(Equal(name))
})
+ It("podman start single container with attach and test the signal", func() {
+ SkipIfRemote()
+ session := podmanTest.Podman([]string{"create", "--entrypoint", "sh", ALPINE, "-c", "exit 1"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ cid := session.OutputToString()
+ session = podmanTest.Podman([]string{"start", "--attach", cid})
+ session.WaitWithDefaultTimeout()
+ // It should forward the signal
+ Expect(session.ExitCode()).To(Equal(1))
+ })
+
It("podman start multiple containers", func() {
session := podmanTest.Podman([]string{"create", "-d", "--name", "foobar99", ALPINE, "ls"})
session.WaitWithDefaultTimeout()