summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml20
-rw-r--r--Makefile7
-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--contrib/spec/podman.spec.in4
-rw-r--r--contrib/systemd/system/podman.service4
-rw-r--r--docs/source/markdown/podman-create.1.md7
-rw-r--r--docs/source/markdown/podman-run.1.md6
-rw-r--r--libpod/define/errors.go3
-rw-r--r--libpod/events/journal_linux.go3
-rw-r--r--nix/nixpkgs.json6
-rw-r--r--pkg/api/handlers/compat/networks.go7
-rw-r--r--pkg/api/handlers/libpod/images.go4
-rw-r--r--pkg/api/handlers/libpod/networks.go6
-rw-r--r--pkg/api/handlers/utils/errors.go9
-rw-r--r--pkg/api/server/register_volumes.go2
-rw-r--r--pkg/domain/entities/volumes.go56
-rw-r--r--pkg/network/config.go5
-rw-r--r--pkg/network/files.go3
-rw-r--r--pkg/network/network.go3
-rw-r--r--test/apiv2/35-networks.at8
-rw-r--r--test/e2e/commit_test.go15
-rw-r--r--test/e2e/run_networking_test.go12
-rw-r--r--test/e2e/run_test.go8
-rw-r--r--test/e2e/run_volume_test.go6
-rw-r--r--test/e2e/search_test.go2
-rw-r--r--test/e2e/start_test.go12
-rw-r--r--test/endpoint/endpoint.go4
-rw-r--r--test/utils/utils.go6
30 files changed, 238 insertions, 58 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index a8f3a2817..22f84d7ec 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -760,21 +760,33 @@ success_task:
static_build_task:
depends_on:
- "gating"
+
gce_instance:
image_name: "${FEDORA_CACHE_IMAGE_NAME}"
cpu: 8
memory: 12
disk: 200
- script: |
+
+ init_script: |
set -ex
setenforce 0
growpart /dev/sda 1 || true
resize2fs /dev/sda1 || true
yum -y install podman
+
+ nix_cache:
+ folder: '.cache'
+ fingerprint_script: |
+ echo "nix-v1-$(sha1sum nix/nixpkgs.json | head -c 40)"
+
+ build_script: |
+ set -ex
mkdir -p /nix
- podman run --rm --privileged -ti -v /:/mnt nixos/nix cp -rfT /nix /mnt/nix
+ mkdir -p .cache
+ mount --bind .cache /nix
+ if [[ -z $(ls -A /nix) ]]; then podman run --rm --privileged -ti -v /:/mnt nixos/nix cp -rfT /nix /mnt/nix; fi
podman run --rm --privileged -ti -v /nix:/nix -v ${PWD}:${PWD} -w ${PWD} nixos/nix nix --print-build-logs --option cores 8 --option max-jobs 8 build --file nix/
+ chown -Rf $(whoami) .cache
+
binaries_artifacts:
path: "result/bin/podman"
- on_failure:
- failed_branch_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_branch_failure.sh |& ${TIMESTAMP}'
diff --git a/Makefile b/Makefile
index 51c2704b7..08a3cddac 100644
--- a/Makefile
+++ b/Makefile
@@ -572,9 +572,14 @@ endif
.PHONY: install.systemd
install.systemd: install.varlink
install ${SELINUXOPT} -m 755 -d ${DESTDIR}${SYSTEMDDIR} ${DESTDIR}${USERSYSTEMDDIR}
- # Install APIV2 services
+ # User services
+ install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.service ${DESTDIR}${USERSYSTEMDDIR}/podman-auto-update.service
+ install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer ${DESTDIR}${USERSYSTEMDDIR}/podman-auto-update.timer
install ${SELINUXOPT} -m 644 contrib/systemd/user/podman.socket ${DESTDIR}${USERSYSTEMDDIR}/podman.socket
install ${SELINUXOPT} -m 644 contrib/systemd/user/podman.service ${DESTDIR}${USERSYSTEMDDIR}/podman.service
+ # System services
+ install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.service ${DESTDIR}${SYSTEMDDIR}/podman-auto-update.service
+ install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer ${DESTDIR}${SYSTEMDDIR}/podman-auto-update.timer
install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket ${DESTDIR}${SYSTEMDDIR}/podman.socket
install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service ${DESTDIR}${SYSTEMDDIR}/podman.service
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/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 1795674e3..2411eaabc 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -500,10 +500,14 @@ export GOPATH=%{buildroot}/%{gopath}:$(pwd)/vendor:%{gopath}
%{_datadir}/zsh/site-functions/*
%{_libexecdir}/%{name}/conmon
%config(noreplace) %{_sysconfdir}/cni/net.d/87-%{name}-bridge.conflist
+%{_unitdir}/podman-auto-update.service
+%{_unitdir}/podman-auto-update.timer
%{_unitdir}/podman.service
%{_unitdir}/podman.socket
%{_usr}/lib/systemd/user/podman.service
%{_usr}/lib/systemd/user/podman.socket
+%{_usr}/lib/systemd/user/podman-auto-update.service
+%{_usr}/lib/systemd/user/podman-auto-update.timer
%if 0%{?with_devel}
%files -n libpod-devel -f devel.file-list
diff --git a/contrib/systemd/system/podman.service b/contrib/systemd/system/podman.service
index 4a63735a3..c8751168d 100644
--- a/contrib/systemd/system/podman.service
+++ b/contrib/systemd/system/podman.service
@@ -8,7 +8,3 @@ StartLimitIntervalSec=0
[Service]
Type=simple
ExecStart=/usr/bin/podman system service
-
-[Install]
-WantedBy=multi-user.target
-Also=podman.socket
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/libpod/define/errors.go b/libpod/define/errors.go
index 4a0df3983..6e372eb5e 100644
--- a/libpod/define/errors.go
+++ b/libpod/define/errors.go
@@ -20,6 +20,9 @@ var (
// ErrNoSuchVolume indicates the requested volume does not exist
ErrNoSuchVolume = errors.New("no such volume")
+ // ErrNoSuchNetwork indicates the requested network does not exist
+ ErrNoSuchNetwork = errors.New("network not found")
+
// ErrNoSuchExecSession indicates that the requested exec session does
// not exist.
ErrNoSuchExecSession = errors.New("no such exec session")
diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go
index 7c2a3e0f2..dc55dbc77 100644
--- a/libpod/events/journal_linux.go
+++ b/libpod/events/journal_linux.go
@@ -4,7 +4,6 @@ package events
import (
"context"
- "fmt"
"strconv"
"time"
@@ -50,7 +49,7 @@ func (e EventJournalD) Write(ee Event) error {
case Volume:
m["PODMAN_NAME"] = ee.Name
}
- return journal.Send(fmt.Sprintf("%s", ee.ToHumanReadable()), journal.PriInfo, m)
+ return journal.Send(string(ee.ToHumanReadable()), journal.PriInfo, m)
}
// Read reads events from the journal and sends qualified events to the event channel
diff --git a/nix/nixpkgs.json b/nix/nixpkgs.json
index 98ed710a4..8eeb4f470 100644
--- a/nix/nixpkgs.json
+++ b/nix/nixpkgs.json
@@ -1,7 +1,7 @@
{
"url": "https://github.com/nixos/nixpkgs",
- "rev": "02591d02a910b3b92092153c5f3419a8d696aa1d",
- "date": "2020-07-09T03:52:28+02:00",
- "sha256": "1pp9v4rqmgx1b298gxix8b79m8pvxy1rcf8l25rxxxxnkr5ls1ng",
+ "rev": "b49e7987632e4c7ab3a093fdfc433e1826c4b9d7",
+ "date": "2020-07-26T09:18:52+02:00",
+ "sha256": "1mj6fy0p24izmasl653s5z4f2ka9v3b6mys45kjrqmkv889yk2r6",
"fetchSubmodules": false
}
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go
index 1e80cc91d..80b7505df 100644
--- a/pkg/api/handlers/compat/networks.go
+++ b/pkg/api/handlers/compat/networks.go
@@ -10,6 +10,7 @@ import (
"github.com/containernetworking/cni/libcni"
"github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/domain/infra/abi"
@@ -44,9 +45,7 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
name := utils.GetName(r)
_, err = network.InspectNetwork(config, name)
if err != nil {
- // TODO our network package does not distinguish between not finding a
- // specific network vs not being able to read it
- utils.InternalServerError(w, err)
+ utils.NetworkNotFound(w, name, err)
return
}
report, err := getNetworkResourceByName(name, runtime)
@@ -285,7 +284,7 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
return
}
if !exists {
- utils.Error(w, "network not found", http.StatusNotFound, network.ErrNetworkNotFound)
+ utils.Error(w, "network not found", http.StatusNotFound, define.ErrNoSuchNetwork)
return
}
if err := network.RemoveNetwork(config, name); err != nil {
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index e0da990c3..51013acf1 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -594,11 +594,9 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
return
}
- // I know mitr hates this ... but doing for now
- if len(query.Repo) > 1 {
+ if len(query.Repo) > 0 {
destImage = fmt.Sprintf("%s:%s", query.Repo, tag)
}
-
commitImage, err := ctr.Commit(r.Context(), destImage, options)
if err != nil && !strings.Contains(err.Error(), "is not running") {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "CommitFailure"))
diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go
index 9237a41ce..475522664 100644
--- a/pkg/api/handlers/libpod/networks.go
+++ b/pkg/api/handlers/libpod/networks.go
@@ -5,10 +5,10 @@ import (
"net/http"
"github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/domain/infra/abi"
- "github.com/containers/podman/v2/pkg/network"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@@ -78,7 +78,7 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
}
if reports[0].Err != nil {
// If the network cannot be found, we return a 404.
- if errors.Cause(err) == network.ErrNetworkNotFound {
+ if errors.Cause(err) == define.ErrNoSuchNetwork {
utils.Error(w, "Something went wrong", http.StatusNotFound, err)
return
}
@@ -104,7 +104,7 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
reports, err := ic.NetworkInspect(r.Context(), []string{name}, options)
if err != nil {
// If the network cannot be found, we return a 404.
- if errors.Cause(err) == network.ErrNetworkNotFound {
+ if errors.Cause(err) == define.ErrNoSuchNetwork {
utils.Error(w, "Something went wrong", http.StatusNotFound, err)
return
}
diff --git a/pkg/api/handlers/utils/errors.go b/pkg/api/handlers/utils/errors.go
index 5a99529c6..bf9b18960 100644
--- a/pkg/api/handlers/utils/errors.go
+++ b/pkg/api/handlers/utils/errors.go
@@ -39,6 +39,7 @@ func VolumeNotFound(w http.ResponseWriter, name string, err error) {
msg := fmt.Sprintf("No such volume: %s", name)
Error(w, msg, http.StatusNotFound, err)
}
+
func ContainerNotFound(w http.ResponseWriter, name string, err error) {
if errors.Cause(err) != define.ErrNoSuchCtr {
InternalServerError(w, err)
@@ -55,6 +56,14 @@ func ImageNotFound(w http.ResponseWriter, name string, err error) {
Error(w, msg, http.StatusNotFound, err)
}
+func NetworkNotFound(w http.ResponseWriter, name string, err error) {
+ if errors.Cause(err) != define.ErrNoSuchNetwork {
+ InternalServerError(w, err)
+ }
+ msg := fmt.Sprintf("No such network: %s", name)
+ Error(w, msg, http.StatusNotFound, err)
+}
+
func PodNotFound(w http.ResponseWriter, name string, err error) {
if errors.Cause(err) != define.ErrNoSuchPod {
InternalServerError(w, err)
diff --git a/pkg/api/server/register_volumes.go b/pkg/api/server/register_volumes.go
index b509a332a..8f7848ed4 100644
--- a/pkg/api/server/register_volumes.go
+++ b/pkg/api/server/register_volumes.go
@@ -128,7 +128,7 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// The boolean `dangling` filter is not yet implemented for this endpoint.
// responses:
// '200':
- // "$ref": "#/responses/DockerVolumeList"
+ // "$ref": "#/responses/VolumeListResponse"
// '500':
// "$ref": "#/responses/InternalError"
r.Handle(VersionedPath("/volumes"), s.APIHandler(compat.ListVolumes)).Methods(http.MethodGet)
diff --git a/pkg/domain/entities/volumes.go b/pkg/domain/entities/volumes.go
index 2311d1f25..53d30ffdf 100644
--- a/pkg/domain/entities/volumes.go
+++ b/pkg/domain/entities/volumes.go
@@ -59,6 +59,42 @@ type VolumeConfigResponse struct {
Anonymous bool `json:"Anonymous"`
}
+// VolumeInfo Volume list response
+// swagger:model VolumeInfo
+type VolumeInfo struct {
+
+ // Date/Time the volume was created.
+ CreatedAt string `json:"CreatedAt,omitempty"`
+
+ // Name of the volume driver used by the volume. Only supports local driver
+ // Required: true
+ Driver string `json:"Driver"`
+
+ // User-defined key/value metadata.
+ // Always included
+ Labels map[string]string `json:"Labels"`
+
+ // Mount path of the volume on the host.
+ // Required: true
+ Mountpoint string `json:"Mountpoint"`
+
+ // Name of the volume.
+ // Required: true
+ Name string `json:"Name"`
+
+ // The driver specific options used when creating the volume.
+ // Required: true
+ Options map[string]string `json:"Options"`
+
+ // The level at which the volume exists.
+ // Libpod does not implement volume scoping, and this is provided solely for
+ // Docker compatibility. The value is only "local".
+ // Required: true
+ Scope string `json:"Scope"`
+
+ // TODO: We don't include the volume `Status` for now
+}
+
type VolumeRmOptions struct {
All bool
Force bool
@@ -94,17 +130,25 @@ type VolumeListReport struct {
VolumeConfigResponse
}
-/*
- * Docker API compatibility types
- */
-// swagger:response DockerVolumeList
-type SwagDockerVolumeListResponse struct {
+// VolumeListBody Volume list response
+// swagger:model VolumeListBody
+type VolumeListBody struct {
+ Volumes []*VolumeInfo
+}
+
+// Volume list response
+// swagger:response VolumeListResponse
+type SwagVolumeListResponse struct {
// in:body
Body struct {
- docker_api_types_volume.VolumeListOKBody
+ VolumeListBody
}
}
+/*
+ * Docker API compatibility types
+ */
+
// swagger:model DockerVolumeCreate
type DockerVolumeCreate docker_api_types_volume.VolumeCreateBody
diff --git a/pkg/network/config.go b/pkg/network/config.go
index a504e0ad0..0115433e1 100644
--- a/pkg/network/config.go
+++ b/pkg/network/config.go
@@ -2,7 +2,6 @@ package network
import (
"encoding/json"
- "errors"
"net"
)
@@ -20,10 +19,6 @@ const (
DefaultPodmanDomainName = "dns.podman"
)
-var (
- ErrNetworkNotFound = errors.New("network not found")
-)
-
// GetDefaultPodmanNetwork outputs the default network for podman
func GetDefaultPodmanNetwork() (*net.IPNet, error) {
_, n, err := net.ParseCIDR("10.88.1.0/24")
diff --git a/pkg/network/files.go b/pkg/network/files.go
index beb3289f3..38ce38b97 100644
--- a/pkg/network/files.go
+++ b/pkg/network/files.go
@@ -10,6 +10,7 @@ import (
"github.com/containernetworking/cni/libcni"
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
"github.com/containers/common/pkg/config"
+ "github.com/containers/podman/v2/libpod/define"
"github.com/pkg/errors"
)
@@ -55,7 +56,7 @@ func GetCNIConfigPathByName(config *config.Config, name string) (string, error)
return confFile, nil
}
}
- return "", errors.Wrap(ErrNetworkNotFound, fmt.Sprintf("unable to find network configuration for %s", name))
+ return "", errors.Wrap(define.ErrNoSuchNetwork, fmt.Sprintf("unable to find network configuration for %s", name))
}
// ReadRawCNIConfByName reads the raw CNI configuration for a CNI
diff --git a/pkg/network/network.go b/pkg/network/network.go
index 6c84c8a8a..b24c72f5f 100644
--- a/pkg/network/network.go
+++ b/pkg/network/network.go
@@ -8,6 +8,7 @@ import (
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
"github.com/containers/common/pkg/config"
+ "github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -200,7 +201,7 @@ func InspectNetwork(config *config.Config, name string) (map[string]interface{},
func Exists(config *config.Config, name string) (bool, error) {
_, err := ReadRawCNIConfByName(config, name)
if err != nil {
- if errors.Cause(err) == ErrNetworkNotFound {
+ if errors.Cause(err) == define.ErrNoSuchNetwork {
return false, nil
}
return false, err
diff --git a/test/apiv2/35-networks.at b/test/apiv2/35-networks.at
new file mode 100644
index 000000000..fff3f3b1f
--- /dev/null
+++ b/test/apiv2/35-networks.at
@@ -0,0 +1,8 @@
+# -*- sh -*-
+#
+# network-related tests
+#
+
+t GET /networks/non-existing-network 404
+
+# vim: filetype=sh
diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go
index 568ee080d..c122ce50f 100644
--- a/test/e2e/commit_test.go
+++ b/test/e2e/commit_test.go
@@ -49,6 +49,21 @@ var _ = Describe("Podman commit", func() {
Expect(StringInSlice("foobar.com/test1-image:latest", data[0].RepoTags)).To(BeTrue())
})
+ It("podman commit single letter container", func() {
+ _, ec, _ := podmanTest.RunLsContainer("test1")
+ Expect(ec).To(Equal(0))
+ Expect(podmanTest.NumberOfContainers()).To(Equal(1))
+
+ session := podmanTest.Podman([]string{"commit", "test1", "a"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ check := podmanTest.Podman([]string{"inspect", "localhost/a:latest"})
+ check.WaitWithDefaultTimeout()
+ data := check.InspectImageJSON()
+ Expect(StringInSlice("localhost/a:latest", data[0].RepoTags)).To(BeTrue())
+ })
+
It("podman container commit container", func() {
_, ec, _ := podmanTest.RunLsContainer("test1")
Expect(ec).To(Equal(0))
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/run_volume_test.go b/test/e2e/run_volume_test.go
index c729423a3..c4ee05af9 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -241,7 +241,7 @@ var _ = Describe("Podman run with volumes", func() {
Expect(mountCmd1.ExitCode()).To(Equal(0))
os.Stdout.Sync()
os.Stderr.Sync()
- mountOut1 := strings.Join(strings.Fields(fmt.Sprintf("%s", mountCmd1.Out.Contents())), " ")
+ mountOut1 := strings.Join(strings.Fields(string(mountCmd1.Out.Contents())), " ")
fmt.Printf("Output: %s", mountOut1)
Expect(strings.Contains(mountOut1, volName)).To(BeFalse())
@@ -257,7 +257,7 @@ var _ = Describe("Podman run with volumes", func() {
Expect(mountCmd2.ExitCode()).To(Equal(0))
os.Stdout.Sync()
os.Stderr.Sync()
- mountOut2 := strings.Join(strings.Fields(fmt.Sprintf("%s", mountCmd2.Out.Contents())), " ")
+ mountOut2 := strings.Join(strings.Fields(string(mountCmd2.Out.Contents())), " ")
fmt.Printf("Output: %s", mountOut2)
Expect(strings.Contains(mountOut2, volName)).To(BeTrue())
@@ -278,7 +278,7 @@ var _ = Describe("Podman run with volumes", func() {
Expect(mountCmd3.ExitCode()).To(Equal(0))
os.Stdout.Sync()
os.Stderr.Sync()
- mountOut3 := strings.Join(strings.Fields(fmt.Sprintf("%s", mountCmd3.Out.Contents())), " ")
+ mountOut3 := strings.Join(strings.Fields(string(mountCmd3.Out.Contents())), " ")
fmt.Printf("Output: %s", mountOut3)
Expect(strings.Contains(mountOut3, volName)).To(BeFalse())
})
diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go
index 104bb4ec8..c6766fe2a 100644
--- a/test/e2e/search_test.go
+++ b/test/e2e/search_test.go
@@ -103,7 +103,7 @@ registries = ['{{.Host}}:{{.Port}}']`
search := podmanTest.Podman([]string{"search", "quay.io/libpod/whalesay"})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Equal(0))
- output := fmt.Sprintf("%s", search.Out.Contents())
+ output := string(search.Out.Contents())
match, _ := regexp.MatchString(`(?m)^quay.io\s+quay.io/libpod/whalesay\s+Static image used for automated testing.+$`, output)
Expect(match).To(BeTrue())
})
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()
diff --git a/test/endpoint/endpoint.go b/test/endpoint/endpoint.go
index 0593b05cd..d2c143824 100644
--- a/test/endpoint/endpoint.go
+++ b/test/endpoint/endpoint.go
@@ -192,12 +192,12 @@ func (p *EndpointTestIntegration) Varlink(endpoint, message string, more bool) *
}
func (s *EndpointSession) StdErrToString() string {
- fields := strings.Fields(fmt.Sprintf("%s", s.Err.Contents()))
+ fields := strings.Fields(string(s.Err.Contents()))
return strings.Join(fields, " ")
}
func (s *EndpointSession) OutputToString() string {
- fields := strings.Fields(fmt.Sprintf("%s", s.Out.Contents()))
+ fields := strings.Fields(string(s.Out.Contents()))
return strings.Join(fields, " ")
}
diff --git a/test/utils/utils.go b/test/utils/utils.go
index 0597cd292..2c454f532 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -215,7 +215,7 @@ func (s *PodmanSession) OutputToString() string {
// where each array item is a line split by newline
func (s *PodmanSession) OutputToStringArray() []string {
var results []string
- output := fmt.Sprintf("%s", s.Out.Contents())
+ output := string(s.Out.Contents())
for _, line := range strings.Split(output, "\n") {
if line != "" {
results = append(results, line)
@@ -226,14 +226,14 @@ func (s *PodmanSession) OutputToStringArray() []string {
// ErrorToString formats session stderr to string
func (s *PodmanSession) ErrorToString() string {
- fields := strings.Fields(fmt.Sprintf("%s", s.Err.Contents()))
+ fields := strings.Fields(string(s.Err.Contents()))
return strings.Join(fields, " ")
}
// ErrorToStringArray returns the stderr output as a []string
// where each array item is a line split by newline
func (s *PodmanSession) ErrorToStringArray() []string {
- output := fmt.Sprintf("%s", s.Err.Contents())
+ output := string(s.Err.Contents())
return strings.Split(output, "\n")
}