Initial commit
This commit is contained in:
0
vendor/github.com/hyperhq/hypercli/integration-cli/skip/.gitkeeper
generated
vendored
Normal file
0
vendor/github.com/hyperhq/hypercli/integration-cli/skip/.gitkeeper
generated
vendored
Normal file
257
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_build_test.go
generated
vendored
Normal file
257
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_build_test.go
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"net/http"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestBuildApiDockerfilePath(c *check.C) {
|
||||
// Test to make sure we stop people from trying to leave the
|
||||
// build context when specifying the path to the dockerfile
|
||||
buffer := new(bytes.Buffer)
|
||||
tw := tar.NewWriter(buffer)
|
||||
defer tw.Close()
|
||||
|
||||
dockerfile := []byte("FROM busybox")
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: "Dockerfile",
|
||||
Size: int64(len(dockerfile)),
|
||||
})
|
||||
//failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, err = tw.Write(dockerfile)
|
||||
// failed to write tar file content
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// failed to close tar archive
|
||||
c.Assert(tw.Close(), checker.IsNil)
|
||||
|
||||
res, body, err := sockRequestRaw("POST", "/build?dockerfile=../Dockerfile", buffer, "application/x-tar")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
|
||||
|
||||
out, err := readBody(body)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Didn't complain about leaving build context
|
||||
c.Assert(string(out), checker.Contains, "Forbidden path outside the build context")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiDockerFileRemote(c *check.C) {
|
||||
testRequires(c, NotUserNamespace)
|
||||
testRequires(c, DaemonIsLinux)
|
||||
server, err := fakeStorage(map[string]string{
|
||||
"testD": `FROM busybox
|
||||
COPY * /tmp/
|
||||
RUN find / -name ba*
|
||||
RUN find /tmp/`,
|
||||
})
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer server.Close()
|
||||
|
||||
res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
buf, err := readBody(body)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Make sure Dockerfile exists.
|
||||
// Make sure 'baz' doesn't exist ANYWHERE despite being mentioned in the URL
|
||||
out := string(buf)
|
||||
c.Assert(out, checker.Contains, "/tmp/Dockerfile")
|
||||
c.Assert(out, checker.Not(checker.Contains), "baz")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiRemoteTarballContext(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
buffer := new(bytes.Buffer)
|
||||
tw := tar.NewWriter(buffer)
|
||||
defer tw.Close()
|
||||
|
||||
dockerfile := []byte("FROM busybox")
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: "Dockerfile",
|
||||
Size: int64(len(dockerfile)),
|
||||
})
|
||||
// failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, err = tw.Write(dockerfile)
|
||||
// failed to write tar file content
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// failed to close tar archive
|
||||
c.Assert(tw.Close(), checker.IsNil)
|
||||
|
||||
server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
|
||||
"testT.tar": buffer,
|
||||
})
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
defer server.Close()
|
||||
|
||||
res, b, err := sockRequestRaw("POST", "/build?remote="+server.URL()+"/testT.tar", nil, "application/tar")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
b.Close()
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiRemoteTarballContextWithCustomDockerfile(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
buffer := new(bytes.Buffer)
|
||||
tw := tar.NewWriter(buffer)
|
||||
defer tw.Close()
|
||||
|
||||
dockerfile := []byte(`FROM busybox
|
||||
RUN echo 'wrong'`)
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: "Dockerfile",
|
||||
Size: int64(len(dockerfile)),
|
||||
})
|
||||
// failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, err = tw.Write(dockerfile)
|
||||
// failed to write tar file content
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
custom := []byte(`FROM busybox
|
||||
RUN echo 'right'
|
||||
`)
|
||||
err = tw.WriteHeader(&tar.Header{
|
||||
Name: "custom",
|
||||
Size: int64(len(custom)),
|
||||
})
|
||||
|
||||
// failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, err = tw.Write(custom)
|
||||
// failed to write tar file content
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// failed to close tar archive
|
||||
c.Assert(tw.Close(), checker.IsNil)
|
||||
|
||||
server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
|
||||
"testT.tar": buffer,
|
||||
})
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
defer server.Close()
|
||||
url := "/build?dockerfile=custom&remote=" + server.URL() + "/testT.tar"
|
||||
res, body, err := sockRequestRaw("POST", url, nil, "application/tar")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
defer body.Close()
|
||||
content, err := readBody(body)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Build used the wrong dockerfile.
|
||||
c.Assert(string(content), checker.Not(checker.Contains), "wrong")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiLowerDockerfile(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
git, err := newFakeGit("repo", map[string]string{
|
||||
"dockerfile": `FROM busybox
|
||||
RUN echo from dockerfile`,
|
||||
}, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer git.Close()
|
||||
|
||||
res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
buf, err := readBody(body)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out := string(buf)
|
||||
c.Assert(out, checker.Contains, "from dockerfile")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiBuildGitWithF(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
git, err := newFakeGit("repo", map[string]string{
|
||||
"baz": `FROM busybox
|
||||
RUN echo from baz`,
|
||||
"Dockerfile": `FROM busybox
|
||||
RUN echo from Dockerfile`,
|
||||
}, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer git.Close()
|
||||
|
||||
// Make sure it tries to 'dockerfile' query param value
|
||||
res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
buf, err := readBody(body)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out := string(buf)
|
||||
c.Assert(out, checker.Contains, "from baz")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiDoubleDockerfile(c *check.C) {
|
||||
testRequires(c, UnixCli) // dockerfile overwrites Dockerfile on Windows
|
||||
git, err := newFakeGit("repo", map[string]string{
|
||||
"Dockerfile": `FROM busybox
|
||||
RUN echo from Dockerfile`,
|
||||
"dockerfile": `FROM busybox
|
||||
RUN echo from dockerfile`,
|
||||
}, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer git.Close()
|
||||
|
||||
// Make sure it tries to 'dockerfile' query param value
|
||||
res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
buf, err := readBody(body)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out := string(buf)
|
||||
c.Assert(out, checker.Contains, "from Dockerfile")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiDockerfileSymlink(c *check.C) {
|
||||
// Test to make sure we stop people from trying to leave the
|
||||
// build context when specifying a symlink as the path to the dockerfile
|
||||
buffer := new(bytes.Buffer)
|
||||
tw := tar.NewWriter(buffer)
|
||||
defer tw.Close()
|
||||
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: "Dockerfile",
|
||||
Typeflag: tar.TypeSymlink,
|
||||
Linkname: "/etc/passwd",
|
||||
})
|
||||
// failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// failed to close tar archive
|
||||
c.Assert(tw.Close(), checker.IsNil)
|
||||
|
||||
res, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
|
||||
|
||||
out, err := readBody(body)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// The reason the error is "Cannot locate specified Dockerfile" is because
|
||||
// in the builder, the symlink is resolved within the context, therefore
|
||||
// Dockerfile -> /etc/passwd becomes etc/passwd from the context which is
|
||||
// a nonexistent file.
|
||||
c.Assert(string(out), checker.Contains, "Cannot locate specified Dockerfile: Dockerfile", check.Commentf("Didn't complain about leaving build context"))
|
||||
}
|
||||
73
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_events_test.go
generated
vendored
Normal file
73
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_events_test.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestEventsApiEmptyOutput(c *check.C) {
|
||||
type apiResp struct {
|
||||
resp *http.Response
|
||||
err error
|
||||
}
|
||||
chResp := make(chan *apiResp)
|
||||
go func() {
|
||||
resp, body, err := sockRequestRaw("GET", "/events", nil, "")
|
||||
body.Close()
|
||||
chResp <- &apiResp{resp, err}
|
||||
}()
|
||||
|
||||
select {
|
||||
case r := <-chResp:
|
||||
c.Assert(r.err, checker.IsNil)
|
||||
c.Assert(r.resp.StatusCode, checker.Equals, http.StatusOK)
|
||||
case <-time.After(3 * time.Second):
|
||||
c.Fatal("timeout waiting for events api to respond, should have responded immediately")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsApiBackwardsCompatible(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
ts := strconv.FormatInt(since, 10)
|
||||
|
||||
out, _ := dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top")
|
||||
containerID := strings.TrimSpace(out)
|
||||
c.Assert(waitRun(containerID), checker.IsNil)
|
||||
|
||||
q := url.Values{}
|
||||
q.Set("since", ts)
|
||||
|
||||
_, body, err := sockRequestRaw("GET", "/events?"+q.Encode(), nil, "")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer body.Close()
|
||||
|
||||
dec := json.NewDecoder(body)
|
||||
var containerCreateEvent *jsonmessage.JSONMessage
|
||||
for {
|
||||
var event jsonmessage.JSONMessage
|
||||
if err := dec.Decode(&event); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
c.Fatal(err)
|
||||
}
|
||||
if event.Status == "create" && event.ID == containerID {
|
||||
containerCreateEvent = &event
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
c.Assert(containerCreateEvent, checker.Not(checker.IsNil))
|
||||
c.Assert(containerCreateEvent.Status, checker.Equals, "create")
|
||||
c.Assert(containerCreateEvent.ID, checker.Equals, containerID)
|
||||
c.Assert(containerCreateEvent.From, checker.Equals, "busybox")
|
||||
}
|
||||
335
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_network_test.go
generated
vendored
Normal file
335
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_network_test.go
generated
vendored
Normal file
@@ -0,0 +1,335 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/docker/engine-api/types"
|
||||
"github.com/docker/engine-api/types/filters"
|
||||
"github.com/docker/engine-api/types/network"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestApiNetworkGetDefaults(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// By default docker daemon creates 3 networks. check if they are present
|
||||
defaults := []string{"bridge", "host", "none"}
|
||||
for _, nn := range defaults {
|
||||
c.Assert(isNetworkAvailable(c, nn), checker.Equals, true)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiNetworkCreateDelete(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// Create a network
|
||||
name := "testnetwork"
|
||||
config := types.NetworkCreate{
|
||||
Name: name,
|
||||
CheckDuplicate: true,
|
||||
}
|
||||
id := createNetwork(c, config, true)
|
||||
c.Assert(isNetworkAvailable(c, name), checker.Equals, true)
|
||||
|
||||
// delete the network and make sure it is deleted
|
||||
deleteNetwork(c, id, true)
|
||||
c.Assert(isNetworkAvailable(c, name), checker.Equals, false)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiNetworkCreateCheckDuplicate(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
name := "testcheckduplicate"
|
||||
configOnCheck := types.NetworkCreate{
|
||||
Name: name,
|
||||
CheckDuplicate: true,
|
||||
}
|
||||
configNotCheck := types.NetworkCreate{
|
||||
Name: name,
|
||||
CheckDuplicate: false,
|
||||
}
|
||||
|
||||
// Creating a new network first
|
||||
createNetwork(c, configOnCheck, true)
|
||||
c.Assert(isNetworkAvailable(c, name), checker.Equals, true)
|
||||
|
||||
// Creating another network with same name and CheckDuplicate must fail
|
||||
createNetwork(c, configOnCheck, false)
|
||||
|
||||
// Creating another network with same name and not CheckDuplicate must succeed
|
||||
createNetwork(c, configNotCheck, true)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiNetworkFilter(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
nr := getNetworkResource(c, getNetworkIDByName(c, "bridge"))
|
||||
c.Assert(nr.Name, checker.Equals, "bridge")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiNetworkInspect(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// Inspect default bridge network
|
||||
nr := getNetworkResource(c, "bridge")
|
||||
c.Assert(nr.Name, checker.Equals, "bridge")
|
||||
|
||||
// run a container and attach it to the default bridge network
|
||||
out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
|
||||
containerID := strings.TrimSpace(out)
|
||||
containerIP := findContainerIP(c, "test", "bridge")
|
||||
|
||||
// inspect default bridge network again and make sure the container is connected
|
||||
nr = getNetworkResource(c, nr.ID)
|
||||
c.Assert(nr.Driver, checker.Equals, "bridge")
|
||||
c.Assert(nr.Scope, checker.Equals, "local")
|
||||
c.Assert(nr.IPAM.Driver, checker.Equals, "default")
|
||||
c.Assert(len(nr.Containers), checker.Equals, 1)
|
||||
c.Assert(nr.Containers[containerID], checker.NotNil)
|
||||
|
||||
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(ip.String(), checker.Equals, containerIP)
|
||||
|
||||
// IPAM configuration inspect
|
||||
ipam := network.IPAM{
|
||||
Driver: "default",
|
||||
Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}},
|
||||
}
|
||||
config := types.NetworkCreate{
|
||||
Name: "br0",
|
||||
Driver: "bridge",
|
||||
IPAM: ipam,
|
||||
Options: map[string]string{"foo": "bar", "opts": "dopts"},
|
||||
}
|
||||
id0 := createNetwork(c, config, true)
|
||||
c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true)
|
||||
|
||||
nr = getNetworkResource(c, id0)
|
||||
c.Assert(len(nr.IPAM.Config), checker.Equals, 1)
|
||||
c.Assert(nr.IPAM.Config[0].Subnet, checker.Equals, "172.28.0.0/16")
|
||||
c.Assert(nr.IPAM.Config[0].IPRange, checker.Equals, "172.28.5.0/24")
|
||||
c.Assert(nr.IPAM.Config[0].Gateway, checker.Equals, "172.28.5.254")
|
||||
c.Assert(nr.Options["foo"], checker.Equals, "bar")
|
||||
c.Assert(nr.Options["opts"], checker.Equals, "dopts")
|
||||
|
||||
// delete the network and make sure it is deleted
|
||||
deleteNetwork(c, id0, true)
|
||||
c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, false)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiNetworkConnectDisconnect(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// Create test network
|
||||
name := "testnetwork"
|
||||
config := types.NetworkCreate{
|
||||
Name: name,
|
||||
}
|
||||
id := createNetwork(c, config, true)
|
||||
nr := getNetworkResource(c, id)
|
||||
c.Assert(nr.Name, checker.Equals, name)
|
||||
c.Assert(nr.ID, checker.Equals, id)
|
||||
c.Assert(len(nr.Containers), checker.Equals, 0)
|
||||
|
||||
// run a container
|
||||
out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
// connect the container to the test network
|
||||
connectNetwork(c, nr.ID, containerID)
|
||||
|
||||
// inspect the network to make sure container is connected
|
||||
nr = getNetworkResource(c, nr.ID)
|
||||
c.Assert(len(nr.Containers), checker.Equals, 1)
|
||||
c.Assert(nr.Containers[containerID], checker.NotNil)
|
||||
|
||||
// check if container IP matches network inspect
|
||||
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
|
||||
c.Assert(err, checker.IsNil)
|
||||
containerIP := findContainerIP(c, "test", "testnetwork")
|
||||
c.Assert(ip.String(), checker.Equals, containerIP)
|
||||
|
||||
// disconnect container from the network
|
||||
disconnectNetwork(c, nr.ID, containerID)
|
||||
nr = getNetworkResource(c, nr.ID)
|
||||
c.Assert(nr.Name, checker.Equals, name)
|
||||
c.Assert(len(nr.Containers), checker.Equals, 0)
|
||||
|
||||
// delete the network
|
||||
deleteNetwork(c, nr.ID, true)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// test0 bridge network
|
||||
ipam0 := network.IPAM{
|
||||
Driver: "default",
|
||||
Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}},
|
||||
}
|
||||
config0 := types.NetworkCreate{
|
||||
Name: "test0",
|
||||
Driver: "bridge",
|
||||
IPAM: ipam0,
|
||||
}
|
||||
id0 := createNetwork(c, config0, true)
|
||||
c.Assert(isNetworkAvailable(c, "test0"), checker.Equals, true)
|
||||
|
||||
ipam1 := network.IPAM{
|
||||
Driver: "default",
|
||||
Config: []network.IPAMConfig{{Subnet: "192.178.128.0/17", Gateway: "192.178.128.1"}},
|
||||
}
|
||||
// test1 bridge network overlaps with test0
|
||||
config1 := types.NetworkCreate{
|
||||
Name: "test1",
|
||||
Driver: "bridge",
|
||||
IPAM: ipam1,
|
||||
}
|
||||
createNetwork(c, config1, false)
|
||||
c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, false)
|
||||
|
||||
ipam2 := network.IPAM{
|
||||
Driver: "default",
|
||||
Config: []network.IPAMConfig{{Subnet: "192.169.0.0/16", Gateway: "192.169.100.100"}},
|
||||
}
|
||||
// test2 bridge network does not overlap
|
||||
config2 := types.NetworkCreate{
|
||||
Name: "test2",
|
||||
Driver: "bridge",
|
||||
IPAM: ipam2,
|
||||
}
|
||||
createNetwork(c, config2, true)
|
||||
c.Assert(isNetworkAvailable(c, "test2"), checker.Equals, true)
|
||||
|
||||
// remove test0 and retry to create test1
|
||||
deleteNetwork(c, id0, true)
|
||||
createNetwork(c, config1, true)
|
||||
c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, true)
|
||||
|
||||
// for networks w/o ipam specified, docker will choose proper non-overlapping subnets
|
||||
createNetwork(c, types.NetworkCreate{Name: "test3"}, true)
|
||||
c.Assert(isNetworkAvailable(c, "test3"), checker.Equals, true)
|
||||
createNetwork(c, types.NetworkCreate{Name: "test4"}, true)
|
||||
c.Assert(isNetworkAvailable(c, "test4"), checker.Equals, true)
|
||||
createNetwork(c, types.NetworkCreate{Name: "test5"}, true)
|
||||
c.Assert(isNetworkAvailable(c, "test5"), checker.Equals, true)
|
||||
|
||||
for i := 1; i < 6; i++ {
|
||||
deleteNetwork(c, fmt.Sprintf("test%d", i), true)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiCreateDeletePredefinedNetworks(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
createDeletePredefinedNetwork(c, "bridge")
|
||||
createDeletePredefinedNetwork(c, "none")
|
||||
createDeletePredefinedNetwork(c, "host")
|
||||
}
|
||||
|
||||
func createDeletePredefinedNetwork(c *check.C, name string) {
|
||||
// Create pre-defined network
|
||||
config := types.NetworkCreate{
|
||||
Name: name,
|
||||
CheckDuplicate: true,
|
||||
}
|
||||
shouldSucceed := false
|
||||
createNetwork(c, config, shouldSucceed)
|
||||
deleteNetwork(c, name, shouldSucceed)
|
||||
}
|
||||
|
||||
func isNetworkAvailable(c *check.C, name string) bool {
|
||||
status, body, err := sockRequest("GET", "/networks", nil)
|
||||
c.Assert(status, checker.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
nJSON := []types.NetworkResource{}
|
||||
err = json.Unmarshal(body, &nJSON)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
for _, n := range nJSON {
|
||||
if n.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getNetworkIDByName(c *check.C, name string) string {
|
||||
var (
|
||||
v = url.Values{}
|
||||
filterArgs = filters.NewArgs()
|
||||
)
|
||||
filterArgs.Add("name", name)
|
||||
filterJSON, err := filters.ToParam(filterArgs)
|
||||
c.Assert(err, checker.IsNil)
|
||||
v.Set("filters", filterJSON)
|
||||
|
||||
status, body, err := sockRequest("GET", "/networks?"+v.Encode(), nil)
|
||||
c.Assert(status, checker.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
nJSON := []types.NetworkResource{}
|
||||
err = json.Unmarshal(body, &nJSON)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(len(nJSON), checker.Equals, 1)
|
||||
|
||||
return nJSON[0].ID
|
||||
}
|
||||
|
||||
func getNetworkResource(c *check.C, id string) *types.NetworkResource {
|
||||
_, obj, err := sockRequest("GET", "/networks/"+id, nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
nr := types.NetworkResource{}
|
||||
err = json.Unmarshal(obj, &nr)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
return &nr
|
||||
}
|
||||
|
||||
func createNetwork(c *check.C, config types.NetworkCreate, shouldSucceed bool) string {
|
||||
status, resp, err := sockRequest("POST", "/networks/create", config)
|
||||
if !shouldSucceed {
|
||||
c.Assert(status, checker.Not(checker.Equals), http.StatusCreated)
|
||||
return ""
|
||||
}
|
||||
|
||||
c.Assert(status, checker.Equals, http.StatusCreated)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
var nr types.NetworkCreateResponse
|
||||
err = json.Unmarshal(resp, &nr)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
return nr.ID
|
||||
}
|
||||
|
||||
func connectNetwork(c *check.C, nid, cid string) {
|
||||
config := types.NetworkConnect{
|
||||
Container: cid,
|
||||
}
|
||||
|
||||
status, _, err := sockRequest("POST", "/networks/"+nid+"/connect", config)
|
||||
c.Assert(status, checker.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func disconnectNetwork(c *check.C, nid, cid string) {
|
||||
config := types.NetworkConnect{
|
||||
Container: cid,
|
||||
}
|
||||
|
||||
status, _, err := sockRequest("POST", "/networks/"+nid+"/disconnect", config)
|
||||
c.Assert(status, checker.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func deleteNetwork(c *check.C, id string, shouldSucceed bool) {
|
||||
status, _, err := sockRequest("DELETE", "/networks/"+id, nil)
|
||||
if !shouldSucceed {
|
||||
c.Assert(status, checker.Not(checker.Equals), http.StatusOK)
|
||||
return
|
||||
}
|
||||
c.Assert(status, checker.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
44
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_resize_test.go
generated
vendored
Normal file
44
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_resize_test.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestResizeApiResponse(c *check.C) {
|
||||
out, _ := runSleepingContainer(c, "-d")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
|
||||
status, _, err := sockRequest("POST", endpoint, nil)
|
||||
c.Assert(status, check.Equals, http.StatusOK)
|
||||
c.Assert(err, check.IsNil)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestResizeApiHeightWidthNoInt(c *check.C) {
|
||||
out, _ := runSleepingContainer(c, "-d")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
endpoint := "/containers/" + cleanedContainerID + "/resize?h=foo&w=bar"
|
||||
status, _, err := sockRequest("POST", endpoint, nil)
|
||||
c.Assert(status, check.Equals, http.StatusInternalServerError)
|
||||
c.Assert(err, check.IsNil)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestResizeApiResponseWhenContainerNotStarted(c *check.C) {
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
// make sure the exited container is not running
|
||||
dockerCmd(c, "wait", cleanedContainerID)
|
||||
|
||||
endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
|
||||
status, body, err := sockRequest("POST", endpoint, nil)
|
||||
c.Assert(status, check.Equals, http.StatusInternalServerError)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
c.Assert(string(body), checker.Contains, "is not running", check.Commentf("resize should fail with message 'Container is not running'"))
|
||||
}
|
||||
102
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_test.go
generated
vendored
Executable file
102
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_test.go
generated
vendored
Executable file
@@ -0,0 +1,102 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestApiOptionsRoute(c *check.C) {
|
||||
status, _, err := sockRequest("OPTIONS", "/", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(status, checker.Equals, http.StatusOK)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiGetEnabledCors(c *check.C) {
|
||||
res, body, err := sockRequestRaw("GET", "/version", nil, "")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
body.Close()
|
||||
// TODO: @runcom incomplete tests, why old integration tests had this headers
|
||||
// and here none of the headers below are in the response?
|
||||
//c.Log(res.Header)
|
||||
//c.Assert(res.Header.Get("Access-Control-Allow-Origin"), check.Equals, "*")
|
||||
//c.Assert(res.Header.Get("Access-Control-Allow-Headers"), check.Equals, "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiVersionStatusCode(c *check.C) {
|
||||
conn, err := sockConn(time.Duration(10 * time.Second))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
client := httputil.NewClientConn(conn, nil)
|
||||
defer client.Close()
|
||||
|
||||
req, err := http.NewRequest("GET", "/v999.0/version", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Header.Set("User-Agent", "Docker-Client/999.0 (os)")
|
||||
|
||||
res, err := client.Do(req)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiClientVersionNewerThanServer(c *check.C) {
|
||||
v := strings.Split(api.DefaultVersion.String(), ".")
|
||||
vMinInt, err := strconv.Atoi(v[1])
|
||||
c.Assert(err, checker.IsNil)
|
||||
vMinInt++
|
||||
v[1] = strconv.Itoa(vMinInt)
|
||||
version := strings.Join(v, ".")
|
||||
|
||||
status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(status, checker.Equals, http.StatusBadRequest)
|
||||
expected := fmt.Sprintf("client is newer than server (client API version: %s, server API version: %s)", version, api.DefaultVersion)
|
||||
c.Assert(strings.TrimSpace(string(body)), checker.Equals, expected)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiClientVersionOldNotSupported(c *check.C) {
|
||||
v := strings.Split(api.MinVersion.String(), ".")
|
||||
vMinInt, err := strconv.Atoi(v[1])
|
||||
c.Assert(err, checker.IsNil)
|
||||
vMinInt--
|
||||
v[1] = strconv.Itoa(vMinInt)
|
||||
version := strings.Join(v, ".")
|
||||
|
||||
status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(status, checker.Equals, http.StatusBadRequest)
|
||||
expected := fmt.Sprintf("client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", version, api.MinVersion)
|
||||
c.Assert(strings.TrimSpace(string(body)), checker.Equals, expected)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestApiDockerApiVersion(c *check.C) {
|
||||
var svrVersion string
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
url := r.URL.Path
|
||||
svrVersion = url
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
// Test using the env var first
|
||||
cmd := exec.Command(dockerBinary, "--region="+server.URL[7:], "version")
|
||||
cmd.Env = append([]string{"DOCKER_API_VERSION=xxx"}, os.Environ()...)
|
||||
out, _, _ := runCommandWithOutput(cmd)
|
||||
|
||||
c.Assert(svrVersion, check.Equals, "/vxxx/version")
|
||||
|
||||
if !strings.Contains(out, "API version: xxx") {
|
||||
c.Fatalf("Out didn't have 'xxx' for the API version, had:\n%s", out)
|
||||
}
|
||||
}
|
||||
35
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_update_unix_test.go
generated
vendored
Normal file
35
vendor/github.com/hyperhq/hypercli/integration-cli/skip/api/hyper_api_update_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestApiUpdateContainer(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, memoryLimitSupport)
|
||||
testRequires(c, swapMemorySupport)
|
||||
|
||||
name := "apiUpdateContainer"
|
||||
hostConfig := map[string]interface{}{
|
||||
"Memory": 314572800,
|
||||
"MemorySwap": 524288000,
|
||||
}
|
||||
dockerCmd(c, "run", "-d", "--name", name, "-m", "200M", "busybox", "top")
|
||||
_, _, err := sockRequest("POST", "/containers/"+name+"/update", hostConfig)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "314572800")
|
||||
file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
|
||||
out, _ := dockerCmd(c, "exec", name, "cat", file)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "314572800")
|
||||
|
||||
c.Assert(inspectField(c, name, "HostConfig.MemorySwap"), checker.Equals, "524288000")
|
||||
file = "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"
|
||||
out, _ = dockerCmd(c, "exec", name, "cat", file)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "524288000")
|
||||
}
|
||||
275
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_authz_unix_test.go
generated
vendored
Normal file
275
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_authz_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/authorization"
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/docker/docker/pkg/plugins"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
const (
|
||||
testAuthZPlugin = "authzplugin"
|
||||
unauthorizedMessage = "User unauthorized authz plugin"
|
||||
errorMessage = "something went wrong..."
|
||||
containerListAPI = "/containers/json"
|
||||
)
|
||||
|
||||
func init() {
|
||||
check.Suite(&DockerAuthzSuite{
|
||||
ds: &DockerSuite{},
|
||||
})
|
||||
}
|
||||
|
||||
type DockerAuthzSuite struct {
|
||||
server *httptest.Server
|
||||
ds *DockerSuite
|
||||
d *Daemon
|
||||
ctrl *authorizationController
|
||||
}
|
||||
|
||||
type authorizationController struct {
|
||||
reqRes authorization.Response // reqRes holds the plugin response to the initial client request
|
||||
resRes authorization.Response // resRes holds the plugin response to the daemon response
|
||||
psRequestCnt int // psRequestCnt counts the number of calls to list container request api
|
||||
psResponseCnt int // psResponseCnt counts the number of calls to list containers response API
|
||||
requestsURIs []string // requestsURIs stores all request URIs that are sent to the authorization controller
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) SetUpTest(c *check.C) {
|
||||
s.d = NewDaemon(c)
|
||||
s.ctrl = &authorizationController{}
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) TearDownTest(c *check.C) {
|
||||
s.d.Stop()
|
||||
s.ds.TearDownTest(c)
|
||||
s.ctrl = nil
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) SetUpSuite(c *check.C) {
|
||||
mux := http.NewServeMux()
|
||||
s.server = httptest.NewServer(mux)
|
||||
c.Assert(s.server, check.NotNil, check.Commentf("Failed to start a HTTP Server"))
|
||||
|
||||
mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
|
||||
b, err := json.Marshal(plugins.Manifest{Implements: []string{authorization.AuthZApiImplements}})
|
||||
c.Assert(err, check.IsNil)
|
||||
w.Write(b)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/AuthZPlugin.AuthZReq", func(w http.ResponseWriter, r *http.Request) {
|
||||
if s.ctrl.reqRes.Err != "" {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
b, err := json.Marshal(s.ctrl.reqRes)
|
||||
c.Assert(err, check.IsNil)
|
||||
w.Write(b)
|
||||
defer r.Body.Close()
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
c.Assert(err, check.IsNil)
|
||||
authReq := authorization.Request{}
|
||||
err = json.Unmarshal(body, &authReq)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
assertBody(c, authReq.RequestURI, authReq.RequestHeaders, authReq.RequestBody)
|
||||
assertAuthHeaders(c, authReq.RequestHeaders)
|
||||
|
||||
// Count only container list api
|
||||
if strings.HasSuffix(authReq.RequestURI, containerListAPI) {
|
||||
s.ctrl.psRequestCnt++
|
||||
}
|
||||
|
||||
s.ctrl.requestsURIs = append(s.ctrl.requestsURIs, authReq.RequestURI)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/AuthZPlugin.AuthZRes", func(w http.ResponseWriter, r *http.Request) {
|
||||
if s.ctrl.resRes.Err != "" {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
b, err := json.Marshal(s.ctrl.resRes)
|
||||
c.Assert(err, check.IsNil)
|
||||
w.Write(b)
|
||||
|
||||
defer r.Body.Close()
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
c.Assert(err, check.IsNil)
|
||||
authReq := authorization.Request{}
|
||||
err = json.Unmarshal(body, &authReq)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
assertBody(c, authReq.RequestURI, authReq.ResponseHeaders, authReq.ResponseBody)
|
||||
assertAuthHeaders(c, authReq.ResponseHeaders)
|
||||
|
||||
// Count only container list api
|
||||
if strings.HasSuffix(authReq.RequestURI, containerListAPI) {
|
||||
s.ctrl.psResponseCnt++
|
||||
}
|
||||
})
|
||||
|
||||
err := os.MkdirAll("/etc/docker/plugins", 0755)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", testAuthZPlugin)
|
||||
err = ioutil.WriteFile(fileName, []byte(s.server.URL), 0644)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// assertAuthHeaders validates authentication headers are removed
|
||||
func assertAuthHeaders(c *check.C, headers map[string]string) error {
|
||||
for k := range headers {
|
||||
if strings.Contains(strings.ToLower(k), "auth") || strings.Contains(strings.ToLower(k), "x-registry") {
|
||||
c.Errorf("Found authentication headers in request '%v'", headers)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// assertBody asserts that body is removed for non text/json requests
|
||||
func assertBody(c *check.C, requestURI string, headers map[string]string, body []byte) {
|
||||
if strings.Contains(strings.ToLower(requestURI), "auth") && len(body) > 0 {
|
||||
//return fmt.Errorf("Body included for authentication endpoint %s", string(body))
|
||||
c.Errorf("Body included for authentication endpoint %s", string(body))
|
||||
}
|
||||
|
||||
for k, v := range headers {
|
||||
if strings.EqualFold(k, "Content-Type") && strings.HasPrefix(v, "text/") || v == "application/json" {
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(body) > 0 {
|
||||
c.Errorf("Body included while it should not (Headers: '%v')", headers)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) TearDownSuite(c *check.C) {
|
||||
if s.server == nil {
|
||||
return
|
||||
}
|
||||
|
||||
s.server.Close()
|
||||
|
||||
err := os.RemoveAll("/etc/docker/plugins")
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) TestAuthZPluginAllowRequest(c *check.C) {
|
||||
// start the daemon and load busybox, --net=none build fails otherwise
|
||||
// cause it needs to pull busybox
|
||||
c.Assert(s.d.StartWithBusybox(), check.IsNil)
|
||||
// restart the daemon and enable the plugin, otherwise busybox loading
|
||||
// is blocked by the plugin itself
|
||||
c.Assert(s.d.Restart("--authorization-plugin="+testAuthZPlugin), check.IsNil)
|
||||
|
||||
s.ctrl.reqRes.Allow = true
|
||||
s.ctrl.resRes.Allow = true
|
||||
|
||||
// Ensure command successful
|
||||
out, err := s.d.Cmd("run", "-d", "busybox", "top")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
id := strings.TrimSpace(out)
|
||||
assertURIRecorded(c, s.ctrl.requestsURIs, "/containers/create")
|
||||
assertURIRecorded(c, s.ctrl.requestsURIs, fmt.Sprintf("/containers/%s/start", id))
|
||||
|
||||
out, err = s.d.Cmd("ps")
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(assertContainerList(out, []string{id}), check.Equals, true)
|
||||
c.Assert(s.ctrl.psRequestCnt, check.Equals, 1)
|
||||
c.Assert(s.ctrl.psResponseCnt, check.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) TestAuthZPluginDenyRequest(c *check.C) {
|
||||
err := s.d.Start("--authorization-plugin=" + testAuthZPlugin)
|
||||
c.Assert(err, check.IsNil)
|
||||
s.ctrl.reqRes.Allow = false
|
||||
s.ctrl.reqRes.Msg = unauthorizedMessage
|
||||
|
||||
// Ensure command is blocked
|
||||
res, err := s.d.Cmd("ps")
|
||||
c.Assert(err, check.NotNil)
|
||||
c.Assert(s.ctrl.psRequestCnt, check.Equals, 1)
|
||||
c.Assert(s.ctrl.psResponseCnt, check.Equals, 0)
|
||||
|
||||
// Ensure unauthorized message appears in response
|
||||
c.Assert(res, check.Equals, fmt.Sprintf("Error response from daemon: authorization denied by plugin %s: %s\n", testAuthZPlugin, unauthorizedMessage))
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) TestAuthZPluginDenyResponse(c *check.C) {
|
||||
err := s.d.Start("--authorization-plugin=" + testAuthZPlugin)
|
||||
c.Assert(err, check.IsNil)
|
||||
s.ctrl.reqRes.Allow = true
|
||||
s.ctrl.resRes.Allow = false
|
||||
s.ctrl.resRes.Msg = unauthorizedMessage
|
||||
|
||||
// Ensure command is blocked
|
||||
res, err := s.d.Cmd("ps")
|
||||
c.Assert(err, check.NotNil)
|
||||
c.Assert(s.ctrl.psRequestCnt, check.Equals, 1)
|
||||
c.Assert(s.ctrl.psResponseCnt, check.Equals, 1)
|
||||
|
||||
// Ensure unauthorized message appears in response
|
||||
c.Assert(res, check.Equals, fmt.Sprintf("Error response from daemon: authorization denied by plugin %s: %s\n", testAuthZPlugin, unauthorizedMessage))
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) TestAuthZPluginErrorResponse(c *check.C) {
|
||||
err := s.d.Start("--authorization-plugin=" + testAuthZPlugin)
|
||||
c.Assert(err, check.IsNil)
|
||||
s.ctrl.reqRes.Allow = true
|
||||
s.ctrl.resRes.Err = errorMessage
|
||||
|
||||
// Ensure command is blocked
|
||||
res, err := s.d.Cmd("ps")
|
||||
c.Assert(err, check.NotNil)
|
||||
|
||||
c.Assert(res, check.Equals, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s\n", testAuthZPlugin, authorization.AuthZApiResponse, errorMessage))
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) TestAuthZPluginErrorRequest(c *check.C) {
|
||||
err := s.d.Start("--authorization-plugin=" + testAuthZPlugin)
|
||||
c.Assert(err, check.IsNil)
|
||||
s.ctrl.reqRes.Err = errorMessage
|
||||
|
||||
// Ensure command is blocked
|
||||
res, err := s.d.Cmd("ps")
|
||||
c.Assert(err, check.NotNil)
|
||||
|
||||
c.Assert(res, check.Equals, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s\n", testAuthZPlugin, authorization.AuthZApiRequest, errorMessage))
|
||||
}
|
||||
|
||||
func (s *DockerAuthzSuite) TestAuthZPluginEnsureNoDuplicatePluginRegistration(c *check.C) {
|
||||
c.Assert(s.d.Start("--authorization-plugin="+testAuthZPlugin, "--authorization-plugin="+testAuthZPlugin), check.IsNil)
|
||||
|
||||
s.ctrl.reqRes.Allow = true
|
||||
s.ctrl.resRes.Allow = true
|
||||
|
||||
out, err := s.d.Cmd("ps")
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
|
||||
// assert plugin is only called once..
|
||||
c.Assert(s.ctrl.psRequestCnt, check.Equals, 1)
|
||||
c.Assert(s.ctrl.psResponseCnt, check.Equals, 1)
|
||||
}
|
||||
|
||||
// assertURIRecorded verifies that the given URI was sent and recorded in the authz plugin
|
||||
func assertURIRecorded(c *check.C, uris []string, uri string) {
|
||||
var found bool
|
||||
for _, u := range uris {
|
||||
if strings.Contains(u, uri) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
c.Fatalf("Expected to find URI '%s', recorded uris '%s'", uri, strings.Join(uris, ","))
|
||||
}
|
||||
}
|
||||
6570
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_build_test.go
generated
vendored
Normal file
6570
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_build_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
206
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_build_unix_test.go
generated
vendored
Normal file
206
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_build_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
|
||||
testRequires(c, cpuCfsQuota)
|
||||
name := "testbuildresourceconstraints"
|
||||
|
||||
ctx, err := fakeContext(`
|
||||
FROM hello-world:frozen
|
||||
RUN ["/hello"]
|
||||
`, map[string]string{})
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "--ulimit", "nofile=42", "-t", name, ".")
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
out, _ := dockerCmd(c, "ps", "-lq")
|
||||
cID := strings.TrimSpace(out)
|
||||
|
||||
type hostConfig struct {
|
||||
Memory int64
|
||||
MemorySwap int64
|
||||
CpusetCpus string
|
||||
CpusetMems string
|
||||
CPUShares int64
|
||||
CPUQuota int64
|
||||
Ulimits []*units.Ulimit
|
||||
}
|
||||
|
||||
cfg := inspectFieldJSON(c, cID, "HostConfig")
|
||||
|
||||
var c1 hostConfig
|
||||
err = json.Unmarshal([]byte(cfg), &c1)
|
||||
c.Assert(err, checker.IsNil, check.Commentf(cfg))
|
||||
|
||||
c.Assert(c1.Memory, checker.Equals, int64(64*1024*1024), check.Commentf("resource constraints not set properly for Memory"))
|
||||
c.Assert(c1.MemorySwap, checker.Equals, int64(-1), check.Commentf("resource constraints not set properly for MemorySwap"))
|
||||
c.Assert(c1.CpusetCpus, checker.Equals, "0", check.Commentf("resource constraints not set properly for CpusetCpus"))
|
||||
c.Assert(c1.CpusetMems, checker.Equals, "0", check.Commentf("resource constraints not set properly for CpusetMems"))
|
||||
c.Assert(c1.CPUShares, checker.Equals, int64(100), check.Commentf("resource constraints not set properly for CPUShares"))
|
||||
c.Assert(c1.CPUQuota, checker.Equals, int64(8000), check.Commentf("resource constraints not set properly for CPUQuota"))
|
||||
c.Assert(c1.Ulimits[0].Name, checker.Equals, "nofile", check.Commentf("resource constraints not set properly for Ulimits"))
|
||||
c.Assert(c1.Ulimits[0].Hard, checker.Equals, int64(42), check.Commentf("resource constraints not set properly for Ulimits"))
|
||||
|
||||
// Make sure constraints aren't saved to image
|
||||
dockerCmd(c, "run", "--name=test", name)
|
||||
|
||||
cfg = inspectFieldJSON(c, "test", "HostConfig")
|
||||
|
||||
var c2 hostConfig
|
||||
err = json.Unmarshal([]byte(cfg), &c2)
|
||||
c.Assert(err, checker.IsNil, check.Commentf(cfg))
|
||||
|
||||
c.Assert(c2.Memory, check.Not(checker.Equals), int64(64*1024*1024), check.Commentf("resource leaked from build for Memory"))
|
||||
c.Assert(c2.MemorySwap, check.Not(checker.Equals), int64(-1), check.Commentf("resource leaked from build for MemorySwap"))
|
||||
c.Assert(c2.CpusetCpus, check.Not(checker.Equals), "0", check.Commentf("resource leaked from build for CpusetCpus"))
|
||||
c.Assert(c2.CpusetMems, check.Not(checker.Equals), "0", check.Commentf("resource leaked from build for CpusetMems"))
|
||||
c.Assert(c2.CPUShares, check.Not(checker.Equals), int64(100), check.Commentf("resource leaked from build for CPUShares"))
|
||||
c.Assert(c2.CPUQuota, check.Not(checker.Equals), int64(8000), check.Commentf("resource leaked from build for CPUQuota"))
|
||||
c.Assert(c2.Ulimits, checker.IsNil, check.Commentf("resource leaked from build for Ulimits"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildAddChangeOwnership(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
name := "testbuildaddown"
|
||||
|
||||
ctx := func() *FakeContext {
|
||||
dockerfile := `
|
||||
FROM busybox
|
||||
ADD foo /bar/
|
||||
RUN [ $(stat -c %U:%G "/bar") = 'root:root' ]
|
||||
RUN [ $(stat -c %U:%G "/bar/foo") = 'root:root' ]
|
||||
`
|
||||
tmpDir, err := ioutil.TempDir("", "fake-context")
|
||||
c.Assert(err, check.IsNil)
|
||||
testFile, err := os.Create(filepath.Join(tmpDir, "foo"))
|
||||
if err != nil {
|
||||
c.Fatalf("failed to create foo file: %v", err)
|
||||
}
|
||||
defer testFile.Close()
|
||||
|
||||
chownCmd := exec.Command("chown", "daemon:daemon", "foo")
|
||||
chownCmd.Dir = tmpDir
|
||||
out, _, err := runCommandWithOutput(chownCmd)
|
||||
if err != nil {
|
||||
c.Fatal(err, out)
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
|
||||
c.Fatalf("failed to open destination dockerfile: %v", err)
|
||||
}
|
||||
return fakeContextFromDir(tmpDir)
|
||||
}()
|
||||
|
||||
defer ctx.Close()
|
||||
|
||||
if _, err := buildImageFromContext(name, ctx, true); err != nil {
|
||||
c.Fatalf("build failed to complete for TestBuildAddChangeOwnership: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that an infinite sleep during a build is killed if the client disconnects.
|
||||
// This test is fairly hairy because there are lots of ways to race.
|
||||
// Strategy:
|
||||
// * Monitor the output of docker events starting from before
|
||||
// * Run a 1-year-long sleep from a docker build.
|
||||
// * When docker events sees container start, close the "docker build" command
|
||||
// * Wait for docker events to emit a dying event.
|
||||
func (s *DockerSuite) TestBuildCancellationKillsSleep(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
name := "testbuildcancellation"
|
||||
|
||||
observer, err := newEventObserver(c)
|
||||
c.Assert(err, checker.IsNil)
|
||||
err = observer.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer observer.Stop()
|
||||
|
||||
// (Note: one year, will never finish)
|
||||
ctx, err := fakeContext("FROM busybox\nRUN sleep 31536000", nil)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer ctx.Close()
|
||||
|
||||
buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".")
|
||||
buildCmd.Dir = ctx.Dir
|
||||
|
||||
stdoutBuild, err := buildCmd.StdoutPipe()
|
||||
if err := buildCmd.Start(); err != nil {
|
||||
c.Fatalf("failed to run build: %s", err)
|
||||
}
|
||||
|
||||
matchCID := regexp.MustCompile("Running in (.+)")
|
||||
scanner := bufio.NewScanner(stdoutBuild)
|
||||
|
||||
outputBuffer := new(bytes.Buffer)
|
||||
var buildID string
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
outputBuffer.WriteString(line)
|
||||
outputBuffer.WriteString("\n")
|
||||
if matches := matchCID.FindStringSubmatch(line); len(matches) > 0 {
|
||||
buildID = matches[1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if buildID == "" {
|
||||
c.Fatalf("Unable to find build container id in build output:\n%s", outputBuffer.String())
|
||||
}
|
||||
|
||||
testActions := map[string]chan bool{
|
||||
"start": make(chan bool),
|
||||
"die": make(chan bool),
|
||||
}
|
||||
|
||||
matcher := matchEventLine(buildID, "container", testActions)
|
||||
processor := processEventMatch(testActions)
|
||||
go observer.Match(matcher, processor)
|
||||
|
||||
select {
|
||||
case <-time.After(10 * time.Second):
|
||||
observer.CheckEventError(c, buildID, "start", matcher)
|
||||
case <-testActions["start"]:
|
||||
// ignore, done
|
||||
}
|
||||
|
||||
// Send a kill to the `docker build` command.
|
||||
// Causes the underlying build to be cancelled due to socket close.
|
||||
if err := buildCmd.Process.Kill(); err != nil {
|
||||
c.Fatalf("error killing build command: %s", err)
|
||||
}
|
||||
|
||||
// Get the exit status of `docker build`, check it exited because killed.
|
||||
if err := buildCmd.Wait(); err != nil && !isKilled(err) {
|
||||
c.Fatalf("wait failed during build run: %T %s", err, err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(10 * time.Second):
|
||||
observer.CheckEventError(c, buildID, "die", matcher)
|
||||
case <-testActions["die"]:
|
||||
// ignore, done
|
||||
}
|
||||
}
|
||||
583
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_by_digest_test.go
generated
vendored
Normal file
583
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_by_digest_test.go
generated
vendored
Normal file
@@ -0,0 +1,583 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/digest"
|
||||
"github.com/docker/distribution/manifest/schema1"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/docker/engine-api/types"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
var (
|
||||
remoteRepoName = "dockercli/busybox-by-dgst"
|
||||
repoName = fmt.Sprintf("%s/%s", privateRegistryURL, remoteRepoName)
|
||||
pushDigestRegex = regexp.MustCompile("[\\S]+: digest: ([\\S]+) size: [0-9]+")
|
||||
digestRegex = regexp.MustCompile("Digest: ([\\S]+)")
|
||||
)
|
||||
|
||||
func setupImage(c *check.C) (digest.Digest, error) {
|
||||
return setupImageWithTag(c, "latest")
|
||||
}
|
||||
|
||||
func setupImageWithTag(c *check.C, tag string) (digest.Digest, error) {
|
||||
containerName := "busyboxbydigest"
|
||||
|
||||
dockerCmd(c, "run", "-d", "-e", "digest=1", "--name", containerName, "busybox")
|
||||
|
||||
// tag the image to upload it to the private registry
|
||||
repoAndTag := repoName + ":" + tag
|
||||
out, _, err := dockerCmdWithError("commit", containerName, repoAndTag)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("image tagging failed: %s", out))
|
||||
|
||||
// delete the container as we don't need it any more
|
||||
err = deleteContainer(containerName)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// push the image
|
||||
out, _, err = dockerCmdWithError("push", repoAndTag)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out))
|
||||
|
||||
// delete our local repo that we previously tagged
|
||||
rmiout, _, err := dockerCmdWithError("rmi", repoAndTag)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error deleting images prior to real test: %s", rmiout))
|
||||
|
||||
matches := pushDigestRegex.FindStringSubmatch(out)
|
||||
c.Assert(matches, checker.HasLen, 2, check.Commentf("unable to parse digest from push output: %s", out))
|
||||
pushDigest := matches[1]
|
||||
|
||||
return digest.Digest(pushDigest), nil
|
||||
}
|
||||
|
||||
func testPullByTagDisplaysDigest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
pushDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
// pull from the registry using the tag
|
||||
out, _ := dockerCmd(c, "pull", repoName)
|
||||
|
||||
// the pull output includes "Digest: <digest>", so find that
|
||||
matches := digestRegex.FindStringSubmatch(out)
|
||||
c.Assert(matches, checker.HasLen, 2, check.Commentf("unable to parse digest from pull output: %s", out))
|
||||
pullDigest := matches[1]
|
||||
|
||||
// make sure the pushed and pull digests match
|
||||
c.Assert(pushDigest.String(), checker.Equals, pullDigest)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
|
||||
testPullByTagDisplaysDigest(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
|
||||
testPullByTagDisplaysDigest(c)
|
||||
}
|
||||
|
||||
func testPullByDigest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
pushDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest)
|
||||
out, _ := dockerCmd(c, "pull", imageReference)
|
||||
|
||||
// the pull output includes "Digest: <digest>", so find that
|
||||
matches := digestRegex.FindStringSubmatch(out)
|
||||
c.Assert(matches, checker.HasLen, 2, check.Commentf("unable to parse digest from pull output: %s", out))
|
||||
pullDigest := matches[1]
|
||||
|
||||
// make sure the pushed and pull digests match
|
||||
c.Assert(pushDigest.String(), checker.Equals, pullDigest)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPullByDigest(c *check.C) {
|
||||
testPullByDigest(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPullByDigest(c *check.C) {
|
||||
testPullByDigest(c)
|
||||
}
|
||||
|
||||
func testPullByDigestNoFallback(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
imageReference := fmt.Sprintf("%s@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", repoName)
|
||||
out, _, err := dockerCmdWithError("pull", imageReference)
|
||||
c.Assert(err, checker.NotNil, check.Commentf("expected non-zero exit status and correct error message when pulling non-existing image"))
|
||||
c.Assert(out, checker.Contains, "manifest unknown", check.Commentf("expected non-zero exit status and correct error message when pulling non-existing image"))
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPullByDigestNoFallback(c *check.C) {
|
||||
testPullByDigestNoFallback(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPullByDigestNoFallback(c *check.C) {
|
||||
testPullByDigestNoFallback(c)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestCreateByDigest(c *check.C) {
|
||||
pushDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest)
|
||||
|
||||
containerName := "createByDigest"
|
||||
dockerCmd(c, "create", "--name", containerName, imageReference)
|
||||
|
||||
res := inspectField(c, containerName, "Config.Image")
|
||||
c.Assert(res, checker.Equals, imageReference)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestRunByDigest(c *check.C) {
|
||||
pushDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest)
|
||||
|
||||
containerName := "runByDigest"
|
||||
out, _ := dockerCmd(c, "run", "--name", containerName, imageReference, "sh", "-c", "echo found=$digest")
|
||||
|
||||
foundRegex := regexp.MustCompile("found=([^\n]+)")
|
||||
matches := foundRegex.FindStringSubmatch(out)
|
||||
c.Assert(matches, checker.HasLen, 2, check.Commentf("unable to parse digest from pull output: %s", out))
|
||||
c.Assert(matches[1], checker.Equals, "1", check.Commentf("Expected %q, got %q", "1", matches[1]))
|
||||
|
||||
res := inspectField(c, containerName, "Config.Image")
|
||||
c.Assert(res, checker.Equals, imageReference)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestRemoveImageByDigest(c *check.C) {
|
||||
digest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
dockerCmd(c, "pull", imageReference)
|
||||
|
||||
// make sure inspect runs ok
|
||||
inspectField(c, imageReference, "Id")
|
||||
|
||||
// do the delete
|
||||
err = deleteImages(imageReference)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("unexpected error deleting image"))
|
||||
|
||||
// try to inspect again - it should error this time
|
||||
_, err = inspectFieldWithError(imageReference, "Id")
|
||||
//unexpected nil err trying to inspect what should be a non-existent image
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "No such image")
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestBuildByDigest(c *check.C) {
|
||||
digest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
dockerCmd(c, "pull", imageReference)
|
||||
|
||||
// get the image id
|
||||
imageID := inspectField(c, imageReference, "Id")
|
||||
|
||||
// do the build
|
||||
name := "buildbydigest"
|
||||
_, err = buildImage(name, fmt.Sprintf(
|
||||
`FROM %s
|
||||
CMD ["/bin/echo", "Hello World"]`, imageReference),
|
||||
true)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// get the build's image id
|
||||
res := inspectField(c, name, "Config.Image")
|
||||
// make sure they match
|
||||
c.Assert(res, checker.Equals, imageID)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestTagByDigest(c *check.C) {
|
||||
digest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
dockerCmd(c, "pull", imageReference)
|
||||
|
||||
// tag it
|
||||
tag := "tagbydigest"
|
||||
dockerCmd(c, "tag", imageReference, tag)
|
||||
|
||||
expectedID := inspectField(c, imageReference, "Id")
|
||||
|
||||
tagID := inspectField(c, tag, "Id")
|
||||
c.Assert(tagID, checker.Equals, expectedID)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestListImagesWithoutDigests(c *check.C) {
|
||||
digest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
dockerCmd(c, "pull", imageReference)
|
||||
|
||||
out, _ := dockerCmd(c, "images")
|
||||
c.Assert(out, checker.Not(checker.Contains), "DIGEST", check.Commentf("list output should not have contained DIGEST header"))
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestListImagesWithDigests(c *check.C) {
|
||||
|
||||
// setup image1
|
||||
digest1, err := setupImageWithTag(c, "tag1")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
imageReference1 := fmt.Sprintf("%s@%s", repoName, digest1)
|
||||
c.Logf("imageReference1 = %s", imageReference1)
|
||||
|
||||
// pull image1 by digest
|
||||
dockerCmd(c, "pull", imageReference1)
|
||||
|
||||
// list images
|
||||
out, _ := dockerCmd(c, "images", "--digests")
|
||||
|
||||
// make sure repo shown, tag=<none>, digest = $digest1
|
||||
re1 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest1.String() + `\s`)
|
||||
c.Assert(re1.MatchString(out), checker.True, check.Commentf("expected %q: %s", re1.String(), out))
|
||||
// setup image2
|
||||
digest2, err := setupImageWithTag(c, "tag2")
|
||||
//error setting up image
|
||||
c.Assert(err, checker.IsNil)
|
||||
imageReference2 := fmt.Sprintf("%s@%s", repoName, digest2)
|
||||
c.Logf("imageReference2 = %s", imageReference2)
|
||||
|
||||
// pull image1 by digest
|
||||
dockerCmd(c, "pull", imageReference1)
|
||||
|
||||
// pull image2 by digest
|
||||
dockerCmd(c, "pull", imageReference2)
|
||||
|
||||
// list images
|
||||
out, _ = dockerCmd(c, "images", "--digests")
|
||||
|
||||
// make sure repo shown, tag=<none>, digest = $digest1
|
||||
c.Assert(re1.MatchString(out), checker.True, check.Commentf("expected %q: %s", re1.String(), out))
|
||||
|
||||
// make sure repo shown, tag=<none>, digest = $digest2
|
||||
re2 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest2.String() + `\s`)
|
||||
c.Assert(re2.MatchString(out), checker.True, check.Commentf("expected %q: %s", re2.String(), out))
|
||||
|
||||
// pull tag1
|
||||
dockerCmd(c, "pull", repoName+":tag1")
|
||||
|
||||
// list images
|
||||
out, _ = dockerCmd(c, "images", "--digests")
|
||||
|
||||
// make sure image 1 has repo, tag, <none> AND repo, <none>, digest
|
||||
reWithTag1 := regexp.MustCompile(`\s*` + repoName + `\s*tag1\s*<none>\s`)
|
||||
reWithDigest1 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest1.String() + `\s`)
|
||||
c.Assert(reWithDigest1.MatchString(out), checker.True, check.Commentf("expected %q: %s", reWithDigest1.String(), out))
|
||||
c.Assert(reWithTag1.MatchString(out), checker.True, check.Commentf("expected %q: %s", reWithTag1.String(), out))
|
||||
// make sure image 2 has repo, <none>, digest
|
||||
c.Assert(re2.MatchString(out), checker.True, check.Commentf("expected %q: %s", re2.String(), out))
|
||||
|
||||
// pull tag 2
|
||||
dockerCmd(c, "pull", repoName+":tag2")
|
||||
|
||||
// list images
|
||||
out, _ = dockerCmd(c, "images", "--digests")
|
||||
|
||||
// make sure image 1 has repo, tag, digest
|
||||
c.Assert(reWithTag1.MatchString(out), checker.True, check.Commentf("expected %q: %s", reWithTag1.String(), out))
|
||||
|
||||
// make sure image 2 has repo, tag, digest
|
||||
reWithTag2 := regexp.MustCompile(`\s*` + repoName + `\s*tag2\s*<none>\s`)
|
||||
reWithDigest2 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest2.String() + `\s`)
|
||||
c.Assert(reWithTag2.MatchString(out), checker.True, check.Commentf("expected %q: %s", reWithTag2.String(), out))
|
||||
c.Assert(reWithDigest2.MatchString(out), checker.True, check.Commentf("expected %q: %s", reWithDigest2.String(), out))
|
||||
|
||||
// list images
|
||||
out, _ = dockerCmd(c, "images", "--digests")
|
||||
|
||||
// make sure image 1 has repo, tag, digest
|
||||
c.Assert(reWithTag1.MatchString(out), checker.True, check.Commentf("expected %q: %s", reWithTag1.String(), out))
|
||||
// make sure image 2 has repo, tag, digest
|
||||
c.Assert(reWithTag2.MatchString(out), checker.True, check.Commentf("expected %q: %s", reWithTag2.String(), out))
|
||||
// make sure busybox has tag, but not digest
|
||||
busyboxRe := regexp.MustCompile(`\s*busybox\s*latest\s*<none>\s`)
|
||||
c.Assert(busyboxRe.MatchString(out), checker.True, check.Commentf("expected %q: %s", busyboxRe.String(), out))
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestInspectImageWithDigests(c *check.C) {
|
||||
digest, err := setupImage(c)
|
||||
c.Assert(err, check.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
dockerCmd(c, "pull", imageReference)
|
||||
|
||||
out, _ := dockerCmd(c, "inspect", imageReference)
|
||||
|
||||
var imageJSON []types.ImageInspect
|
||||
err = json.Unmarshal([]byte(out), &imageJSON)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(imageJSON, checker.HasLen, 1)
|
||||
c.Assert(imageJSON[0].RepoDigests, checker.HasLen, 1)
|
||||
c.Assert(stringutils.InSlice(imageJSON[0].RepoDigests, imageReference), checker.Equals, true)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPsListContainersFilterAncestorImageByDigest(c *check.C) {
|
||||
digest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, digest)
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
dockerCmd(c, "pull", imageReference)
|
||||
|
||||
// build a image from it
|
||||
imageName1 := "images_ps_filter_test"
|
||||
_, err = buildImage(imageName1, fmt.Sprintf(
|
||||
`FROM %s
|
||||
LABEL match me 1`, imageReference), true)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// run a container based on that
|
||||
out, _ := dockerCmd(c, "run", "-d", imageReference, "echo", "hello")
|
||||
expectedID := strings.TrimSpace(out)
|
||||
|
||||
// run a container based on the a descendant of that too
|
||||
out, _ = dockerCmd(c, "run", "-d", imageName1, "echo", "hello")
|
||||
expectedID1 := strings.TrimSpace(out)
|
||||
|
||||
expectedIDs := []string{expectedID, expectedID1}
|
||||
|
||||
// Invalid imageReference
|
||||
out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", fmt.Sprintf("--filter=ancestor=busybox@%s", digest))
|
||||
// Filter container for ancestor filter should be empty
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "")
|
||||
|
||||
// Valid imageReference
|
||||
out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+imageReference)
|
||||
checkPsAncestorFilterOutput(c, out, imageReference, expectedIDs)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C) {
|
||||
pushDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest)
|
||||
dockerCmd(c, "pull", imageReference)
|
||||
// just in case...
|
||||
|
||||
imageID := inspectField(c, imageReference, "Id")
|
||||
|
||||
dockerCmd(c, "rmi", imageID)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestDeleteImageWithDigestAndTag(c *check.C) {
|
||||
pushDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
// pull from the registry using the <name>@<digest> reference
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest)
|
||||
dockerCmd(c, "pull", imageReference)
|
||||
|
||||
imageID := inspectField(c, imageReference, "Id")
|
||||
|
||||
repoTag := repoName + ":sometag"
|
||||
repoTag2 := repoName + ":othertag"
|
||||
dockerCmd(c, "tag", imageReference, repoTag)
|
||||
dockerCmd(c, "tag", imageReference, repoTag2)
|
||||
|
||||
dockerCmd(c, "rmi", repoTag2)
|
||||
|
||||
// rmi should have deleted only repoTag2, because there's another tag
|
||||
inspectField(c, repoTag, "Id")
|
||||
|
||||
dockerCmd(c, "rmi", repoTag)
|
||||
|
||||
// rmi should have deleted the tag, the digest reference, and the image itself
|
||||
_, err = inspectFieldWithError(imageID, "Id")
|
||||
c.Assert(err, checker.NotNil, check.Commentf("image should have been deleted"))
|
||||
}
|
||||
|
||||
// TestPullFailsWithAlteredManifest tests that a `docker pull` fails when
|
||||
// we have modified a manifest blob and its digest cannot be verified.
|
||||
// This is the schema2 version of the test.
|
||||
func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
manifestDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
// Load the target manifest blob.
|
||||
manifestBlob := s.reg.readBlobContents(c, manifestDigest)
|
||||
|
||||
var imgManifest schema2.Manifest
|
||||
err = json.Unmarshal(manifestBlob, &imgManifest)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("unable to decode image manifest from blob"))
|
||||
|
||||
// Change a layer in the manifest.
|
||||
imgManifest.Layers[0].Digest = digest.Digest("sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
|
||||
|
||||
// Move the existing data file aside, so that we can replace it with a
|
||||
// malicious blob of data. NOTE: we defer the returned undo func.
|
||||
undo := s.reg.tempMoveBlobData(c, manifestDigest)
|
||||
defer undo()
|
||||
|
||||
alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", " ")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
|
||||
|
||||
s.reg.writeBlobContents(c, manifestDigest, alteredManifestBlob)
|
||||
|
||||
// Now try pulling that image by digest. We should get an error about
|
||||
// digest verification for the manifest digest.
|
||||
|
||||
// Pull from the registry using the <name>@<digest> reference.
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
|
||||
out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
|
||||
c.Assert(exitStatus, checker.Not(check.Equals), 0)
|
||||
|
||||
expectedErrorMsg := fmt.Sprintf("manifest verification failed for digest %s", manifestDigest)
|
||||
c.Assert(out, checker.Contains, expectedErrorMsg)
|
||||
}
|
||||
|
||||
// TestPullFailsWithAlteredManifest tests that a `docker pull` fails when
|
||||
// we have modified a manifest blob and its digest cannot be verified.
|
||||
// This is the schema1 version of the test.
|
||||
func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
manifestDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
// Load the target manifest blob.
|
||||
manifestBlob := s.reg.readBlobContents(c, manifestDigest)
|
||||
|
||||
var imgManifest schema1.Manifest
|
||||
err = json.Unmarshal(manifestBlob, &imgManifest)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("unable to decode image manifest from blob"))
|
||||
|
||||
// Change a layer in the manifest.
|
||||
imgManifest.FSLayers[0] = schema1.FSLayer{
|
||||
BlobSum: digest.Digest("sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"),
|
||||
}
|
||||
|
||||
// Move the existing data file aside, so that we can replace it with a
|
||||
// malicious blob of data. NOTE: we defer the returned undo func.
|
||||
undo := s.reg.tempMoveBlobData(c, manifestDigest)
|
||||
defer undo()
|
||||
|
||||
alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", " ")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
|
||||
|
||||
s.reg.writeBlobContents(c, manifestDigest, alteredManifestBlob)
|
||||
|
||||
// Now try pulling that image by digest. We should get an error about
|
||||
// digest verification for the manifest digest.
|
||||
|
||||
// Pull from the registry using the <name>@<digest> reference.
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
|
||||
out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
|
||||
c.Assert(exitStatus, checker.Not(check.Equals), 0)
|
||||
|
||||
expectedErrorMsg := fmt.Sprintf("image verification failed for digest %s", manifestDigest)
|
||||
c.Assert(out, checker.Contains, expectedErrorMsg)
|
||||
}
|
||||
|
||||
// TestPullFailsWithAlteredLayer tests that a `docker pull` fails when
|
||||
// we have modified a layer blob and its digest cannot be verified.
|
||||
// This is the schema2 version of the test.
|
||||
func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
manifestDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Load the target manifest blob.
|
||||
manifestBlob := s.reg.readBlobContents(c, manifestDigest)
|
||||
|
||||
var imgManifest schema2.Manifest
|
||||
err = json.Unmarshal(manifestBlob, &imgManifest)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Next, get the digest of one of the layers from the manifest.
|
||||
targetLayerDigest := imgManifest.Layers[0].Digest
|
||||
|
||||
// Move the existing data file aside, so that we can replace it with a
|
||||
// malicious blob of data. NOTE: we defer the returned undo func.
|
||||
undo := s.reg.tempMoveBlobData(c, targetLayerDigest)
|
||||
defer undo()
|
||||
|
||||
// Now make a fake data blob in this directory.
|
||||
s.reg.writeBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
|
||||
|
||||
// Now try pulling that image by digest. We should get an error about
|
||||
// digest verification for the target layer digest.
|
||||
|
||||
// Remove distribution cache to force a re-pull of the blobs
|
||||
if err := os.RemoveAll(filepath.Join(dockerBasePath, "image", s.d.storageDriver, "distribution")); err != nil {
|
||||
c.Fatalf("error clearing distribution cache: %v", err)
|
||||
}
|
||||
|
||||
// Pull from the registry using the <name>@<digest> reference.
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
|
||||
out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
|
||||
c.Assert(exitStatus, checker.Not(check.Equals), 0, check.Commentf("expected a zero exit status"))
|
||||
|
||||
expectedErrorMsg := fmt.Sprintf("filesystem layer verification failed for digest %s", targetLayerDigest)
|
||||
c.Assert(out, checker.Contains, expectedErrorMsg, check.Commentf("expected error message in output: %s", out))
|
||||
}
|
||||
|
||||
// TestPullFailsWithAlteredLayer tests that a `docker pull` fails when
|
||||
// we have modified a layer blob and its digest cannot be verified.
|
||||
// This is the schema1 version of the test.
|
||||
func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
manifestDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Load the target manifest blob.
|
||||
manifestBlob := s.reg.readBlobContents(c, manifestDigest)
|
||||
|
||||
var imgManifest schema1.Manifest
|
||||
err = json.Unmarshal(manifestBlob, &imgManifest)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Next, get the digest of one of the layers from the manifest.
|
||||
targetLayerDigest := imgManifest.FSLayers[0].BlobSum
|
||||
|
||||
// Move the existing data file aside, so that we can replace it with a
|
||||
// malicious blob of data. NOTE: we defer the returned undo func.
|
||||
undo := s.reg.tempMoveBlobData(c, targetLayerDigest)
|
||||
defer undo()
|
||||
|
||||
// Now make a fake data blob in this directory.
|
||||
s.reg.writeBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
|
||||
|
||||
// Now try pulling that image by digest. We should get an error about
|
||||
// digest verification for the target layer digest.
|
||||
|
||||
// Remove distribution cache to force a re-pull of the blobs
|
||||
if err := os.RemoveAll(filepath.Join(dockerBasePath, "image", s.d.storageDriver, "distribution")); err != nil {
|
||||
c.Fatalf("error clearing distribution cache: %v", err)
|
||||
}
|
||||
|
||||
// Pull from the registry using the <name>@<digest> reference.
|
||||
imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
|
||||
out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
|
||||
c.Assert(exitStatus, checker.Not(check.Equals), 0, check.Commentf("expected a zero exit status"))
|
||||
|
||||
expectedErrorMsg := fmt.Sprintf("filesystem layer verification failed for digest %s", targetLayerDigest)
|
||||
c.Assert(out, checker.Contains, expectedErrorMsg, check.Commentf("expected error message in output: %s", out))
|
||||
}
|
||||
189
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_commit_test.go
generated
vendored
Normal file
189
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_commit_test.go
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestCommitAfterContainerIsDone(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-i", "-a", "stdin", "busybox", "echo", "foo")
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
dockerCmd(c, "wait", cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(c, "commit", cleanedContainerID)
|
||||
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
|
||||
dockerCmd(c, "inspect", cleanedImageID)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCommitWithoutPause(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-i", "-a", "stdin", "busybox", "echo", "foo")
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
dockerCmd(c, "wait", cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(c, "commit", "-p=false", cleanedContainerID)
|
||||
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
|
||||
dockerCmd(c, "inspect", cleanedImageID)
|
||||
}
|
||||
|
||||
//test commit a paused container should not unpause it after commit
|
||||
func (s *DockerSuite) TestCommitPausedContainer(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
defer unpauseAllContainers()
|
||||
out, _ := dockerCmd(c, "run", "-i", "-d", "busybox")
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
dockerCmd(c, "pause", cleanedContainerID)
|
||||
|
||||
out, _ = dockerCmd(c, "commit", cleanedContainerID)
|
||||
|
||||
out = inspectField(c, cleanedContainerID, "State.Paused")
|
||||
// commit should not unpause a paused container
|
||||
c.Assert(out, checker.Contains, "true")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCommitNewFile(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
dockerCmd(c, "run", "--name", "commiter", "busybox", "/bin/sh", "-c", "echo koye > /foo")
|
||||
|
||||
imageID, _ := dockerCmd(c, "commit", "commiter")
|
||||
imageID = strings.TrimSpace(imageID)
|
||||
|
||||
out, _ := dockerCmd(c, "run", imageID, "cat", "/foo")
|
||||
actual := strings.TrimSpace(out)
|
||||
c.Assert(actual, checker.Equals, "koye")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCommitHardlink(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
firstOutput, _ := dockerCmd(c, "run", "-t", "--name", "hardlinks", "busybox", "sh", "-c", "touch file1 && ln file1 file2 && ls -di file1 file2")
|
||||
|
||||
chunks := strings.Split(strings.TrimSpace(firstOutput), " ")
|
||||
inode := chunks[0]
|
||||
chunks = strings.SplitAfterN(strings.TrimSpace(firstOutput), " ", 2)
|
||||
c.Assert(chunks[1], checker.Contains, chunks[0], check.Commentf("Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:]))
|
||||
|
||||
imageID, _ := dockerCmd(c, "commit", "hardlinks", "hardlinks")
|
||||
imageID = strings.TrimSpace(imageID)
|
||||
|
||||
secondOutput, _ := dockerCmd(c, "run", "-t", "hardlinks", "ls", "-di", "file1", "file2")
|
||||
|
||||
chunks = strings.Split(strings.TrimSpace(secondOutput), " ")
|
||||
inode = chunks[0]
|
||||
chunks = strings.SplitAfterN(strings.TrimSpace(secondOutput), " ", 2)
|
||||
c.Assert(chunks[1], checker.Contains, chunks[0], check.Commentf("Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:]))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCommitTTY(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
dockerCmd(c, "run", "-t", "--name", "tty", "busybox", "/bin/ls")
|
||||
|
||||
imageID, _ := dockerCmd(c, "commit", "tty", "ttytest")
|
||||
imageID = strings.TrimSpace(imageID)
|
||||
|
||||
dockerCmd(c, "run", "ttytest", "/bin/ls")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCommitWithHostBindMount(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
dockerCmd(c, "run", "--name", "bind-commit", "-v", "/dev/null:/winning", "busybox", "true")
|
||||
|
||||
imageID, _ := dockerCmd(c, "commit", "bind-commit", "bindtest")
|
||||
imageID = strings.TrimSpace(imageID)
|
||||
|
||||
dockerCmd(c, "run", "bindtest", "true")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCommitChange(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
dockerCmd(c, "run", "--name", "test", "busybox", "true")
|
||||
|
||||
imageID, _ := dockerCmd(c, "commit",
|
||||
"--change", "EXPOSE 8080",
|
||||
"--change", "ENV DEBUG true",
|
||||
"--change", "ENV test 1",
|
||||
"--change", "ENV PATH /foo",
|
||||
"--change", "LABEL foo bar",
|
||||
"--change", "CMD [\"/bin/sh\"]",
|
||||
"--change", "WORKDIR /opt",
|
||||
"--change", "ENTRYPOINT [\"/bin/sh\"]",
|
||||
"--change", "USER testuser",
|
||||
"--change", "VOLUME /var/lib/docker",
|
||||
"--change", "ONBUILD /usr/local/bin/python-build --dir /app/src",
|
||||
"test", "test-commit")
|
||||
imageID = strings.TrimSpace(imageID)
|
||||
|
||||
expected := map[string]string{
|
||||
"Config.ExposedPorts": "map[8080/tcp:{}]",
|
||||
"Config.Env": "[DEBUG=true test=1 PATH=/foo]",
|
||||
"Config.Labels": "map[foo:bar]",
|
||||
"Config.Cmd": "{[/bin/sh]}",
|
||||
"Config.WorkingDir": "/opt",
|
||||
"Config.Entrypoint": "{[/bin/sh]}",
|
||||
"Config.User": "testuser",
|
||||
"Config.Volumes": "map[/var/lib/docker:{}]",
|
||||
"Config.OnBuild": "[/usr/local/bin/python-build --dir /app/src]",
|
||||
}
|
||||
|
||||
for conf, value := range expected {
|
||||
res := inspectField(c, imageID, conf)
|
||||
if res != value {
|
||||
c.Errorf("%s('%s'), expected %s", conf, res, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: commit --run is deprecated, remove this once --run is removed
|
||||
func (s *DockerSuite) TestCommitMergeConfigRun(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
name := "commit-test"
|
||||
out, _ := dockerCmd(c, "run", "-d", "-e=FOO=bar", "busybox", "/bin/sh", "-c", "echo testing > /tmp/foo")
|
||||
id := strings.TrimSpace(out)
|
||||
|
||||
dockerCmd(c, "commit", `--run={"Cmd": ["cat", "/tmp/foo"]}`, id, "commit-test")
|
||||
|
||||
out, _ = dockerCmd(c, "run", "--name", name, "commit-test")
|
||||
//run config in committed container was not merged
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "testing")
|
||||
|
||||
type cfg struct {
|
||||
Env []string
|
||||
Cmd []string
|
||||
}
|
||||
config1 := cfg{}
|
||||
inspectFieldAndMarshall(c, id, "Config", &config1)
|
||||
|
||||
config2 := cfg{}
|
||||
inspectFieldAndMarshall(c, name, "Config", &config2)
|
||||
|
||||
// Env has at least PATH loaded as well here, so let's just grab the FOO one
|
||||
var env1, env2 string
|
||||
for _, e := range config1.Env {
|
||||
if strings.HasPrefix(e, "FOO") {
|
||||
env1 = e
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, e := range config2.Env {
|
||||
if strings.HasPrefix(e, "FOO") {
|
||||
env2 = e
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(config1.Env) != len(config2.Env) || env1 != env2 && env2 != "" {
|
||||
c.Fatalf("expected envs to match: %v - %v", config1.Env, config2.Env)
|
||||
}
|
||||
}
|
||||
489
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_cp_from_container_test.go
generated
vendored
Normal file
489
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_cp_from_container_test.go
generated
vendored
Normal file
@@ -0,0 +1,489 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// docker cp CONTAINER:PATH LOCALPATH
|
||||
|
||||
// Try all of the test cases from the archive package which implements the
|
||||
// internals of `docker cp` and ensure that the behavior matches when actually
|
||||
// copying to and from containers.
|
||||
|
||||
// Basic assumptions about SRC and DST:
|
||||
// 1. SRC must exist.
|
||||
// 2. If SRC ends with a trailing separator, it must be a directory.
|
||||
// 3. DST parent directory must exist.
|
||||
// 4. If DST exists as a file, it must not end with a trailing separator.
|
||||
|
||||
// First get these easy error cases out of the way.
|
||||
|
||||
// Test for error when SRC does not exist.
|
||||
func (s *DockerSuite) TestCpFromErrSrcNotExists(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-err-src-not-exists")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
err := runDockerCp(c, containerCpPath(containerID, "file1"), tmpDir)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// Test for error when SRC ends in a trailing
|
||||
// path separator but it exists as a file.
|
||||
func (s *DockerSuite) TestCpFromErrSrcNotDir(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-err-src-not-dir")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
err := runDockerCp(c, containerCpPathTrailingSep(containerID, "file1"), tmpDir)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// Test for error when SRC is a valid file or directory,
|
||||
// bu the DST parent directory does not exist.
|
||||
func (s *DockerSuite) TestCpFromErrDstParentNotExists(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-err-dst-parent-not-exists")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
// Try with a file source.
|
||||
srcPath := containerCpPath(containerID, "/file1")
|
||||
dstPath := cpPath(tmpDir, "notExists", "file1")
|
||||
|
||||
err := runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
|
||||
|
||||
// Try with a directory source.
|
||||
srcPath = containerCpPath(containerID, "/dir1")
|
||||
|
||||
err = runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// Test for error when DST ends in a trailing
|
||||
// path separator but exists as a file.
|
||||
func (s *DockerSuite) TestCpFromErrDstNotDir(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-err-dst-not-dir")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
// Try with a file source.
|
||||
srcPath := containerCpPath(containerID, "/file1")
|
||||
dstPath := cpPathTrailingSep(tmpDir, "file1")
|
||||
|
||||
err := runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
|
||||
|
||||
// Try with a directory source.
|
||||
srcPath = containerCpPath(containerID, "/dir1")
|
||||
|
||||
err = runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// Check that copying from a container to a local symlink copies to the symlink
|
||||
// target and does not overwrite the local symlink itself.
|
||||
func (s *DockerSuite) TestCpFromSymlinkDestination(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-err-dst-not-dir")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
// First, copy a file from the container to a symlink to a file. This
|
||||
// should overwrite the symlink target contents with the source contents.
|
||||
srcPath := containerCpPath(containerID, "/file2")
|
||||
dstPath := cpPath(tmpDir, "symlinkToFile1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, dstPath, "file1"), checker.IsNil)
|
||||
|
||||
// The file should have the contents of "file2" now.
|
||||
c.Assert(fileContentEquals(c, cpPath(tmpDir, "file1"), "file2\n"), checker.IsNil)
|
||||
|
||||
// Next, copy a file from the container to a symlink to a directory. This
|
||||
// should copy the file into the symlink target directory.
|
||||
dstPath = cpPath(tmpDir, "symlinkToDir1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, dstPath, "dir1"), checker.IsNil)
|
||||
|
||||
// The file should have the contents of "file2" now.
|
||||
c.Assert(fileContentEquals(c, cpPath(tmpDir, "file2"), "file2\n"), checker.IsNil)
|
||||
|
||||
// Next, copy a file from the container to a symlink to a file that does
|
||||
// not exist (a broken symlink). This should create the target file with
|
||||
// the contents of the source file.
|
||||
dstPath = cpPath(tmpDir, "brokenSymlinkToFileX")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, dstPath, "fileX"), checker.IsNil)
|
||||
|
||||
// The file should have the contents of "file2" now.
|
||||
c.Assert(fileContentEquals(c, cpPath(tmpDir, "fileX"), "file2\n"), checker.IsNil)
|
||||
|
||||
// Next, copy a directory from the container to a symlink to a local
|
||||
// directory. This should copy the directory into the symlink target
|
||||
// directory and not modify the symlink.
|
||||
srcPath = containerCpPath(containerID, "/dir2")
|
||||
dstPath = cpPath(tmpDir, "symlinkToDir1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, dstPath, "dir1"), checker.IsNil)
|
||||
|
||||
// The directory should now contain a copy of "dir2".
|
||||
c.Assert(fileContentEquals(c, cpPath(tmpDir, "dir1/dir2/file2-1"), "file2-1\n"), checker.IsNil)
|
||||
|
||||
// Next, copy a directory from the container to a symlink to a local
|
||||
// directory that does not exist (a broken symlink). This should create
|
||||
// the target as a directory with the contents of the source directory. It
|
||||
// should not modify the symlink.
|
||||
dstPath = cpPath(tmpDir, "brokenSymlinkToDirX")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, dstPath, "dirX"), checker.IsNil)
|
||||
|
||||
// The "dirX" directory should now be a copy of "dir2".
|
||||
c.Assert(fileContentEquals(c, cpPath(tmpDir, "dirX/file2-1"), "file2-1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// Possibilities are reduced to the remaining 10 cases:
|
||||
//
|
||||
// case | srcIsDir | onlyDirContents | dstExists | dstIsDir | dstTrSep | action
|
||||
// ===================================================================================================
|
||||
// A | no | - | no | - | no | create file
|
||||
// B | no | - | no | - | yes | error
|
||||
// C | no | - | yes | no | - | overwrite file
|
||||
// D | no | - | yes | yes | - | create file in dst dir
|
||||
// E | yes | no | no | - | - | create dir, copy contents
|
||||
// F | yes | no | yes | no | - | error
|
||||
// G | yes | no | yes | yes | - | copy dir and contents
|
||||
// H | yes | yes | no | - | - | create dir, copy contents
|
||||
// I | yes | yes | yes | no | - | error
|
||||
// J | yes | yes | yes | yes | - | copy dir contents
|
||||
//
|
||||
|
||||
// A. SRC specifies a file and DST (no trailing path separator) doesn't
|
||||
// exist. This should create a file with the name DST and copy the
|
||||
// contents of the source file into it.
|
||||
func (s *DockerSuite) TestCpFromCaseA(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-a")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
srcPath := containerCpPath(containerID, "/root/file1")
|
||||
dstPath := cpPath(tmpDir, "itWorks.txt")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// B. SRC specifies a file and DST (with trailing path separator) doesn't
|
||||
// exist. This should cause an error because the copy operation cannot
|
||||
// create a directory when copying a single file.
|
||||
func (s *DockerSuite) TestCpFromCaseB(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-b")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
srcPath := containerCpPath(containerID, "/file1")
|
||||
dstDir := cpPathTrailingSep(tmpDir, "testDir")
|
||||
|
||||
err := runDockerCp(c, srcPath, dstDir)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpDirNotExist(err), checker.True, check.Commentf("expected DirNotExists error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// C. SRC specifies a file and DST exists as a file. This should overwrite
|
||||
// the file at DST with the contents of the source file.
|
||||
func (s *DockerSuite) TestCpFromCaseC(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-c")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcPath := containerCpPath(containerID, "/root/file1")
|
||||
dstPath := cpPath(tmpDir, "file2")
|
||||
|
||||
// Ensure the local file starts with different content.
|
||||
c.Assert(fileContentEquals(c, dstPath, "file2\n"), checker.IsNil)
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// D. SRC specifies a file and DST exists as a directory. This should place
|
||||
// a copy of the source file inside it using the basename from SRC. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpFromCaseD(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-d")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcPath := containerCpPath(containerID, "/file1")
|
||||
dstDir := cpPath(tmpDir, "dir1")
|
||||
dstPath := filepath.Join(dstDir, "file1")
|
||||
|
||||
// Ensure that dstPath doesn't exist.
|
||||
_, err := os.Stat(dstPath)
|
||||
c.Assert(os.IsNotExist(err), checker.True, check.Commentf("did not expect dstPath %q to exist", dstPath))
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// unable to remove dstDir
|
||||
c.Assert(os.RemoveAll(dstDir), checker.IsNil)
|
||||
|
||||
// unable to make dstDir
|
||||
c.Assert(os.MkdirAll(dstDir, os.FileMode(0755)), checker.IsNil)
|
||||
|
||||
dstDir = cpPathTrailingSep(tmpDir, "dir1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// E. SRC specifies a directory and DST does not exist. This should create a
|
||||
// directory at DST and copy the contents of the SRC directory into the DST
|
||||
// directory. Ensure this works whether DST has a trailing path separator or
|
||||
// not.
|
||||
func (s *DockerSuite) TestCpFromCaseE(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-e")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
srcDir := containerCpPath(containerID, "dir1")
|
||||
dstDir := cpPath(tmpDir, "testDir")
|
||||
dstPath := filepath.Join(dstDir, "file1-1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1-1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// unable to remove dstDir
|
||||
c.Assert(os.RemoveAll(dstDir), checker.IsNil)
|
||||
|
||||
dstDir = cpPathTrailingSep(tmpDir, "testDir")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1-1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// F. SRC specifies a directory and DST exists as a file. This should cause an
|
||||
// error as it is not possible to overwrite a file with a directory.
|
||||
func (s *DockerSuite) TestCpFromCaseF(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-f")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := containerCpPath(containerID, "/root/dir1")
|
||||
dstFile := cpPath(tmpDir, "file1")
|
||||
|
||||
err := runDockerCp(c, srcDir, dstFile)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpCannotCopyDir(err), checker.True, check.Commentf("expected ErrCannotCopyDir error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// G. SRC specifies a directory and DST exists as a directory. This should copy
|
||||
// the SRC directory and all its contents to the DST directory. Ensure this
|
||||
// works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpFromCaseG(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-g")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := containerCpPath(containerID, "/root/dir1")
|
||||
dstDir := cpPath(tmpDir, "dir2")
|
||||
resultDir := filepath.Join(dstDir, "dir1")
|
||||
dstPath := filepath.Join(resultDir, "file1-1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1-1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// unable to remove dstDir
|
||||
c.Assert(os.RemoveAll(dstDir), checker.IsNil)
|
||||
|
||||
// unable to make dstDir
|
||||
c.Assert(os.MkdirAll(dstDir, os.FileMode(0755)), checker.IsNil)
|
||||
|
||||
dstDir = cpPathTrailingSep(tmpDir, "dir2")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1-1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// H. SRC specifies a directory's contents only and DST does not exist. This
|
||||
// should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpFromCaseH(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-h")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
srcDir := containerCpPathTrailingSep(containerID, "dir1") + "."
|
||||
dstDir := cpPath(tmpDir, "testDir")
|
||||
dstPath := filepath.Join(dstDir, "file1-1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1-1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// unable to remove resultDir
|
||||
c.Assert(os.RemoveAll(dstDir), checker.IsNil)
|
||||
|
||||
dstDir = cpPathTrailingSep(tmpDir, "testDir")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1-1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// I. SRC specifies a directory's contents only and DST exists as a file. This
|
||||
// should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
func (s *DockerSuite) TestCpFromCaseI(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-i")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := containerCpPathTrailingSep(containerID, "/root/dir1") + "."
|
||||
dstFile := cpPath(tmpDir, "file1")
|
||||
|
||||
err := runDockerCp(c, srcDir, dstFile)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpCannotCopyDir(err), checker.True, check.Commentf("expected ErrCannotCopyDir error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// J. SRC specifies a directory's contents only and DST exists as a directory.
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpFromCaseJ(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-from-case-j")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := containerCpPathTrailingSep(containerID, "/root/dir1") + "."
|
||||
dstDir := cpPath(tmpDir, "dir2")
|
||||
dstPath := filepath.Join(dstDir, "file1-1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1-1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// unable to remove dstDir
|
||||
c.Assert(os.RemoveAll(dstDir), checker.IsNil)
|
||||
|
||||
// unable to make dstDir
|
||||
c.Assert(os.MkdirAll(dstDir, os.FileMode(0755)), checker.IsNil)
|
||||
|
||||
dstDir = cpPathTrailingSep(tmpDir, "dir2")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
c.Assert(fileContentEquals(c, dstPath, "file1-1\n"), checker.IsNil)
|
||||
}
|
||||
665
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_cp_test.go
generated
vendored
Normal file
665
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_cp_test.go
generated
vendored
Normal file
@@ -0,0 +1,665 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
const (
|
||||
cpTestPathParent = "/some"
|
||||
cpTestPath = "/some/path"
|
||||
cpTestName = "test"
|
||||
cpFullPath = "/some/path/test"
|
||||
|
||||
cpContainerContents = "holla, i am the container"
|
||||
cpHostContents = "hello, i am the host"
|
||||
)
|
||||
|
||||
// Ensure that an all-local path case returns an error.
|
||||
func (s *DockerSuite) TestCpLocalOnly(c *check.C) {
|
||||
err := runDockerCp(c, "foo", "bar")
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(err.Error(), checker.Contains, "must specify at least one container source")
|
||||
}
|
||||
|
||||
// Test for #5656
|
||||
// Check that garbage paths don't escape the container's rootfs
|
||||
func (s *DockerSuite) TestCpGarbagePath(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
c.Assert(os.MkdirAll(cpTestPath, os.ModeDir), checker.IsNil)
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
||||
fmt.Fprintf(hostFile, "%s", cpHostContents)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
tmpname := filepath.Join(tmpdir, cpTestName)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
path := path.Join("../../../../../../../../../../../../", cpFullPath)
|
||||
|
||||
dockerCmd(c, "cp", containerID+":"+path, tmpdir)
|
||||
|
||||
file, _ := os.Open(tmpname)
|
||||
defer file.Close()
|
||||
|
||||
test, err := ioutil.ReadAll(file)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// output matched host file -- garbage path can escape container rootfs
|
||||
c.Assert(string(test), checker.Not(checker.Equals), cpHostContents)
|
||||
|
||||
// output doesn't match the input for garbage path
|
||||
c.Assert(string(test), checker.Equals, cpContainerContents)
|
||||
}
|
||||
|
||||
// Check that relative paths are relative to the container's rootfs
|
||||
func (s *DockerSuite) TestCpRelativePath(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
c.Assert(os.MkdirAll(cpTestPath, os.ModeDir), checker.IsNil)
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
||||
fmt.Fprintf(hostFile, "%s", cpHostContents)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
tmpname := filepath.Join(tmpdir, cpTestName)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
var relPath string
|
||||
if path.IsAbs(cpFullPath) {
|
||||
// normally this is `filepath.Rel("/", cpFullPath)` but we cannot
|
||||
// get this unix-path manipulation on windows with filepath.
|
||||
relPath = cpFullPath[1:]
|
||||
}
|
||||
c.Assert(path.IsAbs(cpFullPath), checker.True, check.Commentf("path %s was assumed to be an absolute path", cpFullPath))
|
||||
|
||||
dockerCmd(c, "cp", containerID+":"+relPath, tmpdir)
|
||||
|
||||
file, _ := os.Open(tmpname)
|
||||
defer file.Close()
|
||||
|
||||
test, err := ioutil.ReadAll(file)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// output matched host file -- relative path can escape container rootfs
|
||||
c.Assert(string(test), checker.Not(checker.Equals), cpHostContents)
|
||||
|
||||
// output doesn't match the input for relative path
|
||||
c.Assert(string(test), checker.Equals, cpContainerContents)
|
||||
}
|
||||
|
||||
// Check that absolute paths are relative to the container's rootfs
|
||||
func (s *DockerSuite) TestCpAbsolutePath(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
c.Assert(os.MkdirAll(cpTestPath, os.ModeDir), checker.IsNil)
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
||||
fmt.Fprintf(hostFile, "%s", cpHostContents)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
tmpname := filepath.Join(tmpdir, cpTestName)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
path := cpFullPath
|
||||
|
||||
dockerCmd(c, "cp", containerID+":"+path, tmpdir)
|
||||
|
||||
file, _ := os.Open(tmpname)
|
||||
defer file.Close()
|
||||
|
||||
test, err := ioutil.ReadAll(file)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// output matched host file -- absolute path can escape container rootfs
|
||||
c.Assert(string(test), checker.Not(checker.Equals), cpHostContents)
|
||||
|
||||
// output doesn't match the input for absolute path
|
||||
c.Assert(string(test), checker.Equals, cpContainerContents)
|
||||
}
|
||||
|
||||
// Test for #5619
|
||||
// Check that absolute symlinks are still relative to the container's rootfs
|
||||
func (s *DockerSuite) TestCpAbsoluteSymlink(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpFullPath+" container_path")
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
c.Assert(os.MkdirAll(cpTestPath, os.ModeDir), checker.IsNil)
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
||||
fmt.Fprintf(hostFile, "%s", cpHostContents)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
tmpname := filepath.Join(tmpdir, "container_path")
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
path := path.Join("/", "container_path")
|
||||
|
||||
dockerCmd(c, "cp", containerID+":"+path, tmpdir)
|
||||
|
||||
// We should have copied a symlink *NOT* the file itself!
|
||||
linkTarget, err := os.Readlink(tmpname)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
c.Assert(linkTarget, checker.Equals, filepath.FromSlash(cpFullPath))
|
||||
}
|
||||
|
||||
// Check that symlinks to a directory behave as expected when copying one from
|
||||
// a container.
|
||||
func (s *DockerSuite) TestCpFromSymlinkToDirectory(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpTestPathParent+" /dir_link")
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
testDir, err := ioutil.TempDir("", "test-cp-from-symlink-to-dir-")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(testDir)
|
||||
|
||||
// This copy command should copy the symlink, not the target, into the
|
||||
// temporary directory.
|
||||
dockerCmd(c, "cp", containerID+":"+"/dir_link", testDir)
|
||||
|
||||
expectedPath := filepath.Join(testDir, "dir_link")
|
||||
linkTarget, err := os.Readlink(expectedPath)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
c.Assert(linkTarget, checker.Equals, filepath.FromSlash(cpTestPathParent))
|
||||
|
||||
os.Remove(expectedPath)
|
||||
|
||||
// This copy command should resolve the symlink (note the trailing
|
||||
// separator), copying the target into the temporary directory.
|
||||
dockerCmd(c, "cp", containerID+":"+"/dir_link/", testDir)
|
||||
|
||||
// It *should not* have copied the directory using the target's name, but
|
||||
// used the given name instead.
|
||||
unexpectedPath := filepath.Join(testDir, cpTestPathParent)
|
||||
stat, err := os.Lstat(unexpectedPath)
|
||||
if err == nil {
|
||||
out = fmt.Sprintf("target name was copied: %q - %q", stat.Mode(), stat.Name())
|
||||
}
|
||||
c.Assert(err, checker.NotNil, check.Commentf(out))
|
||||
|
||||
// It *should* have copied the directory using the asked name "dir_link".
|
||||
stat, err = os.Lstat(expectedPath)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("unable to stat resource at %q", expectedPath))
|
||||
|
||||
c.Assert(stat.IsDir(), checker.True, check.Commentf("should have copied a directory but got %q instead", stat.Mode()))
|
||||
}
|
||||
|
||||
// Check that symlinks to a directory behave as expected when copying one to a
|
||||
// container.
|
||||
func (s *DockerSuite) TestCpToSymlinkToDirectory(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, SameHostDaemon) // Requires local volume mount bind.
|
||||
|
||||
testVol, err := ioutil.TempDir("", "test-cp-to-symlink-to-dir-")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(testVol)
|
||||
|
||||
// Create a test container with a local volume. We will test by copying
|
||||
// to the volume path in the container which we can then verify locally.
|
||||
out, _ := dockerCmd(c, "create", "-v", testVol+":/testVol", "busybox")
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
// Create a temp directory to hold a test file nested in a direcotry.
|
||||
testDir, err := ioutil.TempDir("", "test-cp-to-symlink-to-dir-")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(testDir)
|
||||
|
||||
// This file will be at "/testDir/some/path/test" and will be copied into
|
||||
// the test volume later.
|
||||
hostTestFilename := filepath.Join(testDir, cpFullPath)
|
||||
c.Assert(os.MkdirAll(filepath.Dir(hostTestFilename), os.FileMode(0700)), checker.IsNil)
|
||||
c.Assert(ioutil.WriteFile(hostTestFilename, []byte(cpHostContents), os.FileMode(0600)), checker.IsNil)
|
||||
|
||||
// Now create another temp directory to hold a symlink to the
|
||||
// "/testDir/some" directory.
|
||||
linkDir, err := ioutil.TempDir("", "test-cp-to-symlink-to-dir-")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(linkDir)
|
||||
|
||||
// Then symlink "/linkDir/dir_link" to "/testdir/some".
|
||||
linkTarget := filepath.Join(testDir, cpTestPathParent)
|
||||
localLink := filepath.Join(linkDir, "dir_link")
|
||||
c.Assert(os.Symlink(linkTarget, localLink), checker.IsNil)
|
||||
|
||||
// Now copy that symlink into the test volume in the container.
|
||||
dockerCmd(c, "cp", localLink, containerID+":/testVol")
|
||||
|
||||
// This copy command should have copied the symlink *not* the target.
|
||||
expectedPath := filepath.Join(testVol, "dir_link")
|
||||
actualLinkTarget, err := os.Readlink(expectedPath)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("unable to read symlink at %q", expectedPath))
|
||||
|
||||
c.Assert(actualLinkTarget, checker.Equals, linkTarget)
|
||||
|
||||
// Good, now remove that copied link for the next test.
|
||||
os.Remove(expectedPath)
|
||||
|
||||
// This copy command should resolve the symlink (note the trailing
|
||||
// separator), copying the target into the test volume directory in the
|
||||
// container.
|
||||
dockerCmd(c, "cp", localLink+"/", containerID+":/testVol")
|
||||
|
||||
// It *should not* have copied the directory using the target's name, but
|
||||
// used the given name instead.
|
||||
unexpectedPath := filepath.Join(testVol, cpTestPathParent)
|
||||
stat, err := os.Lstat(unexpectedPath)
|
||||
if err == nil {
|
||||
out = fmt.Sprintf("target name was copied: %q - %q", stat.Mode(), stat.Name())
|
||||
}
|
||||
c.Assert(err, checker.NotNil, check.Commentf(out))
|
||||
|
||||
// It *should* have copied the directory using the asked name "dir_link".
|
||||
stat, err = os.Lstat(expectedPath)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("unable to stat resource at %q", expectedPath))
|
||||
|
||||
c.Assert(stat.IsDir(), checker.True, check.Commentf("should have copied a directory but got %q instead", stat.Mode()))
|
||||
|
||||
// And this directory should contain the file copied from the host at the
|
||||
// expected location: "/testVol/dir_link/path/test"
|
||||
expectedFilepath := filepath.Join(testVol, "dir_link/path/test")
|
||||
fileContents, err := ioutil.ReadFile(expectedFilepath)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
c.Assert(string(fileContents), checker.Equals, cpHostContents)
|
||||
}
|
||||
|
||||
// Test for #5619
|
||||
// Check that symlinks which are part of the resource path are still relative to the container's rootfs
|
||||
func (s *DockerSuite) TestCpSymlinkComponent(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpTestPath+" container_path")
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
c.Assert(os.MkdirAll(cpTestPath, os.ModeDir), checker.IsNil)
|
||||
|
||||
hostFile, err := os.Create(cpFullPath)
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer hostFile.Close()
|
||||
defer os.RemoveAll(cpTestPathParent)
|
||||
|
||||
fmt.Fprintf(hostFile, "%s", cpHostContents)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
tmpname := filepath.Join(tmpdir, cpTestName)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
path := path.Join("/", "container_path", cpTestName)
|
||||
|
||||
dockerCmd(c, "cp", containerID+":"+path, tmpdir)
|
||||
|
||||
file, _ := os.Open(tmpname)
|
||||
defer file.Close()
|
||||
|
||||
test, err := ioutil.ReadAll(file)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// output matched host file -- symlink path component can escape container rootfs
|
||||
c.Assert(string(test), checker.Not(checker.Equals), cpHostContents)
|
||||
|
||||
// output doesn't match the input for symlink path component
|
||||
c.Assert(string(test), checker.Equals, cpContainerContents)
|
||||
}
|
||||
|
||||
// Check that cp with unprivileged user doesn't return any error
|
||||
func (s *DockerSuite) TestCpUnprivilegedUser(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, UnixCli) // uses chmod/su: not available on windows
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "touch "+cpTestName)
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
c.Assert(os.Chmod(tmpdir, 0777), checker.IsNil)
|
||||
|
||||
path := cpTestName
|
||||
|
||||
_, _, err = runCommandWithOutput(exec.Command("su", "unprivilegeduser", "-c", dockerBinary+" cp "+containerID+":"+path+" "+tmpdir))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("couldn't copy with unprivileged user: %s:%s", containerID, path))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCpSpecialFiles(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
outDir, err := ioutil.TempDir("", "cp-test-special-files")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(outDir)
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "touch /foo")
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
// Copy actual /etc/resolv.conf
|
||||
dockerCmd(c, "cp", containerID+":/etc/resolv.conf", outDir)
|
||||
|
||||
expected, err := readContainerFile(containerID, "resolv.conf")
|
||||
actual, err := ioutil.ReadFile(outDir + "/resolv.conf")
|
||||
|
||||
// Expected copied file to be duplicate of the container resolvconf
|
||||
c.Assert(bytes.Equal(actual, expected), checker.True)
|
||||
|
||||
// Copy actual /etc/hosts
|
||||
dockerCmd(c, "cp", containerID+":/etc/hosts", outDir)
|
||||
|
||||
expected, err = readContainerFile(containerID, "hosts")
|
||||
actual, err = ioutil.ReadFile(outDir + "/hosts")
|
||||
|
||||
// Expected copied file to be duplicate of the container hosts
|
||||
c.Assert(bytes.Equal(actual, expected), checker.True)
|
||||
|
||||
// Copy actual /etc/resolv.conf
|
||||
dockerCmd(c, "cp", containerID+":/etc/hostname", outDir)
|
||||
|
||||
expected, err = readContainerFile(containerID, "hostname")
|
||||
actual, err = ioutil.ReadFile(outDir + "/hostname")
|
||||
|
||||
// Expected copied file to be duplicate of the container resolvconf
|
||||
c.Assert(bytes.Equal(actual, expected), checker.True)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCpVolumePath(c *check.C) {
|
||||
// stat /tmp/cp-test-volumepath851508420/test gets permission denied for the user
|
||||
testRequires(c, NotUserNamespace)
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "cp-test-volumepath")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
outDir, err := ioutil.TempDir("", "cp-test-volumepath-out")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(outDir)
|
||||
_, err = os.Create(tmpDir + "/test")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-d", "-v", "/foo", "-v", tmpDir+"/test:/test", "-v", tmpDir+":/baz", "busybox", "/bin/sh", "-c", "touch /foo/bar")
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
// Copy actual volume path
|
||||
dockerCmd(c, "cp", containerID+":/foo", outDir)
|
||||
|
||||
stat, err := os.Stat(outDir + "/foo")
|
||||
c.Assert(err, checker.IsNil)
|
||||
// expected copied content to be dir
|
||||
c.Assert(stat.IsDir(), checker.True)
|
||||
stat, err = os.Stat(outDir + "/foo/bar")
|
||||
c.Assert(err, checker.IsNil)
|
||||
// Expected file `bar` to be a file
|
||||
c.Assert(stat.IsDir(), checker.False)
|
||||
|
||||
// Copy file nested in volume
|
||||
dockerCmd(c, "cp", containerID+":/foo/bar", outDir)
|
||||
|
||||
stat, err = os.Stat(outDir + "/bar")
|
||||
c.Assert(err, checker.IsNil)
|
||||
// Expected file `bar` to be a file
|
||||
c.Assert(stat.IsDir(), checker.False)
|
||||
|
||||
// Copy Bind-mounted dir
|
||||
dockerCmd(c, "cp", containerID+":/baz", outDir)
|
||||
stat, err = os.Stat(outDir + "/baz")
|
||||
c.Assert(err, checker.IsNil)
|
||||
// Expected `baz` to be a dir
|
||||
c.Assert(stat.IsDir(), checker.True)
|
||||
|
||||
// Copy file nested in bind-mounted dir
|
||||
dockerCmd(c, "cp", containerID+":/baz/test", outDir)
|
||||
fb, err := ioutil.ReadFile(outDir + "/baz/test")
|
||||
c.Assert(err, checker.IsNil)
|
||||
fb2, err := ioutil.ReadFile(tmpDir + "/test")
|
||||
c.Assert(err, checker.IsNil)
|
||||
// Expected copied file to be duplicate of bind-mounted file
|
||||
c.Assert(bytes.Equal(fb, fb2), checker.True)
|
||||
|
||||
// Copy bind-mounted file
|
||||
dockerCmd(c, "cp", containerID+":/test", outDir)
|
||||
fb, err = ioutil.ReadFile(outDir + "/test")
|
||||
c.Assert(err, checker.IsNil)
|
||||
fb2, err = ioutil.ReadFile(tmpDir + "/test")
|
||||
c.Assert(err, checker.IsNil)
|
||||
// Expected copied file to be duplicate of bind-mounted file
|
||||
c.Assert(bytes.Equal(fb, fb2), checker.True)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCpToDot(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /test")
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
cwd, err := os.Getwd()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.Chdir(cwd)
|
||||
c.Assert(os.Chdir(tmpdir), checker.IsNil)
|
||||
dockerCmd(c, "cp", containerID+":/test", ".")
|
||||
content, err := ioutil.ReadFile("./test")
|
||||
c.Assert(string(content), checker.Equals, "lololol\n")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCpToStdout(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /test")
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "cp", containerID+":/test", "-"),
|
||||
exec.Command("tar", "-vtf", "-"))
|
||||
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
c.Assert(out, checker.Contains, "test")
|
||||
c.Assert(out, checker.Contains, "-rw")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCpNameHasColon(c *check.C) {
|
||||
testRequires(c, SameHostDaemon, DaemonIsLinux)
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /te:s:t")
|
||||
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
dockerCmd(c, "cp", containerID+":/te:s:t", tmpdir)
|
||||
content, err := ioutil.ReadFile(tmpdir + "/te:s:t")
|
||||
c.Assert(string(content), checker.Equals, "lololol\n")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCopyAndRestart(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
expectedMsg := "hello"
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "echo", expectedMsg)
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "test-docker-restart-after-copy-")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
dockerCmd(c, "cp", fmt.Sprintf("%s:/etc/group", containerID), tmpDir)
|
||||
|
||||
out, _ = dockerCmd(c, "start", "-a", containerID)
|
||||
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, expectedMsg)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCopyCreatedContainer(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
dockerCmd(c, "create", "--name", "test_cp", "-v", "/test", "busybox")
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "test")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
dockerCmd(c, "cp", "test_cp:/bin/sh", tmpDir)
|
||||
}
|
||||
|
||||
// test copy with option `-L`: following symbol link
|
||||
// Check that symlinks to a file behave as expected when copying one from
|
||||
// a container to host following symbol link
|
||||
func (s *DockerSuite) TestCpSymlinkFromConToHostFollowSymlink(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpFullPath+" /dir_link")
|
||||
if exitCode != 0 {
|
||||
c.Fatal("failed to create a container", out)
|
||||
}
|
||||
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", cleanedContainerID)
|
||||
if strings.TrimSpace(out) != "0" {
|
||||
c.Fatal("failed to set up container", out)
|
||||
}
|
||||
|
||||
testDir, err := ioutil.TempDir("", "test-cp-symlink-container-to-host-follow-symlink")
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(testDir)
|
||||
|
||||
// This copy command should copy the symlink, not the target, into the
|
||||
// temporary directory.
|
||||
dockerCmd(c, "cp", "-L", cleanedContainerID+":"+"/dir_link", testDir)
|
||||
|
||||
expectedPath := filepath.Join(testDir, "dir_link")
|
||||
|
||||
expected := []byte(cpContainerContents)
|
||||
actual, err := ioutil.ReadFile(expectedPath)
|
||||
|
||||
if !bytes.Equal(actual, expected) {
|
||||
c.Fatalf("Expected copied file to be duplicate of the container symbol link target")
|
||||
}
|
||||
os.Remove(expectedPath)
|
||||
|
||||
// now test copy symbol link to an non-existing file in host
|
||||
expectedPath = filepath.Join(testDir, "somefile_host")
|
||||
// expectedPath shouldn't exist, if exists, remove it
|
||||
if _, err := os.Lstat(expectedPath); err == nil {
|
||||
os.Remove(expectedPath)
|
||||
}
|
||||
|
||||
dockerCmd(c, "cp", "-L", cleanedContainerID+":"+"/dir_link", expectedPath)
|
||||
|
||||
actual, err = ioutil.ReadFile(expectedPath)
|
||||
|
||||
if !bytes.Equal(actual, expected) {
|
||||
c.Fatalf("Expected copied file to be duplicate of the container symbol link target")
|
||||
}
|
||||
defer os.Remove(expectedPath)
|
||||
}
|
||||
605
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_cp_to_container_test.go
generated
vendored
Normal file
605
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_cp_to_container_test.go
generated
vendored
Normal file
@@ -0,0 +1,605 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// docker cp LOCALPATH CONTAINER:PATH
|
||||
|
||||
// Try all of the test cases from the archive package which implements the
|
||||
// internals of `docker cp` and ensure that the behavior matches when actually
|
||||
// copying to and from containers.
|
||||
|
||||
// Basic assumptions about SRC and DST:
|
||||
// 1. SRC must exist.
|
||||
// 2. If SRC ends with a trailing separator, it must be a directory.
|
||||
// 3. DST parent directory must exist.
|
||||
// 4. If DST exists as a file, it must not end with a trailing separator.
|
||||
|
||||
// First get these easy error cases out of the way.
|
||||
|
||||
// Test for error when SRC does not exist.
|
||||
func (s *DockerSuite) TestCpToErrSrcNotExists(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-err-src-not-exists")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
srcPath := cpPath(tmpDir, "file1")
|
||||
dstPath := containerCpPath(containerID, "file1")
|
||||
|
||||
err := runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// Test for error when SRC ends in a trailing
|
||||
// path separator but it exists as a file.
|
||||
func (s *DockerSuite) TestCpToErrSrcNotDir(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-err-src-not-dir")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcPath := cpPathTrailingSep(tmpDir, "file1")
|
||||
dstPath := containerCpPath(containerID, "testDir")
|
||||
|
||||
err := runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotDir(err), checker.True, check.Commentf("expected IsNotDir error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// Test for error when SRC is a valid file or directory,
|
||||
// bu the DST parent directory does not exist.
|
||||
func (s *DockerSuite) TestCpToErrDstParentNotExists(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-err-dst-parent-not-exists")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
// Try with a file source.
|
||||
srcPath := cpPath(tmpDir, "file1")
|
||||
dstPath := containerCpPath(containerID, "/notExists", "file1")
|
||||
|
||||
err := runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
|
||||
|
||||
// Try with a directory source.
|
||||
srcPath = cpPath(tmpDir, "dir1")
|
||||
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// Test for error when DST ends in a trailing path separator but exists as a
|
||||
// file. Also test that we cannot overwrite an existing directory with a
|
||||
// non-directory and cannot overwrite an existing
|
||||
func (s *DockerSuite) TestCpToErrDstNotDir(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-err-dst-not-dir")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
// Try with a file source.
|
||||
srcPath := cpPath(tmpDir, "dir1/file1-1")
|
||||
dstPath := containerCpPathTrailingSep(containerID, "file1")
|
||||
|
||||
// The client should encounter an error trying to stat the destination
|
||||
// and then be unable to copy since the destination is asserted to be a
|
||||
// directory but does not exist.
|
||||
err := runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpDirNotExist(err), checker.True, check.Commentf("expected DirNotExist error, but got %T: %s", err, err))
|
||||
|
||||
// Try with a directory source.
|
||||
srcPath = cpPath(tmpDir, "dir1")
|
||||
|
||||
// The client should encounter an error trying to stat the destination and
|
||||
// then decide to extract to the parent directory instead with a rebased
|
||||
// name in the source archive, but this directory would overwrite the
|
||||
// existing file with the same name.
|
||||
err = runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCannotOverwriteNonDirWithDir(err), checker.True, check.Commentf("expected CannotOverwriteNonDirWithDir error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// Check that copying from a local path to a symlink in a container copies to
|
||||
// the symlink target and does not overwrite the container symlink itself.
|
||||
func (s *DockerSuite) TestCpToSymlinkDestination(c *check.C) {
|
||||
// stat /tmp/test-cp-to-symlink-destination-262430901/vol3 gets permission denied for the user
|
||||
testRequires(c, NotUserNamespace)
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, SameHostDaemon) // Requires local volume mount bind.
|
||||
|
||||
testVol := getTestDir(c, "test-cp-to-symlink-destination-")
|
||||
defer os.RemoveAll(testVol)
|
||||
|
||||
makeTestContentInDir(c, testVol)
|
||||
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
volumes: defaultVolumes(testVol), // Our bind mount is at /vol2
|
||||
})
|
||||
|
||||
// First, copy a local file to a symlink to a file in the container. This
|
||||
// should overwrite the symlink target contents with the source contents.
|
||||
srcPath := cpPath(testVol, "file2")
|
||||
dstPath := containerCpPath(containerID, "/vol2/symlinkToFile1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, cpPath(testVol, "symlinkToFile1"), "file1"), checker.IsNil)
|
||||
|
||||
// The file should have the contents of "file2" now.
|
||||
c.Assert(fileContentEquals(c, cpPath(testVol, "file1"), "file2\n"), checker.IsNil)
|
||||
|
||||
// Next, copy a local file to a symlink to a directory in the container.
|
||||
// This should copy the file into the symlink target directory.
|
||||
dstPath = containerCpPath(containerID, "/vol2/symlinkToDir1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, cpPath(testVol, "symlinkToDir1"), "dir1"), checker.IsNil)
|
||||
|
||||
// The file should have the contents of "file2" now.
|
||||
c.Assert(fileContentEquals(c, cpPath(testVol, "file2"), "file2\n"), checker.IsNil)
|
||||
|
||||
// Next, copy a file to a symlink to a file that does not exist (a broken
|
||||
// symlink) in the container. This should create the target file with the
|
||||
// contents of the source file.
|
||||
dstPath = containerCpPath(containerID, "/vol2/brokenSymlinkToFileX")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, cpPath(testVol, "brokenSymlinkToFileX"), "fileX"), checker.IsNil)
|
||||
|
||||
// The file should have the contents of "file2" now.
|
||||
c.Assert(fileContentEquals(c, cpPath(testVol, "fileX"), "file2\n"), checker.IsNil)
|
||||
|
||||
// Next, copy a local directory to a symlink to a directory in the
|
||||
// container. This should copy the directory into the symlink target
|
||||
// directory and not modify the symlink.
|
||||
srcPath = cpPath(testVol, "/dir2")
|
||||
dstPath = containerCpPath(containerID, "/vol2/symlinkToDir1")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, cpPath(testVol, "symlinkToDir1"), "dir1"), checker.IsNil)
|
||||
|
||||
// The directory should now contain a copy of "dir2".
|
||||
c.Assert(fileContentEquals(c, cpPath(testVol, "dir1/dir2/file2-1"), "file2-1\n"), checker.IsNil)
|
||||
|
||||
// Next, copy a local directory to a symlink to a local directory that does
|
||||
// not exist (a broken symlink) in the container. This should create the
|
||||
// target as a directory with the contents of the source directory. It
|
||||
// should not modify the symlink.
|
||||
dstPath = containerCpPath(containerID, "/vol2/brokenSymlinkToDirX")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// The symlink should not have been modified.
|
||||
c.Assert(symlinkTargetEquals(c, cpPath(testVol, "brokenSymlinkToDirX"), "dirX"), checker.IsNil)
|
||||
|
||||
// The "dirX" directory should now be a copy of "dir2".
|
||||
c.Assert(fileContentEquals(c, cpPath(testVol, "dirX/file2-1"), "file2-1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// Possibilities are reduced to the remaining 10 cases:
|
||||
//
|
||||
// case | srcIsDir | onlyDirContents | dstExists | dstIsDir | dstTrSep | action
|
||||
// ===================================================================================================
|
||||
// A | no | - | no | - | no | create file
|
||||
// B | no | - | no | - | yes | error
|
||||
// C | no | - | yes | no | - | overwrite file
|
||||
// D | no | - | yes | yes | - | create file in dst dir
|
||||
// E | yes | no | no | - | - | create dir, copy contents
|
||||
// F | yes | no | yes | no | - | error
|
||||
// G | yes | no | yes | yes | - | copy dir and contents
|
||||
// H | yes | yes | no | - | - | create dir, copy contents
|
||||
// I | yes | yes | yes | no | - | error
|
||||
// J | yes | yes | yes | yes | - | copy dir contents
|
||||
//
|
||||
|
||||
// A. SRC specifies a file and DST (no trailing path separator) doesn't
|
||||
// exist. This should create a file with the name DST and copy the
|
||||
// contents of the source file into it.
|
||||
func (s *DockerSuite) TestCpToCaseA(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
workDir: "/root", command: makeCatFileCommand("itWorks.txt"),
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-a")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcPath := cpPath(tmpDir, "file1")
|
||||
dstPath := containerCpPath(containerID, "/root/itWorks.txt")
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// B. SRC specifies a file and DST (with trailing path separator) doesn't
|
||||
// exist. This should cause an error because the copy operation cannot
|
||||
// create a directory when copying a single file.
|
||||
func (s *DockerSuite) TestCpToCaseB(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
command: makeCatFileCommand("testDir/file1"),
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-b")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcPath := cpPath(tmpDir, "file1")
|
||||
dstDir := containerCpPathTrailingSep(containerID, "testDir")
|
||||
|
||||
err := runDockerCp(c, srcPath, dstDir)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpDirNotExist(err), checker.True, check.Commentf("expected DirNotExists error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// C. SRC specifies a file and DST exists as a file. This should overwrite
|
||||
// the file at DST with the contents of the source file.
|
||||
func (s *DockerSuite) TestCpToCaseC(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
command: makeCatFileCommand("file2"),
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-c")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcPath := cpPath(tmpDir, "file1")
|
||||
dstPath := containerCpPath(containerID, "/root/file2")
|
||||
|
||||
// Ensure the container's file starts with the original content.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file2\n"), checker.IsNil)
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstPath), checker.IsNil)
|
||||
|
||||
// Should now contain file1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// D. SRC specifies a file and DST exists as a directory. This should place
|
||||
// a copy of the source file inside it using the basename from SRC. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpToCaseD(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true,
|
||||
command: makeCatFileCommand("/dir1/file1"),
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-d")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcPath := cpPath(tmpDir, "file1")
|
||||
dstDir := containerCpPath(containerID, "dir1")
|
||||
|
||||
// Ensure that dstPath doesn't exist.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, ""), checker.IsNil)
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// Make new destination container.
|
||||
containerID = makeTestContainer(c, testContainerOptions{
|
||||
addContent: true,
|
||||
command: makeCatFileCommand("/dir1/file1"),
|
||||
})
|
||||
|
||||
dstDir = containerCpPathTrailingSep(containerID, "dir1")
|
||||
|
||||
// Ensure that dstPath doesn't exist.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, ""), checker.IsNil)
|
||||
|
||||
c.Assert(runDockerCp(c, srcPath, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// E. SRC specifies a directory and DST does not exist. This should create a
|
||||
// directory at DST and copy the contents of the SRC directory into the DST
|
||||
// directory. Ensure this works whether DST has a trailing path separator or
|
||||
// not.
|
||||
func (s *DockerSuite) TestCpToCaseE(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
command: makeCatFileCommand("/testDir/file1-1"),
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-e")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := cpPath(tmpDir, "dir1")
|
||||
dstDir := containerCpPath(containerID, "testDir")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1-1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1-1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// Make new destination container.
|
||||
containerID = makeTestContainer(c, testContainerOptions{
|
||||
command: makeCatFileCommand("/testDir/file1-1"),
|
||||
})
|
||||
|
||||
dstDir = containerCpPathTrailingSep(containerID, "testDir")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1-1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1-1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// F. SRC specifies a directory and DST exists as a file. This should cause an
|
||||
// error as it is not possible to overwrite a file with a directory.
|
||||
func (s *DockerSuite) TestCpToCaseF(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-f")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := cpPath(tmpDir, "dir1")
|
||||
dstFile := containerCpPath(containerID, "/root/file1")
|
||||
|
||||
err := runDockerCp(c, srcDir, dstFile)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpCannotCopyDir(err), checker.True, check.Commentf("expected ErrCannotCopyDir error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// G. SRC specifies a directory and DST exists as a directory. This should copy
|
||||
// the SRC directory and all its contents to the DST directory. Ensure this
|
||||
// works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpToCaseG(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
command: makeCatFileCommand("dir2/dir1/file1-1"),
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-g")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := cpPath(tmpDir, "dir1")
|
||||
dstDir := containerCpPath(containerID, "/root/dir2")
|
||||
|
||||
// Ensure that dstPath doesn't exist.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, ""), checker.IsNil)
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1-1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1-1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// Make new destination container.
|
||||
containerID = makeTestContainer(c, testContainerOptions{
|
||||
addContent: true,
|
||||
command: makeCatFileCommand("/dir2/dir1/file1-1"),
|
||||
})
|
||||
|
||||
dstDir = containerCpPathTrailingSep(containerID, "/dir2")
|
||||
|
||||
// Ensure that dstPath doesn't exist.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, ""), checker.IsNil)
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1-1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1-1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// H. SRC specifies a directory's contents only and DST does not exist. This
|
||||
// should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpToCaseH(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
command: makeCatFileCommand("/testDir/file1-1"),
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-h")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := cpPathTrailingSep(tmpDir, "dir1") + "."
|
||||
dstDir := containerCpPath(containerID, "testDir")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1-1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1-1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// Make new destination container.
|
||||
containerID = makeTestContainer(c, testContainerOptions{
|
||||
command: makeCatFileCommand("/testDir/file1-1"),
|
||||
})
|
||||
|
||||
dstDir = containerCpPathTrailingSep(containerID, "testDir")
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1-1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1-1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// I. SRC specifies a directory's contents only and DST exists as a file. This
|
||||
// should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
func (s *DockerSuite) TestCpToCaseI(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-i")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := cpPathTrailingSep(tmpDir, "dir1") + "."
|
||||
dstFile := containerCpPath(containerID, "/root/file1")
|
||||
|
||||
err := runDockerCp(c, srcDir, dstFile)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpCannotCopyDir(err), checker.True, check.Commentf("expected ErrCannotCopyDir error, but got %T: %s", err, err))
|
||||
}
|
||||
|
||||
// J. SRC specifies a directory's contents only and DST exists as a directory.
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpToCaseJ(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
addContent: true, workDir: "/root",
|
||||
command: makeCatFileCommand("/dir2/file1-1"),
|
||||
})
|
||||
|
||||
tmpDir := getTestDir(c, "test-cp-to-case-j")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
srcDir := cpPathTrailingSep(tmpDir, "dir1") + "."
|
||||
dstDir := containerCpPath(containerID, "/dir2")
|
||||
|
||||
// Ensure that dstPath doesn't exist.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, ""), checker.IsNil)
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1-1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1-1\n"), checker.IsNil)
|
||||
|
||||
// Now try again but using a trailing path separator for dstDir.
|
||||
|
||||
// Make new destination container.
|
||||
containerID = makeTestContainer(c, testContainerOptions{
|
||||
command: makeCatFileCommand("/dir2/file1-1"),
|
||||
})
|
||||
|
||||
dstDir = containerCpPathTrailingSep(containerID, "/dir2")
|
||||
|
||||
// Ensure that dstPath doesn't exist.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, ""), checker.IsNil)
|
||||
|
||||
c.Assert(runDockerCp(c, srcDir, dstDir), checker.IsNil)
|
||||
|
||||
// Should now contain file1-1's contents.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, "file1-1\n"), checker.IsNil)
|
||||
}
|
||||
|
||||
// The `docker cp` command should also ensure that you cannot
|
||||
// write to a container rootfs that is marked as read-only.
|
||||
func (s *DockerSuite) TestCpToErrReadOnlyRootfs(c *check.C) {
|
||||
// --read-only + userns has remount issues
|
||||
testRequires(c, DaemonIsLinux, NotUserNamespace)
|
||||
tmpDir := getTestDir(c, "test-cp-to-err-read-only-rootfs")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
readOnly: true, workDir: "/root",
|
||||
command: makeCatFileCommand("shouldNotExist"),
|
||||
})
|
||||
|
||||
srcPath := cpPath(tmpDir, "file1")
|
||||
dstPath := containerCpPath(containerID, "/root/shouldNotExist")
|
||||
|
||||
err := runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpCannotCopyReadOnly(err), checker.True, check.Commentf("expected ErrContainerRootfsReadonly error, but got %T: %s", err, err))
|
||||
|
||||
// Ensure that dstPath doesn't exist.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, ""), checker.IsNil)
|
||||
}
|
||||
|
||||
// The `docker cp` command should also ensure that you
|
||||
// cannot write to a volume that is mounted as read-only.
|
||||
func (s *DockerSuite) TestCpToErrReadOnlyVolume(c *check.C) {
|
||||
// --read-only + userns has remount issues
|
||||
testRequires(c, DaemonIsLinux, NotUserNamespace)
|
||||
tmpDir := getTestDir(c, "test-cp-to-err-read-only-volume")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
makeTestContentInDir(c, tmpDir)
|
||||
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
volumes: defaultVolumes(tmpDir), workDir: "/root",
|
||||
command: makeCatFileCommand("/vol_ro/shouldNotExist"),
|
||||
})
|
||||
|
||||
srcPath := cpPath(tmpDir, "file1")
|
||||
dstPath := containerCpPath(containerID, "/vol_ro/shouldNotExist")
|
||||
|
||||
err := runDockerCp(c, srcPath, dstPath)
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
c.Assert(isCpCannotCopyReadOnly(err), checker.True, check.Commentf("expected ErrVolumeReadonly error, but got %T: %s", err, err))
|
||||
|
||||
// Ensure that dstPath doesn't exist.
|
||||
c.Assert(containerStartOutputEquals(c, containerID, ""), checker.IsNil)
|
||||
}
|
||||
303
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_cp_utils.go
generated
vendored
Normal file
303
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_cp_utils.go
generated
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
type fileType uint32
|
||||
|
||||
const (
|
||||
ftRegular fileType = iota
|
||||
ftDir
|
||||
ftSymlink
|
||||
)
|
||||
|
||||
type fileData struct {
|
||||
filetype fileType
|
||||
path string
|
||||
contents string
|
||||
}
|
||||
|
||||
func (fd fileData) creationCommand() string {
|
||||
var command string
|
||||
|
||||
switch fd.filetype {
|
||||
case ftRegular:
|
||||
// Don't overwrite the file if it already exists!
|
||||
command = fmt.Sprintf("if [ ! -f %s ]; then echo %q > %s; fi", fd.path, fd.contents, fd.path)
|
||||
case ftDir:
|
||||
command = fmt.Sprintf("mkdir -p %s", fd.path)
|
||||
case ftSymlink:
|
||||
command = fmt.Sprintf("ln -fs %s %s", fd.contents, fd.path)
|
||||
}
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
func mkFilesCommand(fds []fileData) string {
|
||||
commands := make([]string, len(fds))
|
||||
|
||||
for i, fd := range fds {
|
||||
commands[i] = fd.creationCommand()
|
||||
}
|
||||
|
||||
return strings.Join(commands, " && ")
|
||||
}
|
||||
|
||||
var defaultFileData = []fileData{
|
||||
{ftRegular, "file1", "file1"},
|
||||
{ftRegular, "file2", "file2"},
|
||||
{ftRegular, "file3", "file3"},
|
||||
{ftRegular, "file4", "file4"},
|
||||
{ftRegular, "file5", "file5"},
|
||||
{ftRegular, "file6", "file6"},
|
||||
{ftRegular, "file7", "file7"},
|
||||
{ftDir, "dir1", ""},
|
||||
{ftRegular, "dir1/file1-1", "file1-1"},
|
||||
{ftRegular, "dir1/file1-2", "file1-2"},
|
||||
{ftDir, "dir2", ""},
|
||||
{ftRegular, "dir2/file2-1", "file2-1"},
|
||||
{ftRegular, "dir2/file2-2", "file2-2"},
|
||||
{ftDir, "dir3", ""},
|
||||
{ftRegular, "dir3/file3-1", "file3-1"},
|
||||
{ftRegular, "dir3/file3-2", "file3-2"},
|
||||
{ftDir, "dir4", ""},
|
||||
{ftRegular, "dir4/file3-1", "file4-1"},
|
||||
{ftRegular, "dir4/file3-2", "file4-2"},
|
||||
{ftDir, "dir5", ""},
|
||||
{ftSymlink, "symlinkToFile1", "file1"},
|
||||
{ftSymlink, "symlinkToDir1", "dir1"},
|
||||
{ftSymlink, "brokenSymlinkToFileX", "fileX"},
|
||||
{ftSymlink, "brokenSymlinkToDirX", "dirX"},
|
||||
{ftSymlink, "symlinkToAbsDir", "/root"},
|
||||
}
|
||||
|
||||
func defaultMkContentCommand() string {
|
||||
return mkFilesCommand(defaultFileData)
|
||||
}
|
||||
|
||||
func makeTestContentInDir(c *check.C, dir string) {
|
||||
for _, fd := range defaultFileData {
|
||||
path := filepath.Join(dir, filepath.FromSlash(fd.path))
|
||||
switch fd.filetype {
|
||||
case ftRegular:
|
||||
c.Assert(ioutil.WriteFile(path, []byte(fd.contents+"\n"), os.FileMode(0666)), checker.IsNil)
|
||||
case ftDir:
|
||||
c.Assert(os.Mkdir(path, os.FileMode(0777)), checker.IsNil)
|
||||
case ftSymlink:
|
||||
c.Assert(os.Symlink(fd.contents, path), checker.IsNil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type testContainerOptions struct {
|
||||
addContent bool
|
||||
readOnly bool
|
||||
volumes []string
|
||||
workDir string
|
||||
command string
|
||||
}
|
||||
|
||||
func makeTestContainer(c *check.C, options testContainerOptions) (containerID string) {
|
||||
if options.addContent {
|
||||
mkContentCmd := defaultMkContentCommand()
|
||||
if options.command == "" {
|
||||
options.command = mkContentCmd
|
||||
} else {
|
||||
options.command = fmt.Sprintf("%s && %s", defaultMkContentCommand(), options.command)
|
||||
}
|
||||
}
|
||||
|
||||
if options.command == "" {
|
||||
options.command = "#(nop)"
|
||||
}
|
||||
|
||||
args := []string{"run", "-d"}
|
||||
|
||||
for _, volume := range options.volumes {
|
||||
args = append(args, "-v", volume)
|
||||
}
|
||||
|
||||
if options.workDir != "" {
|
||||
args = append(args, "-w", options.workDir)
|
||||
}
|
||||
|
||||
if options.readOnly {
|
||||
args = append(args, "--read-only")
|
||||
}
|
||||
|
||||
args = append(args, "busybox", "/bin/sh", "-c", options.command)
|
||||
|
||||
out, _ := dockerCmd(c, args...)
|
||||
|
||||
containerID = strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
|
||||
exitCode := strings.TrimSpace(out)
|
||||
if exitCode != "0" {
|
||||
out, _ = dockerCmd(c, "logs", containerID)
|
||||
}
|
||||
c.Assert(exitCode, checker.Equals, "0", check.Commentf("failed to make test container: %s", out))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func makeCatFileCommand(path string) string {
|
||||
return fmt.Sprintf("if [ -f %s ]; then cat %s; fi", path, path)
|
||||
}
|
||||
|
||||
func cpPath(pathElements ...string) string {
|
||||
localizedPathElements := make([]string, len(pathElements))
|
||||
for i, path := range pathElements {
|
||||
localizedPathElements[i] = filepath.FromSlash(path)
|
||||
}
|
||||
return strings.Join(localizedPathElements, string(filepath.Separator))
|
||||
}
|
||||
|
||||
func cpPathTrailingSep(pathElements ...string) string {
|
||||
return fmt.Sprintf("%s%c", cpPath(pathElements...), filepath.Separator)
|
||||
}
|
||||
|
||||
func containerCpPath(containerID string, pathElements ...string) string {
|
||||
joined := strings.Join(pathElements, "/")
|
||||
return fmt.Sprintf("%s:%s", containerID, joined)
|
||||
}
|
||||
|
||||
func containerCpPathTrailingSep(containerID string, pathElements ...string) string {
|
||||
return fmt.Sprintf("%s/", containerCpPath(containerID, pathElements...))
|
||||
}
|
||||
|
||||
func runDockerCp(c *check.C, src, dst string) (err error) {
|
||||
c.Logf("running `docker cp %s %s`", src, dst)
|
||||
|
||||
args := []string{"cp", src, dst}
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, args...))
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error executing `docker cp` command: %s: %s", err, out)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func startContainerGetOutput(c *check.C, containerID string) (out string, err error) {
|
||||
c.Logf("running `docker start -a %s`", containerID)
|
||||
|
||||
args := []string{"start", "-a", containerID}
|
||||
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, args...))
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error executing `docker start` command: %s: %s", err, out)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getTestDir(c *check.C, label string) (tmpDir string) {
|
||||
var err error
|
||||
|
||||
tmpDir, err = ioutil.TempDir("", label)
|
||||
// unable to make temporary directory
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func isCpNotExist(err error) bool {
|
||||
return strings.Contains(err.Error(), "no such file or directory") || strings.Contains(err.Error(), "cannot find the file specified")
|
||||
}
|
||||
|
||||
func isCpDirNotExist(err error) bool {
|
||||
return strings.Contains(err.Error(), archive.ErrDirNotExists.Error())
|
||||
}
|
||||
|
||||
func isCpNotDir(err error) bool {
|
||||
return strings.Contains(err.Error(), archive.ErrNotDirectory.Error()) || strings.Contains(err.Error(), "filename, directory name, or volume label syntax is incorrect")
|
||||
}
|
||||
|
||||
func isCpCannotCopyDir(err error) bool {
|
||||
return strings.Contains(err.Error(), archive.ErrCannotCopyDir.Error())
|
||||
}
|
||||
|
||||
func isCpCannotCopyReadOnly(err error) bool {
|
||||
return strings.Contains(err.Error(), "marked read-only")
|
||||
}
|
||||
|
||||
func isCannotOverwriteNonDirWithDir(err error) bool {
|
||||
return strings.Contains(err.Error(), "cannot overwrite non-directory")
|
||||
}
|
||||
|
||||
func fileContentEquals(c *check.C, filename, contents string) (err error) {
|
||||
c.Logf("checking that file %q contains %q\n", filename, contents)
|
||||
|
||||
fileBytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
expectedBytes, err := ioutil.ReadAll(strings.NewReader(contents))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Equal(fileBytes, expectedBytes) {
|
||||
err = fmt.Errorf("file content not equal - expected %q, got %q", string(expectedBytes), string(fileBytes))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func symlinkTargetEquals(c *check.C, symlink, expectedTarget string) (err error) {
|
||||
c.Logf("checking that the symlink %q points to %q\n", symlink, expectedTarget)
|
||||
|
||||
actualTarget, err := os.Readlink(symlink)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if actualTarget != expectedTarget {
|
||||
err = fmt.Errorf("symlink target points to %q not %q", actualTarget, expectedTarget)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func containerStartOutputEquals(c *check.C, containerID, contents string) (err error) {
|
||||
c.Logf("checking that container %q start output contains %q\n", containerID, contents)
|
||||
|
||||
out, err := startContainerGetOutput(c, containerID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if out != contents {
|
||||
err = fmt.Errorf("output contents not equal - expected %q, got %q", contents, out)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func defaultVolumes(tmpDir string) []string {
|
||||
if SameHostDaemon.Condition() {
|
||||
return []string{
|
||||
"/vol1",
|
||||
fmt.Sprintf("%s:/vol2", tmpDir),
|
||||
fmt.Sprintf("%s:/vol3", filepath.Join(tmpDir, "vol3")),
|
||||
fmt.Sprintf("%s:/vol_ro:ro", filepath.Join(tmpDir, "vol_ro")),
|
||||
}
|
||||
}
|
||||
|
||||
// Can't bind-mount volumes with separate host daemon.
|
||||
return []string{"/vol1", "/vol2", "/vol3", "/vol_ro:/vol_ro:ro"}
|
||||
}
|
||||
2118
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_daemon_test.go
generated
vendored
Executable file
2118
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_daemon_test.go
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
87
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_diff_test.go
generated
vendored
Normal file
87
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_diff_test.go
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// ensure that an added file shows up in docker diff
|
||||
func (s *DockerSuite) TestDiffFilenameShownInOutput(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerCmd := `echo foo > /root/bar`
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", containerCmd)
|
||||
|
||||
cleanCID := strings.TrimSpace(out)
|
||||
out, _ = dockerCmd(c, "diff", cleanCID)
|
||||
|
||||
found := false
|
||||
for _, line := range strings.Split(out, "\n") {
|
||||
if strings.Contains("A /root/bar", line) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
c.Assert(found, checker.True)
|
||||
}
|
||||
|
||||
// test to ensure GH #3840 doesn't occur any more
|
||||
func (s *DockerSuite) TestDiffEnsureInitLayerFilesAreIgnored(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// this is a list of files which shouldn't show up in `docker diff`
|
||||
initLayerFiles := []string{"/etc/resolv.conf", "/etc/hostname", "/etc/hosts", "/.dockerenv"}
|
||||
containerCount := 5
|
||||
|
||||
// we might not run into this problem from the first run, so start a few containers
|
||||
for i := 0; i < containerCount; i++ {
|
||||
containerCmd := `echo foo > /root/bar`
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", containerCmd)
|
||||
|
||||
cleanCID := strings.TrimSpace(out)
|
||||
out, _ = dockerCmd(c, "diff", cleanCID)
|
||||
|
||||
for _, filename := range initLayerFiles {
|
||||
c.Assert(out, checker.Not(checker.Contains), filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestDiffEnsureOnlyKmsgAndPtmx(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "sleep", "0")
|
||||
|
||||
cleanCID := strings.TrimSpace(out)
|
||||
out, _ = dockerCmd(c, "diff", cleanCID)
|
||||
|
||||
expected := map[string]bool{
|
||||
"C /dev": true,
|
||||
"A /dev/full": true, // busybox
|
||||
"C /dev/ptmx": true, // libcontainer
|
||||
"A /dev/mqueue": true,
|
||||
"A /dev/kmsg": true,
|
||||
"A /dev/fd": true,
|
||||
"A /dev/fuse": true,
|
||||
"A /dev/ptmx": true,
|
||||
"A /dev/null": true,
|
||||
"A /dev/random": true,
|
||||
"A /dev/stdout": true,
|
||||
"A /dev/stderr": true,
|
||||
"A /dev/tty1": true,
|
||||
"A /dev/stdin": true,
|
||||
"A /dev/tty": true,
|
||||
"A /dev/urandom": true,
|
||||
"A /dev/zero": true,
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(out, "\n") {
|
||||
c.Assert(line == "" || expected[line], checker.True)
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/docker/docker/pull/14381#discussion_r33859347
|
||||
func (s *DockerSuite) TestDiffEmptyArgClientError(c *check.C) {
|
||||
out, _, err := dockerCmdWithError("diff", "")
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "Container name cannot be empty")
|
||||
}
|
||||
605
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_events_test.go
generated
vendored
Normal file
605
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_events_test.go
generated
vendored
Normal file
@@ -0,0 +1,605 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestEventsTimestampFormats(c *check.C) {
|
||||
image := "busybox"
|
||||
|
||||
// Start stopwatch, generate an event
|
||||
time.Sleep(1 * time.Second) // so that we don't grab events from previous test occured in the same second
|
||||
start := daemonTime(c)
|
||||
dockerCmd(c, "tag", image, "timestamptest:1")
|
||||
dockerCmd(c, "rmi", "timestamptest:1")
|
||||
time.Sleep(1 * time.Second) // so that until > since
|
||||
end := daemonTime(c)
|
||||
|
||||
// List of available time formats to --since
|
||||
unixTs := func(t time.Time) string { return fmt.Sprintf("%v", t.Unix()) }
|
||||
rfc3339 := func(t time.Time) string { return t.Format(time.RFC3339) }
|
||||
duration := func(t time.Time) string { return time.Now().Sub(t).String() }
|
||||
|
||||
// --since=$start must contain only the 'untag' event
|
||||
for _, f := range []func(time.Time) string{unixTs, rfc3339, duration} {
|
||||
since, until := f(start), f(end)
|
||||
out, _ := dockerCmd(c, "events", "--since="+since, "--until="+until)
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(events, checker.HasLen, 2, check.Commentf("unexpected events, was expecting only 2 events tag/untag (since=%s, until=%s) out=%s", since, until, out))
|
||||
c.Assert(out, checker.Contains, "untag", check.Commentf("expected 'untag' event not found (since=%s, until=%s)", since, until))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsUntag(c *check.C) {
|
||||
image := "busybox"
|
||||
dockerCmd(c, "tag", image, "utest:tag1")
|
||||
dockerCmd(c, "tag", image, "utest:tag2")
|
||||
dockerCmd(c, "rmi", "utest:tag1")
|
||||
dockerCmd(c, "rmi", "utest:tag2")
|
||||
eventsCmd := exec.Command(dockerBinary, "events", "--since=1")
|
||||
out, exitCode, _, err := runCommandWithOutputForDuration(eventsCmd, time.Duration(time.Millisecond*2500))
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(exitCode, checker.Equals, 0, check.Commentf("Failed to get events"))
|
||||
events := strings.Split(out, "\n")
|
||||
nEvents := len(events)
|
||||
// The last element after the split above will be an empty string, so we
|
||||
// get the two elements before the last, which are the untags we're
|
||||
// looking for.
|
||||
for _, v := range events[nEvents-3 : nEvents-1] {
|
||||
c.Assert(v, checker.Contains, "untag", check.Commentf("event should be untag"))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsContainerFailStartDie(c *check.C) {
|
||||
_, _, err := dockerCmdWithError("run", "--name", "testeventdie", "busybox", "blerg")
|
||||
c.Assert(err, checker.NotNil, check.Commentf("Container run with command blerg should have failed, but it did not"))
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
|
||||
nEvents := len(events)
|
||||
c.Assert(nEvents, checker.GreaterOrEqualThan, 1) //Missing expected event
|
||||
|
||||
actions := eventActionsByIDAndType(c, events, "testeventdie", "container")
|
||||
|
||||
var startEvent bool
|
||||
var dieEvent bool
|
||||
for _, a := range actions {
|
||||
switch a {
|
||||
case "start":
|
||||
startEvent = true
|
||||
case "die":
|
||||
dieEvent = true
|
||||
}
|
||||
}
|
||||
c.Assert(startEvent, checker.True, check.Commentf("Start event not found: %v\n%v", actions, events))
|
||||
c.Assert(dieEvent, checker.True, check.Commentf("Die event not found: %v\n%v", actions, events))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsLimit(c *check.C) {
|
||||
// TODO Windows CI: This test is not reliable enough on Windows TP4. Reports
|
||||
// multiple errors in the analytic log sometimes.
|
||||
// [NetSetupHelper::InstallVirtualMiniport()@2153] NetSetup install of ROOT\VMS_MP\0001 failed with error 0x80070002
|
||||
// This should be able to be enabled on TP5.
|
||||
testRequires(c, DaemonIsLinux)
|
||||
var waitGroup sync.WaitGroup
|
||||
errChan := make(chan error, 17)
|
||||
|
||||
args := []string{"run", "--rm", "busybox", "true"}
|
||||
for i := 0; i < 17; i++ {
|
||||
waitGroup.Add(1)
|
||||
go func() {
|
||||
defer waitGroup.Done()
|
||||
errChan <- exec.Command(dockerBinary, args...).Run()
|
||||
}()
|
||||
}
|
||||
|
||||
waitGroup.Wait()
|
||||
close(errChan)
|
||||
|
||||
for err := range errChan {
|
||||
c.Assert(err, checker.IsNil, check.Commentf("%q failed with error", strings.Join(args, " ")))
|
||||
}
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(out, "\n")
|
||||
nEvents := len(events) - 1
|
||||
c.Assert(nEvents, checker.Equals, 64, check.Commentf("events should be limited to 64, but received %d", nEvents))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsContainerEvents(c *check.C) {
|
||||
containerID, _ := dockerCmd(c, "run", "--rm", "--name", "container-events-test", "busybox", "true")
|
||||
containerID = strings.TrimSpace(containerID)
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(out, "\n")
|
||||
events = events[:len(events)-1]
|
||||
|
||||
nEvents := len(events)
|
||||
c.Assert(nEvents, checker.GreaterOrEqualThan, 5) //Missing expected event
|
||||
containerEvents := eventActionsByIDAndType(c, events, "container-events-test", "container")
|
||||
c.Assert(containerEvents, checker.HasLen, 5, check.Commentf("events: %v", events))
|
||||
|
||||
c.Assert(containerEvents[0], checker.Equals, "create", check.Commentf(out))
|
||||
c.Assert(containerEvents[1], checker.Equals, "attach", check.Commentf(out))
|
||||
c.Assert(containerEvents[2], checker.Equals, "start", check.Commentf(out))
|
||||
c.Assert(containerEvents[3], checker.Equals, "die", check.Commentf(out))
|
||||
c.Assert(containerEvents[4], checker.Equals, "destroy", check.Commentf(out))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsContainerEventsAttrSort(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
containerID, _ := dockerCmd(c, "run", "-d", "--name", "container-events-test", "busybox", "true")
|
||||
containerID = strings.TrimSpace(containerID)
|
||||
|
||||
out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(out, "\n")
|
||||
|
||||
nEvents := len(events)
|
||||
c.Assert(nEvents, checker.GreaterOrEqualThan, 3) //Missing expected event
|
||||
matchedEvents := 0
|
||||
for _, event := range events {
|
||||
matches := parseEventText(event)
|
||||
if matches["id"] != containerID {
|
||||
continue
|
||||
}
|
||||
if matches["eventType"] == "container" && matches["action"] == "create" {
|
||||
matchedEvents++
|
||||
c.Assert(out, checker.Contains, "(image=busybox, name=container-events-test)", check.Commentf("Event attributes not sorted"))
|
||||
} else if matches["eventType"] == "container" && matches["action"] == "start" {
|
||||
matchedEvents++
|
||||
c.Assert(out, checker.Contains, "(image=busybox, name=container-events-test)", check.Commentf("Event attributes not sorted"))
|
||||
}
|
||||
}
|
||||
c.Assert(matchedEvents, checker.Equals, 2)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsContainerEventsSinceUnixEpoch(c *check.C) {
|
||||
dockerCmd(c, "run", "--rm", "--name", "since-epoch-test", "busybox", "true")
|
||||
timeBeginning := time.Unix(0, 0).Format(time.RFC3339Nano)
|
||||
timeBeginning = strings.Replace(timeBeginning, "Z", ".000000000Z", -1)
|
||||
out, _ := dockerCmd(c, "events", fmt.Sprintf("--since='%s'", timeBeginning), fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(out, "\n")
|
||||
events = events[:len(events)-1]
|
||||
|
||||
nEvents := len(events)
|
||||
c.Assert(nEvents, checker.GreaterOrEqualThan, 5) //Missing expected event
|
||||
containerEvents := eventActionsByIDAndType(c, events, "since-epoch-test", "container")
|
||||
c.Assert(containerEvents, checker.HasLen, 5, check.Commentf("events: %v", events))
|
||||
|
||||
c.Assert(containerEvents[0], checker.Equals, "create", check.Commentf(out))
|
||||
c.Assert(containerEvents[1], checker.Equals, "attach", check.Commentf(out))
|
||||
c.Assert(containerEvents[2], checker.Equals, "start", check.Commentf(out))
|
||||
c.Assert(containerEvents[3], checker.Equals, "die", check.Commentf(out))
|
||||
c.Assert(containerEvents[4], checker.Equals, "destroy", check.Commentf(out))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsImageTag(c *check.C) {
|
||||
time.Sleep(1 * time.Second) // because API has seconds granularity
|
||||
since := daemonTime(c).Unix()
|
||||
image := "testimageevents:tag"
|
||||
dockerCmd(c, "tag", "busybox", image)
|
||||
|
||||
out, _ := dockerCmd(c, "events",
|
||||
fmt.Sprintf("--since=%d", since),
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(events, checker.HasLen, 1, check.Commentf("was expecting 1 event. out=%s", out))
|
||||
event := strings.TrimSpace(events[0])
|
||||
|
||||
matches := parseEventText(event)
|
||||
c.Assert(matchEventID(matches, image), checker.True, check.Commentf("matches: %v\nout:\n%s", matches, out))
|
||||
c.Assert(matches["action"], checker.Equals, "tag")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsImagePull(c *check.C) {
|
||||
// TODO Windows: Enable this test once pull and reliable image names are available
|
||||
testRequires(c, DaemonIsLinux)
|
||||
since := daemonTime(c).Unix()
|
||||
testRequires(c, Network)
|
||||
|
||||
dockerCmd(c, "pull", "hello-world")
|
||||
|
||||
out, _ := dockerCmd(c, "events",
|
||||
fmt.Sprintf("--since=%d", since),
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
event := strings.TrimSpace(events[len(events)-1])
|
||||
matches := parseEventText(event)
|
||||
c.Assert(matches["id"], checker.Equals, "hello-world:latest")
|
||||
c.Assert(matches["action"], checker.Equals, "pull")
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsImageImport(c *check.C) {
|
||||
// TODO Windows CI. This should be portable once export/import are
|
||||
// more reliable (@swernli)
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
since := daemonTime(c).Unix()
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "export", cleanedContainerID),
|
||||
exec.Command(dockerBinary, "import", "-"),
|
||||
)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("import failed with output: %q", out))
|
||||
imageRef := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", "event=import")
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(events, checker.HasLen, 1)
|
||||
matches := parseEventText(events[0])
|
||||
c.Assert(matches["id"], checker.Equals, imageRef, check.Commentf("matches: %v\nout:\n%s\n", matches, out))
|
||||
c.Assert(matches["action"], checker.Equals, "import", check.Commentf("matches: %v\nout:\n%s\n", matches, out))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilters(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
dockerCmd(c, "run", "--rm", "busybox", "true")
|
||||
dockerCmd(c, "run", "--rm", "busybox", "true")
|
||||
out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", "event=die")
|
||||
parseEvents(c, out, "die")
|
||||
|
||||
out, _ = dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", "event=die", "--filter", "event=start")
|
||||
parseEvents(c, out, "die|start")
|
||||
|
||||
// make sure we at least got 2 start events
|
||||
count := strings.Count(out, "start")
|
||||
c.Assert(strings.Count(out, "start"), checker.GreaterOrEqualThan, 2, check.Commentf("should have had 2 start events but had %d, out: %s", count, out))
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilterImageName(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
out, _ := dockerCmd(c, "run", "--name", "container_1", "-d", "busybox:latest", "true")
|
||||
container1 := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "run", "--name", "container_2", "-d", "busybox", "true")
|
||||
container2 := strings.TrimSpace(out)
|
||||
|
||||
name := "busybox"
|
||||
out, _ = dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", fmt.Sprintf("image=%s", name))
|
||||
events := strings.Split(out, "\n")
|
||||
events = events[:len(events)-1]
|
||||
c.Assert(events, checker.Not(checker.HasLen), 0) //Expected events but found none for the image busybox:latest
|
||||
count1 := 0
|
||||
count2 := 0
|
||||
|
||||
for _, e := range events {
|
||||
if strings.Contains(e, container1) {
|
||||
count1++
|
||||
} else if strings.Contains(e, container2) {
|
||||
count2++
|
||||
}
|
||||
}
|
||||
c.Assert(count1, checker.Not(checker.Equals), 0, check.Commentf("Expected event from container but got %d from %s", count1, container1))
|
||||
c.Assert(count2, checker.Not(checker.Equals), 0, check.Commentf("Expected event from container but got %d from %s", count2, container2))
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilterLabels(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
label := "io.docker.testing=foo"
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-d", "-l", label, "busybox:latest", "true")
|
||||
container1 := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "run", "-d", "busybox", "true")
|
||||
container2 := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(
|
||||
c,
|
||||
"events",
|
||||
fmt.Sprintf("--since=%d", since),
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()),
|
||||
"--filter", fmt.Sprintf("label=%s", label))
|
||||
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(len(events), checker.Equals, 3)
|
||||
|
||||
for _, e := range events {
|
||||
c.Assert(e, checker.Contains, container1)
|
||||
c.Assert(e, checker.Not(checker.Contains), container2)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilterImageLabels(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
name := "labelfiltertest"
|
||||
label := "io.docker.testing=image"
|
||||
|
||||
// Build a test image.
|
||||
_, err := buildImage(name, fmt.Sprintf(`
|
||||
FROM busybox:latest
|
||||
LABEL %s`, label), true)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("Couldn't create image"))
|
||||
|
||||
dockerCmd(c, "tag", name, "labelfiltertest:tag1")
|
||||
dockerCmd(c, "tag", name, "labelfiltertest:tag2")
|
||||
dockerCmd(c, "tag", "busybox:latest", "labelfiltertest:tag3")
|
||||
|
||||
out, _ := dockerCmd(
|
||||
c,
|
||||
"events",
|
||||
fmt.Sprintf("--since=%d", since),
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()),
|
||||
"--filter", fmt.Sprintf("label=%s", label),
|
||||
"--filter", "type=image")
|
||||
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
|
||||
// 2 events from the "docker tag" command, another one is from "docker build"
|
||||
c.Assert(events, checker.HasLen, 3, check.Commentf("Events == %s", events))
|
||||
for _, e := range events {
|
||||
c.Assert(e, checker.Contains, "labelfiltertest")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilterContainer(c *check.C) {
|
||||
since := fmt.Sprintf("%d", daemonTime(c).Unix())
|
||||
nameID := make(map[string]string)
|
||||
|
||||
for _, name := range []string{"container_1", "container_2"} {
|
||||
dockerCmd(c, "run", "--name", name, "busybox", "true")
|
||||
id := inspectField(c, name, "Id")
|
||||
nameID[name] = id
|
||||
}
|
||||
|
||||
until := fmt.Sprintf("%d", daemonTime(c).Unix())
|
||||
|
||||
checkEvents := func(id string, events []string) error {
|
||||
if len(events) != 4 { // create, attach, start, die
|
||||
return fmt.Errorf("expected 4 events, got %v", events)
|
||||
}
|
||||
for _, event := range events {
|
||||
matches := parseEventText(event)
|
||||
if !matchEventID(matches, id) {
|
||||
return fmt.Errorf("expected event for container id %s: %s - parsed container id: %s", id, event, matches["id"])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for name, ID := range nameID {
|
||||
// filter by names
|
||||
out, _ := dockerCmd(c, "events", "--since", since, "--until", until, "--filter", "container="+name)
|
||||
events := strings.Split(strings.TrimSuffix(out, "\n"), "\n")
|
||||
c.Assert(checkEvents(ID, events), checker.IsNil)
|
||||
|
||||
// filter by ID's
|
||||
out, _ = dockerCmd(c, "events", "--since", since, "--until", until, "--filter", "container="+ID)
|
||||
events = strings.Split(strings.TrimSuffix(out, "\n"), "\n")
|
||||
c.Assert(checkEvents(ID, events), checker.IsNil)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsCommit(c *check.C) {
|
||||
// Problematic on Windows as cannot commit a running container
|
||||
testRequires(c, DaemonIsLinux)
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
out, _ := runSleepingContainer(c, "-d")
|
||||
cID := strings.TrimSpace(out)
|
||||
c.Assert(waitRun(cID), checker.IsNil)
|
||||
|
||||
dockerCmd(c, "commit", "-m", "test", cID)
|
||||
dockerCmd(c, "stop", cID)
|
||||
|
||||
out, _ = dockerCmd(c, "events", "--since=0", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
|
||||
c.Assert(out, checker.Contains, "commit", check.Commentf("Missing 'commit' log event"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsCopy(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
// Build a test image.
|
||||
id, err := buildImage("cpimg", `
|
||||
FROM busybox
|
||||
RUN echo HI > /file`, true)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("Couldn't create image"))
|
||||
|
||||
// Create an empty test file.
|
||||
tempFile, err := ioutil.TempFile("", "test-events-copy-")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
c.Assert(tempFile.Close(), checker.IsNil)
|
||||
|
||||
dockerCmd(c, "create", "--name=cptest", id)
|
||||
|
||||
dockerCmd(c, "cp", "cptest:/file", tempFile.Name())
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=cptest", "--until="+strconv.Itoa(int(since)))
|
||||
c.Assert(out, checker.Contains, "archive-path", check.Commentf("Missing 'archive-path' log event\n"))
|
||||
|
||||
dockerCmd(c, "cp", tempFile.Name(), "cptest:/filecopy")
|
||||
|
||||
out, _ = dockerCmd(c, "events", "--since=0", "-f", "container=cptest", "--until="+strconv.Itoa(int(since)))
|
||||
c.Assert(out, checker.Contains, "extract-to-dir", check.Commentf("Missing 'extract-to-dir' log event"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsResize(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
|
||||
cID := strings.TrimSpace(out)
|
||||
c.Assert(waitRun(cID), checker.IsNil)
|
||||
|
||||
endpoint := "/containers/" + cID + "/resize?h=80&w=24"
|
||||
status, _, err := sockRequest("POST", endpoint, nil)
|
||||
c.Assert(status, checker.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
dockerCmd(c, "stop", cID)
|
||||
|
||||
out, _ = dockerCmd(c, "events", "--since=0", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
|
||||
c.Assert(out, checker.Contains, "resize", check.Commentf("Missing 'resize' log event"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsAttach(c *check.C) {
|
||||
// TODO Windows CI: Figure out why this test fails intermittently (TP4 and TP5).
|
||||
testRequires(c, DaemonIsLinux)
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-di", "busybox", "cat")
|
||||
cID := strings.TrimSpace(out)
|
||||
|
||||
cmd := exec.Command(dockerBinary, "attach", cID)
|
||||
stdin, err := cmd.StdinPipe()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer stdin.Close()
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer stdout.Close()
|
||||
c.Assert(cmd.Start(), checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
// Make sure we're done attaching by writing/reading some stuff
|
||||
_, err = stdin.Write([]byte("hello\n"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
out, err = bufio.NewReader(stdout).ReadString('\n')
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "hello", check.Commentf("expected 'hello'"))
|
||||
|
||||
c.Assert(stdin.Close(), checker.IsNil)
|
||||
|
||||
dockerCmd(c, "kill", cID)
|
||||
|
||||
out, _ = dockerCmd(c, "events", "--since=0", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
|
||||
c.Assert(out, checker.Contains, "attach", check.Commentf("Missing 'attach' log event"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsRename(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
dockerCmd(c, "run", "--name", "oldName", "busybox", "true")
|
||||
dockerCmd(c, "rename", "oldName", "newName")
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=newName", "--until="+strconv.Itoa(int(since)))
|
||||
c.Assert(out, checker.Contains, "rename", check.Commentf("Missing 'rename' log event\n"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsTop(c *check.C) {
|
||||
// Problematic on Windows as Windows does not support top
|
||||
testRequires(c, DaemonIsLinux)
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
out, _ := runSleepingContainer(c, "-d")
|
||||
cID := strings.TrimSpace(out)
|
||||
c.Assert(waitRun(cID), checker.IsNil)
|
||||
|
||||
dockerCmd(c, "top", cID)
|
||||
dockerCmd(c, "stop", cID)
|
||||
|
||||
out, _ = dockerCmd(c, "events", "--since=0", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
|
||||
c.Assert(out, checker.Contains, " top", check.Commentf("Missing 'top' log event"))
|
||||
}
|
||||
|
||||
// #13753
|
||||
func (s *DockerSuite) TestEventsDefaultEmpty(c *check.C) {
|
||||
dockerCmd(c, "run", "busybox")
|
||||
out, _ := dockerCmd(c, "events", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "")
|
||||
}
|
||||
|
||||
// #14316
|
||||
func (s *DockerRegistrySuite) TestEventsImageFilterPush(c *check.C) {
|
||||
// Problematic to port for Windows CI during TP4/TP5 timeframe while
|
||||
// not supporting push
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, Network)
|
||||
since := daemonTime(c).Unix()
|
||||
repoName := fmt.Sprintf("%v/dockercli/testf", privateRegistryURL)
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
|
||||
cID := strings.TrimSpace(out)
|
||||
c.Assert(waitRun(cID), checker.IsNil)
|
||||
|
||||
dockerCmd(c, "commit", cID, repoName)
|
||||
dockerCmd(c, "stop", cID)
|
||||
dockerCmd(c, "push", repoName)
|
||||
|
||||
out, _ = dockerCmd(c, "events", "--since=0", "-f", "image="+repoName, "-f", "event=push", "--until="+strconv.Itoa(int(since)))
|
||||
c.Assert(out, checker.Contains, repoName, check.Commentf("Missing 'push' log event for %s", repoName))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilterType(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
name := "labelfiltertest"
|
||||
label := "io.docker.testing=image"
|
||||
|
||||
// Build a test image.
|
||||
_, err := buildImage(name, fmt.Sprintf(`
|
||||
FROM busybox:latest
|
||||
LABEL %s`, label), true)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("Couldn't create image"))
|
||||
|
||||
dockerCmd(c, "tag", name, "labelfiltertest:tag1")
|
||||
dockerCmd(c, "tag", name, "labelfiltertest:tag2")
|
||||
dockerCmd(c, "tag", "busybox:latest", "labelfiltertest:tag3")
|
||||
|
||||
out, _ := dockerCmd(
|
||||
c,
|
||||
"events",
|
||||
fmt.Sprintf("--since=%d", since),
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()),
|
||||
"--filter", fmt.Sprintf("label=%s", label),
|
||||
"--filter", "type=image")
|
||||
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
|
||||
// 2 events from the "docker tag" command, another one is from "docker build"
|
||||
c.Assert(events, checker.HasLen, 3, check.Commentf("Events == %s", events))
|
||||
for _, e := range events {
|
||||
c.Assert(e, checker.Contains, "labelfiltertest")
|
||||
}
|
||||
|
||||
out, _ = dockerCmd(
|
||||
c,
|
||||
"events",
|
||||
fmt.Sprintf("--since=%d", since),
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()),
|
||||
"--filter", fmt.Sprintf("label=%s", label),
|
||||
"--filter", "type=container")
|
||||
events = strings.Split(strings.TrimSpace(out), "\n")
|
||||
|
||||
// Events generated by the container that builds the image
|
||||
c.Assert(events, checker.HasLen, 3, check.Commentf("Events == %s", events))
|
||||
|
||||
out, _ = dockerCmd(
|
||||
c,
|
||||
"events",
|
||||
fmt.Sprintf("--since=%d", since),
|
||||
fmt.Sprintf("--until=%d", daemonTime(c).Unix()),
|
||||
"--filter", "type=network")
|
||||
events = strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(len(events), checker.GreaterOrEqualThan, 1, check.Commentf("Events == %s", events))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilterImageInContainerAction(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
dockerCmd(c, "run", "--name", "test-container", "-d", "busybox", "true")
|
||||
waitRun("test-container")
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--filter", "image=busybox", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(len(events), checker.GreaterThan, 1, check.Commentf(out))
|
||||
}
|
||||
362
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_events_unix_test.go
generated
vendored
Normal file
362
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_events_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
"github.com/kr/pty"
|
||||
)
|
||||
|
||||
// #5979
|
||||
func (s *DockerSuite) TestEventsRedirectStdout(c *check.C) {
|
||||
since := daemonTime(c).Unix()
|
||||
dockerCmd(c, "run", "busybox", "true")
|
||||
|
||||
file, err := ioutil.TempFile("", "")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("could not create temp file"))
|
||||
defer os.Remove(file.Name())
|
||||
|
||||
command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, daemonTime(c).Unix(), file.Name())
|
||||
_, tty, err := pty.Open()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("Could not open pty"))
|
||||
cmd := exec.Command("sh", "-c", command)
|
||||
cmd.Stdin = tty
|
||||
cmd.Stdout = tty
|
||||
cmd.Stderr = tty
|
||||
c.Assert(cmd.Run(), checker.IsNil, check.Commentf("run err for command %q", command))
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
for _, ch := range scanner.Text() {
|
||||
c.Assert(unicode.IsControl(ch), checker.False, check.Commentf("found control character %v", []byte(string(ch))))
|
||||
}
|
||||
}
|
||||
c.Assert(scanner.Err(), checker.IsNil, check.Commentf("Scan err for command %q", command))
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, oomControl, memoryLimitSupport, NotGCCGO)
|
||||
|
||||
errChan := make(chan error)
|
||||
go func() {
|
||||
defer close(errChan)
|
||||
out, exitCode, _ := dockerCmdWithError("run", "--name", "oomFalse", "-m", "10MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done")
|
||||
if expected := 137; exitCode != expected {
|
||||
errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out)
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case err := <-errChan:
|
||||
c.Assert(err, checker.IsNil)
|
||||
case <-time.After(30 * time.Second):
|
||||
c.Fatal("Timeout waiting for container to die on OOM")
|
||||
}
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=oomFalse", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSuffix(out, "\n"), "\n")
|
||||
nEvents := len(events)
|
||||
|
||||
c.Assert(nEvents, checker.GreaterOrEqualThan, 5) //Missing expected event
|
||||
c.Assert(parseEventAction(c, events[nEvents-5]), checker.Equals, "create")
|
||||
c.Assert(parseEventAction(c, events[nEvents-4]), checker.Equals, "attach")
|
||||
c.Assert(parseEventAction(c, events[nEvents-3]), checker.Equals, "start")
|
||||
c.Assert(parseEventAction(c, events[nEvents-2]), checker.Equals, "oom")
|
||||
c.Assert(parseEventAction(c, events[nEvents-1]), checker.Equals, "die")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsOOMDisableTrue(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, oomControl, memoryLimitSupport, NotGCCGO, NotArm)
|
||||
|
||||
errChan := make(chan error)
|
||||
observer, err := newEventObserver(c)
|
||||
c.Assert(err, checker.IsNil)
|
||||
err = observer.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer observer.Stop()
|
||||
|
||||
go func() {
|
||||
defer close(errChan)
|
||||
out, exitCode, _ := dockerCmdWithError("run", "--oom-kill-disable=true", "--name", "oomTrue", "-m", "10MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done")
|
||||
if expected := 137; exitCode != expected {
|
||||
errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out)
|
||||
}
|
||||
}()
|
||||
|
||||
c.Assert(waitRun("oomTrue"), checker.IsNil)
|
||||
defer dockerCmd(c, "kill", "oomTrue")
|
||||
containerID := inspectField(c, "oomTrue", "Id")
|
||||
|
||||
testActions := map[string]chan bool{
|
||||
"oom": make(chan bool),
|
||||
}
|
||||
|
||||
matcher := matchEventLine(containerID, "container", testActions)
|
||||
processor := processEventMatch(testActions)
|
||||
go observer.Match(matcher, processor)
|
||||
|
||||
select {
|
||||
case <-time.After(20 * time.Second):
|
||||
observer.CheckEventError(c, containerID, "oom", matcher)
|
||||
case <-testActions["oom"]:
|
||||
// ignore, done
|
||||
case errRun := <-errChan:
|
||||
if errRun != nil {
|
||||
c.Fatalf("%v", errRun)
|
||||
} else {
|
||||
c.Fatalf("container should be still running but it's not")
|
||||
}
|
||||
}
|
||||
|
||||
status := inspectField(c, "oomTrue", "State.Status")
|
||||
c.Assert(strings.TrimSpace(status), checker.Equals, "running", check.Commentf("container should be still running"))
|
||||
}
|
||||
|
||||
// #18453
|
||||
func (s *DockerSuite) TestEventsContainerFilterByName(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
cOut, _ := dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top")
|
||||
c1 := strings.TrimSpace(cOut)
|
||||
waitRun("foo")
|
||||
cOut, _ = dockerCmd(c, "run", "--name=bar", "-d", "busybox", "top")
|
||||
c2 := strings.TrimSpace(cOut)
|
||||
waitRun("bar")
|
||||
out, _ := dockerCmd(c, "events", "-f", "container=foo", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
c.Assert(out, checker.Contains, c1, check.Commentf(out))
|
||||
c.Assert(out, checker.Not(checker.Contains), c2, check.Commentf(out))
|
||||
}
|
||||
|
||||
// #18453
|
||||
func (s *DockerSuite) TestEventsContainerFilterBeforeCreate(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
var (
|
||||
out string
|
||||
ch chan struct{}
|
||||
)
|
||||
ch = make(chan struct{})
|
||||
|
||||
// calculate the time it takes to create and start a container and sleep 2 seconds
|
||||
// this is to make sure the docker event will recevie the event of container
|
||||
since := daemonTime(c).Unix()
|
||||
id, _ := dockerCmd(c, "run", "-d", "busybox", "top")
|
||||
cID := strings.TrimSpace(id)
|
||||
waitRun(cID)
|
||||
time.Sleep(2 * time.Second)
|
||||
duration := daemonTime(c).Unix() - since
|
||||
|
||||
go func() {
|
||||
out, _ = dockerCmd(c, "events", "-f", "container=foo", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()+2*duration))
|
||||
close(ch)
|
||||
}()
|
||||
// Sleep 2 second to wait docker event to start
|
||||
time.Sleep(2 * time.Second)
|
||||
id, _ = dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top")
|
||||
cID = strings.TrimSpace(id)
|
||||
waitRun(cID)
|
||||
<-ch
|
||||
c.Assert(out, checker.Contains, cID, check.Commentf("Missing event of container (foo)"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestVolumeEvents(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
// Observe create/mount volume actions
|
||||
dockerCmd(c, "volume", "create", "--name", "test-event-volume-local")
|
||||
dockerCmd(c, "run", "--name", "test-volume-container", "--volume", "test-event-volume-local:/foo", "-d", "busybox", "true")
|
||||
waitRun("test-volume-container")
|
||||
|
||||
// Observe unmount/destroy volume actions
|
||||
dockerCmd(c, "rm", "-f", "test-volume-container")
|
||||
dockerCmd(c, "volume", "rm", "test-event-volume-local")
|
||||
|
||||
out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(len(events), checker.GreaterThan, 4)
|
||||
|
||||
volumeEvents := eventActionsByIDAndType(c, events, "test-event-volume-local", "volume")
|
||||
c.Assert(volumeEvents, checker.HasLen, 4)
|
||||
c.Assert(volumeEvents[0], checker.Equals, "create")
|
||||
c.Assert(volumeEvents[1], checker.Equals, "mount")
|
||||
c.Assert(volumeEvents[2], checker.Equals, "unmount")
|
||||
c.Assert(volumeEvents[3], checker.Equals, "destroy")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestNetworkEvents(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
// Observe create/connect network actions
|
||||
dockerCmd(c, "network", "create", "test-event-network-local")
|
||||
dockerCmd(c, "run", "--name", "test-network-container", "--net", "test-event-network-local", "-d", "busybox", "true")
|
||||
waitRun("test-network-container")
|
||||
|
||||
// Observe disconnect/destroy network actions
|
||||
dockerCmd(c, "rm", "-f", "test-network-container")
|
||||
dockerCmd(c, "network", "rm", "test-event-network-local")
|
||||
|
||||
out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(len(events), checker.GreaterThan, 4)
|
||||
|
||||
netEvents := eventActionsByIDAndType(c, events, "test-event-network-local", "network")
|
||||
c.Assert(netEvents, checker.HasLen, 4)
|
||||
c.Assert(netEvents[0], checker.Equals, "create")
|
||||
c.Assert(netEvents[1], checker.Equals, "connect")
|
||||
c.Assert(netEvents[2], checker.Equals, "disconnect")
|
||||
c.Assert(netEvents[3], checker.Equals, "destroy")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsStreaming(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
observer, err := newEventObserver(c)
|
||||
c.Assert(err, checker.IsNil)
|
||||
err = observer.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer observer.Stop()
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox:latest", "true")
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
testActions := map[string]chan bool{
|
||||
"create": make(chan bool),
|
||||
"start": make(chan bool),
|
||||
"die": make(chan bool),
|
||||
"destroy": make(chan bool),
|
||||
}
|
||||
|
||||
matcher := matchEventLine(containerID, "container", testActions)
|
||||
processor := processEventMatch(testActions)
|
||||
go observer.Match(matcher, processor)
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
observer.CheckEventError(c, containerID, "create", matcher)
|
||||
case <-testActions["create"]:
|
||||
// ignore, done
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
observer.CheckEventError(c, containerID, "start", matcher)
|
||||
case <-testActions["start"]:
|
||||
// ignore, done
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
observer.CheckEventError(c, containerID, "die", matcher)
|
||||
case <-testActions["die"]:
|
||||
// ignore, done
|
||||
}
|
||||
|
||||
dockerCmd(c, "rm", containerID)
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
observer.CheckEventError(c, containerID, "destroy", matcher)
|
||||
case <-testActions["destroy"]:
|
||||
// ignore, done
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsImageUntagDelete(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
observer, err := newEventObserver(c)
|
||||
c.Assert(err, checker.IsNil)
|
||||
err = observer.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer observer.Stop()
|
||||
|
||||
name := "testimageevents"
|
||||
imageID, err := buildImage(name,
|
||||
`FROM scratch
|
||||
MAINTAINER "docker"`,
|
||||
true)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(deleteImages(name), checker.IsNil)
|
||||
|
||||
testActions := map[string]chan bool{
|
||||
"untag": make(chan bool),
|
||||
"delete": make(chan bool),
|
||||
}
|
||||
|
||||
matcher := matchEventLine(imageID, "image", testActions)
|
||||
processor := processEventMatch(testActions)
|
||||
go observer.Match(matcher, processor)
|
||||
|
||||
select {
|
||||
case <-time.After(10 * time.Second):
|
||||
observer.CheckEventError(c, imageID, "untag", matcher)
|
||||
case <-testActions["untag"]:
|
||||
// ignore, done
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(10 * time.Second):
|
||||
observer.CheckEventError(c, imageID, "delete", matcher)
|
||||
case <-testActions["delete"]:
|
||||
// ignore, done
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilterVolumeAndNetworkType(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
dockerCmd(c, "network", "create", "test-event-network-type")
|
||||
dockerCmd(c, "volume", "create", "--name", "test-event-volume-type")
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--filter", "type=volume", "--filter", "type=network", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(len(events), checker.GreaterOrEqualThan, 2, check.Commentf(out))
|
||||
|
||||
networkActions := eventActionsByIDAndType(c, events, "test-event-network-type", "network")
|
||||
volumeActions := eventActionsByIDAndType(c, events, "test-event-volume-type", "volume")
|
||||
|
||||
c.Assert(volumeActions[0], checker.Equals, "create")
|
||||
c.Assert(networkActions[0], checker.Equals, "create")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilterVolumeID(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
dockerCmd(c, "volume", "create", "--name", "test-event-volume-id")
|
||||
out, _ := dockerCmd(c, "events", "--filter", "volume=test-event-volume-id", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(events, checker.HasLen, 1)
|
||||
|
||||
c.Assert(events[0], checker.Contains, "test-event-volume-id")
|
||||
c.Assert(events[0], checker.Contains, "driver=local")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestEventsFilterNetworkID(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
since := daemonTime(c).Unix()
|
||||
|
||||
dockerCmd(c, "network", "create", "test-event-network-local")
|
||||
out, _ := dockerCmd(c, "events", "--filter", "network=test-event-network-local", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(events, checker.HasLen, 1)
|
||||
|
||||
c.Assert(events[0], checker.Contains, "test-event-network-local")
|
||||
c.Assert(events[0], checker.Contains, "type=bridge")
|
||||
}
|
||||
76
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_experimental_test.go
generated
vendored
Normal file
76
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_experimental_test.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// +build experimental
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestExperimentalVersion(c *check.C) {
|
||||
out, _ := dockerCmd(c, "version")
|
||||
for _, line := range strings.Split(out, "\n") {
|
||||
if strings.HasPrefix(line, "Experimental (client):") || strings.HasPrefix(line, "Experimental (server):") {
|
||||
c.Assert(line, checker.Matches, "*true")
|
||||
}
|
||||
}
|
||||
|
||||
out, _ = dockerCmd(c, "-v")
|
||||
c.Assert(out, checker.Contains, ", experimental", check.Commentf("docker version did not contain experimental"))
|
||||
}
|
||||
|
||||
// user namespaces test: run daemon with remapped root setting
|
||||
// 1. validate uid/gid maps are set properly
|
||||
// 2. verify that files created are owned by remapped root
|
||||
func (s *DockerDaemonSuite) TestDaemonUserNamespaceRootSetting(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
||||
|
||||
c.Assert(s.d.StartWithBusybox("--userns-remap", "default"), checker.IsNil)
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "userns")
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// we need to find the uid and gid of the remapped root from the daemon's root dir info
|
||||
uidgid := strings.Split(filepath.Base(s.d.root), ".")
|
||||
c.Assert(uidgid, checker.HasLen, 2, check.Commentf("Should have gotten uid/gid strings from root dirname: %s", filepath.Base(s.d.root)))
|
||||
uid, err := strconv.Atoi(uidgid[0])
|
||||
c.Assert(err, checker.IsNil, check.Commentf("Can't parse uid"))
|
||||
gid, err := strconv.Atoi(uidgid[1])
|
||||
c.Assert(err, checker.IsNil, check.Commentf("Can't parse gid"))
|
||||
|
||||
//writeable by the remapped root UID/GID pair
|
||||
c.Assert(os.Chown(tmpDir, uid, gid), checker.IsNil)
|
||||
|
||||
out, err := s.d.Cmd("run", "-d", "--name", "userns", "-v", tmpDir+":/goofy", "busybox", "sh", "-c", "touch /goofy/testfile; top")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("Output: %s", out))
|
||||
|
||||
pid, err := s.d.Cmd("inspect", "--format='{{.State.Pid}}'", "userns")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("Could not inspect running container: out: %q", pid))
|
||||
// check the uid and gid maps for the PID to ensure root is remapped
|
||||
// (cmd = cat /proc/<pid>/uid_map | grep -E '0\s+9999\s+1')
|
||||
out, rc1, err := runCommandPipelineWithOutput(
|
||||
exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/uid_map"),
|
||||
exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", uid)))
|
||||
c.Assert(rc1, checker.Equals, 0, check.Commentf("Didn't match uid_map: output: %s", out))
|
||||
|
||||
out, rc2, err := runCommandPipelineWithOutput(
|
||||
exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/gid_map"),
|
||||
exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", gid)))
|
||||
c.Assert(rc2, checker.Equals, 0, check.Commentf("Didn't match gid_map: output: %s", out))
|
||||
|
||||
// check that the touched file is owned by remapped uid:gid
|
||||
stat, err := system.Stat(filepath.Join(tmpDir, "testfile"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(stat.UID(), checker.Equals, uint32(uid), check.Commentf("Touched file not owned by remapped root UID"))
|
||||
c.Assert(stat.GID(), checker.Equals, uint32(gid), check.Commentf("Touched file not owned by remapped root GID"))
|
||||
}
|
||||
49
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_export_import_test.go
generated
vendored
Normal file
49
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_export_import_test.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// export an image and try to import it into a new one
|
||||
func (s *DockerSuite) TestExportContainerAndImportImage(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := "testexportcontainerandimportimage"
|
||||
|
||||
dockerCmd(c, "run", "--name", containerID, "busybox", "true")
|
||||
|
||||
out, _ := dockerCmd(c, "export", containerID)
|
||||
|
||||
importCmd := exec.Command(dockerBinary, "import", "-", "repo/testexp:v1")
|
||||
importCmd.Stdin = strings.NewReader(out)
|
||||
out, _, err := runCommandWithOutput(importCmd)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to import image repo/testexp:v1: %s", out))
|
||||
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
c.Assert(cleanedImageID, checker.Not(checker.Equals), "", check.Commentf("output should have been an image id"))
|
||||
}
|
||||
|
||||
// Used to test output flag in the export command
|
||||
func (s *DockerSuite) TestExportContainerWithOutputAndImportImage(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := "testexportcontainerwithoutputandimportimage"
|
||||
|
||||
dockerCmd(c, "run", "--name", containerID, "busybox", "true")
|
||||
dockerCmd(c, "export", "--output=testexp.tar", containerID)
|
||||
defer os.Remove("testexp.tar")
|
||||
|
||||
out, _, err := runCommandWithOutput(exec.Command("cat", "testexp.tar"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
importCmd := exec.Command(dockerBinary, "import", "-", "repo/testexp:v1")
|
||||
importCmd.Stdin = strings.NewReader(out)
|
||||
out, _, err = runCommandWithOutput(importCmd)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to import image repo/testexp:v1: %s", out))
|
||||
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
c.Assert(cleanedImageID, checker.Not(checker.Equals), "", check.Commentf("output should have been an image id"))
|
||||
}
|
||||
354
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_external_graphdriver_unix_test.go
generated
vendored
Normal file
354
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_external_graphdriver_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,354 @@
|
||||
// +build experimental
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/daemon/graphdriver"
|
||||
"github.com/docker/docker/daemon/graphdriver/vfs"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func init() {
|
||||
check.Suite(&DockerExternalGraphdriverSuite{
|
||||
ds: &DockerSuite{},
|
||||
})
|
||||
}
|
||||
|
||||
type DockerExternalGraphdriverSuite struct {
|
||||
server *httptest.Server
|
||||
ds *DockerSuite
|
||||
d *Daemon
|
||||
ec *graphEventsCounter
|
||||
}
|
||||
|
||||
type graphEventsCounter struct {
|
||||
activations int
|
||||
creations int
|
||||
removals int
|
||||
gets int
|
||||
puts int
|
||||
stats int
|
||||
cleanups int
|
||||
exists int
|
||||
init int
|
||||
metadata int
|
||||
diff int
|
||||
applydiff int
|
||||
changes int
|
||||
diffsize int
|
||||
}
|
||||
|
||||
func (s *DockerExternalGraphdriverSuite) SetUpTest(c *check.C) {
|
||||
s.d = NewDaemon(c)
|
||||
s.ec = &graphEventsCounter{}
|
||||
}
|
||||
|
||||
func (s *DockerExternalGraphdriverSuite) TearDownTest(c *check.C) {
|
||||
s.d.Stop()
|
||||
s.ds.TearDownTest(c)
|
||||
}
|
||||
|
||||
func (s *DockerExternalGraphdriverSuite) SetUpSuite(c *check.C) {
|
||||
mux := http.NewServeMux()
|
||||
s.server = httptest.NewServer(mux)
|
||||
|
||||
type graphDriverRequest struct {
|
||||
ID string `json:",omitempty"`
|
||||
Parent string `json:",omitempty"`
|
||||
MountLabel string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type graphDriverResponse struct {
|
||||
Err error `json:",omitempty"`
|
||||
Dir string `json:",omitempty"`
|
||||
Exists bool `json:",omitempty"`
|
||||
Status [][2]string `json:",omitempty"`
|
||||
Metadata map[string]string `json:",omitempty"`
|
||||
Changes []archive.Change `json:",omitempty"`
|
||||
Size int64 `json:",omitempty"`
|
||||
}
|
||||
|
||||
respond := func(w http.ResponseWriter, data interface{}) {
|
||||
w.Header().Set("Content-Type", "appplication/vnd.docker.plugins.v1+json")
|
||||
switch t := data.(type) {
|
||||
case error:
|
||||
fmt.Fprintln(w, fmt.Sprintf(`{"Err": %q}`, t.Error()))
|
||||
case string:
|
||||
fmt.Fprintln(w, t)
|
||||
default:
|
||||
json.NewEncoder(w).Encode(&data)
|
||||
}
|
||||
}
|
||||
|
||||
decReq := func(b io.ReadCloser, out interface{}, w http.ResponseWriter) error {
|
||||
defer b.Close()
|
||||
if err := json.NewDecoder(b).Decode(&out); err != nil {
|
||||
http.Error(w, fmt.Sprintf("error decoding json: %s", err.Error()), 500)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
base, err := ioutil.TempDir("", "external-graph-test")
|
||||
c.Assert(err, check.IsNil)
|
||||
vfsProto, err := vfs.Init(base, []string{}, nil, nil)
|
||||
c.Assert(err, check.IsNil, check.Commentf("error initializing graph driver"))
|
||||
driver := graphdriver.NewNaiveDiffDriver(vfsProto, nil, nil)
|
||||
|
||||
mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.activations++
|
||||
respond(w, `{"Implements": ["GraphDriver"]}`)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Init", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.init++
|
||||
respond(w, "{}")
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Create", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.creations++
|
||||
|
||||
var req graphDriverRequest
|
||||
if err := decReq(r.Body, &req, w); err != nil {
|
||||
return
|
||||
}
|
||||
if err := driver.Create(req.ID, req.Parent, ""); err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
respond(w, "{}")
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Remove", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.removals++
|
||||
|
||||
var req graphDriverRequest
|
||||
if err := decReq(r.Body, &req, w); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := driver.Remove(req.ID); err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
respond(w, "{}")
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Get", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.gets++
|
||||
|
||||
var req graphDriverRequest
|
||||
if err := decReq(r.Body, &req, w); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
dir, err := driver.Get(req.ID, req.MountLabel)
|
||||
if err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
respond(w, &graphDriverResponse{Dir: dir})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Put", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.puts++
|
||||
|
||||
var req graphDriverRequest
|
||||
if err := decReq(r.Body, &req, w); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := driver.Put(req.ID); err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
respond(w, "{}")
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Exists", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.exists++
|
||||
|
||||
var req graphDriverRequest
|
||||
if err := decReq(r.Body, &req, w); err != nil {
|
||||
return
|
||||
}
|
||||
respond(w, &graphDriverResponse{Exists: driver.Exists(req.ID)})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Status", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.stats++
|
||||
respond(w, &graphDriverResponse{Status: driver.Status()})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Cleanup", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.cleanups++
|
||||
err := driver.Cleanup()
|
||||
if err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
respond(w, `{}`)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.GetMetadata", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.metadata++
|
||||
|
||||
var req graphDriverRequest
|
||||
if err := decReq(r.Body, &req, w); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data, err := driver.GetMetadata(req.ID)
|
||||
if err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
respond(w, &graphDriverResponse{Metadata: data})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Diff", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.diff++
|
||||
|
||||
var req graphDriverRequest
|
||||
if err := decReq(r.Body, &req, w); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
diff, err := driver.Diff(req.ID, req.Parent)
|
||||
if err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
io.Copy(w, diff)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.Changes", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.changes++
|
||||
var req graphDriverRequest
|
||||
if err := decReq(r.Body, &req, w); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
changes, err := driver.Changes(req.ID, req.Parent)
|
||||
if err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
respond(w, &graphDriverResponse{Changes: changes})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.ApplyDiff", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.applydiff++
|
||||
var diff archive.Reader = r.Body
|
||||
defer r.Body.Close()
|
||||
|
||||
id := r.URL.Query().Get("id")
|
||||
parent := r.URL.Query().Get("parent")
|
||||
|
||||
if id == "" {
|
||||
http.Error(w, fmt.Sprintf("missing id"), 409)
|
||||
}
|
||||
|
||||
size, err := driver.ApplyDiff(id, parent, diff)
|
||||
if err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
respond(w, &graphDriverResponse{Size: size})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/GraphDriver.DiffSize", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.diffsize++
|
||||
|
||||
var req graphDriverRequest
|
||||
if err := decReq(r.Body, &req, w); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
size, err := driver.DiffSize(req.ID, req.Parent)
|
||||
if err != nil {
|
||||
respond(w, err)
|
||||
return
|
||||
}
|
||||
respond(w, &graphDriverResponse{Size: size})
|
||||
})
|
||||
|
||||
err = os.MkdirAll("/etc/docker/plugins", 0755)
|
||||
c.Assert(err, check.IsNil, check.Commentf("error creating /etc/docker/plugins"))
|
||||
|
||||
err = ioutil.WriteFile("/etc/docker/plugins/test-external-graph-driver.spec", []byte(s.server.URL), 0644)
|
||||
c.Assert(err, check.IsNil, check.Commentf("error writing to /etc/docker/plugins/test-external-graph-driver.spec"))
|
||||
}
|
||||
|
||||
func (s *DockerExternalGraphdriverSuite) TearDownSuite(c *check.C) {
|
||||
s.server.Close()
|
||||
|
||||
err := os.RemoveAll("/etc/docker/plugins")
|
||||
c.Assert(err, check.IsNil, check.Commentf("error removing /etc/docker/plugins"))
|
||||
}
|
||||
|
||||
func (s *DockerExternalGraphdriverSuite) TestExternalGraphDriver(c *check.C) {
|
||||
if err := s.d.StartWithBusybox("-s", "test-external-graph-driver"); err != nil {
|
||||
b, _ := ioutil.ReadFile(s.d.LogFileName())
|
||||
c.Assert(err, check.IsNil, check.Commentf("\n%s", string(b)))
|
||||
}
|
||||
|
||||
out, err := s.d.Cmd("run", "-d", "--name=graphtest", "busybox", "sh", "-c", "echo hello > /hello")
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
|
||||
err = s.d.Restart("-s", "test-external-graph-driver")
|
||||
|
||||
out, err = s.d.Cmd("inspect", "--format='{{.GraphDriver.Name}}'", "graphtest")
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(strings.TrimSpace(out), check.Equals, "test-external-graph-driver")
|
||||
|
||||
out, err = s.d.Cmd("diff", "graphtest")
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(strings.Contains(out, "A /hello"), check.Equals, true)
|
||||
|
||||
out, err = s.d.Cmd("rm", "-f", "graphtest")
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
|
||||
out, err = s.d.Cmd("info")
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
|
||||
err = s.d.Stop()
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
// Don't check s.ec.exists, because the daemon no longer calls the
|
||||
// Exists function.
|
||||
c.Assert(s.ec.activations, check.Equals, 2)
|
||||
c.Assert(s.ec.init, check.Equals, 2)
|
||||
c.Assert(s.ec.creations >= 1, check.Equals, true)
|
||||
c.Assert(s.ec.removals >= 1, check.Equals, true)
|
||||
c.Assert(s.ec.gets >= 1, check.Equals, true)
|
||||
c.Assert(s.ec.puts >= 1, check.Equals, true)
|
||||
c.Assert(s.ec.stats, check.Equals, 3)
|
||||
c.Assert(s.ec.cleanups, check.Equals, 2)
|
||||
c.Assert(s.ec.applydiff >= 1, check.Equals, true)
|
||||
c.Assert(s.ec.changes, check.Equals, 1)
|
||||
c.Assert(s.ec.diffsize, check.Equals, 0)
|
||||
c.Assert(s.ec.diff, check.Equals, 0)
|
||||
c.Assert(s.ec.metadata, check.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *DockerExternalGraphdriverSuite) TestExternalGraphDriverPull(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
c.Assert(s.d.Start(), check.IsNil)
|
||||
|
||||
out, err := s.d.Cmd("pull", "busybox:latest")
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
|
||||
out, err = s.d.Cmd("run", "-d", "busybox", "top")
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
}
|
||||
97
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_import_test.go
generated
vendored
Normal file
97
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_import_test.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestImportDisplay(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "export", cleanedContainerID),
|
||||
exec.Command(dockerBinary, "import", "-"),
|
||||
)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
c.Assert(out, checker.Count, "\n", 1, check.Commentf("display is expected 1 '\\n' but didn't"))
|
||||
|
||||
image := strings.TrimSpace(out)
|
||||
out, _ = dockerCmd(c, "run", "--rm", image, "true")
|
||||
c.Assert(out, checker.Equals, "", check.Commentf("command output should've been nothing."))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestImportBadURL(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _, err := dockerCmdWithError("import", "http://nourl/bad")
|
||||
c.Assert(err, checker.NotNil, check.Commentf("import was supposed to fail but didn't"))
|
||||
c.Assert(out, checker.Contains, "dial tcp", check.Commentf("expected an error msg but didn't get one"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestImportFile(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
dockerCmd(c, "run", "--name", "test-import", "busybox", "true")
|
||||
|
||||
temporaryFile, err := ioutil.TempFile("", "exportImportTest")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to create temporary file"))
|
||||
defer os.Remove(temporaryFile.Name())
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "export", "test-import")
|
||||
runCmd.Stdout = bufio.NewWriter(temporaryFile)
|
||||
|
||||
_, err = runCommand(runCmd)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to export a container"))
|
||||
|
||||
out, _ := dockerCmd(c, "import", temporaryFile.Name())
|
||||
c.Assert(out, checker.Count, "\n", 1, check.Commentf("display is expected 1 '\\n' but didn't"))
|
||||
image := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "run", "--rm", image, "true")
|
||||
c.Assert(out, checker.Equals, "", check.Commentf("command output should've been nothing."))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestImportFileWithMessage(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
dockerCmd(c, "run", "--name", "test-import", "busybox", "true")
|
||||
|
||||
temporaryFile, err := ioutil.TempFile("", "exportImportTest")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to create temporary file"))
|
||||
defer os.Remove(temporaryFile.Name())
|
||||
|
||||
runCmd := exec.Command(dockerBinary, "export", "test-import")
|
||||
runCmd.Stdout = bufio.NewWriter(temporaryFile)
|
||||
|
||||
_, err = runCommand(runCmd)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to export a container"))
|
||||
|
||||
message := "Testing commit message"
|
||||
out, _ := dockerCmd(c, "import", "-m", message, temporaryFile.Name())
|
||||
c.Assert(out, checker.Count, "\n", 1, check.Commentf("display is expected 1 '\\n' but didn't"))
|
||||
image := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "history", image)
|
||||
split := strings.Split(out, "\n")
|
||||
|
||||
c.Assert(split, checker.HasLen, 3, check.Commentf("expected 3 lines from image history"))
|
||||
r := regexp.MustCompile("[\\s]{2,}")
|
||||
split = r.Split(split[1], -1)
|
||||
|
||||
c.Assert(message, checker.Equals, split[3], check.Commentf("didn't get expected value in commit message"))
|
||||
|
||||
out, _ = dockerCmd(c, "run", "--rm", image, "true")
|
||||
c.Assert(out, checker.Equals, "", check.Commentf("command output should've been nothing"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestImportFileNonExistentFile(c *check.C) {
|
||||
_, _, err := dockerCmdWithError("import", "example.com/myImage.tar")
|
||||
c.Assert(err, checker.NotNil, check.Commentf("import non-existing file must failed"))
|
||||
}
|
||||
93
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_nat_test.go
generated
vendored
Normal file
93
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_nat_test.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func startServerContainer(c *check.C, msg string, port int) string {
|
||||
name := "server"
|
||||
cmd := []string{
|
||||
"-d",
|
||||
"-p", fmt.Sprintf("%d:%d", port, port),
|
||||
"busybox",
|
||||
"sh", "-c", fmt.Sprintf("echo %q | nc -lp %d", msg, port),
|
||||
}
|
||||
c.Assert(waitForContainer(name, cmd...), check.IsNil)
|
||||
return name
|
||||
}
|
||||
|
||||
func getExternalAddress(c *check.C) net.IP {
|
||||
iface, err := net.InterfaceByName("eth0")
|
||||
if err != nil {
|
||||
c.Skip(fmt.Sprintf("Test not running with `make test`. Interface eth0 not found: %v", err))
|
||||
}
|
||||
|
||||
ifaceAddrs, err := iface.Addrs()
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(ifaceAddrs, checker.Not(checker.HasLen), 0)
|
||||
|
||||
ifaceIP, _, err := net.ParseCIDR(ifaceAddrs[0].String())
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
return ifaceIP
|
||||
}
|
||||
|
||||
func getContainerLogs(c *check.C, containerID string) string {
|
||||
out, _ := dockerCmd(c, "logs", containerID)
|
||||
return strings.Trim(out, "\r\n")
|
||||
}
|
||||
|
||||
func getContainerStatus(c *check.C, containerID string) string {
|
||||
out := inspectField(c, containerID, "State.Running")
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestNetworkNat(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
||||
msg := "it works"
|
||||
startServerContainer(c, msg, 8080)
|
||||
endpoint := getExternalAddress(c)
|
||||
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", endpoint.String(), 8080))
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
data, err := ioutil.ReadAll(conn)
|
||||
conn.Close()
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
final := strings.TrimRight(string(data), "\n")
|
||||
c.Assert(final, checker.Equals, msg)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestNetworkLocalhostTCPNat(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
||||
var (
|
||||
msg = "hi yall"
|
||||
)
|
||||
startServerContainer(c, msg, 8081)
|
||||
conn, err := net.Dial("tcp", "localhost:8081")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
data, err := ioutil.ReadAll(conn)
|
||||
conn.Close()
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
final := strings.TrimRight(string(data), "\n")
|
||||
c.Assert(final, checker.Equals, msg)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestNetworkLoopbackNat(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, SameHostDaemon, NotUserNamespace)
|
||||
msg := "it works"
|
||||
startServerContainer(c, msg, 8080)
|
||||
endpoint := getExternalAddress(c)
|
||||
out, _ := dockerCmd(c, "run", "-t", "--net=container:server", "busybox",
|
||||
"sh", "-c", fmt.Sprintf("stty raw && nc -w 5 %s 8080", endpoint.String()))
|
||||
final := strings.TrimRight(string(out), "\n")
|
||||
c.Assert(final, checker.Equals, msg)
|
||||
}
|
||||
91
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_netmode_test.go
generated
vendored
Normal file
91
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_netmode_test.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// GH14530. Validates combinations of --net= with other options
|
||||
|
||||
// stringCheckPS is how the output of PS starts in order to validate that
|
||||
// the command executed in a container did really run PS correctly.
|
||||
const stringCheckPS = "PID USER"
|
||||
|
||||
// DockerCmdWithFail executes a docker command that is supposed to fail and returns
|
||||
// the output, the exit code. If the command returns an Nil error, it will fail and
|
||||
// stop the tests.
|
||||
func dockerCmdWithFail(c *check.C, args ...string) (string, int) {
|
||||
out, status, err := dockerCmdWithError(args...)
|
||||
c.Assert(err, check.NotNil, check.Commentf("%v", out))
|
||||
return out, status
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestNetHostname(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, NotUserNamespace)
|
||||
|
||||
out, _ := dockerCmd(c, "run", "-h=name", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, stringCheckPS)
|
||||
|
||||
out, _ = dockerCmd(c, "run", "--net=host", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, stringCheckPS)
|
||||
|
||||
out, _ = dockerCmd(c, "run", "-h=name", "--net=bridge", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, stringCheckPS)
|
||||
|
||||
out, _ = dockerCmd(c, "run", "-h=name", "--net=none", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, stringCheckPS)
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "-h=name", "--net=host", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkHostname.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "-h=name", "--net=container:other", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkHostname.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=container", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, "--net: invalid net mode: invalid container format container:<name|id>")
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=weird", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, "network weird not found")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestConflictContainerNetworkAndLinks(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, NotUserNamespace)
|
||||
|
||||
out, _ := dockerCmdWithFail(c, "run", "--net=container:other", "--link=zip:zap", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictContainerNetworkAndLinks.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=host", "--link=zip:zap", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictHostNetworkAndLinks.Error())
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestConflictNetworkModeAndOptions(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, NotUserNamespace)
|
||||
|
||||
out, _ := dockerCmdWithFail(c, "run", "--net=host", "--dns=8.8.8.8", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkAndDNS.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=container:other", "--dns=8.8.8.8", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkAndDNS.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=host", "--add-host=name:8.8.8.8", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkHosts.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=container:other", "--add-host=name:8.8.8.8", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkHosts.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=host", "--mac-address=92:d0:c6:0a:29:33", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictContainerNetworkAndMac.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=container:other", "--mac-address=92:d0:c6:0a:29:33", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictContainerNetworkAndMac.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=container:other", "-P", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkPublishPorts.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=container:other", "-p", "8080", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkPublishPorts.Error())
|
||||
|
||||
out, _ = dockerCmdWithFail(c, "run", "--net=container:other", "--expose", "8000-9000", "busybox", "ps")
|
||||
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkExposePorts.Error())
|
||||
}
|
||||
1389
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_network_unix_test.go
generated
vendored
Normal file
1389
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_network_unix_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
30
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_oom_killed_test.go
generated
vendored
Normal file
30
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_oom_killed_test.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestInspectOomKilledTrue(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, memoryLimitSupport)
|
||||
|
||||
name := "testoomkilled"
|
||||
_, exitCode, _ := dockerCmdWithError("run", "--name", name, "--memory", "32MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done")
|
||||
|
||||
c.Assert(exitCode, checker.Equals, 137, check.Commentf("OOM exit should be 137"))
|
||||
|
||||
oomKilled := inspectField(c, name, "State.OOMKilled")
|
||||
c.Assert(oomKilled, checker.Equals, "true")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestInspectOomKilledFalse(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, memoryLimitSupport)
|
||||
|
||||
name := "testoomkilled"
|
||||
dockerCmd(c, "run", "--name", name, "--memory", "32MB", "busybox", "sh", "-c", "echo hello world")
|
||||
|
||||
oomKilled := inspectField(c, name, "State.OOMKilled")
|
||||
c.Assert(oomKilled, checker.Equals, "false")
|
||||
}
|
||||
67
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_pause_test.go
generated
vendored
Normal file
67
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_pause_test.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestPause(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
defer unpauseAllContainers()
|
||||
|
||||
name := "testeventpause"
|
||||
dockerCmd(c, "run", "-d", "--name", name, "busybox", "top")
|
||||
|
||||
dockerCmd(c, "pause", name)
|
||||
pausedContainers, err := getSliceOfPausedContainers()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(len(pausedContainers), checker.Equals, 1)
|
||||
|
||||
dockerCmd(c, "unpause", name)
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
actions := eventActionsByIDAndType(c, events, name, "container")
|
||||
|
||||
c.Assert(actions[len(actions)-2], checker.Equals, "pause")
|
||||
c.Assert(actions[len(actions)-1], checker.Equals, "unpause")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPauseMultipleContainers(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
defer unpauseAllContainers()
|
||||
|
||||
containers := []string{
|
||||
"testpausewithmorecontainers1",
|
||||
"testpausewithmorecontainers2",
|
||||
}
|
||||
for _, name := range containers {
|
||||
dockerCmd(c, "run", "-d", "--name", name, "busybox", "top")
|
||||
}
|
||||
dockerCmd(c, append([]string{"pause"}, containers...)...)
|
||||
pausedContainers, err := getSliceOfPausedContainers()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(len(pausedContainers), checker.Equals, len(containers))
|
||||
|
||||
dockerCmd(c, append([]string{"unpause"}, containers...)...)
|
||||
|
||||
out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
||||
events := strings.Split(strings.TrimSpace(out), "\n")
|
||||
|
||||
for _, name := range containers {
|
||||
actions := eventActionsByIDAndType(c, events, name, "container")
|
||||
|
||||
c.Assert(actions[len(actions)-2], checker.Equals, "pause")
|
||||
c.Assert(actions[len(actions)-1], checker.Equals, "unpause")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPauseFailsOnWindows(c *check.C) {
|
||||
testRequires(c, DaemonIsWindows)
|
||||
dockerCmd(c, "run", "-d", "--name=test", "busybox", "sleep 3")
|
||||
out, _, _ := dockerCmdWithError("pause", "test")
|
||||
c.Assert(out, checker.Contains, "Windows: Containers cannot be paused")
|
||||
}
|
||||
53
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_proxy_test.go
generated
vendored
Executable file
53
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_proxy_test.go
generated
vendored
Executable file
@@ -0,0 +1,53 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestCliProxyDisableProxyUnixSock(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, SameHostDaemon) // test is valid when DOCKER_HOST=unix://..
|
||||
|
||||
cmd := exec.Command(dockerBinary, "info")
|
||||
cmd.Env = appendBaseEnv([]string{"HTTP_PROXY=http://127.0.0.1:9999"})
|
||||
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("%v", out))
|
||||
|
||||
}
|
||||
|
||||
// Can't use localhost here since go has a special case to not use proxy if connecting to localhost
|
||||
// See https://golang.org/pkg/net/http/#ProxyFromEnvironment
|
||||
func (s *DockerDaemonSuite) TestCliProxyProxyTCPSock(c *check.C) {
|
||||
testRequires(c, SameHostDaemon)
|
||||
// get the IP to use to connect since we can't use localhost
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
c.Assert(err, checker.IsNil)
|
||||
var ip string
|
||||
for _, addr := range addrs {
|
||||
sAddr := addr.String()
|
||||
if !strings.Contains(sAddr, "127.0.0.1") {
|
||||
addrArr := strings.Split(sAddr, "/")
|
||||
ip = addrArr[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
c.Assert(ip, checker.Not(checker.Equals), "")
|
||||
|
||||
err = s.d.Start("--region", "tcp://"+ip+":2375")
|
||||
c.Assert(err, checker.IsNil)
|
||||
cmd := exec.Command(dockerBinary, "info")
|
||||
cmd.Env = []string{"DOCKER_HOST=tcp://" + ip + ":2375", "HTTP_PROXY=127.0.0.1:9999"}
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
c.Assert(err, checker.NotNil, check.Commentf("%v", out))
|
||||
// Test with no_proxy
|
||||
cmd.Env = append(cmd.Env, "NO_PROXY="+ip)
|
||||
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "info"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("%v", out))
|
||||
}
|
||||
363
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_pull_local_test.go
generated
vendored
Normal file
363
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_pull_local_test.go
generated
vendored
Normal file
@@ -0,0 +1,363 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/digest"
|
||||
"github.com/docker/distribution/manifest"
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// testPullImageWithAliases pulls a specific image tag and verifies that any aliases (i.e., other
|
||||
// tags for the same image) are not also pulled down.
|
||||
//
|
||||
// Ref: docker/docker#8141
|
||||
func testPullImageWithAliases(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
|
||||
repos := []string{}
|
||||
for _, tag := range []string{"recent", "fresh"} {
|
||||
repos = append(repos, fmt.Sprintf("%v:%v", repoName, tag))
|
||||
}
|
||||
|
||||
// Tag and push the same image multiple times.
|
||||
for _, repo := range repos {
|
||||
dockerCmd(c, "tag", "busybox", repo)
|
||||
dockerCmd(c, "push", repo)
|
||||
}
|
||||
|
||||
// Clear local images store.
|
||||
args := append([]string{"rmi"}, repos...)
|
||||
dockerCmd(c, args...)
|
||||
|
||||
// Pull a single tag and verify it doesn't bring down all aliases.
|
||||
dockerCmd(c, "pull", repos[0])
|
||||
dockerCmd(c, "inspect", repos[0])
|
||||
for _, repo := range repos[1:] {
|
||||
_, _, err := dockerCmdWithError("inspect", repo)
|
||||
c.Assert(err, checker.NotNil, check.Commentf("Image %v shouldn't have been pulled down", repo))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) {
|
||||
testPullImageWithAliases(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPullImageWithAliases(c *check.C) {
|
||||
testPullImageWithAliases(c)
|
||||
}
|
||||
|
||||
// testConcurrentPullWholeRepo pulls the same repo concurrently.
|
||||
func testConcurrentPullWholeRepo(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
|
||||
repos := []string{}
|
||||
for _, tag := range []string{"recent", "fresh", "todays"} {
|
||||
repo := fmt.Sprintf("%v:%v", repoName, tag)
|
||||
_, err := buildImage(repo, fmt.Sprintf(`
|
||||
FROM busybox
|
||||
ENTRYPOINT ["/bin/echo"]
|
||||
ENV FOO foo
|
||||
ENV BAR bar
|
||||
CMD echo %s
|
||||
`, repo), true)
|
||||
c.Assert(err, checker.IsNil)
|
||||
dockerCmd(c, "push", repo)
|
||||
repos = append(repos, repo)
|
||||
}
|
||||
|
||||
// Clear local images store.
|
||||
args := append([]string{"rmi"}, repos...)
|
||||
dockerCmd(c, args...)
|
||||
|
||||
// Run multiple re-pulls concurrently
|
||||
results := make(chan error)
|
||||
numPulls := 3
|
||||
|
||||
for i := 0; i != numPulls; i++ {
|
||||
go func() {
|
||||
_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", "-a", repoName))
|
||||
results <- err
|
||||
}()
|
||||
}
|
||||
|
||||
// These checks are separate from the loop above because the check
|
||||
// package is not goroutine-safe.
|
||||
for i := 0; i != numPulls; i++ {
|
||||
err := <-results
|
||||
c.Assert(err, checker.IsNil, check.Commentf("concurrent pull failed with error: %v", err))
|
||||
}
|
||||
|
||||
// Ensure all tags were pulled successfully
|
||||
for _, repo := range repos {
|
||||
dockerCmd(c, "inspect", repo)
|
||||
out, _ := dockerCmd(c, "run", "--rm", repo)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "/bin/sh -c echo "+repo)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) testConcurrentPullWholeRepo(c *check.C) {
|
||||
testConcurrentPullWholeRepo(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) testConcurrentPullWholeRepo(c *check.C) {
|
||||
testConcurrentPullWholeRepo(c)
|
||||
}
|
||||
|
||||
// testConcurrentFailingPull tries a concurrent pull that doesn't succeed.
|
||||
func testConcurrentFailingPull(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
|
||||
// Run multiple pulls concurrently
|
||||
results := make(chan error)
|
||||
numPulls := 3
|
||||
|
||||
for i := 0; i != numPulls; i++ {
|
||||
go func() {
|
||||
_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repoName+":asdfasdf"))
|
||||
results <- err
|
||||
}()
|
||||
}
|
||||
|
||||
// These checks are separate from the loop above because the check
|
||||
// package is not goroutine-safe.
|
||||
for i := 0; i != numPulls; i++ {
|
||||
err := <-results
|
||||
c.Assert(err, checker.NotNil, check.Commentf("expected pull to fail"))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) testConcurrentFailingPull(c *check.C) {
|
||||
testConcurrentFailingPull(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) testConcurrentFailingPull(c *check.C) {
|
||||
testConcurrentFailingPull(c)
|
||||
}
|
||||
|
||||
// testConcurrentPullMultipleTags pulls multiple tags from the same repo
|
||||
// concurrently.
|
||||
func testConcurrentPullMultipleTags(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
|
||||
repos := []string{}
|
||||
for _, tag := range []string{"recent", "fresh", "todays"} {
|
||||
repo := fmt.Sprintf("%v:%v", repoName, tag)
|
||||
_, err := buildImage(repo, fmt.Sprintf(`
|
||||
FROM busybox
|
||||
ENTRYPOINT ["/bin/echo"]
|
||||
ENV FOO foo
|
||||
ENV BAR bar
|
||||
CMD echo %s
|
||||
`, repo), true)
|
||||
c.Assert(err, checker.IsNil)
|
||||
dockerCmd(c, "push", repo)
|
||||
repos = append(repos, repo)
|
||||
}
|
||||
|
||||
// Clear local images store.
|
||||
args := append([]string{"rmi"}, repos...)
|
||||
dockerCmd(c, args...)
|
||||
|
||||
// Re-pull individual tags, in parallel
|
||||
results := make(chan error)
|
||||
|
||||
for _, repo := range repos {
|
||||
go func(repo string) {
|
||||
_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repo))
|
||||
results <- err
|
||||
}(repo)
|
||||
}
|
||||
|
||||
// These checks are separate from the loop above because the check
|
||||
// package is not goroutine-safe.
|
||||
for range repos {
|
||||
err := <-results
|
||||
c.Assert(err, checker.IsNil, check.Commentf("concurrent pull failed with error: %v", err))
|
||||
}
|
||||
|
||||
// Ensure all tags were pulled successfully
|
||||
for _, repo := range repos {
|
||||
dockerCmd(c, "inspect", repo)
|
||||
out, _ := dockerCmd(c, "run", "--rm", repo)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "/bin/sh -c echo "+repo)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
|
||||
testConcurrentPullMultipleTags(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
|
||||
testConcurrentPullMultipleTags(c)
|
||||
}
|
||||
|
||||
// testPullIDStability verifies that pushing an image and pulling it back
|
||||
// preserves the image ID.
|
||||
func testPullIDStability(c *check.C) {
|
||||
derivedImage := privateRegistryURL + "/dockercli/id-stability"
|
||||
baseImage := "busybox"
|
||||
|
||||
_, err := buildImage(derivedImage, fmt.Sprintf(`
|
||||
FROM %s
|
||||
ENV derived true
|
||||
ENV asdf true
|
||||
RUN dd if=/dev/zero of=/file bs=1024 count=1024
|
||||
CMD echo %s
|
||||
`, baseImage, derivedImage), true)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
originalID, err := getIDByName(derivedImage)
|
||||
if err != nil {
|
||||
c.Fatalf("error inspecting: %v", err)
|
||||
}
|
||||
dockerCmd(c, "push", derivedImage)
|
||||
|
||||
// Pull
|
||||
out, _ := dockerCmd(c, "pull", derivedImage)
|
||||
if strings.Contains(out, "Pull complete") {
|
||||
c.Fatalf("repull redownloaded a layer: %s", out)
|
||||
}
|
||||
|
||||
derivedIDAfterPull, err := getIDByName(derivedImage)
|
||||
if err != nil {
|
||||
c.Fatalf("error inspecting: %v", err)
|
||||
}
|
||||
|
||||
if derivedIDAfterPull != originalID {
|
||||
c.Fatal("image's ID unexpectedly changed after a repush/repull")
|
||||
}
|
||||
|
||||
// Make sure the image runs correctly
|
||||
out, _ = dockerCmd(c, "run", "--rm", derivedImage)
|
||||
if strings.TrimSpace(out) != derivedImage {
|
||||
c.Fatalf("expected %s; got %s", derivedImage, out)
|
||||
}
|
||||
|
||||
// Confirm that repushing and repulling does not change the computed ID
|
||||
dockerCmd(c, "push", derivedImage)
|
||||
dockerCmd(c, "rmi", derivedImage)
|
||||
dockerCmd(c, "pull", derivedImage)
|
||||
|
||||
derivedIDAfterPull, err = getIDByName(derivedImage)
|
||||
if err != nil {
|
||||
c.Fatalf("error inspecting: %v", err)
|
||||
}
|
||||
|
||||
if derivedIDAfterPull != originalID {
|
||||
c.Fatal("image's ID unexpectedly changed after a repush/repull")
|
||||
}
|
||||
if err != nil {
|
||||
c.Fatalf("error inspecting: %v", err)
|
||||
}
|
||||
|
||||
// Make sure the image still runs
|
||||
out, _ = dockerCmd(c, "run", "--rm", derivedImage)
|
||||
if strings.TrimSpace(out) != derivedImage {
|
||||
c.Fatalf("expected %s; got %s", derivedImage, out)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPullIDStability(c *check.C) {
|
||||
testPullIDStability(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPullIDStability(c *check.C) {
|
||||
testPullIDStability(c)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPullManifestList(c *check.C) {
|
||||
testRequires(c, NotArm)
|
||||
pushDigest, err := setupImage(c)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||
|
||||
// Inject a manifest list into the registry
|
||||
manifestList := &manifestlist.ManifestList{
|
||||
Versioned: manifest.Versioned{
|
||||
SchemaVersion: 2,
|
||||
MediaType: manifestlist.MediaTypeManifestList,
|
||||
},
|
||||
Manifests: []manifestlist.ManifestDescriptor{
|
||||
{
|
||||
Descriptor: distribution.Descriptor{
|
||||
Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b",
|
||||
Size: 3253,
|
||||
MediaType: schema2.MediaTypeManifest,
|
||||
},
|
||||
Platform: manifestlist.PlatformSpec{
|
||||
Architecture: "bogus_arch",
|
||||
OS: "bogus_os",
|
||||
},
|
||||
},
|
||||
{
|
||||
Descriptor: distribution.Descriptor{
|
||||
Digest: pushDigest,
|
||||
Size: 3253,
|
||||
MediaType: schema2.MediaTypeManifest,
|
||||
},
|
||||
Platform: manifestlist.PlatformSpec{
|
||||
Architecture: runtime.GOARCH,
|
||||
OS: runtime.GOOS,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
manifestListJSON, err := json.MarshalIndent(manifestList, "", " ")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error marshalling manifest list"))
|
||||
|
||||
manifestListDigest := digest.FromBytes(manifestListJSON)
|
||||
hexDigest := manifestListDigest.Hex()
|
||||
|
||||
registryV2Path := filepath.Join(s.reg.dir, "docker", "registry", "v2")
|
||||
|
||||
// Write manifest list to blob store
|
||||
blobDir := filepath.Join(registryV2Path, "blobs", "sha256", hexDigest[:2], hexDigest)
|
||||
err = os.MkdirAll(blobDir, 0755)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error creating blob dir"))
|
||||
blobPath := filepath.Join(blobDir, "data")
|
||||
err = ioutil.WriteFile(blobPath, []byte(manifestListJSON), 0644)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error writing manifest list"))
|
||||
|
||||
// Add to revision store
|
||||
revisionDir := filepath.Join(registryV2Path, "repositories", remoteRepoName, "_manifests", "revisions", "sha256", hexDigest)
|
||||
err = os.Mkdir(revisionDir, 0755)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error creating revision dir"))
|
||||
revisionPath := filepath.Join(revisionDir, "link")
|
||||
err = ioutil.WriteFile(revisionPath, []byte(manifestListDigest.String()), 0644)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error writing revision link"))
|
||||
|
||||
// Update tag
|
||||
tagPath := filepath.Join(registryV2Path, "repositories", remoteRepoName, "_manifests", "tags", "latest", "current", "link")
|
||||
err = ioutil.WriteFile(tagPath, []byte(manifestListDigest.String()), 0644)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error writing tag link"))
|
||||
|
||||
// Verify that the image can be pulled through the manifest list.
|
||||
out, _ := dockerCmd(c, "pull", repoName)
|
||||
|
||||
// The pull output includes "Digest: <digest>", so find that
|
||||
matches := digestRegex.FindStringSubmatch(out)
|
||||
c.Assert(matches, checker.HasLen, 2, check.Commentf("unable to parse digest from pull output: %s", out))
|
||||
pullDigest := matches[1]
|
||||
|
||||
// Make sure the pushed and pull digests match
|
||||
c.Assert(manifestListDigest.String(), checker.Equals, pullDigest)
|
||||
|
||||
// Was the image actually created?
|
||||
dockerCmd(c, "inspect", repoName)
|
||||
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
}
|
||||
253
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_pull_trusted_test.go
generated
vendored
Normal file
253
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_pull_trusted_test.go
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPull(c *check.C) {
|
||||
repoName := s.setupTrustedImage(c, "trusted-pull")
|
||||
|
||||
// Try pull
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err := runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(out))
|
||||
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
// Try untrusted pull to ensure we pushed the tag to the registry
|
||||
pullCmd = exec.Command(dockerBinary, "pull", "--disable-content-trust=true", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedIsolatedPull(c *check.C) {
|
||||
repoName := s.setupTrustedImage(c, "trusted-isolated-pull")
|
||||
|
||||
// Try pull (run from isolated directory without trust information)
|
||||
pullCmd := exec.Command(dockerBinary, "--config", "/tmp/docker-isolated", "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err := runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(string(out)))
|
||||
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestUntrustedPull(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercliuntrusted/pulltest:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
dockerCmd(c, "push", repoName)
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
|
||||
// Try trusted pull on untrusted tag
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err := runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Error: remote trust data does not exist", check.Commentf(out))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestPullWhenCertExpired(c *check.C) {
|
||||
c.Skip("Currently changes system time, causing instability")
|
||||
repoName := s.setupTrustedImage(c, "trusted-cert-expired")
|
||||
|
||||
// Certificates have 10 years of expiration
|
||||
elevenYearsFromNow := time.Now().Add(time.Hour * 24 * 365 * 11)
|
||||
|
||||
runAtDifferentDate(elevenYearsFromNow, func() {
|
||||
// Try pull
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err := runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "could not validate the path to a trusted root", check.Commentf(out))
|
||||
})
|
||||
|
||||
runAtDifferentDate(elevenYearsFromNow, func() {
|
||||
// Try pull
|
||||
pullCmd := exec.Command(dockerBinary, "pull", "--disable-content-trust", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err := runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPullFromBadTrustServer(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockerclievilpull/trusted:latest", privateRegistryURL)
|
||||
evilLocalConfigDir, err := ioutil.TempDir("", "evil-local-config-dir")
|
||||
if err != nil {
|
||||
c.Fatalf("Failed to create local temp dir")
|
||||
}
|
||||
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Signing and pushing trust metadata", check.Commentf(out))
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
|
||||
// Try pull
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(out))
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
|
||||
// Kill the notary server, start a new "evil" one.
|
||||
s.not.Close()
|
||||
s.not, err = newTestNotary(c)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf("Restarting notary server failed."))
|
||||
|
||||
// In order to make an evil server, lets re-init a client (with a different trust dir) and push new data.
|
||||
// tag an image and upload it to the private registry
|
||||
dockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName)
|
||||
|
||||
// Push up to the new server
|
||||
pushCmd = exec.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err = runCommandWithOutput(pushCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Signing and pushing trust metadata", check.Commentf(out))
|
||||
|
||||
// Now, try pulling with the original client from this new trust server. This should fail.
|
||||
pullCmd = exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "valid signatures did not meet threshold", check.Commentf(out))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPullWithExpiredSnapshot(c *check.C) {
|
||||
c.Skip("Currently changes system time, causing instability")
|
||||
repoName := fmt.Sprintf("%v/dockercliexpiredtimestamppull/trusted:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
// Push with default passphrases
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Signing and pushing trust metadata", check.Commentf(out))
|
||||
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
|
||||
// Snapshots last for three years. This should be expired
|
||||
fourYearsLater := time.Now().Add(time.Hour * 24 * 365 * 4)
|
||||
|
||||
runAtDifferentDate(fourYearsLater, func() {
|
||||
// Try pull
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.NotNil, check.Commentf("Missing expected error running trusted pull with expired snapshots"))
|
||||
c.Assert(string(out), checker.Contains, "repository out-of-date", check.Commentf(out))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedOfflinePull(c *check.C) {
|
||||
repoName := s.setupTrustedImage(c, "trusted-offline-pull")
|
||||
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmdWithServer(pullCmd, "https://invalidnotaryserver")
|
||||
out, _, err := runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "error contacting notary server", check.Commentf(out))
|
||||
// Do valid trusted pull to warm cache
|
||||
pullCmd = exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(out))
|
||||
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
|
||||
// Try pull again with invalid notary server, should use cache
|
||||
pullCmd = exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmdWithServer(pullCmd, "https://invalidnotaryserver")
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Tagging", check.Commentf(out))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPullDelete(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/%s:latest", privateRegistryURL, "trusted-pull-delete")
|
||||
// tag the image and upload it to the private registry
|
||||
_, err := buildImage(repoName, `
|
||||
FROM busybox
|
||||
CMD echo trustedpulldelete
|
||||
`, true)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
if err != nil {
|
||||
c.Fatalf("Error running trusted push: %s\n%s", err, out)
|
||||
}
|
||||
if !strings.Contains(string(out), "Signing and pushing trust metadata") {
|
||||
c.Fatalf("Missing expected output on trusted push:\n%s", out)
|
||||
}
|
||||
|
||||
if out, status := dockerCmd(c, "rmi", repoName); status != 0 {
|
||||
c.Fatalf("Error removing image %q\n%s", repoName, out)
|
||||
}
|
||||
|
||||
// Try pull
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
|
||||
matches := digestRegex.FindStringSubmatch(out)
|
||||
c.Assert(matches, checker.HasLen, 2, check.Commentf("unable to parse digest from pull output: %s", out))
|
||||
pullDigest := matches[1]
|
||||
|
||||
imageID := inspectField(c, repoName, "Id")
|
||||
|
||||
imageByDigest := repoName + "@" + pullDigest
|
||||
byDigestID := inspectField(c, imageByDigest, "Id")
|
||||
|
||||
c.Assert(byDigestID, checker.Equals, imageID)
|
||||
|
||||
// rmi of tag should also remove the digest reference
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
|
||||
_, err = inspectFieldWithError(imageByDigest, "Id")
|
||||
c.Assert(err, checker.NotNil, check.Commentf("digest reference should have been removed"))
|
||||
|
||||
_, err = inspectFieldWithError(imageID, "Id")
|
||||
c.Assert(err, checker.NotNil, check.Commentf("image should have been deleted"))
|
||||
}
|
||||
467
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_push_test.go
generated
vendored
Normal file
467
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_push_test.go
generated
vendored
Normal file
@@ -0,0 +1,467 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/digest"
|
||||
"github.com/docker/docker/cliconfig"
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// Pushing an image to a private registry.
|
||||
func testPushBusyboxImage(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
// tag the image to upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
// push the image to the registry
|
||||
dockerCmd(c, "push", repoName)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) {
|
||||
testPushBusyboxImage(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPushBusyboxImage(c *check.C) {
|
||||
testPushBusyboxImage(c)
|
||||
}
|
||||
|
||||
// pushing an image without a prefix should throw an error
|
||||
func (s *DockerSuite) TestPushUnprefixedRepo(c *check.C) {
|
||||
out, _, err := dockerCmdWithError("push", "busybox")
|
||||
c.Assert(err, check.NotNil, check.Commentf("pushing an unprefixed repo didn't result in a non-zero exit status: %s", out))
|
||||
}
|
||||
|
||||
func testPushUntagged(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
expected := "Repository does not exist"
|
||||
|
||||
out, _, err := dockerCmdWithError("push", repoName)
|
||||
c.Assert(err, check.NotNil, check.Commentf("pushing the image to the private registry should have failed: output %q", out))
|
||||
c.Assert(out, checker.Contains, expected, check.Commentf("pushing the image failed"))
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) {
|
||||
testPushUntagged(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPushUntagged(c *check.C) {
|
||||
testPushUntagged(c)
|
||||
}
|
||||
|
||||
func testPushBadTag(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox:latest", privateRegistryURL)
|
||||
expected := "does not exist"
|
||||
|
||||
out, _, err := dockerCmdWithError("push", repoName)
|
||||
c.Assert(err, check.NotNil, check.Commentf("pushing the image to the private registry should have failed: output %q", out))
|
||||
c.Assert(out, checker.Contains, expected, check.Commentf("pushing the image failed"))
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) {
|
||||
testPushBadTag(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPushBadTag(c *check.C) {
|
||||
testPushBadTag(c)
|
||||
}
|
||||
|
||||
func testPushMultipleTags(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
repoTag1 := fmt.Sprintf("%v/dockercli/busybox:t1", privateRegistryURL)
|
||||
repoTag2 := fmt.Sprintf("%v/dockercli/busybox:t2", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoTag1)
|
||||
|
||||
dockerCmd(c, "tag", "busybox", repoTag2)
|
||||
|
||||
dockerCmd(c, "push", repoName)
|
||||
|
||||
// Ensure layer list is equivalent for repoTag1 and repoTag2
|
||||
out1, _ := dockerCmd(c, "pull", repoTag1)
|
||||
|
||||
imageAlreadyExists := ": Image already exists"
|
||||
var out1Lines []string
|
||||
for _, outputLine := range strings.Split(out1, "\n") {
|
||||
if strings.Contains(outputLine, imageAlreadyExists) {
|
||||
out1Lines = append(out1Lines, outputLine)
|
||||
}
|
||||
}
|
||||
|
||||
out2, _ := dockerCmd(c, "pull", repoTag2)
|
||||
|
||||
var out2Lines []string
|
||||
for _, outputLine := range strings.Split(out2, "\n") {
|
||||
if strings.Contains(outputLine, imageAlreadyExists) {
|
||||
out1Lines = append(out1Lines, outputLine)
|
||||
}
|
||||
}
|
||||
c.Assert(out2Lines, checker.HasLen, len(out1Lines))
|
||||
|
||||
for i := range out1Lines {
|
||||
c.Assert(out1Lines[i], checker.Equals, out2Lines[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) {
|
||||
testPushMultipleTags(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPushMultipleTags(c *check.C) {
|
||||
testPushMultipleTags(c)
|
||||
}
|
||||
|
||||
func testPushEmptyLayer(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL)
|
||||
emptyTarball, err := ioutil.TempFile("", "empty_tarball")
|
||||
c.Assert(err, check.IsNil, check.Commentf("Unable to create test file"))
|
||||
|
||||
tw := tar.NewWriter(emptyTarball)
|
||||
err = tw.Close()
|
||||
c.Assert(err, check.IsNil, check.Commentf("Error creating empty tarball"))
|
||||
|
||||
freader, err := os.Open(emptyTarball.Name())
|
||||
c.Assert(err, check.IsNil, check.Commentf("Could not open test tarball"))
|
||||
|
||||
importCmd := exec.Command(dockerBinary, "import", "-", repoName)
|
||||
importCmd.Stdin = freader
|
||||
out, _, err := runCommandWithOutput(importCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("import failed: %q", out))
|
||||
|
||||
// Now verify we can push it
|
||||
out, _, err = dockerCmdWithError("push", repoName)
|
||||
c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out))
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) {
|
||||
testPushEmptyLayer(c)
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestPushEmptyLayer(c *check.C) {
|
||||
testPushEmptyLayer(c)
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestCrossRepositoryLayerPush(c *check.C) {
|
||||
sourceRepoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
// tag the image to upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", sourceRepoName)
|
||||
// push the image to the registry
|
||||
out1, _, err := dockerCmdWithError("push", sourceRepoName)
|
||||
c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out1))
|
||||
// ensure that none of the layers were mounted from another repository during push
|
||||
c.Assert(strings.Contains(out1, "Mounted from"), check.Equals, false)
|
||||
|
||||
digest1 := digest.DigestRegexp.FindString(out1)
|
||||
c.Assert(len(digest1), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
|
||||
|
||||
destRepoName := fmt.Sprintf("%v/dockercli/crossrepopush", privateRegistryURL)
|
||||
// retag the image to upload the same layers to another repo in the same registry
|
||||
dockerCmd(c, "tag", "busybox", destRepoName)
|
||||
// push the image to the registry
|
||||
out2, _, err := dockerCmdWithError("push", destRepoName)
|
||||
c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out2))
|
||||
// ensure that layers were mounted from the first repo during push
|
||||
c.Assert(strings.Contains(out2, "Mounted from dockercli/busybox"), check.Equals, true)
|
||||
|
||||
digest2 := digest.DigestRegexp.FindString(out2)
|
||||
c.Assert(len(digest2), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
|
||||
c.Assert(digest1, check.Equals, digest2)
|
||||
|
||||
// ensure that we can pull and run the cross-repo-pushed repository
|
||||
dockerCmd(c, "rmi", destRepoName)
|
||||
dockerCmd(c, "pull", destRepoName)
|
||||
out3, _ := dockerCmd(c, "run", destRepoName, "echo", "-n", "hello world")
|
||||
c.Assert(out3, check.Equals, "hello world")
|
||||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) TestCrossRepositoryLayerPushNotSupported(c *check.C) {
|
||||
sourceRepoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
// tag the image to upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", sourceRepoName)
|
||||
// push the image to the registry
|
||||
out1, _, err := dockerCmdWithError("push", sourceRepoName)
|
||||
c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out1))
|
||||
// ensure that none of the layers were mounted from another repository during push
|
||||
c.Assert(strings.Contains(out1, "Mounted from"), check.Equals, false)
|
||||
|
||||
digest1 := digest.DigestRegexp.FindString(out1)
|
||||
c.Assert(len(digest1), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
|
||||
|
||||
destRepoName := fmt.Sprintf("%v/dockercli/crossrepopush", privateRegistryURL)
|
||||
// retag the image to upload the same layers to another repo in the same registry
|
||||
dockerCmd(c, "tag", "busybox", destRepoName)
|
||||
// push the image to the registry
|
||||
out2, _, err := dockerCmdWithError("push", destRepoName)
|
||||
c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out2))
|
||||
// schema1 registry should not support cross-repo layer mounts, so ensure that this does not happen
|
||||
c.Assert(strings.Contains(out2, "Mounted from dockercli/busybox"), check.Equals, false)
|
||||
|
||||
digest2 := digest.DigestRegexp.FindString(out2)
|
||||
c.Assert(len(digest2), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
|
||||
c.Assert(digest1, check.Equals, digest2)
|
||||
|
||||
// ensure that we can pull and run the second pushed repository
|
||||
dockerCmd(c, "rmi", destRepoName)
|
||||
dockerCmd(c, "pull", destRepoName)
|
||||
out3, _ := dockerCmd(c, "run", destRepoName, "echo", "-n", "hello world")
|
||||
c.Assert(out3, check.Equals, "hello world")
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPush(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockerclitrusted/pushtest:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push"))
|
||||
|
||||
// Try pull after push
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithEnvPasswords(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockerclienv/trusted:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, "12345678", "12345678")
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push"))
|
||||
|
||||
// Try pull after push
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
|
||||
}
|
||||
|
||||
// This test ensures backwards compatibility with old ENV variables. Should be
|
||||
// deprecated by 1.10
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithDeprecatedEnvPasswords(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercli/trusteddeprecated:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "12345678")
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push"))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithFailingServer(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockerclitrusted/failingserver:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmdWithServer(pushCmd, "https://example.com:81/")
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.NotNil, check.Commentf("Missing error while running trusted push w/ no server"))
|
||||
c.Assert(out, checker.Contains, "error contacting notary server", check.Commentf("Missing expected output on trusted push"))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithoutServerAndUntrusted(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockerclitrusted/trustedandnot:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", "--disable-content-trust", repoName)
|
||||
s.trustedCmdWithServer(pushCmd, "https://example.com/")
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push with no server and --disable-content-trust failed: %s\n%s", err, out))
|
||||
c.Assert(out, check.Not(checker.Contains), "Error establishing connection to notary repository", check.Commentf("Missing expected output on trusted push with --disable-content-trust:"))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithExistingTag(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockerclitag/trusted:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
dockerCmd(c, "push", repoName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag"))
|
||||
|
||||
// Try pull after push
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithExistingSignedTag(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockerclipushpush/trusted:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
// Do a trusted push
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag"))
|
||||
|
||||
// Do another trusted push
|
||||
pushCmd = exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err = runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag"))
|
||||
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
|
||||
// Try pull to ensure the double push did not break our ability to pull
|
||||
pullCmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Error running trusted pull: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Status: Downloaded", check.Commentf("Missing expected output on trusted pull with --disable-content-trust"))
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithIncorrectPassphraseForNonRoot(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercliincorretpwd/trusted:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
// Push with default passphrases
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push:\n%s", out))
|
||||
|
||||
// Push with wrong passphrases
|
||||
pushCmd = exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, "12345678", "87654321")
|
||||
out, _, err = runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with short targets passphrase: \n%s", out))
|
||||
c.Assert(out, checker.Contains, "could not find necessary signing keys", check.Commentf("Missing expected output on trusted push with short targets/snapsnot passphrase"))
|
||||
}
|
||||
|
||||
// This test ensures backwards compatibility with old ENV variables. Should be
|
||||
// deprecated by 1.10
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithIncorrectDeprecatedPassphraseForNonRoot(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockercliincorretdeprecatedpwd/trusted:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
// Push with default passphrases
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push"))
|
||||
|
||||
// Push with wrong passphrases
|
||||
pushCmd = exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "87654321")
|
||||
out, _, err = runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with short targets passphrase: \n%s", out))
|
||||
c.Assert(out, checker.Contains, "could not find necessary signing keys", check.Commentf("Missing expected output on trusted push with short targets/snapsnot passphrase"))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithExpiredSnapshot(c *check.C) {
|
||||
c.Skip("Currently changes system time, causing instability")
|
||||
repoName := fmt.Sprintf("%v/dockercliexpiredsnapshot/trusted:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
// Push with default passphrases
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push"))
|
||||
|
||||
// Snapshots last for three years. This should be expired
|
||||
fourYearsLater := time.Now().Add(time.Hour * 24 * 365 * 4)
|
||||
|
||||
runAtDifferentDate(fourYearsLater, func() {
|
||||
// Push with wrong passphrases
|
||||
pushCmd = exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err = runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with expired snapshot: \n%s", out))
|
||||
c.Assert(out, checker.Contains, "repository out-of-date", check.Commentf("Missing expected output on trusted push with expired snapshot"))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithExpiredTimestamp(c *check.C) {
|
||||
c.Skip("Currently changes system time, causing instability")
|
||||
repoName := fmt.Sprintf("%v/dockercliexpiredtimestamppush/trusted:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
// Push with default passphrases
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push"))
|
||||
|
||||
// The timestamps expire in two weeks. Lets check three
|
||||
threeWeeksLater := time.Now().Add(time.Hour * 24 * 21)
|
||||
|
||||
// Should succeed because the server transparently re-signs one
|
||||
runAtDifferentDate(threeWeeksLater, func() {
|
||||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with expired timestamp"))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithReleasesDelegation(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockerclireleasedelegation/trusted", privateRegistryURL)
|
||||
targetName := fmt.Sprintf("%s:latest", repoName)
|
||||
pwd := "12345678"
|
||||
s.setupDelegations(c, repoName, pwd)
|
||||
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", targetName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "-D", "push", targetName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, pwd, pwd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag"))
|
||||
|
||||
// Try pull after push
|
||||
pullCmd := exec.Command(dockerBinary, "pull", targetName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
|
||||
|
||||
// check to make sure that the target has been added to targets/releases and not targets
|
||||
contents, err := ioutil.ReadFile(filepath.Join(cliconfig.ConfigDir(), "trust/tuf", repoName, "metadata/targets.json"))
|
||||
c.Assert(err, check.IsNil, check.Commentf("Unable to read targets metadata"))
|
||||
c.Assert(strings.Contains(string(contents), `"latest"`), checker.False, check.Commentf(string(contents)))
|
||||
|
||||
contents, err = ioutil.ReadFile(filepath.Join(cliconfig.ConfigDir(), "trust/tuf", repoName, "metadata/targets/releases.json"))
|
||||
c.Assert(err, check.IsNil, check.Commentf("Unable to read targets/releases metadata"))
|
||||
c.Assert(string(contents), checker.Contains, `"latest"`, check.Commentf(string(contents)))
|
||||
}
|
||||
303
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_save_load_test.go
generated
vendored
Normal file
303
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_save_load_test.go
generated
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/digest"
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// save a repo using gz compression and try to load it using stdout
|
||||
func (s *DockerSuite) TestSaveXzAndLoadRepoStdout(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
name := "test-save-xz-and-load-repo-stdout"
|
||||
dockerCmd(c, "run", "--name", name, "busybox", "true")
|
||||
|
||||
repoName := "foobar-save-load-test-xz-gz"
|
||||
out, _ := dockerCmd(c, "commit", name, repoName)
|
||||
|
||||
dockerCmd(c, "inspect", repoName)
|
||||
|
||||
repoTarball, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName),
|
||||
exec.Command("xz", "-c"),
|
||||
exec.Command("gzip", "-c"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save repo: %v %v", out, err))
|
||||
deleteImages(repoName)
|
||||
|
||||
loadCmd := exec.Command(dockerBinary, "load")
|
||||
loadCmd.Stdin = strings.NewReader(repoTarball)
|
||||
out, _, err = runCommandWithOutput(loadCmd)
|
||||
c.Assert(err, checker.NotNil, check.Commentf("expected error, but succeeded with no error and output: %v", out))
|
||||
|
||||
after, _, err := dockerCmdWithError("inspect", repoName)
|
||||
c.Assert(err, checker.NotNil, check.Commentf("the repo should not exist: %v", after))
|
||||
}
|
||||
|
||||
// save a repo using xz+gz compression and try to load it using stdout
|
||||
func (s *DockerSuite) TestSaveXzGzAndLoadRepoStdout(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
name := "test-save-xz-gz-and-load-repo-stdout"
|
||||
dockerCmd(c, "run", "--name", name, "busybox", "true")
|
||||
|
||||
repoName := "foobar-save-load-test-xz-gz"
|
||||
dockerCmd(c, "commit", name, repoName)
|
||||
|
||||
dockerCmd(c, "inspect", repoName)
|
||||
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName),
|
||||
exec.Command("xz", "-c"),
|
||||
exec.Command("gzip", "-c"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save repo: %v %v", out, err))
|
||||
|
||||
deleteImages(repoName)
|
||||
|
||||
loadCmd := exec.Command(dockerBinary, "load")
|
||||
loadCmd.Stdin = strings.NewReader(out)
|
||||
out, _, err = runCommandWithOutput(loadCmd)
|
||||
c.Assert(err, checker.NotNil, check.Commentf("expected error, but succeeded with no error and output: %v", out))
|
||||
|
||||
after, _, err := dockerCmdWithError("inspect", repoName)
|
||||
c.Assert(err, checker.NotNil, check.Commentf("the repo should not exist: %v", after))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestSaveSingleTag(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
repoName := "foobar-save-single-tag-test"
|
||||
dockerCmd(c, "tag", "busybox:latest", fmt.Sprintf("%v:latest", repoName))
|
||||
|
||||
out, _ := dockerCmd(c, "images", "-q", "--no-trunc", repoName)
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", fmt.Sprintf("%v:latest", repoName)),
|
||||
exec.Command("tar", "t"),
|
||||
exec.Command("grep", "-E", fmt.Sprintf("(^repositories$|%v)", cleanedImageID)))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save repo with image ID and 'repositories' file: %s, %v", out, err))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestSaveCheckTimes(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
repoName := "busybox:latest"
|
||||
out, _ := dockerCmd(c, "inspect", repoName)
|
||||
data := []struct {
|
||||
ID string
|
||||
Created time.Time
|
||||
}{}
|
||||
err := json.Unmarshal([]byte(out), &data)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to marshal from %q: err %v", repoName, err))
|
||||
c.Assert(len(data), checker.Not(checker.Equals), 0, check.Commentf("failed to marshal the data from %q", repoName))
|
||||
tarTvTimeFormat := "2006-01-02 15:04"
|
||||
out, _, err = runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName),
|
||||
exec.Command("tar", "tv"),
|
||||
exec.Command("grep", "-E", fmt.Sprintf("%s %s", data[0].Created.Format(tarTvTimeFormat), digest.Digest(data[0].ID).Hex())))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save repo with image ID and 'repositories' file: %s, %v", out, err))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestSaveImageId(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
repoName := "foobar-save-image-id-test"
|
||||
dockerCmd(c, "tag", "emptyfs:latest", fmt.Sprintf("%v:latest", repoName))
|
||||
|
||||
out, _ := dockerCmd(c, "images", "-q", "--no-trunc", repoName)
|
||||
cleanedLongImageID := strings.TrimPrefix(strings.TrimSpace(out), "sha256:")
|
||||
|
||||
out, _ = dockerCmd(c, "images", "-q", repoName)
|
||||
cleanedShortImageID := strings.TrimSpace(out)
|
||||
|
||||
// Make sure IDs are not empty
|
||||
c.Assert(cleanedLongImageID, checker.Not(check.Equals), "", check.Commentf("Id should not be empty."))
|
||||
c.Assert(cleanedShortImageID, checker.Not(check.Equals), "", check.Commentf("Id should not be empty."))
|
||||
|
||||
saveCmd := exec.Command(dockerBinary, "save", cleanedShortImageID)
|
||||
tarCmd := exec.Command("tar", "t")
|
||||
|
||||
var err error
|
||||
tarCmd.Stdin, err = saveCmd.StdoutPipe()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("cannot set stdout pipe for tar: %v", err))
|
||||
grepCmd := exec.Command("grep", cleanedLongImageID)
|
||||
grepCmd.Stdin, err = tarCmd.StdoutPipe()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("cannot set stdout pipe for grep: %v", err))
|
||||
|
||||
c.Assert(tarCmd.Start(), checker.IsNil, check.Commentf("tar failed with error: %v", err))
|
||||
c.Assert(saveCmd.Start(), checker.IsNil, check.Commentf("docker save failed with error: %v", err))
|
||||
defer func() {
|
||||
saveCmd.Wait()
|
||||
tarCmd.Wait()
|
||||
dockerCmd(c, "rmi", repoName)
|
||||
}()
|
||||
|
||||
out, _, err = runCommandWithOutput(grepCmd)
|
||||
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save repo with image ID: %s, %v", out, err))
|
||||
}
|
||||
|
||||
// save a repo and try to load it using flags
|
||||
func (s *DockerSuite) TestSaveAndLoadRepoFlags(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
name := "test-save-and-load-repo-flags"
|
||||
dockerCmd(c, "run", "--name", name, "busybox", "true")
|
||||
|
||||
repoName := "foobar-save-load-test"
|
||||
|
||||
deleteImages(repoName)
|
||||
dockerCmd(c, "commit", name, repoName)
|
||||
|
||||
before, _ := dockerCmd(c, "inspect", repoName)
|
||||
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName),
|
||||
exec.Command(dockerBinary, "load"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
|
||||
|
||||
after, _ := dockerCmd(c, "inspect", repoName)
|
||||
c.Assert(before, checker.Equals, after, check.Commentf("inspect is not the same after a save / load"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestSaveMultipleNames(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
repoName := "foobar-save-multi-name-test"
|
||||
|
||||
// Make one image
|
||||
dockerCmd(c, "tag", "emptyfs:latest", fmt.Sprintf("%v-one:latest", repoName))
|
||||
|
||||
// Make two images
|
||||
dockerCmd(c, "tag", "emptyfs:latest", fmt.Sprintf("%v-two:latest", repoName))
|
||||
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", fmt.Sprintf("%v-one", repoName), fmt.Sprintf("%v-two:latest", repoName)),
|
||||
exec.Command("tar", "xO", "repositories"),
|
||||
exec.Command("grep", "-q", "-E", "(-one|-two)"),
|
||||
)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save multiple repos: %s, %v", out, err))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestSaveRepoWithMultipleImages(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
makeImage := func(from string, tag string) string {
|
||||
var (
|
||||
out string
|
||||
)
|
||||
out, _ = dockerCmd(c, "run", "-d", from, "true")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "commit", cleanedContainerID, tag)
|
||||
imageID := strings.TrimSpace(out)
|
||||
return imageID
|
||||
}
|
||||
|
||||
repoName := "foobar-save-multi-images-test"
|
||||
tagFoo := repoName + ":foo"
|
||||
tagBar := repoName + ":bar"
|
||||
|
||||
idFoo := makeImage("busybox:latest", tagFoo)
|
||||
idBar := makeImage("busybox:latest", tagBar)
|
||||
|
||||
deleteImages(repoName)
|
||||
|
||||
// create the archive
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName, "busybox:latest"),
|
||||
exec.Command("tar", "t"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save multiple images: %s, %v", out, err))
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(out), "\n")
|
||||
var actual []string
|
||||
for _, l := range lines {
|
||||
if regexp.MustCompile("^[a-f0-9]{64}\\.json$").Match([]byte(l)) {
|
||||
actual = append(actual, strings.TrimSuffix(l, ".json"))
|
||||
}
|
||||
}
|
||||
|
||||
// make the list of expected layers
|
||||
out = inspectField(c, "busybox:latest", "Id")
|
||||
expected := []string{strings.TrimSpace(out), idFoo, idBar}
|
||||
|
||||
// prefixes are not in tar
|
||||
for i := range expected {
|
||||
expected[i] = digest.Digest(expected[i]).Hex()
|
||||
}
|
||||
|
||||
sort.Strings(actual)
|
||||
sort.Strings(expected)
|
||||
c.Assert(actual, checker.DeepEquals, expected, check.Commentf("archive does not contains the right layers: got %v, expected %v, output: %q", actual, expected, out))
|
||||
}
|
||||
|
||||
// Issue #6722 #5892 ensure directories are included in changes
|
||||
func (s *DockerSuite) TestSaveDirectoryPermissions(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
layerEntries := []string{"opt/", "opt/a/", "opt/a/b/", "opt/a/b/c"}
|
||||
layerEntriesAUFS := []string{"./", ".wh..wh.aufs", ".wh..wh.orph/", ".wh..wh.plnk/", "opt/", "opt/a/", "opt/a/b/", "opt/a/b/c"}
|
||||
|
||||
name := "save-directory-permissions"
|
||||
tmpDir, err := ioutil.TempDir("", "save-layers-with-directories")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to create temporary directory: %s", err))
|
||||
extractionDirectory := filepath.Join(tmpDir, "image-extraction-dir")
|
||||
os.Mkdir(extractionDirectory, 0777)
|
||||
|
||||
defer os.RemoveAll(tmpDir)
|
||||
_, err = buildImage(name,
|
||||
`FROM busybox
|
||||
RUN adduser -D user && mkdir -p /opt/a/b && chown -R user:user /opt/a
|
||||
RUN touch /opt/a/b/c && chown user:user /opt/a/b/c`,
|
||||
true)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("%v", err))
|
||||
|
||||
out, _, err := runCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", name),
|
||||
exec.Command("tar", "-xf", "-", "-C", extractionDirectory),
|
||||
)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save and extract image: %s", out))
|
||||
|
||||
dirs, err := ioutil.ReadDir(extractionDirectory)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to get a listing of the layer directories: %s", err))
|
||||
|
||||
found := false
|
||||
for _, entry := range dirs {
|
||||
var entriesSansDev []string
|
||||
if entry.IsDir() {
|
||||
layerPath := filepath.Join(extractionDirectory, entry.Name(), "layer.tar")
|
||||
|
||||
f, err := os.Open(layerPath)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to open %s: %s", layerPath, err))
|
||||
|
||||
entries, err := listTar(f)
|
||||
for _, e := range entries {
|
||||
if !strings.Contains(e, "dev/") {
|
||||
entriesSansDev = append(entriesSansDev, e)
|
||||
}
|
||||
}
|
||||
c.Assert(err, checker.IsNil, check.Commentf("encountered error while listing tar entries: %s", err))
|
||||
|
||||
if reflect.DeepEqual(entriesSansDev, layerEntries) || reflect.DeepEqual(entriesSansDev, layerEntriesAUFS) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.Assert(found, checker.Equals, true, check.Commentf("failed to find the layer with the right content listing"))
|
||||
|
||||
}
|
||||
|
||||
// Test loading a weird image where one of the layers is of zero size.
|
||||
// The layer.tar file is actually zero bytes, no padding or anything else.
|
||||
// See issue: 18170
|
||||
func (s *DockerSuite) TestLoadZeroSizeLayer(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
dockerCmd(c, "load", "-i", "fixtures/load/emptyLayer.tar")
|
||||
}
|
||||
67
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_save_load_unix_test.go
generated
vendored
Normal file
67
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_save_load_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
"github.com/kr/pty"
|
||||
)
|
||||
|
||||
// save a repo and try to load it using stdout
|
||||
func (s *DockerSuite) TestSaveAndLoadRepoStdout(c *check.C) {
|
||||
name := "test-save-and-load-repo-stdout"
|
||||
dockerCmd(c, "run", "--name", name, "busybox", "true")
|
||||
|
||||
repoName := "foobar-save-load-test"
|
||||
before, _ := dockerCmd(c, "commit", name, repoName)
|
||||
before = strings.TrimRight(before, "\n")
|
||||
|
||||
tmpFile, err := ioutil.TempFile("", "foobar-save-load-test.tar")
|
||||
c.Assert(err, check.IsNil)
|
||||
defer os.Remove(tmpFile.Name())
|
||||
|
||||
saveCmd := exec.Command(dockerBinary, "save", repoName)
|
||||
saveCmd.Stdout = tmpFile
|
||||
|
||||
_, err = runCommand(saveCmd)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
tmpFile, err = os.Open(tmpFile.Name())
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
deleteImages(repoName)
|
||||
|
||||
loadCmd := exec.Command(dockerBinary, "load")
|
||||
loadCmd.Stdin = tmpFile
|
||||
|
||||
out, _, err := runCommandWithOutput(loadCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
|
||||
after := inspectField(c, repoName, "Id")
|
||||
after = strings.TrimRight(after, "\n")
|
||||
|
||||
c.Assert(after, check.Equals, before) //inspect is not the same after a save / load
|
||||
|
||||
deleteImages(repoName)
|
||||
|
||||
pty, tty, err := pty.Open()
|
||||
c.Assert(err, check.IsNil)
|
||||
cmd := exec.Command(dockerBinary, "save", repoName)
|
||||
cmd.Stdin = tty
|
||||
cmd.Stdout = tty
|
||||
cmd.Stderr = tty
|
||||
c.Assert(cmd.Start(), check.IsNil)
|
||||
c.Assert(cmd.Wait(), check.NotNil) //did not break writing to a TTY
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
|
||||
n, err := pty.Read(buf)
|
||||
c.Assert(err, check.IsNil) //could not read tty output
|
||||
c.Assert(string(buf[:n]), checker.Contains, "Cowardly refusing", check.Commentf("help output is not being yielded", out))
|
||||
}
|
||||
44
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_sni_test.go
generated
vendored
Normal file
44
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_sni_test.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestClientSetsTLSServerName(c *check.C) {
|
||||
c.Skip("Flakey test")
|
||||
// there may be more than one hit to the server for each registry request
|
||||
serverNameReceived := []string{}
|
||||
var serverName string
|
||||
|
||||
virtualHostServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
serverNameReceived = append(serverNameReceived, r.TLS.ServerName)
|
||||
}))
|
||||
defer virtualHostServer.Close()
|
||||
// discard TLS handshake errors written by default to os.Stderr
|
||||
virtualHostServer.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
|
||||
|
||||
u, err := url.Parse(virtualHostServer.URL)
|
||||
c.Assert(err, check.IsNil)
|
||||
hostPort := u.Host
|
||||
serverName = strings.Split(hostPort, ":")[0]
|
||||
|
||||
repoName := fmt.Sprintf("%v/dockercli/image:latest", hostPort)
|
||||
cmd := exec.Command(dockerBinary, "pull", repoName)
|
||||
cmd.Run()
|
||||
|
||||
// check that the fake server was hit at least once
|
||||
c.Assert(len(serverNameReceived) > 0, check.Equals, true)
|
||||
// check that for each hit the right server name was received
|
||||
for _, item := range serverNameReceived {
|
||||
c.Check(item, check.Equals, serverName)
|
||||
}
|
||||
}
|
||||
412
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_start_volume_driver_unix_test.go
generated
vendored
Normal file
412
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_start_volume_driver_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,412 @@
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func init() {
|
||||
check.Suite(&DockerExternalVolumeSuite{
|
||||
ds: &DockerSuite{},
|
||||
})
|
||||
}
|
||||
|
||||
type eventCounter struct {
|
||||
activations int
|
||||
creations int
|
||||
removals int
|
||||
mounts int
|
||||
unmounts int
|
||||
paths int
|
||||
lists int
|
||||
gets int
|
||||
}
|
||||
|
||||
type DockerExternalVolumeSuite struct {
|
||||
server *httptest.Server
|
||||
ds *DockerSuite
|
||||
d *Daemon
|
||||
ec *eventCounter
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) SetUpTest(c *check.C) {
|
||||
s.d = NewDaemon(c)
|
||||
s.ec = &eventCounter{}
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) TearDownTest(c *check.C) {
|
||||
s.d.Stop()
|
||||
s.ds.TearDownTest(c)
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) SetUpSuite(c *check.C) {
|
||||
mux := http.NewServeMux()
|
||||
s.server = httptest.NewServer(mux)
|
||||
|
||||
type pluginRequest struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type pluginResp struct {
|
||||
Mountpoint string `json:",omitempty"`
|
||||
Err string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type vol struct {
|
||||
Name string
|
||||
Mountpoint string
|
||||
}
|
||||
var volList []vol
|
||||
|
||||
read := func(b io.ReadCloser) (pluginRequest, error) {
|
||||
defer b.Close()
|
||||
var pr pluginRequest
|
||||
if err := json.NewDecoder(b).Decode(&pr); err != nil {
|
||||
return pr, err
|
||||
}
|
||||
return pr, nil
|
||||
}
|
||||
|
||||
send := func(w http.ResponseWriter, data interface{}) {
|
||||
switch t := data.(type) {
|
||||
case error:
|
||||
http.Error(w, t.Error(), 500)
|
||||
case string:
|
||||
w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
|
||||
fmt.Fprintln(w, t)
|
||||
default:
|
||||
w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
|
||||
json.NewEncoder(w).Encode(&data)
|
||||
}
|
||||
}
|
||||
|
||||
mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.activations++
|
||||
send(w, `{"Implements": ["VolumeDriver"]}`)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Create", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.creations++
|
||||
pr, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
volList = append(volList, vol{Name: pr.Name})
|
||||
send(w, nil)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.List", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.lists++
|
||||
send(w, map[string][]vol{"Volumes": volList})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Get", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.gets++
|
||||
pr, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range volList {
|
||||
if v.Name == pr.Name {
|
||||
v.Mountpoint = hostVolumePath(pr.Name)
|
||||
send(w, map[string]vol{"Volume": v})
|
||||
return
|
||||
}
|
||||
}
|
||||
send(w, `{"Err": "no such volume"}`)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Remove", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.removals++
|
||||
pr, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(hostVolumePath(pr.Name)); err != nil {
|
||||
send(w, &pluginResp{Err: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
for i, v := range volList {
|
||||
if v.Name == pr.Name {
|
||||
if err := os.RemoveAll(hostVolumePath(v.Name)); err != nil {
|
||||
send(w, fmt.Sprintf(`{"Err": "%v"}`, err))
|
||||
return
|
||||
}
|
||||
volList = append(volList[:i], volList[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
send(w, nil)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Path", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.paths++
|
||||
|
||||
pr, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
p := hostVolumePath(pr.Name)
|
||||
send(w, &pluginResp{Mountpoint: p})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Mount", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.mounts++
|
||||
|
||||
pr, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := hostVolumePath(pr.Name)
|
||||
if err := os.MkdirAll(p, 0755); err != nil {
|
||||
send(w, &pluginResp{Err: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(p, "test"), []byte(s.server.URL), 0644); err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
send(w, &pluginResp{Mountpoint: p})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Unmount", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.unmounts++
|
||||
|
||||
_, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
send(w, nil)
|
||||
})
|
||||
|
||||
err := os.MkdirAll("/etc/docker/plugins", 0755)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = ioutil.WriteFile("/etc/docker/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) TearDownSuite(c *check.C) {
|
||||
s.server.Close()
|
||||
|
||||
err := os.RemoveAll("/etc/docker/plugins")
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverNamed(c *check.C) {
|
||||
err := s.d.StartWithBusybox()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, err := s.d.Cmd("run", "--rm", "--name", "test-data", "-v", "external-volume-test:/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", "busybox:latest", "cat", "/tmp/external-volume-test/test")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, s.server.URL)
|
||||
|
||||
_, err = s.d.Cmd("volume", "rm", "external-volume-test")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
p := hostVolumePath("external-volume-test")
|
||||
_, err = os.Lstat(p)
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(os.IsNotExist(err), checker.True, check.Commentf("Expected volume path in host to not exist: %s, %v\n", p, err))
|
||||
|
||||
c.Assert(s.ec.activations, checker.Equals, 1)
|
||||
c.Assert(s.ec.creations, checker.Equals, 1)
|
||||
c.Assert(s.ec.removals, checker.Equals, 1)
|
||||
c.Assert(s.ec.mounts, checker.Equals, 1)
|
||||
c.Assert(s.ec.unmounts, checker.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverUnnamed(c *check.C) {
|
||||
err := s.d.StartWithBusybox()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, err := s.d.Cmd("run", "--rm", "--name", "test-data", "-v", "/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", "busybox:latest", "cat", "/tmp/external-volume-test/test")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, s.server.URL)
|
||||
|
||||
c.Assert(s.ec.activations, checker.Equals, 1)
|
||||
c.Assert(s.ec.creations, checker.Equals, 1)
|
||||
c.Assert(s.ec.removals, checker.Equals, 1)
|
||||
c.Assert(s.ec.mounts, checker.Equals, 1)
|
||||
c.Assert(s.ec.unmounts, checker.Equals, 1)
|
||||
}
|
||||
|
||||
func (s DockerExternalVolumeSuite) TestExternalVolumeDriverVolumesFrom(c *check.C) {
|
||||
err := s.d.StartWithBusybox()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, err := s.d.Cmd("run", "-d", "--name", "vol-test1", "-v", "/foo", "--volume-driver", "test-external-volume-driver", "busybox:latest")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
out, err = s.d.Cmd("run", "--rm", "--volumes-from", "vol-test1", "--name", "vol-test2", "busybox", "ls", "/tmp")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
out, err = s.d.Cmd("rm", "-fv", "vol-test1")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
c.Assert(s.ec.activations, checker.Equals, 1)
|
||||
c.Assert(s.ec.creations, checker.Equals, 1)
|
||||
c.Assert(s.ec.removals, checker.Equals, 1)
|
||||
c.Assert(s.ec.mounts, checker.Equals, 2)
|
||||
c.Assert(s.ec.unmounts, checker.Equals, 2)
|
||||
}
|
||||
|
||||
func (s DockerExternalVolumeSuite) TestExternalVolumeDriverDeleteContainer(c *check.C) {
|
||||
err := s.d.StartWithBusybox()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, err := s.d.Cmd("run", "-d", "--name", "vol-test1", "-v", "/foo", "--volume-driver", "test-external-volume-driver", "busybox:latest")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
out, err = s.d.Cmd("rm", "-fv", "vol-test1")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
c.Assert(s.ec.activations, checker.Equals, 1)
|
||||
c.Assert(s.ec.creations, checker.Equals, 1)
|
||||
c.Assert(s.ec.removals, checker.Equals, 1)
|
||||
c.Assert(s.ec.mounts, checker.Equals, 1)
|
||||
c.Assert(s.ec.unmounts, checker.Equals, 1)
|
||||
}
|
||||
|
||||
func hostVolumePath(name string) string {
|
||||
return fmt.Sprintf("/var/lib/docker/volumes/%s", name)
|
||||
}
|
||||
|
||||
// Make sure a request to use a down driver doesn't block other requests
|
||||
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverLookupNotBlocked(c *check.C) {
|
||||
specPath := "/etc/docker/plugins/down-driver.spec"
|
||||
err := ioutil.WriteFile(specPath, []byte("tcp://127.0.0.7:9999"), 0644)
|
||||
c.Assert(err, check.IsNil)
|
||||
defer os.RemoveAll(specPath)
|
||||
|
||||
chCmd1 := make(chan struct{})
|
||||
chCmd2 := make(chan error)
|
||||
cmd1 := exec.Command(dockerBinary, "volume", "create", "-d", "down-driver")
|
||||
cmd2 := exec.Command(dockerBinary, "volume", "create")
|
||||
|
||||
c.Assert(cmd1.Start(), checker.IsNil)
|
||||
defer cmd1.Process.Kill()
|
||||
time.Sleep(100 * time.Millisecond) // ensure API has been called
|
||||
c.Assert(cmd2.Start(), checker.IsNil)
|
||||
|
||||
go func() {
|
||||
cmd1.Wait()
|
||||
close(chCmd1)
|
||||
}()
|
||||
go func() {
|
||||
chCmd2 <- cmd2.Wait()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-chCmd1:
|
||||
cmd2.Process.Kill()
|
||||
c.Fatalf("volume create with down driver finished unexpectedly")
|
||||
case err := <-chCmd2:
|
||||
c.Assert(err, checker.IsNil)
|
||||
case <-time.After(5 * time.Second):
|
||||
cmd2.Process.Kill()
|
||||
c.Fatal("volume creates are blocked by previous create requests when previous driver is down")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverRetryNotImmediatelyExists(c *check.C) {
|
||||
err := s.d.StartWithBusybox()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
specPath := "/etc/docker/plugins/test-external-volume-driver-retry.spec"
|
||||
os.RemoveAll(specPath)
|
||||
defer os.RemoveAll(specPath)
|
||||
|
||||
errchan := make(chan error)
|
||||
go func() {
|
||||
if out, err := s.d.Cmd("run", "--rm", "--name", "test-data-retry", "-v", "external-volume-test:/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver-retry", "busybox:latest"); err != nil {
|
||||
errchan <- fmt.Errorf("%v:\n%s", err, out)
|
||||
}
|
||||
close(errchan)
|
||||
}()
|
||||
go func() {
|
||||
// wait for a retry to occur, then create spec to allow plugin to register
|
||||
time.Sleep(2000 * time.Millisecond)
|
||||
// no need to check for an error here since it will get picked up by the timeout later
|
||||
ioutil.WriteFile(specPath, []byte(s.server.URL), 0644)
|
||||
}()
|
||||
|
||||
select {
|
||||
case err := <-errchan:
|
||||
c.Assert(err, checker.IsNil)
|
||||
case <-time.After(8 * time.Second):
|
||||
c.Fatal("volume creates fail when plugin not immediately available")
|
||||
}
|
||||
|
||||
_, err = s.d.Cmd("volume", "rm", "external-volume-test")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
c.Assert(s.ec.activations, checker.Equals, 1)
|
||||
c.Assert(s.ec.creations, checker.Equals, 1)
|
||||
c.Assert(s.ec.removals, checker.Equals, 1)
|
||||
c.Assert(s.ec.mounts, checker.Equals, 1)
|
||||
c.Assert(s.ec.unmounts, checker.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverBindExternalVolume(c *check.C) {
|
||||
dockerCmd(c, "volume", "create", "-d", "test-external-volume-driver", "--name", "foo")
|
||||
dockerCmd(c, "run", "-d", "--name", "testing", "-v", "foo:/bar", "busybox", "top")
|
||||
|
||||
var mounts []struct {
|
||||
Name string
|
||||
Driver string
|
||||
}
|
||||
out := inspectFieldJSON(c, "testing", "Mounts")
|
||||
c.Assert(json.NewDecoder(strings.NewReader(out)).Decode(&mounts), checker.IsNil)
|
||||
c.Assert(len(mounts), checker.Equals, 1, check.Commentf(out))
|
||||
c.Assert(mounts[0].Name, checker.Equals, "foo")
|
||||
c.Assert(mounts[0].Driver, checker.Equals, "test-external-volume-driver")
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) TesttExternalVolumeDriverList(c *check.C) {
|
||||
dockerCmd(c, "volume", "create", "-d", "test-external-volume-driver", "--name", "abc")
|
||||
out, _ := dockerCmd(c, "volume", "ls")
|
||||
ls := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(len(ls), check.Equals, 2, check.Commentf("\n%s", out))
|
||||
|
||||
vol := strings.Fields(ls[len(ls)-1])
|
||||
c.Assert(len(vol), check.Equals, 2, check.Commentf("%v", vol))
|
||||
c.Assert(vol[0], check.Equals, "test-external-volume-driver")
|
||||
c.Assert(vol[1], check.Equals, "abc")
|
||||
|
||||
c.Assert(s.ec.lists, check.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverGet(c *check.C) {
|
||||
out, _, err := dockerCmdWithError("volume", "inspect", "dummy")
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(s.ec.gets, check.Equals, 1)
|
||||
c.Assert(out, checker.Contains, "No such volume")
|
||||
}
|
||||
251
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_tag_test.go
generated
vendored
Normal file
251
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_tag_test.go
generated
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// tagging a named image in a new unprefixed repo should work
|
||||
func (s *DockerSuite) TestTagUnprefixedRepoByName(c *check.C) {
|
||||
// Don't attempt to pull on Windows as not in hub. It's installed
|
||||
// as an image through .ensure-frozen-images-windows
|
||||
if daemonPlatform != "windows" {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
}
|
||||
|
||||
dockerCmd(c, "tag", "busybox:latest", "testfoobarbaz")
|
||||
}
|
||||
|
||||
// tagging an image by ID in a new unprefixed repo should work
|
||||
func (s *DockerSuite) TestTagUnprefixedRepoByID(c *check.C) {
|
||||
imageID := inspectField(c, "busybox", "Id")
|
||||
dockerCmd(c, "tag", imageID, "testfoobarbaz")
|
||||
}
|
||||
|
||||
// ensure we don't allow the use of invalid repository names; these tag operations should fail
|
||||
func (s *DockerSuite) TestTagInvalidUnprefixedRepo(c *check.C) {
|
||||
invalidRepos := []string{"fo$z$", "Foo@3cc", "Foo$3", "Foo*3", "Fo^3", "Foo!3", "F)xcz(", "fo%asd"}
|
||||
|
||||
for _, repo := range invalidRepos {
|
||||
out, _, err := dockerCmdWithError("tag", "busybox", repo)
|
||||
c.Assert(err, checker.NotNil, check.Commentf("tag busybox %v should have failed : %v", repo, out))
|
||||
}
|
||||
}
|
||||
|
||||
// ensure we don't allow the use of invalid tags; these tag operations should fail
|
||||
func (s *DockerSuite) TestTagInvalidPrefixedRepo(c *check.C) {
|
||||
longTag := stringutils.GenerateRandomAlphaOnlyString(121)
|
||||
|
||||
invalidTags := []string{"repo:fo$z$", "repo:Foo@3cc", "repo:Foo$3", "repo:Foo*3", "repo:Fo^3", "repo:Foo!3", "repo:%goodbye", "repo:#hashtagit", "repo:F)xcz(", "repo:-foo", "repo:..", longTag}
|
||||
|
||||
for _, repotag := range invalidTags {
|
||||
out, _, err := dockerCmdWithError("tag", "busybox", repotag)
|
||||
c.Assert(err, checker.NotNil, check.Commentf("tag busybox %v should have failed : %v", repotag, out))
|
||||
}
|
||||
}
|
||||
|
||||
// ensure we allow the use of valid tags
|
||||
func (s *DockerSuite) TestTagValidPrefixedRepo(c *check.C) {
|
||||
// Don't attempt to pull on Windows as not in hub. It's installed
|
||||
// as an image through .ensure-frozen-images-windows
|
||||
if daemonPlatform != "windows" {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
}
|
||||
|
||||
validRepos := []string{"fooo/bar", "fooaa/test", "foooo:t"}
|
||||
|
||||
for _, repo := range validRepos {
|
||||
_, _, err := dockerCmdWithError("tag", "busybox:latest", repo)
|
||||
if err != nil {
|
||||
c.Errorf("tag busybox %v should have worked: %s", repo, err)
|
||||
continue
|
||||
}
|
||||
deleteImages(repo)
|
||||
}
|
||||
}
|
||||
|
||||
// tag an image with an existed tag name without -f option should work
|
||||
func (s *DockerSuite) TestTagExistedNameWithoutForce(c *check.C) {
|
||||
// Don't attempt to pull on Windows as not in hub. It's installed
|
||||
// as an image through .ensure-frozen-images-windows
|
||||
if daemonPlatform != "windows" {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
}
|
||||
|
||||
dockerCmd(c, "tag", "busybox:latest", "busybox:test")
|
||||
}
|
||||
|
||||
// tag an image with an existed tag name with -f option should work
|
||||
func (s *DockerSuite) TestTagExistedNameWithForce(c *check.C) {
|
||||
// Don't attempt to pull on Windows as not in hub. It's installed
|
||||
// as an image through .ensure-frozen-images-windows
|
||||
if daemonPlatform != "windows" {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
}
|
||||
dockerCmd(c, "tag", "busybox:latest", "busybox:test")
|
||||
dockerCmd(c, "tag", "-f", "busybox:latest", "busybox:test")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestTagWithPrefixHyphen(c *check.C) {
|
||||
// TODO Windows CI. This fails on TP4 docker, but has since been fixed.
|
||||
// Enable these tests for TP5.
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// Don't attempt to pull on Windows as not in hub. It's installed
|
||||
// as an image through .ensure-frozen-images-windows
|
||||
if daemonPlatform != "windows" {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
}
|
||||
// test repository name begin with '-'
|
||||
out, _, err := dockerCmdWithError("tag", "busybox:latest", "-busybox:test")
|
||||
c.Assert(err, checker.NotNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "Error parsing reference", check.Commentf("tag a name begin with '-' should failed"))
|
||||
|
||||
// test namespace name begin with '-'
|
||||
out, _, err = dockerCmdWithError("tag", "busybox:latest", "-test/busybox:test")
|
||||
c.Assert(err, checker.NotNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "Error parsing reference", check.Commentf("tag a name begin with '-' should failed"))
|
||||
|
||||
// test index name begin with '-'
|
||||
out, _, err = dockerCmdWithError("tag", "busybox:latest", "-index:5000/busybox:test")
|
||||
c.Assert(err, checker.NotNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "Error parsing reference", check.Commentf("tag a name begin with '-' should failed"))
|
||||
}
|
||||
|
||||
// ensure tagging using official names works
|
||||
// ensure all tags result in the same name
|
||||
func (s *DockerSuite) TestTagOfficialNames(c *check.C) {
|
||||
// TODO Windows CI. This fails on TP4 docker, but has since been fixed.
|
||||
// Enable these tests for TP5.
|
||||
testRequires(c, DaemonIsLinux)
|
||||
names := []string{
|
||||
"docker.io/busybox",
|
||||
"index.docker.io/busybox",
|
||||
"library/busybox",
|
||||
"docker.io/library/busybox",
|
||||
"index.docker.io/library/busybox",
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
out, exitCode, err := dockerCmdWithError("tag", "busybox:latest", name+":latest")
|
||||
if err != nil || exitCode != 0 {
|
||||
c.Errorf("tag busybox %v should have worked: %s, %s", name, err, out)
|
||||
continue
|
||||
}
|
||||
|
||||
// ensure we don't have multiple tag names.
|
||||
out, _, err = dockerCmdWithError("images")
|
||||
if err != nil {
|
||||
c.Errorf("listing images failed with errors: %v, %s", err, out)
|
||||
} else if strings.Contains(out, name) {
|
||||
c.Errorf("images should not have listed '%s'", name)
|
||||
deleteImages(name + ":latest")
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
_, exitCode, err := dockerCmdWithError("tag", name+":latest", "fooo/bar:latest")
|
||||
if err != nil || exitCode != 0 {
|
||||
c.Errorf("tag %v fooo/bar should have worked: %s", name, err)
|
||||
continue
|
||||
}
|
||||
deleteImages("fooo/bar:latest")
|
||||
}
|
||||
}
|
||||
|
||||
// ensure tags can not match digests
|
||||
func (s *DockerSuite) TestTagMatchesDigest(c *check.C) {
|
||||
// TODO Windows CI. This can be enabled for TP5, but will fail on TP4.
|
||||
// This is due to the content addressibility changes which are not
|
||||
// in the TP4 version of Docker.
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// Don't attempt to pull on Windows as not in hub. It's installed
|
||||
// as an image through .ensure-frozen-images-windows
|
||||
if daemonPlatform != "windows" {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
}
|
||||
digest := "busybox@sha256:abcdef76720241213f5303bda7704ec4c2ef75613173910a56fb1b6e20251507"
|
||||
// test setting tag fails
|
||||
_, _, err := dockerCmdWithError("tag", "busybox:latest", digest)
|
||||
if err == nil {
|
||||
c.Fatal("digest tag a name should have failed")
|
||||
}
|
||||
// check that no new image matches the digest
|
||||
_, _, err = dockerCmdWithError("inspect", digest)
|
||||
if err == nil {
|
||||
c.Fatal("inspecting by digest should have failed")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestTagInvalidRepoName(c *check.C) {
|
||||
// TODO Windows CI. This can be enabled for TP5, but will fail on the
|
||||
// TP4 version of docker.
|
||||
testRequires(c, DaemonIsLinux)
|
||||
// Don't attempt to pull on Windows as not in hub. It's installed
|
||||
// as an image through .ensure-frozen-images-windows
|
||||
if daemonPlatform != "windows" {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
}
|
||||
|
||||
// test setting tag fails
|
||||
_, _, err := dockerCmdWithError("tag", "busybox:latest", "sha256:sometag")
|
||||
if err == nil {
|
||||
c.Fatal("tagging with image named \"sha256\" should have failed")
|
||||
}
|
||||
}
|
||||
|
||||
// ensure tags cannot create ambiguity with image ids
|
||||
func (s *DockerSuite) TestTagTruncationAmbiguity(c *check.C) {
|
||||
//testRequires(c, DaemonIsLinux)
|
||||
// Don't attempt to pull on Windows as not in hub. It's installed
|
||||
// as an image through .ensure-frozen-images-windows
|
||||
if daemonPlatform != "windows" {
|
||||
if err := pullImageIfNotExist("busybox:latest"); err != nil {
|
||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||
}
|
||||
}
|
||||
imageID, err := buildImage("notbusybox:latest",
|
||||
`FROM busybox
|
||||
MAINTAINER dockerio`,
|
||||
true)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
truncatedImageID := stringid.TruncateID(imageID)
|
||||
truncatedTag := fmt.Sprintf("notbusybox:%s", truncatedImageID)
|
||||
|
||||
id := inspectField(c, truncatedTag, "Id")
|
||||
|
||||
// Ensure inspect by image id returns image for image id
|
||||
c.Assert(id, checker.Equals, imageID)
|
||||
c.Logf("Built image: %s", imageID)
|
||||
|
||||
// test setting tag fails
|
||||
_, _, err = dockerCmdWithError("tag", "busybox:latest", truncatedTag)
|
||||
if err != nil {
|
||||
c.Fatalf("Error tagging with an image id: %s", err)
|
||||
}
|
||||
|
||||
id = inspectField(c, truncatedTag, "Id")
|
||||
|
||||
// Ensure id is imageID and not busybox:latest
|
||||
c.Assert(id, checker.Not(checker.Equals), imageID)
|
||||
}
|
||||
43
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_top_test.go
generated
vendored
Normal file
43
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_top_test.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestTopMultipleArgs(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-i", "-d", "busybox", "top")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
out, _ = dockerCmd(c, "top", cleanedContainerID, "-o", "pid")
|
||||
c.Assert(out, checker.Contains, "PID", check.Commentf("did not see PID after top -o pid: %s", out))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestTopNonPrivileged(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-i", "-d", "busybox", "top")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
out1, _ := dockerCmd(c, "top", cleanedContainerID)
|
||||
out2, _ := dockerCmd(c, "top", cleanedContainerID)
|
||||
dockerCmd(c, "kill", cleanedContainerID)
|
||||
|
||||
c.Assert(out1, checker.Contains, "top", check.Commentf("top should've listed `top` in the process list, but failed the first time"))
|
||||
c.Assert(out2, checker.Contains, "top", check.Commentf("top should've listed `top` in the process list, but failed the second time"))
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestTopPrivileged(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, NotUserNamespace)
|
||||
out, _ := dockerCmd(c, "run", "--privileged", "-i", "-d", "busybox", "top")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
out1, _ := dockerCmd(c, "top", cleanedContainerID)
|
||||
out2, _ := dockerCmd(c, "top", cleanedContainerID)
|
||||
dockerCmd(c, "kill", cleanedContainerID)
|
||||
|
||||
c.Assert(out1, checker.Contains, "top", check.Commentf("top should've listed `top` in the process list, but failed the first time"))
|
||||
c.Assert(out2, checker.Contains, "top", check.Commentf("top should've listed `top` in the process list, but failed the second time"))
|
||||
}
|
||||
171
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_update_unix_test.go
generated
vendored
Normal file
171
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_update_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/docker/engine-api/types"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestUpdateRunningContainer(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, memoryLimitSupport)
|
||||
|
||||
name := "test-update-container"
|
||||
dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "busybox", "top")
|
||||
dockerCmd(c, "update", "-m", "500M", name)
|
||||
|
||||
c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "524288000")
|
||||
|
||||
file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
|
||||
out, _ := dockerCmd(c, "exec", name, "cat", file)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "524288000")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestUpdateRunningContainerWithRestart(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, memoryLimitSupport)
|
||||
|
||||
name := "test-update-container"
|
||||
dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "busybox", "top")
|
||||
dockerCmd(c, "update", "-m", "500M", name)
|
||||
dockerCmd(c, "restart", name)
|
||||
|
||||
c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "524288000")
|
||||
|
||||
file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
|
||||
out, _ := dockerCmd(c, "exec", name, "cat", file)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "524288000")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestUpdateStoppedContainer(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, memoryLimitSupport)
|
||||
|
||||
name := "test-update-container"
|
||||
file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
|
||||
dockerCmd(c, "run", "--name", name, "-m", "300M", "busybox", "cat", file)
|
||||
dockerCmd(c, "update", "-m", "500M", name)
|
||||
|
||||
c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "524288000")
|
||||
|
||||
out, _ := dockerCmd(c, "start", "-a", name)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "524288000")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestUpdatePausedContainer(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, cpuShare)
|
||||
|
||||
name := "test-update-container"
|
||||
dockerCmd(c, "run", "-d", "--name", name, "--cpu-shares", "1000", "busybox", "top")
|
||||
dockerCmd(c, "pause", name)
|
||||
dockerCmd(c, "update", "--cpu-shares", "500", name)
|
||||
|
||||
c.Assert(inspectField(c, name, "HostConfig.CPUShares"), checker.Equals, "500")
|
||||
|
||||
dockerCmd(c, "unpause", name)
|
||||
file := "/sys/fs/cgroup/cpu/cpu.shares"
|
||||
out, _ := dockerCmd(c, "exec", name, "cat", file)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "500")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestUpdateWithUntouchedFields(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, memoryLimitSupport)
|
||||
testRequires(c, cpuShare)
|
||||
|
||||
name := "test-update-container"
|
||||
dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "--cpu-shares", "800", "busybox", "top")
|
||||
dockerCmd(c, "update", "-m", "500M", name)
|
||||
|
||||
// Update memory and not touch cpus, `cpuset.cpus` should still have the old value
|
||||
out := inspectField(c, name, "HostConfig.CPUShares")
|
||||
c.Assert(out, check.Equals, "800")
|
||||
|
||||
file := "/sys/fs/cgroup/cpu/cpu.shares"
|
||||
out, _ = dockerCmd(c, "exec", name, "cat", file)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "800")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestUpdateContainerInvalidValue(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, memoryLimitSupport)
|
||||
|
||||
name := "test-update-container"
|
||||
dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "busybox", "true")
|
||||
out, _, err := dockerCmdWithError("update", "-m", "2M", name)
|
||||
c.Assert(err, check.NotNil)
|
||||
expected := "Minimum memory limit allowed is 4MB"
|
||||
c.Assert(out, checker.Contains, expected)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestUpdateContainerWithoutFlags(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, memoryLimitSupport)
|
||||
|
||||
name := "test-update-container"
|
||||
dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "busybox", "true")
|
||||
_, _, err := dockerCmdWithError("update", name)
|
||||
c.Assert(err, check.NotNil)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestUpdateKernelMemory(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, kernelMemorySupport)
|
||||
|
||||
name := "test-update-container"
|
||||
dockerCmd(c, "run", "-d", "--name", name, "--kernel-memory", "50M", "busybox", "top")
|
||||
_, _, err := dockerCmdWithError("update", "--kernel-memory", "100M", name)
|
||||
// Update kernel memory to a running container is not allowed.
|
||||
c.Assert(err, check.NotNil)
|
||||
|
||||
// Update kernel memory to a running container with failure should not change HostConfig
|
||||
c.Assert(inspectField(c, name, "HostConfig.KernelMemory"), checker.Equals, "52428800")
|
||||
|
||||
dockerCmd(c, "stop", name)
|
||||
dockerCmd(c, "update", "--kernel-memory", "100M", name)
|
||||
dockerCmd(c, "start", name)
|
||||
|
||||
c.Assert(inspectField(c, name, "HostConfig.KernelMemory"), checker.Equals, "104857600")
|
||||
|
||||
file := "/sys/fs/cgroup/memory/memory.kmem.limit_in_bytes"
|
||||
out, _ := dockerCmd(c, "exec", name, "cat", file)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "104857600")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestUpdateStats(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
testRequires(c, memoryLimitSupport)
|
||||
testRequires(c, cpuCfsQuota)
|
||||
name := "foo"
|
||||
dockerCmd(c, "run", "-d", "-ti", "--name", name, "-m", "500m", "busybox")
|
||||
|
||||
c.Assert(waitRun(name), checker.IsNil)
|
||||
|
||||
getMemLimit := func(id string) uint64 {
|
||||
resp, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", id), nil, "")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(resp.Header.Get("Content-Type"), checker.Equals, "application/json")
|
||||
|
||||
var v *types.Stats
|
||||
err = json.NewDecoder(body).Decode(&v)
|
||||
c.Assert(err, checker.IsNil)
|
||||
body.Close()
|
||||
|
||||
return v.MemoryStats.Limit
|
||||
}
|
||||
preMemLimit := getMemLimit(name)
|
||||
|
||||
dockerCmd(c, "update", "--cpu-quota", "2000", name)
|
||||
|
||||
curMemLimit := getMemLimit(name)
|
||||
|
||||
c.Assert(preMemLimit, checker.Equals, curMemLimit)
|
||||
|
||||
}
|
||||
126
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_v2_only_test.go
generated
vendored
Normal file
126
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_v2_only_test.go
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func makefile(contents string) (string, func(), error) {
|
||||
cleanup := func() {
|
||||
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile(".", "tmp")
|
||||
if err != nil {
|
||||
return "", cleanup, err
|
||||
}
|
||||
err = ioutil.WriteFile(f.Name(), []byte(contents), os.ModePerm)
|
||||
if err != nil {
|
||||
return "", cleanup, err
|
||||
}
|
||||
|
||||
cleanup = func() {
|
||||
err := os.Remove(f.Name())
|
||||
if err != nil {
|
||||
fmt.Println("Error removing tmpfile")
|
||||
}
|
||||
}
|
||||
return f.Name(), cleanup, nil
|
||||
|
||||
}
|
||||
|
||||
// TestV2Only ensures that a daemon in v2-only mode does not
|
||||
// attempt to contact any v1 registry endpoints.
|
||||
func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
|
||||
reg, err := newTestRegistry(c)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
reg.registerHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(404)
|
||||
})
|
||||
|
||||
reg.registerHandler("/v1/.*", func(w http.ResponseWriter, r *http.Request) {
|
||||
c.Fatal("V1 registry contacted")
|
||||
})
|
||||
|
||||
repoName := fmt.Sprintf("%s/busybox", reg.hostport)
|
||||
|
||||
err = s.d.Start("--insecure-registry", reg.hostport, "--disable-legacy-registry=true")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.hostport))
|
||||
c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
|
||||
defer cleanup()
|
||||
|
||||
s.d.Cmd("build", "--file", dockerfileName, ".")
|
||||
|
||||
s.d.Cmd("run", repoName)
|
||||
s.d.Cmd("login", "-u", "richard", "-p", "testtest", "-e", "testuser@testdomain.com", reg.hostport)
|
||||
s.d.Cmd("tag", "busybox", repoName)
|
||||
s.d.Cmd("push", repoName)
|
||||
s.d.Cmd("pull", repoName)
|
||||
}
|
||||
|
||||
// TestV1 starts a daemon in 'normal' mode
|
||||
// and ensure v1 endpoints are hit for the following operations:
|
||||
// login, push, pull, build & run
|
||||
func (s *DockerRegistrySuite) TestV1(c *check.C) {
|
||||
reg, err := newTestRegistry(c)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
v2Pings := 0
|
||||
reg.registerHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
|
||||
v2Pings++
|
||||
// V2 ping 404 causes fallback to v1
|
||||
w.WriteHeader(404)
|
||||
})
|
||||
|
||||
v1Pings := 0
|
||||
reg.registerHandler("/v1/_ping", func(w http.ResponseWriter, r *http.Request) {
|
||||
v1Pings++
|
||||
})
|
||||
|
||||
v1Logins := 0
|
||||
reg.registerHandler("/v1/users/", func(w http.ResponseWriter, r *http.Request) {
|
||||
v1Logins++
|
||||
})
|
||||
|
||||
v1Repo := 0
|
||||
reg.registerHandler("/v1/repositories/busybox/", func(w http.ResponseWriter, r *http.Request) {
|
||||
v1Repo++
|
||||
})
|
||||
|
||||
reg.registerHandler("/v1/repositories/busybox/images", func(w http.ResponseWriter, r *http.Request) {
|
||||
v1Repo++
|
||||
})
|
||||
|
||||
err = s.d.Start("--insecure-registry", reg.hostport, "--disable-legacy-registry=false")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.hostport))
|
||||
c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
|
||||
defer cleanup()
|
||||
|
||||
s.d.Cmd("build", "--file", dockerfileName, ".")
|
||||
c.Assert(v1Repo, check.Not(check.Equals), 0, check.Commentf("Expected v1 repository access after build"))
|
||||
|
||||
repoName := fmt.Sprintf("%s/busybox", reg.hostport)
|
||||
s.d.Cmd("run", repoName)
|
||||
c.Assert(v1Repo, check.Not(check.Equals), 1, check.Commentf("Expected v1 repository access after run"))
|
||||
|
||||
s.d.Cmd("login", "-u", "richard", "-p", "testtest", "-e", "testuser@testdomain.com", reg.hostport)
|
||||
c.Assert(v1Logins, check.Not(check.Equals), 0, check.Commentf("Expected v1 login attempt"))
|
||||
|
||||
s.d.Cmd("tag", "busybox", repoName)
|
||||
s.d.Cmd("push", repoName)
|
||||
|
||||
c.Assert(v1Repo, check.Equals, 2)
|
||||
c.Assert(v1Pings, check.Equals, 1)
|
||||
|
||||
s.d.Cmd("pull", repoName)
|
||||
c.Assert(v1Repo, check.Equals, 3, check.Commentf("Expected v1 repository access after pull"))
|
||||
}
|
||||
215
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_volume_driver_compat_unix_test.go
generated
vendored
Normal file
215
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_volume_driver_compat_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func init() {
|
||||
check.Suite(&DockerExternalVolumeSuiteCompatV1_1{
|
||||
ds: &DockerSuite{},
|
||||
})
|
||||
}
|
||||
|
||||
type DockerExternalVolumeSuiteCompatV1_1 struct {
|
||||
server *httptest.Server
|
||||
ds *DockerSuite
|
||||
d *Daemon
|
||||
ec *eventCounter
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuiteCompatV1_1) SetUpTest(c *check.C) {
|
||||
s.d = NewDaemon(c)
|
||||
s.ec = &eventCounter{}
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuiteCompatV1_1) TearDownTest(c *check.C) {
|
||||
s.d.Stop()
|
||||
s.ds.TearDownTest(c)
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuiteCompatV1_1) SetUpSuite(c *check.C) {
|
||||
mux := http.NewServeMux()
|
||||
s.server = httptest.NewServer(mux)
|
||||
|
||||
type pluginRequest struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type pluginResp struct {
|
||||
Mountpoint string `json:",omitempty"`
|
||||
Err string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type vol struct {
|
||||
Name string
|
||||
Mountpoint string
|
||||
}
|
||||
var volList []vol
|
||||
|
||||
read := func(b io.ReadCloser) (pluginRequest, error) {
|
||||
defer b.Close()
|
||||
var pr pluginRequest
|
||||
if err := json.NewDecoder(b).Decode(&pr); err != nil {
|
||||
return pr, err
|
||||
}
|
||||
return pr, nil
|
||||
}
|
||||
|
||||
send := func(w http.ResponseWriter, data interface{}) {
|
||||
switch t := data.(type) {
|
||||
case error:
|
||||
http.Error(w, t.Error(), 500)
|
||||
case string:
|
||||
w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
|
||||
fmt.Fprintln(w, t)
|
||||
default:
|
||||
w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
|
||||
json.NewEncoder(w).Encode(&data)
|
||||
}
|
||||
}
|
||||
|
||||
mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.activations++
|
||||
send(w, `{"Implements": ["VolumeDriver"]}`)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Create", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.creations++
|
||||
pr, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
volList = append(volList, vol{Name: pr.Name})
|
||||
send(w, nil)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Remove", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.removals++
|
||||
pr, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(hostVolumePath(pr.Name)); err != nil {
|
||||
send(w, &pluginResp{Err: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
for i, v := range volList {
|
||||
if v.Name == pr.Name {
|
||||
if err := os.RemoveAll(hostVolumePath(v.Name)); err != nil {
|
||||
send(w, fmt.Sprintf(`{"Err": "%v"}`, err))
|
||||
return
|
||||
}
|
||||
volList = append(volList[:i], volList[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
send(w, nil)
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Path", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.paths++
|
||||
|
||||
pr, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
p := hostVolumePath(pr.Name)
|
||||
send(w, &pluginResp{Mountpoint: p})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Mount", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.mounts++
|
||||
|
||||
pr, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := hostVolumePath(pr.Name)
|
||||
if err := os.MkdirAll(p, 0755); err != nil {
|
||||
send(w, &pluginResp{Err: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(p, "test"), []byte(s.server.URL), 0644); err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
send(w, &pluginResp{Mountpoint: p})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/VolumeDriver.Unmount", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.ec.unmounts++
|
||||
|
||||
_, err := read(r.Body)
|
||||
if err != nil {
|
||||
send(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
send(w, nil)
|
||||
})
|
||||
|
||||
err := os.MkdirAll("/etc/docker/plugins", 0755)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = ioutil.WriteFile("/etc/docker/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuiteCompatV1_1) TearDownSuite(c *check.C) {
|
||||
s.server.Close()
|
||||
|
||||
err := os.RemoveAll("/etc/docker/plugins")
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuiteCompatV1_1) TestExternalVolumeDriverCompatV1_1(c *check.C) {
|
||||
err := s.d.StartWithBusybox()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, err := s.d.Cmd("run", "--name=test", "-v", "foo:/bar", "--volume-driver", "test-external-volume-driver", "busybox", "sh", "-c", "echo hello > /bar/hello")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
out, err = s.d.Cmd("rm", "test")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
out, err = s.d.Cmd("run", "--name=test2", "-v", "foo:/bar", "busybox", "cat", "/bar/hello")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "hello")
|
||||
|
||||
err = s.d.Restart()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, err = s.d.Cmd("start", "-a", "test2")
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "hello")
|
||||
|
||||
out, err = s.d.Cmd("rm", "test2")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
out, err = s.d.Cmd("volume", "inspect", "foo")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
out, err = s.d.Cmd("volume", "rm", "foo")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
}
|
||||
95
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_wait_test.go
generated
vendored
Normal file
95
vendor/github.com/hyperhq/hypercli/integration-cli/skip/cli/hyper_cli_wait_test.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// non-blocking wait with 0 exit code
|
||||
func (s *DockerSuite) TestWaitNonBlockedExitZero(c *check.C) {
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "true")
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
err := waitInspect(containerID, "{{.State.Running}}", "false", 30*time.Second)
|
||||
c.Assert(err, checker.IsNil) //Container should have stopped by now
|
||||
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0", check.Commentf("failed to set up container, %v", out))
|
||||
|
||||
}
|
||||
|
||||
// blocking wait with 0 exit code
|
||||
func (s *DockerSuite) TestWaitBlockedExitZero(c *check.C) {
|
||||
// Windows busybox does not support trap in this way, not sleep with sub-second
|
||||
// granularity. It will always exit 0x40010004.
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "trap 'exit 0' TERM; while true; do usleep 10; done")
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
c.Assert(waitRun(containerID), checker.IsNil)
|
||||
|
||||
chWait := make(chan string)
|
||||
go func() {
|
||||
out, _, _ := runCommandWithOutput(exec.Command(dockerBinary, "wait", containerID))
|
||||
chWait <- out
|
||||
}()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
dockerCmd(c, "stop", containerID)
|
||||
|
||||
select {
|
||||
case status := <-chWait:
|
||||
c.Assert(strings.TrimSpace(status), checker.Equals, "0", check.Commentf("expected exit 0, got %s", status))
|
||||
case <-time.After(2 * time.Second):
|
||||
c.Fatal("timeout waiting for `docker wait` to exit")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// non-blocking wait with random exit code
|
||||
func (s *DockerSuite) TestWaitNonBlockedExitRandom(c *check.C) {
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "exit 99")
|
||||
containerID := strings.TrimSpace(out)
|
||||
|
||||
err := waitInspect(containerID, "{{.State.Running}}", "false", 30*time.Second)
|
||||
c.Assert(err, checker.IsNil) //Container should have stopped by now
|
||||
out, _ = dockerCmd(c, "wait", containerID)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "99", check.Commentf("failed to set up container, %v", out))
|
||||
|
||||
}
|
||||
|
||||
// blocking wait with random exit code
|
||||
func (s *DockerSuite) TestWaitBlockedExitRandom(c *check.C) {
|
||||
// Cannot run on Windows as trap in Windows busybox does not support trap in this way.
|
||||
testRequires(c, DaemonIsLinux)
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "trap 'exit 99' TERM; while true; do usleep 10; done")
|
||||
containerID := strings.TrimSpace(out)
|
||||
c.Assert(waitRun(containerID), checker.IsNil)
|
||||
|
||||
chWait := make(chan error)
|
||||
waitCmd := exec.Command(dockerBinary, "wait", containerID)
|
||||
waitCmdOut := bytes.NewBuffer(nil)
|
||||
waitCmd.Stdout = waitCmdOut
|
||||
c.Assert(waitCmd.Start(), checker.IsNil)
|
||||
go func() {
|
||||
chWait <- waitCmd.Wait()
|
||||
}()
|
||||
|
||||
dockerCmd(c, "stop", containerID)
|
||||
|
||||
select {
|
||||
case err := <-chWait:
|
||||
c.Assert(err, checker.IsNil)
|
||||
status, err := waitCmdOut.ReadString('\n')
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(strings.TrimSpace(status), checker.Equals, "99", check.Commentf("expected exit 99, got %s", status))
|
||||
case <-time.After(2 * time.Second):
|
||||
waitCmd.Process.Kill()
|
||||
c.Fatal("timeout waiting for `docker wait` to exit")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user