// #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 *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 *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *check.C) {
	testRequires(c, DaemonIsLinux)

	c1 := struct {
		Image      string
		CpusetCpus string
	}{"busybox", "1-42,,"}
	name := "wrong-cpuset-cpus"
	status, body, err := sockRequest("POST", "/containers/create?name="+name, c1)
	c.Assert(err, check.IsNil)
	c.Assert(status, check.Equals, http.StatusInternalServerError)
	expected := "Invalid value 1-42,, for cpuset cpus.\n"
	c.Assert(string(body), check.Equals, expected, check.Commentf("Expected output to contain %q, got %q", expected, string(body)))

	c2 := struct {
		Image      string
		CpusetMems string
	}{"busybox", "42-3,1--"}
	name = "wrong-cpuset-mems"
	status, body, err = sockRequest("POST", "/containers/create?name="+name, c2)
	c.Assert(err, check.IsNil)
	c.Assert(status, check.Equals, http.StatusInternalServerError)
	expected = "Invalid value 42-3,1-- for cpuset mems.\n"
	c.Assert(string(body), check.Equals, expected, check.Commentf("Expected output to contain %q, got %q", expected, string(body)))
}
func (s *DockerSuite) TestEventsLimit(c *check.C) {
	// Limit to 8 goroutines creating containers in order to prevent timeouts
	// creating so many containers simultaneously on Windows
	sem := make(chan bool, 8)
	numContainers := 17
	errChan := make(chan error, numContainers)

	args := []string{"run", "--rm", "busybox", "true"}
	for i := 0; i < numContainers; i++ {
		sem <- true
		go func() {
			defer func() { <-sem }()
			out, err := exec.Command(dockerBinary, args...).CombinedOutput()
			if err != nil {
				err = fmt.Errorf("%v: %s", err, string(out))
			}
			errChan <- err
		}()
	}

	// Wait for all goroutines to finish
	for i := 0; i < cap(sem); i++ {
		sem <- true
	}
	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", "--until", daemonUnixTime(c))
	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) TestEventsAttach(c *check.C) {
	// TODO Windows CI: Figure out why this test fails intermittently (TP5).
	testRequires(c, DaemonIsLinux)

	out, _ := dockerCmd(c, "run", "-di", "busybox", "cat")
	cID := strings.TrimSpace(out)
	c.Assert(waitRun(cID), checker.IsNil)

	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)
	c.Assert(waitExited(cID, 5*time.Second), checker.IsNil)

	until := daemonUnixTime(c)
	out, _ = dockerCmd(c, "events", "-f", "container="+cID, "--until="+until)
	c.Assert(out, checker.Contains, "attach", check.Commentf("Missing 'attach' log event"))
}
func (s *DockerSuite) TestEventsFilterImageLabels(c *check.C) {
	since := daemonUnixTime(c)
	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",
		"--since", since,
		"--until", daemonUnixTime(c),
		"--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) TestEventsPluginOps(c *check.C) {
	testRequires(c, DaemonIsLinux, ExperimentalDaemon)

	pluginName := "tiborvass/no-remove:latest"
	since := daemonUnixTime(c)

	dockerCmd(c, "plugin", "install", pluginName, "--grant-all-permissions")
	dockerCmd(c, "plugin", "disable", pluginName)
	dockerCmd(c, "plugin", "remove", pluginName)

	out, _ := dockerCmd(c, "events", "--since", since, "--until", daemonUnixTime(c))
	events := strings.Split(out, "\n")
	events = events[:len(events)-1]

	nEvents := len(events)
	c.Assert(nEvents, checker.GreaterOrEqualThan, 4)

	pluginEvents := eventActionsByIDAndType(c, events, pluginName, "plugin")
	c.Assert(pluginEvents, checker.HasLen, 4, check.Commentf("events: %v", events))

	c.Assert(pluginEvents[0], checker.Equals, "pull", check.Commentf(out))
	c.Assert(pluginEvents[1], checker.Equals, "enable", check.Commentf(out))
	c.Assert(pluginEvents[2], checker.Equals, "disable", check.Commentf(out))
	c.Assert(pluginEvents[3], checker.Equals, "remove", check.Commentf(out))
}
func (s *DockerSuite) TestExecWithPrivileged(c *check.C) {
	// Not applicable on Windows
	testRequires(c, DaemonIsLinux, NotUserNamespace)
	// Start main loop which attempts mknod repeatedly
	dockerCmd(c, "run", "-d", "--name", "parent", "--cap-drop=ALL", "busybox", "sh", "-c", `while (true); do if [ -e /exec_priv ]; then cat /exec_priv && mknod /tmp/sda b 8 0 && echo "Success"; else echo "Privileged exec has not run yet"; fi; usleep 10000; done`)

	// Check exec mknod doesn't work
	cmd := exec.Command(dockerBinary, "exec", "parent", "sh", "-c", "mknod /tmp/sdb b 8 16")
	out, _, err := runCommandWithOutput(cmd)
	c.Assert(err, checker.NotNil, check.Commentf("exec mknod in --cap-drop=ALL container without --privileged should fail"))
	c.Assert(out, checker.Contains, "Operation not permitted", check.Commentf("exec mknod in --cap-drop=ALL container without --privileged should fail"))

	// Check exec mknod does work with --privileged
	cmd = exec.Command(dockerBinary, "exec", "--privileged", "parent", "sh", "-c", `echo "Running exec --privileged" > /exec_priv && mknod /tmp/sdb b 8 16 && usleep 50000 && echo "Finished exec --privileged" > /exec_priv && echo ok`)
	out, _, err = runCommandWithOutput(cmd)
	c.Assert(err, checker.IsNil)

	actual := strings.TrimSpace(out)
	c.Assert(actual, checker.Equals, "ok", check.Commentf("exec mknod in --cap-drop=ALL container with --privileged failed, output: %q", out))

	// Check subsequent unprivileged exec cannot mknod
	cmd = exec.Command(dockerBinary, "exec", "parent", "sh", "-c", "mknod /tmp/sdc b 8 32")
	out, _, err = runCommandWithOutput(cmd)
	c.Assert(err, checker.NotNil, check.Commentf("repeating exec mknod in --cap-drop=ALL container after --privileged without --privileged should fail"))
	c.Assert(out, checker.Contains, "Operation not permitted", check.Commentf("repeating exec mknod in --cap-drop=ALL container after --privileged without --privileged should fail"))

	// Confirm at no point was mknod allowed
	logCmd := exec.Command(dockerBinary, "logs", "parent")
	out, _, err = runCommandWithOutput(logCmd)
	c.Assert(err, checker.IsNil)
	c.Assert(out, checker.Not(checker.Contains), "Success")

}
func (s *DockerSuite) TestEventsAttach(c *check.C) {
	testRequires(c, DaemonIsLinux)
	since := daemonTime(c).Unix()

	out, _ := dockerCmd(c, "run", "-di", "busybox", "/bin/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, "stop", cID)

	out, _ = dockerCmd(c, "events", "--since=0", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
	c.Assert(out, checker.Contains, " attach\n", check.Commentf("Missing 'attach' log event"))
}
func (s *DockerSuite) TestEventsTimestampFormats(c *check.C) {
	testRequires(c, DaemonIsLinux)
	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) TestContainerApiTop(c *check.C) {
	// Problematic on Windows as Windows does not support top
	testRequires(c, DaemonIsLinux)
	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "top")
	id := strings.TrimSpace(string(out))
	c.Assert(waitRun(id), checker.IsNil)

	type topResp struct {
		Titles    []string
		Processes [][]string
	}
	var top topResp
	status, b, err := sockRequest("GET", "/containers/"+id+"/top?ps_args=aux", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(json.Unmarshal(b, &top), checker.IsNil)
	c.Assert(top.Titles, checker.HasLen, 11, check.Commentf("expected 11 titles, found %d: %v", len(top.Titles), top.Titles))

	if top.Titles[0] != "USER" || top.Titles[10] != "COMMAND" {
		c.Fatalf("expected `USER` at `Titles[0]` and `COMMAND` at Titles[10]: %v", top.Titles)
	}
	c.Assert(top.Processes, checker.HasLen, 2, check.Commentf("expected 2 processes, found %d: %v", len(top.Processes), top.Processes))
	c.Assert(top.Processes[0][10], checker.Equals, "/bin/sh -c top")
	c.Assert(top.Processes[1][10], checker.Equals, "top")
}
func (s *DockerSuite) TestContainerApiPause(c *check.C) {
	// Problematic on Windows as Windows does not support pause
	testRequires(c, DaemonIsLinux)
	defer unpauseAllContainers()
	out, _ := dockerCmd(c, "run", "-d", "busybox", "sleep", "30")
	ContainerID := strings.TrimSpace(out)

	status, _, err := sockRequest("POST", "/containers/"+ContainerID+"/pause", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusNoContent)

	pausedContainers, err := getSliceOfPausedContainers()
	c.Assert(err, checker.IsNil, check.Commentf("error thrown while checking if containers were paused"))

	if len(pausedContainers) != 1 || stringid.TruncateID(ContainerID) != pausedContainers[0] {
		c.Fatalf("there should be one paused container and not %d", len(pausedContainers))
	}

	status, _, err = sockRequest("POST", "/containers/"+ContainerID+"/unpause", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusNoContent)

	pausedContainers, err = getSliceOfPausedContainers()
	c.Assert(err, checker.IsNil, check.Commentf("error thrown while checking if containers were paused"))
	c.Assert(pausedContainers, checker.IsNil, check.Commentf("There should be no paused container."))
}
func (s *DockerSuite) TestContainerApiGetChanges(c *check.C) {
	// Not supported on Windows as Windows does not support docker diff (/containers/name/changes)
	testRequires(c, DaemonIsLinux)
	name := "changescontainer"
	dockerCmd(c, "run", "--name", name, "busybox", "rm", "/etc/passwd")

	status, body, err := sockRequest("GET", "/containers/"+name+"/changes", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusOK)

	changes := []struct {
		Kind int
		Path string
	}{}
	c.Assert(json.Unmarshal(body, &changes), checker.IsNil, check.Commentf("unable to unmarshal response body"))

	// Check the changelog for removal of /etc/passwd
	success := false
	for _, elem := range changes {
		if elem.Path == "/etc/passwd" && elem.Kind == 2 {
			success = true
		}
	}
	c.Assert(success, checker.True, check.Commentf("/etc/passwd has been removed but is not present in the diff"))
}
func (s *DockerSwarmSuite) TestPsListContainersFilterIsTask(c *check.C) {
	d := s.AddDaemon(c, true, true)

	// Create a bare container
	out, err := d.Cmd("run", "-d", "--name=bare-container", "busybox", "top")
	c.Assert(err, checker.IsNil)
	bareID := strings.TrimSpace(out)[:12]
	// Create a service
	name := "busybox-top"
	out, err = d.Cmd("service", "create", "--name", name, "busybox", "top")
	c.Assert(err, checker.IsNil)
	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")

	// make sure task has been deployed.
	waitAndAssert(c, defaultReconciliationTimeout, d.checkServiceRunningTasks(c, name), checker.Equals, 1)

	// Filter non-tasks
	out, err = d.Cmd("ps", "-a", "-q", "--filter=is-task=false")
	c.Assert(err, checker.IsNil)
	psOut := strings.TrimSpace(out)
	c.Assert(psOut, checker.Equals, bareID, check.Commentf("Expected id %s, got %s for is-task label, output %q", bareID, psOut, out))

	// Filter tasks
	out, err = d.Cmd("ps", "-a", "-q", "--filter=is-task=true")
	c.Assert(err, checker.IsNil)
	lines := strings.Split(strings.Trim(out, "\n "), "\n")
	c.Assert(lines, checker.HasLen, 1)
	c.Assert(lines[0], checker.Not(checker.Equals), bareID, check.Commentf("Expected not %s, but got it for is-task label, output %q", bareID, out))
}
Exemple #15
0
// TestPullAllTagsFromCentralRegistry pulls using `all-tags` for a given image and verifies that it
// results in more images than a naked pull.
func (s *DockerHubPullSuite) TestPullAllTagsFromCentralRegistry(c *check.C) {
	testRequires(c, DaemonIsLinux)
	s.Cmd(c, "pull", "busybox")
	outImageCmd := s.Cmd(c, "images", "busybox")
	splitOutImageCmd := strings.Split(strings.TrimSpace(outImageCmd), "\n")
	c.Assert(splitOutImageCmd, checker.HasLen, 2, check.Commentf("expected a single entry in images\n%v", outImageCmd))

	s.Cmd(c, "pull", "--all-tags=true", "busybox")
	outImageAllTagCmd := s.Cmd(c, "images", "busybox")
	if linesCount := strings.Count(outImageAllTagCmd, "\n"); linesCount <= 2 {
		c.Fatalf("pulling all tags should provide more images, got %d", linesCount-1)
	}

	// Verify that the line for 'busybox:latest' is left unchanged.
	var latestLine string
	for _, line := range strings.Split(outImageAllTagCmd, "\n") {
		if strings.HasPrefix(line, "busybox") && strings.Contains(line, "latest") {
			latestLine = line
			break
		}
	}
	c.Assert(latestLine, checker.Not(checker.Equals), "", check.Commentf("no entry for busybox:latest found after pulling all tags"))
	splitLatest := strings.Fields(latestLine)
	splitCurrent := strings.Fields(splitOutImageCmd[1])
	c.Assert(splitLatest, checker.DeepEquals, splitCurrent, check.Commentf("busybox:latest was changed after pulling all tags"))
}
Exemple #16
0
// NewDaemon returns a Daemon instance to be used for testing.
// This will create a directory such as d123456789 in the folder specified by $DEST.
// The daemon will not automatically start.
func NewDaemon(c *check.C) *Daemon {
	dest := os.Getenv("DEST")
	c.Assert(dest, check.Not(check.Equals), "", check.Commentf("Please set the DEST environment variable"))

	id := fmt.Sprintf("d%d", time.Now().UnixNano()%100000000)
	dir := filepath.Join(dest, id)
	daemonFolder, err := filepath.Abs(dir)
	c.Assert(err, check.IsNil, check.Commentf("Could not make %q an absolute path", dir))
	daemonRoot := filepath.Join(daemonFolder, "root")

	c.Assert(os.MkdirAll(daemonRoot, 0755), check.IsNil, check.Commentf("Could not create daemon root %q", dir))

	userlandProxy := true
	if env := os.Getenv("DOCKER_USERLANDPROXY"); env != "" {
		if val, err := strconv.ParseBool(env); err != nil {
			userlandProxy = val
		}
	}

	return &Daemon{
		Command:       "daemon",
		id:            id,
		c:             c,
		folder:        daemonFolder,
		root:          daemonRoot,
		storageDriver: os.Getenv("DOCKER_GRAPHDRIVER"),
		userlandProxy: userlandProxy,
	}
}
func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) {
	// macvlan bridge mode -  empty parent interface containers can reach each other internally but not externally
	testRequires(c, DaemonIsLinux, MacvlanKernelSupport, NotUserNamespace, NotArm)
	netName := "dm-subinterface"
	out, err := createMasterDummy(c, "dm-dummy0")
	c.Assert(err, check.IsNil, check.Commentf(out))
	out, err = createVlanInterface(c, "dm-dummy0", "dm-dummy0.20", "20")
	c.Assert(err, check.IsNil, check.Commentf(out))
	// create a network using an existing parent interface
	dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.20", netName)
	assertNwIsAvailable(c, netName)

	// start containers on 802.1q tagged '-o parent' sub-interface
	dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=first", "busybox", "top")
	c.Assert(waitRun("first"), check.IsNil)
	dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=second", "busybox", "top")
	c.Assert(waitRun("second"), check.IsNil)
	// verify containers can communicate
	_, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
	c.Assert(err, check.IsNil)

	// remove the containers
	dockerCmd(c, "rm", "-f", "first")
	dockerCmd(c, "rm", "-f", "second")
	// delete the network while preserving the parent link
	dockerCmd(c, "network", "rm", netName)
	assertNwNotAvailable(c, netName)
	// verify the network delete did not delete the predefined sub-interface
	out, err = linkExists(c, "dm-dummy0.20")
	c.Assert(err, check.IsNil, check.Commentf(out))
	// delete the parent interface which also collects the slave
	deleteInterface(c, "dm-dummy0")
	c.Assert(err, check.IsNil, check.Commentf(out))
}
func (s *DockerSuite) TestEventsLimit(c *check.C) {
	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) TestCreateWithLargePortRange(c *check.C) {
	out, _ := dockerCmd(c, "create", "-p", "1-65535:1-65535/tcp", "busybox", "echo")

	cleanedContainerID := strings.TrimSpace(out)

	out, _ = dockerCmd(c, "inspect", cleanedContainerID)

	containers := []struct {
		HostConfig *struct {
			PortBindings map[nat.Port][]nat.PortBinding
		}
	}{}

	err := json.Unmarshal([]byte(out), &containers)
	c.Assert(err, check.IsNil, check.Commentf("Error inspecting the container: %s", err))
	c.Assert(containers, checker.HasLen, 1)

	cont := containers[0]
	c.Assert(cont.HostConfig, check.NotNil, check.Commentf("Expected HostConfig, got none"))
	c.Assert(cont.HostConfig.PortBindings, checker.HasLen, 65535)

	for k, v := range cont.HostConfig.PortBindings {
		c.Assert(v, checker.HasLen, 1)
		c.Assert(k.Port(), checker.Equals, v[0].HostPort, check.Commentf("Expected host port %s to match published port %s", k.Port(), v[0].HostPort))
	}

}
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, err := inspectField(imageReference, "Id")
	c.Assert(err, checker.IsNil, check.Commentf("error getting image 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, err := inspectField(name, "Config.Image")
	c.Assert(err, checker.IsNil)
	// make sure they match
	c.Assert(res, checker.Equals, imageID)
}
func (s *DockerSuite) TestEventsFilterImageName(c *check.C) {
	since := daemonUnixTime(c)

	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", "--since", since, "--until", daemonUnixTime(c), "--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 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 (s *DockerSuite) TestEventsCopy(c *check.C) {
	// 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())

	until := daemonUnixTime(c)
	out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=cptest", "--until="+until)
	c.Assert(out, checker.Contains, "archive-path", check.Commentf("Missing 'archive-path' log event\n"))

	dockerCmd(c, "cp", tempFile.Name(), "cptest:/filecopy")

	until = daemonUnixTime(c)
	out, _ = dockerCmd(c, "events", "-f", "container=cptest", "--until="+until)
	c.Assert(out, checker.Contains, "extract-to-dir", check.Commentf("Missing 'extract-to-dir' log event"))
}
func (s *DockerSwarmSuite) TestServiceCreateMountVolume(c *check.C) {
	d := s.AddDaemon(c, true, true)
	out, err := d.Cmd("service", "create", "--mount", "type=volume,source=foo,target=/foo", "busybox", "top")
	c.Assert(err, checker.IsNil, check.Commentf(out))
	id := strings.TrimSpace(out)

	var tasks []swarm.Task
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		tasks = d.getServiceTasks(c, id)
		return len(tasks) > 0, nil
	}, checker.Equals, true)

	task := tasks[0]
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		if task.NodeID == "" || task.Status.ContainerStatus.ContainerID == "" {
			task = d.getTask(c, task.ID)
		}
		return task.NodeID != "" && task.Status.ContainerStatus.ContainerID != "", nil
	}, checker.Equals, true)

	out, err = s.nodeCmd(c, task.NodeID, "inspect", "--format", "{{json .Mounts}}", task.Status.ContainerStatus.ContainerID)
	c.Assert(err, checker.IsNil, check.Commentf(out))

	var mounts []types.MountPoint
	c.Assert(json.Unmarshal([]byte(out), &mounts), checker.IsNil)
	c.Assert(mounts, checker.HasLen, 1)

	c.Assert(mounts[0].Name, checker.Equals, "foo")
	c.Assert(mounts[0].Destination, checker.Equals, "/foo")
	c.Assert(mounts[0].RW, checker.Equals, true)
}
// #25798
func (s *DockerSuite) TestEventsSpecialFiltersWithExecCreate(c *check.C) {
	since := daemonUnixTime(c)
	runSleepingContainer(c, "--name", "test-container", "-d")
	waitRun("test-container")

	dockerCmd(c, "exec", "test-container", "echo", "hello-world")

	out, _ := dockerCmd(
		c,
		"events",
		"--since", since,
		"--until", daemonUnixTime(c),
		"--filter",
		"event='exec_create: echo hello-world'",
	)

	events := strings.Split(strings.TrimSpace(out), "\n")
	c.Assert(len(events), checker.Equals, 1, check.Commentf(out))

	out, _ = dockerCmd(
		c,
		"events",
		"--since", since,
		"--until", daemonUnixTime(c),
		"--filter",
		"event=exec_create",
	)
	c.Assert(len(events), checker.Equals, 1, check.Commentf(out))
}
func (s *DockerSuite) TestLogsSince(c *check.C) {
	name := "testlogssince"
	dockerCmd(c, "run", "--name="+name, "busybox", "/bin/sh", "-c", "for i in $(seq 1 3); do sleep 2; echo log$i; done")
	out, _ := dockerCmd(c, "logs", "-t", name)

	log2Line := strings.Split(strings.Split(out, "\n")[1], " ")
	t, err := time.Parse(time.RFC3339Nano, log2Line[0]) // the timestamp log2 is written
	c.Assert(err, checker.IsNil)
	since := t.Unix() + 1 // add 1s so log1 & log2 doesn't show up
	out, _ = dockerCmd(c, "logs", "-t", fmt.Sprintf("--since=%v", since), name)

	// Skip 2 seconds
	unexpected := []string{"log1", "log2"}
	for _, v := range unexpected {
		c.Assert(out, checker.Not(checker.Contains), v, check.Commentf("unexpected log message returned, since=%v", since))
	}

	// Test to make sure a bad since format is caught by the client
	out, _, _ = dockerCmdWithError("logs", "-t", "--since=2006-01-02T15:04:0Z", name)
	c.Assert(out, checker.Contains, "cannot parse \"0Z\" as \"05\"", check.Commentf("bad since format passed to server"))

	// Test with default value specified and parameter omitted
	expected := []string{"log1", "log2", "log3"}
	for _, cmd := range []*exec.Cmd{
		exec.Command(dockerBinary, "logs", "-t", name),
		exec.Command(dockerBinary, "logs", "-t", "--since=0", name),
	} {
		out, _, err = runCommandWithOutput(cmd)
		c.Assert(err, checker.IsNil, check.Commentf("failed to log container: %s", out))
		for _, v := range expected {
			c.Assert(out, checker.Contains, v)
		}
	}
}
func (s *DockerSuite) TestLogsSinceFutureFollow(c *check.C) {
	// TODO Windows TP5 - Figure out why this test is so flakey. Disabled for now.
	testRequires(c, DaemonIsLinux)
	name := "testlogssincefuturefollow"
	out, _ := dockerCmd(c, "run", "-d", "--name", name, "busybox", "/bin/sh", "-c", `for i in $(seq 1 5); do echo log$i; sleep 1; done`)

	// Extract one timestamp from the log file to give us a starting point for
	// our `--since` argument. Because the log producer runs in the background,
	// we need to check repeatedly for some output to be produced.
	var timestamp string
	for i := 0; i != 100 && timestamp == ""; i++ {
		if out, _ = dockerCmd(c, "logs", "-t", name); out == "" {
			time.Sleep(time.Millisecond * 100) // Retry
		} else {
			timestamp = strings.Split(strings.Split(out, "\n")[0], " ")[0]
		}
	}

	c.Assert(timestamp, checker.Not(checker.Equals), "")
	t, err := time.Parse(time.RFC3339Nano, timestamp)
	c.Assert(err, check.IsNil)

	since := t.Unix() + 2
	out, _ = dockerCmd(c, "logs", "-t", "-f", fmt.Sprintf("--since=%v", since), name)
	c.Assert(out, checker.Not(checker.HasLen), 0, check.Commentf("cannot read from empty log"))
	lines := strings.Split(strings.TrimSpace(out), "\n")
	for _, v := range lines {
		ts, err := time.Parse(time.RFC3339Nano, strings.Split(v, " ")[0])
		c.Assert(err, checker.IsNil, check.Commentf("cannot parse timestamp output from log: '%v'", v))
		c.Assert(ts.Unix() >= since, checker.Equals, true, check.Commentf("earlier log found. since=%v logdate=%v", since, ts))
	}
}
Exemple #28
0
func (s *DockerSwarmSuite) TestAPISwarmNodeRemove(c *check.C) {
	testRequires(c, Network)
	d1 := s.AddDaemon(c, true, true)
	d2 := s.AddDaemon(c, true, false)
	_ = s.AddDaemon(c, true, false)

	nodes := d1.listNodes(c)
	c.Assert(len(nodes), checker.Equals, 3, check.Commentf("nodes: %#v", nodes))

	// Getting the info so we can take the NodeID
	d2Info, err := d2.info()
	c.Assert(err, checker.IsNil)

	// forceful removal of d2 should work
	d1.removeNode(c, d2Info.NodeID, true)

	nodes = d1.listNodes(c)
	c.Assert(len(nodes), checker.Equals, 2, check.Commentf("nodes: %#v", nodes))

	// Restart the node that was removed
	err = d2.Restart()
	c.Assert(err, checker.IsNil)

	// Give some time for the node to rejoin
	time.Sleep(1 * time.Second)

	// Make sure the node didn't rejoin
	nodes = d1.listNodes(c)
	c.Assert(len(nodes), checker.Equals, 2, check.Commentf("nodes: %#v", nodes))
}
// #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 *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"))
	})
}