// #9981 - Allow a docker created volume (ie, one in /var/lib/docker/volumes) to be used to overwrite (via passing in Binds on api start) an existing volume func (s *DockerSuite) TestPostContainerBindNormalVolume(c *check.C) { testRequires(c, DaemonIsLinux) dockerCmd(c, "create", "-v", "/foo", "--name=one", "busybox") fooDir, err := inspectMountSourceField("one", "/foo") if err != nil { c.Fatal(err) } dockerCmd(c, "create", "-v", "/foo", "--name=two", "busybox") bindSpec := map[string][]string{"Binds": {fooDir + ":/foo"}} status, _, err := sockRequest("POST", "/containers/two/start", bindSpec) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusNoContent) fooDir2, err := inspectMountSourceField("two", "/foo") if err != nil { c.Fatal(err) } if fooDir2 != fooDir { c.Fatalf("expected volume path to be %s, got: %s", fooDir, fooDir2) } }
func (s *DockerSuite) TestBuildApiDoubleDockerfile(c *check.C) { testRequires(c, UnixCli) // dockerfile overwrites Dockerfile on Windows git, err := fakeGIT("repo", map[string]string{ "Dockerfile": `FROM busybox RUN echo from Dockerfile`, "dockerfile": `FROM busybox RUN echo from dockerfile`, }, false) if err != nil { c.Fatal(err) } 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(res.StatusCode, check.Equals, http.StatusOK) c.Assert(err, check.IsNil) buf, err := readBody(body) if err != nil { c.Fatal(err) } out := string(buf) if !strings.Contains(out, "from Dockerfile") { c.Fatalf("Incorrect output: %s", out) } }
// TestRunSeccompProfileDenyChmod checks that 'docker run --security-opt seccomp=/tmp/profile.json busybox chmod 400 /etc/hostname' exits with operation not permitted. func (s *DockerSuite) TestRunSeccompProfileDenyChmod(c *check.C) { testRequires(c, SameHostDaemon, seccompEnabled) jsonData := `{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "name": "chmod", "action": "SCMP_ACT_ERRNO" } ] }` tmpFile, err := ioutil.TempFile("", "profile.json") defer tmpFile.Close() if err != nil { c.Fatal(err) } if _, err := tmpFile.Write([]byte(jsonData)); err != nil { c.Fatal(err) } runCmd := exec.Command(dockerBinary, "run", "--security-opt", "seccomp="+tmpFile.Name(), "busybox", "chmod", "400", "/etc/hostname") out, _, _ := runCommandWithOutput(runCmd) if !strings.Contains(out, "Operation not permitted") { c.Fatalf("expected chmod with seccomp profile denied to fail, got %s", out) } }
// #6509 func (s *DockerSuite) TestRunRedirectStdout(c *check.C) { checkRedirect := func(command string) { _, 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.Start(), checker.IsNil) ch := make(chan error) go func() { ch <- cmd.Wait() close(ch) }() select { case <-time.After(10 * time.Second): c.Fatal("command timeout") case err := <-ch: c.Assert(err, checker.IsNil, check.Commentf("wait err")) } } checkRedirect(dockerBinary + " run -i busybox cat /etc/passwd | grep -q root") checkRedirect(dockerBinary + " run busybox cat /etc/passwd | grep -q root") }
func (s *DockerSuite) TestContainerApiVerifyHeader(c *check.C) { testRequires(c, DaemonIsLinux) config := map[string]interface{}{ "Image": "busybox", } create := func(ct string) (*http.Response, io.ReadCloser, error) { jsonData := bytes.NewBuffer(nil) if err := json.NewEncoder(jsonData).Encode(config); err != nil { c.Fatal(err) } return sockRequestRaw("POST", "/containers/create", jsonData, ct) } // Try with no content-type res, body, err := create("") c.Assert(err, check.IsNil) c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError) body.Close() // Try with wrong content-type res, body, err = create("application/xml") c.Assert(err, check.IsNil) c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError) body.Close() // now application/json res, body, err = create("application/json") c.Assert(err, check.IsNil) c.Assert(res.StatusCode, check.Equals, http.StatusCreated) body.Close() }
func UtilCreateNetworkMode(c *check.C, networkMode string) { config := map[string]interface{}{ "Image": "busybox", "HostConfig": map[string]interface{}{"NetworkMode": networkMode}, } status, body, err := sockRequest("POST", "/containers/create", config) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusCreated) var container types.ContainerCreateResponse if err := json.Unmarshal(body, &container); err != nil { c.Fatal(err) } status, body, err = sockRequest("GET", "/containers/"+container.ID+"/json", nil) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusOK) var containerJSON types.ContainerJSON if err := json.Unmarshal(body, &containerJSON); err != nil { c.Fatal(err) } if containerJSON.HostConfig.NetworkMode != runconfig.NetworkMode(networkMode) { c.Fatalf("Mismatched NetworkMode, Expected %s, Actual: %s ", networkMode, containerJSON.HostConfig.NetworkMode) } }
func (s *DockerSuite) TestContainerApiCommit(c *check.C) { testRequires(c, DaemonIsLinux) cName := "testapicommit" dockerCmd(c, "run", "--name="+cName, "busybox", "/bin/sh", "-c", "touch /test") name := "TestContainerApiCommit" status, b, err := sockRequest("POST", "/commit?repo="+name+"&testtag=tag&container="+cName, nil) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusCreated) type resp struct { ID string } var img resp if err := json.Unmarshal(b, &img); err != nil { c.Fatal(err) } cmd, err := inspectField(img.ID, "Config.Cmd") if err != nil { c.Fatal(err) } if cmd != "{[/bin/sh -c touch /test]}" { c.Fatalf("got wrong Cmd from commit: %q", cmd) } // sanity check, make sure the image is what we think it is dockerCmd(c, "run", img.ID, "ls", "/test") }
func (s *DockerSuite) TestContainerApiStartVolumeBinds(c *check.C) { testRequires(c, DaemonIsLinux) name := "testing" config := map[string]interface{}{ "Image": "busybox", "Volumes": map[string]struct{}{"/tmp": {}}, } status, _, err := sockRequest("POST", "/containers/create?name="+name, config) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusCreated) bindPath := randomTmpDirPath("test", daemonPlatform) config = map[string]interface{}{ "Binds": []string{bindPath + ":/tmp"}, } status, _, err = sockRequest("POST", "/containers/"+name+"/start", config) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusNoContent) pth, err := inspectMountSourceField(name, "/tmp") if err != nil { c.Fatal(err) } if pth != bindPath { c.Fatalf("expected volume host path to be %s, got %s", bindPath, pth) } }
func (s *DockerSuite) TestExecStopNotHanging(c *check.C) { // TODO Windows CI: Requires some extra work. Consider copying the // runSleepingContainer helper to have an exec version. testRequires(c, DaemonIsLinux) dockerCmd(c, "run", "-d", "--name", "testing", "busybox", "top") err := exec.Command(dockerBinary, "exec", "testing", "top").Start() c.Assert(err, checker.IsNil) type dstop struct { out []byte err error } ch := make(chan dstop) go func() { out, err := exec.Command(dockerBinary, "stop", "testing").CombinedOutput() ch <- dstop{out, err} close(ch) }() select { case <-time.After(3 * time.Second): c.Fatal("Container stop timed out") case s := <-ch: c.Assert(s.err, check.IsNil) } }
func (s *DockerSuite) TestExecTTYWithoutStdin(c *check.C) { out, _ := dockerCmd(c, "run", "-d", "-ti", "busybox") id := strings.TrimSpace(out) c.Assert(waitRun(id), checker.IsNil) errChan := make(chan error) go func() { defer close(errChan) cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true") if _, err := cmd.StdinPipe(); err != nil { errChan <- err return } expected := "the input device is not a TTY" if runtime.GOOS == "windows" { expected += ". If you are using mintty, try prefixing the command with 'winpty'" } if out, _, err := runCommandWithOutput(cmd); err == nil { errChan <- fmt.Errorf("exec should have failed") return } else if !strings.Contains(out, expected) { errChan <- fmt.Errorf("exec failed with error %q: expected %q", out, expected) return } }() select { case err := <-errChan: c.Assert(err, check.IsNil) case <-time.After(3 * time.Second): c.Fatal("exec is running but should have failed") } }
func (s *DockerSuite) TestLinksInspectLinksStopped(c *check.C) { var ( expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}} result []string ) dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top") dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top") dockerCmd(c, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true") links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links") if err != nil { c.Fatal(err) } err = unmarshalJSON([]byte(links), &result) if err != nil { c.Fatal(err) } output := convertSliceOfStringsToMap(result) equal := reflect.DeepEqual(output, expected) if !equal { c.Fatalf("Links %s, but expected %s", result, expected) } }
func (s *DockerSuite) TestPluginBasicOps(c *check.C) { testRequires(c, DaemonIsLinux, ExperimentalDaemon) _, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", pNameWithTag) c.Assert(err, checker.IsNil) out, _, err := dockerCmdWithError("plugin", "ls") c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, pName) c.Assert(out, checker.Contains, pTag) c.Assert(out, checker.Contains, "true") id, _, err := dockerCmdWithError("plugin", "inspect", "-f", "{{.Id}}", pNameWithTag) c.Assert(err, checker.IsNil) out, _, err = dockerCmdWithError("plugin", "remove", pNameWithTag) c.Assert(out, checker.Contains, "is enabled") _, _, err = dockerCmdWithError("plugin", "disable", pNameWithTag) c.Assert(err, checker.IsNil) out, _, err = dockerCmdWithError("plugin", "remove", pNameWithTag) c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, pNameWithTag) _, err = os.Stat(filepath.Join(dockerBasePath, "plugins", id)) if !os.IsNotExist(err) { c.Fatal(err) } }
func (s *DockerSuite) TestContainerApiCreate(c *check.C) { config := map[string]interface{}{ "Image": "busybox", "Cmd": []string{"/bin/sh", "-c", "touch /test && ls /test"}, } status, b, err := sockRequest("POST", "/containers/create", config) c.Assert(status, check.Equals, http.StatusCreated) c.Assert(err, check.IsNil) type createResp struct { Id string } var container createResp if err := json.Unmarshal(b, &container); err != nil { c.Fatal(err) } out, err := exec.Command(dockerBinary, "start", "-a", container.Id).CombinedOutput() if err != nil { c.Fatal(out, err) } if strings.TrimSpace(string(out)) != "/test" { c.Fatalf("expected output `/test`, got %q", out) } }
func (s *DockerSuite) TestContainerApiGetExport(c *check.C) { name := "exportcontainer" runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "touch", "/test") out, _, err := runCommandWithOutput(runCmd) if err != nil { c.Fatalf("Error on container creation: %v, output: %q", err, out) } status, body, err := sockRequest("GET", "/containers/"+name+"/export", nil) c.Assert(status, check.Equals, http.StatusOK) c.Assert(err, check.IsNil) found := false for tarReader := tar.NewReader(bytes.NewReader(body)); ; { h, err := tarReader.Next() if err != nil { if err == io.EOF { break } c.Fatal(err) } if h.Name == "test" { found = true break } } if !found { c.Fatalf("The created test file has not been found in the exported image") } }
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() if err := tw.WriteHeader(&tar.Header{ Name: "Dockerfile", Typeflag: tar.TypeSymlink, Linkname: "/etc/passwd", }); err != nil { c.Fatalf("failed to write tar file header: %v", err) } if err := tw.Close(); err != nil { c.Fatalf("failed to close tar archive: %v", err) } res, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar") c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError) c.Assert(err, check.IsNil) out, err := readBody(body) if err != nil { c.Fatal(err) } // 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. if !strings.Contains(string(out), "Cannot locate specified Dockerfile: Dockerfile") { c.Fatalf("Didn't complain about leaving build context: %s", out) } }
func (s *DockerSuite) TestContainerApiDeleteRemoveLinks(c *check.C) { testRequires(c, DaemonIsLinux) out, _ := dockerCmd(c, "run", "-d", "--name", "tlink1", "busybox", "top") id := strings.TrimSpace(out) c.Assert(waitRun(id), check.IsNil) out, _ = dockerCmd(c, "run", "--link", "tlink1:tlink1", "--name", "tlink2", "-d", "busybox", "top") id2 := strings.TrimSpace(out) c.Assert(waitRun(id2), check.IsNil) links, err := inspectFieldJSON(id2, "HostConfig.Links") c.Assert(err, check.IsNil) if links != "[\"/tlink1:/tlink2/tlink1\"]" { c.Fatal("expected to have links between containers") } status, _, err := sockRequest("DELETE", "/containers/tlink2/tlink1?link=1", nil) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusNoContent) linksPostRm, err := inspectFieldJSON(id2, "HostConfig.Links") c.Assert(err, check.IsNil) if linksPostRm != "null" { c.Fatal("call to api deleteContainer links should have removed the specified links") } }
func (s *DockerSuite) TestContainerApiGetExport(c *check.C) { testRequires(c, DaemonIsLinux) name := "exportcontainer" dockerCmd(c, "run", "--name", name, "busybox", "touch", "/test") status, body, err := sockRequest("GET", "/containers/"+name+"/export", nil) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusOK) found := false for tarReader := tar.NewReader(bytes.NewReader(body)); ; { h, err := tarReader.Next() if err != nil { if err == io.EOF { break } c.Fatal(err) } if h.Name == "test" { found = true break } } if !found { c.Fatalf("The created test file has not been found in the exported image") } }
func (s *DockerSuite) TestExecInteractive(c *check.C) { testRequires(c, DaemonIsLinux) dockerCmd(c, "run", "-d", "--name", "testing", "busybox", "sh", "-c", "echo test > /tmp/file && top") execCmd := exec.Command(dockerBinary, "exec", "-i", "testing", "sh") stdin, err := execCmd.StdinPipe() c.Assert(err, checker.IsNil) stdout, err := execCmd.StdoutPipe() c.Assert(err, checker.IsNil) err = execCmd.Start() c.Assert(err, checker.IsNil) _, err = stdin.Write([]byte("cat /tmp/file\n")) c.Assert(err, checker.IsNil) r := bufio.NewReader(stdout) line, err := r.ReadString('\n') c.Assert(err, checker.IsNil) line = strings.TrimSpace(line) c.Assert(line, checker.Equals, "test") err = stdin.Close() c.Assert(err, checker.IsNil) errChan := make(chan error) go func() { errChan <- execCmd.Wait() close(errChan) }() select { case err := <-errChan: c.Assert(err, checker.IsNil) case <-time.After(1 * time.Second): c.Fatal("docker exec failed to exit on stdin close") } }
func (s *DockerSuite) TestCreateByImageID(c *check.C) { imageName := "testcreatebyimageid" imageID, err := buildImage(imageName, `FROM busybox MAINTAINER dockerio`, true) if err != nil { c.Fatal(err) } truncatedImageID := stringid.TruncateID(imageID) dockerCmd(c, "create", imageID) dockerCmd(c, "create", truncatedImageID) dockerCmd(c, "create", fmt.Sprintf("%s:%s", imageName, truncatedImageID)) // Ensure this fails out, exit, _ := dockerCmdWithError("create", fmt.Sprintf("%s:%s", imageName, imageID)) if exit == 0 { c.Fatalf("expected non-zero exit code; received %d", exit) } if expected := "Error parsing reference"; !strings.Contains(out, expected) { c.Fatalf(`Expected %q in output; got: %s`, expected, out) } out, exit, _ = dockerCmdWithError("create", fmt.Sprintf("%s:%s", "wrongimage", truncatedImageID)) if exit == 0 { c.Fatalf("expected non-zero exit code; received %d", exit) } if expected := "Unable to find image"; !strings.Contains(out, expected) { c.Fatalf(`Expected %q in output; got: %s`, expected, out) } }
func (s *DockerSuite) TestExecTtyWithoutStdin(c *check.C) { out, _ := dockerCmd(c, "run", "-d", "-ti", "busybox") id := strings.TrimSpace(out) if err := waitRun(id); err != nil { c.Fatal(err) } errChan := make(chan error) go func() { defer close(errChan) cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true") if _, err := cmd.StdinPipe(); err != nil { errChan <- err return } expected := "cannot enable tty mode" if out, _, err := runCommandWithOutput(cmd); err == nil { errChan <- fmt.Errorf("exec should have failed") return } else if !strings.Contains(out, expected) { errChan <- fmt.Errorf("exec failed with error %q: expected %q", out, expected) return } }() select { case err := <-errChan: c.Assert(err, check.IsNil) case <-time.After(3 * time.Second): c.Fatal("exec is running but should have failed") } }
func (s *DockerSuite) TestContainerApiCreateWithDomainName(c *check.C) { testRequires(c, DaemonIsLinux) domainName := "test-domain" config := map[string]interface{}{ "Image": "busybox", "Domainname": domainName, } status, body, err := sockRequest("POST", "/containers/create", config) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusCreated) var container types.ContainerCreateResponse if err := json.Unmarshal(body, &container); err != nil { c.Fatal(err) } status, body, err = sockRequest("GET", "/containers/"+container.ID+"/json", nil) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusOK) var containerJSON types.ContainerJSON if err := json.Unmarshal(body, &containerJSON); err != nil { c.Fatal(err) } if containerJSON.Config.Domainname != domainName { c.Fatalf("Mismatched Domainname, Expected %s, Actual: %s ", domainName, containerJSON.Config.Domainname) } }
func (s *DockerSuite) TestExecStopNotHanging(c *check.C) { dockerCmd(c, "run", "-d", "--name", "testing", "busybox", "top") if err := exec.Command(dockerBinary, "exec", "testing", "top").Start(); err != nil { c.Fatal(err) } type dstop struct { out []byte err error } ch := make(chan dstop) go func() { out, err := exec.Command(dockerBinary, "stop", "testing").CombinedOutput() ch <- dstop{out, err} close(ch) }() select { case <-time.After(3 * time.Second): c.Fatal("Container stop timed out") case s := <-ch: c.Assert(s.err, check.IsNil) } }
func (s *DockerSuite) TestContainerApiCreateWithCpuSharesCpuset(c *check.C) { testRequires(c, DaemonIsLinux) config := map[string]interface{}{ "Image": "busybox", "CpuShares": 512, "CpusetCpus": "0,1", } status, body, err := sockRequest("POST", "/containers/create", config) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusCreated) var container types.ContainerCreateResponse if err := json.Unmarshal(body, &container); err != nil { c.Fatal(err) } status, body, err = sockRequest("GET", "/containers/"+container.ID+"/json", nil) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusOK) var containerJSON types.ContainerJSON c.Assert(json.Unmarshal(body, &containerJSON), check.IsNil) out, err := inspectField(containerJSON.ID, "HostConfig.CpuShares") c.Assert(err, check.IsNil) c.Assert(out, check.Equals, "512") outCpuset, errCpuset := inspectField(containerJSON.ID, "HostConfig.CpusetCpus") c.Assert(errCpuset, check.IsNil, check.Commentf("Output: %s", outCpuset)) c.Assert(outCpuset, check.Equals, "0,1") }
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") }
// Issue 7941 - test to make sure a "null" in JSON is just ignored. // W/o this fix a null in JSON would be parsed into a string var as "null" func (s *DockerSuite) TestContainerApiPostCreateNull(c *check.C) { testRequires(c, DaemonIsLinux) config := `{ "Hostname":"", "Domainname":"", "Memory":0, "MemorySwap":0, "CpuShares":0, "Cpuset":null, "AttachStdin":true, "AttachStdout":true, "AttachStderr":true, "ExposedPorts":{}, "Tty":true, "OpenStdin":true, "StdinOnce":true, "Env":[], "Cmd":"ls", "Image":"busybox", "Volumes":{}, "WorkingDir":"", "Entrypoint":null, "NetworkDisabled":false, "OnBuild":null}` res, body, err := sockRequestRaw("POST", "/containers/create", strings.NewReader(config), "application/json") c.Assert(err, check.IsNil) c.Assert(res.StatusCode, check.Equals, http.StatusCreated) b, err := readBody(body) if err != nil { c.Fatal(err) } type createResp struct { ID string } var container createResp if err := json.Unmarshal(b, &container); err != nil { c.Fatal(err) } out, err := inspectField(container.ID, "HostConfig.CpusetCpus") if err != nil { c.Fatal(err, out) } if out != "" { c.Fatalf("expected empty string, got %q", out) } outMemory, errMemory := inspectField(container.ID, "HostConfig.Memory") c.Assert(outMemory, check.Equals, "0") if errMemory != nil { c.Fatal(errMemory, outMemory) } outMemorySwap, errMemorySwap := inspectField(container.ID, "HostConfig.MemorySwap") c.Assert(outMemorySwap, check.Equals, "0") if errMemorySwap != nil { c.Fatal(errMemorySwap, outMemorySwap) } }
// 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", "*****@*****.**", reg.hostport) s.d.Cmd("tag", "busybox", repoName) s.d.Cmd("push", repoName) s.d.Cmd("pull", repoName) }
// TestRunSeccompProfileDenyUnshare checks that 'docker run --security-opt seccomp=/tmp/profile.json debian:jessie unshare' exits with operation not permitted. func (s *DockerSuite) TestRunSeccompProfileDenyUnshare(c *check.C) { testRequires(c, SameHostDaemon, seccompEnabled, NotArm, Apparmor) jsonData := `{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "name": "unshare", "action": "SCMP_ACT_ERRNO" } ] }` tmpFile, err := ioutil.TempFile("", "profile.json") defer tmpFile.Close() if err != nil { c.Fatal(err) } if _, err := tmpFile.Write([]byte(jsonData)); err != nil { c.Fatal(err) } runCmd := exec.Command(dockerBinary, "run", "--security-opt", "apparmor=unconfined", "--security-opt", "seccomp="+tmpFile.Name(), "debian:jessie", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc") out, _, _ := runCommandWithOutput(runCmd) if !strings.Contains(out, "Operation not permitted") { c.Fatalf("expected unshare with seccomp profile denied to fail, got %s", out) } }
func (s *DockerSuite) TestContainerApiCopy(c *check.C) { testRequires(c, DaemonIsLinux) name := "test-container-api-copy" dockerCmd(c, "run", "--name", name, "busybox", "touch", "/test.txt") postData := types.CopyConfig{ Resource: "/test.txt", } status, body, err := sockRequest("POST", "/containers/"+name+"/copy", postData) c.Assert(err, check.IsNil) c.Assert(status, check.Equals, http.StatusOK) found := false for tarReader := tar.NewReader(bytes.NewReader(body)); ; { h, err := tarReader.Next() if err != nil { if err == io.EOF { break } c.Fatal(err) } if h.Name == "test.txt" { found = true break } } c.Assert(found, check.Equals, true) }
// TestRunSeccompProfileDenyUnshareUserns checks that 'docker run debian:jessie unshare --map-root-user --user sh -c whoami' with a specific profile to // deny unhare of a userns exits with operation not permitted. func (s *DockerSuite) TestRunSeccompProfileDenyUnshareUserns(c *check.C) { testRequires(c, SameHostDaemon, seccompEnabled, NotArm, Apparmor) // from sched.h jsonData := fmt.Sprintf(`{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "name": "unshare", "action": "SCMP_ACT_ERRNO", "args": [ { "index": 0, "value": %d, "op": "SCMP_CMP_EQ" } ] } ] }`, uint64(0x10000000)) tmpFile, err := ioutil.TempFile("", "profile.json") defer tmpFile.Close() if err != nil { c.Fatal(err) } if _, err := tmpFile.Write([]byte(jsonData)); err != nil { c.Fatal(err) } runCmd := exec.Command(dockerBinary, "run", "--security-opt", "apparmor=unconfined", "--security-opt", "seccomp="+tmpFile.Name(), "debian:jessie", "unshare", "--map-root-user", "--user", "sh", "-c", "whoami") out, _, _ := runCommandWithOutput(runCmd) if !strings.Contains(out, "Operation not permitted") { c.Fatalf("expected unshare userns with seccomp profile denied to fail, got %s", out) } }
func (s *DockerSuite) TestBuildApiDockerFileRemote(c *check.C) { server, err := fakeStorage(map[string]string{ "testD": `FROM busybox COPY * /tmp/ RUN find / -name ba* RUN find /tmp/`, }) if err != nil { c.Fatal(err) } defer server.Close() res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json") c.Assert(res.StatusCode, check.Equals, http.StatusOK) c.Assert(err, check.IsNil) buf, err := readBody(body) if err != nil { c.Fatal(err) } // Make sure Dockerfile exists. // Make sure 'baz' doesn't exist ANYWHERE despite being mentioned in the URL out := string(buf) if !strings.Contains(out, "/tmp/Dockerfile") || strings.Contains(out, "baz") { c.Fatalf("Incorrect output: %s", out) } }