Merge component 'engine' from git@github.com:moby/moby master

This commit is contained in:
GordonTheTurtle
2017-12-22 17:06:13 +00:00
5 changed files with 101 additions and 68 deletions

View File

@ -28,7 +28,7 @@ func New() *Events {
}
}
// Subscribe adds new listener to events, returns slice of 64 stored
// Subscribe adds new listener to events, returns slice of 256 stored
// last events, a channel in which you can expect new events (in form
// of interface{}, so you need type assertion), and a function to call
// to stop the stream of events.
@ -46,7 +46,7 @@ func (e *Events) Subscribe() ([]eventtypes.Message, chan interface{}, func()) {
return current, l, cancel
}
// SubscribeTopic adds new listener to events, returns slice of 64 stored
// SubscribeTopic adds new listener to events, returns slice of 256 stored
// last events, a channel in which you can expect new events (in form
// of interface{}, so you need type assertion).
func (e *Events) SubscribeTopic(since, until time.Time, ef *Filter) ([]eventtypes.Message, chan interface{}) {

View File

@ -135,21 +135,28 @@ func TestLogEvents(t *testing.T) {
t.Fatalf("Must be %d events, got %d", eventsLimit, len(current))
}
first := current[0]
if first.Status != "action_16" {
t.Fatalf("First action is %s, must be action_16", first.Status)
// TODO remove this once we removed the deprecated `ID`, `Status`, and `From` fields
if first.Action != first.Status {
// Verify that the (deprecated) Status is set to the expected value
t.Fatalf("Action (%s) does not match Status (%s)", first.Action, first.Status)
}
if first.Action != "action_16" {
t.Fatalf("First action is %s, must be action_16", first.Action)
}
last := current[len(current)-1]
if last.Status != "action_271" {
t.Fatalf("Last action is %s, must be action_271", last.Status)
if last.Action != "action_271" {
t.Fatalf("Last action is %s, must be action_271", last.Action)
}
firstC := msgs[0]
if firstC.Status != "action_272" {
t.Fatalf("First action is %s, must be action_272", firstC.Status)
if firstC.Action != "action_272" {
t.Fatalf("First action is %s, must be action_272", firstC.Action)
}
lastC := msgs[len(msgs)-1]
if lastC.Status != "action_281" {
t.Fatalf("Last action is %s, must be action_281", lastC.Status)
if lastC.Action != "action_281" {
t.Fatalf("Last action is %s, must be action_281", lastC.Action)
}
}

View File

@ -4860,7 +4860,7 @@ func (s *DockerSuite) TestBuildBuildTimeArgDefinitionWithNoEnvInjection(c *check
}
}
func (s *DockerSuite) TestBuildBuildTimeArgMultipleFrom(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageArg(c *check.C) {
imgName := "multifrombldargtest"
dockerfile := `FROM busybox
ARG foo=abc
@ -4884,7 +4884,7 @@ func (s *DockerSuite) TestBuildBuildTimeArgMultipleFrom(c *check.C) {
c.Assert(result.Stdout(), checker.Contains, "bar=def")
}
func (s *DockerSuite) TestBuildBuildTimeFromArgMultipleFrom(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageGlobalArg(c *check.C) {
imgName := "multifrombldargtest"
dockerfile := `ARG tag=nosuchtag
FROM busybox:${tag}
@ -4909,7 +4909,7 @@ func (s *DockerSuite) TestBuildBuildTimeFromArgMultipleFrom(c *check.C) {
c.Assert(result.Stdout(), checker.Contains, "tag=latest")
}
func (s *DockerSuite) TestBuildBuildTimeUnusedArgMultipleFrom(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageUnusedArg(c *check.C) {
imgName := "multifromunusedarg"
dockerfile := `FROM busybox
ARG foo
@ -5727,7 +5727,7 @@ func (s *DockerSuite) TestBuildCacheFrom(c *check.C) {
c.Assert(layers1[len(layers1)-1], checker.Not(checker.Equals), layers2[len(layers1)-1])
}
func (s *DockerSuite) TestBuildCacheMultipleFrom(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageCache(c *check.C) {
testRequires(c, DaemonIsLinux) // All tests that do save are skipped in windows
dockerfile := `
FROM busybox
@ -5888,7 +5888,7 @@ func (s *DockerSuite) TestBuildContChar(c *check.C) {
c.Assert(result.Combined(), checker.Contains, "Step 2/2 : RUN echo hi \\\\\n")
}
func (s *DockerSuite) TestBuildCopyFromPreviousRootFS(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageCopyFromSyntax(c *check.C) {
dockerfile := `
FROM busybox AS first
COPY foo bar
@ -5946,7 +5946,7 @@ func (s *DockerSuite) TestBuildCopyFromPreviousRootFS(c *check.C) {
cli.DockerCmd(c, "run", "build4", "cat", "baz").Assert(c, icmd.Expected{Out: "pqr"})
}
func (s *DockerSuite) TestBuildCopyFromPreviousRootFSErrors(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageCopyFromErrors(c *check.C) {
testCases := []struct {
dockerfile string
expectedError string
@ -5993,7 +5993,7 @@ func (s *DockerSuite) TestBuildCopyFromPreviousRootFSErrors(c *check.C) {
}
}
func (s *DockerSuite) TestBuildCopyFromPreviousFrom(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageMultipleBuilds(c *check.C) {
dockerfile := `
FROM busybox
COPY foo bar`
@ -6026,7 +6026,7 @@ func (s *DockerSuite) TestBuildCopyFromPreviousFrom(c *check.C) {
c.Assert(strings.TrimSpace(out), check.Equals, "def")
}
func (s *DockerSuite) TestBuildCopyFromImplicitFrom(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageImplicitFrom(c *check.C) {
dockerfile := `
FROM busybox
COPY --from=busybox /etc/passwd /mypasswd
@ -6053,7 +6053,7 @@ func (s *DockerSuite) TestBuildCopyFromImplicitFrom(c *check.C) {
}
}
func (s *DockerRegistrySuite) TestBuildCopyFromImplicitPullingFrom(c *check.C) {
func (s *DockerRegistrySuite) TestBuildMultiStageImplicitPull(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/testf", privateRegistryURL)
dockerfile := `
@ -6083,7 +6083,7 @@ func (s *DockerRegistrySuite) TestBuildCopyFromImplicitPullingFrom(c *check.C) {
cli.Docker(cli.Args("run", "build1", "cat", "baz")).Assert(c, icmd.Expected{Out: "abc"})
}
func (s *DockerSuite) TestBuildFromPreviousBlock(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageNameVariants(c *check.C) {
dockerfile := `
FROM busybox as foo
COPY foo /
@ -6094,7 +6094,7 @@ func (s *DockerSuite) TestBuildFromPreviousBlock(c *check.C) {
FROM foo
COPY --from=foo1 foo f1
COPY --from=FOo2 foo f2
` // foo2 case also tests that names are canse insensitive
` // foo2 case also tests that names are case insensitive
ctx := fakecontext.New(c, "",
fakecontext.WithDockerfile(dockerfile),
fakecontext.WithFiles(map[string]string{
@ -6108,7 +6108,7 @@ func (s *DockerSuite) TestBuildFromPreviousBlock(c *check.C) {
cli.Docker(cli.Args("run", "build1", "cat", "f2")).Assert(c, icmd.Expected{Out: "bar2"})
}
func (s *DockerTrustSuite) TestCopyFromTrustedBuild(c *check.C) {
func (s *DockerTrustSuite) TestBuildMultiStageTrusted(c *check.C) {
img1 := s.setupTrustedImage(c, "trusted-build1")
img2 := s.setupTrustedImage(c, "trusted-build2")
dockerFile := fmt.Sprintf(`
@ -6130,7 +6130,7 @@ func (s *DockerTrustSuite) TestCopyFromTrustedBuild(c *check.C) {
dockerCmdWithResult("run", name, "cat", "bar").Assert(c, icmd.Expected{Out: "ok"})
}
func (s *DockerSuite) TestBuildCopyFromPreviousFromWindows(c *check.C) {
func (s *DockerSuite) TestBuildMultiStageMultipleBuildsWindows(c *check.C) {
testRequires(c, DaemonIsWindows)
dockerfile := `
FROM ` + testEnv.MinimalBaseImage() + `
@ -6218,7 +6218,7 @@ func (s *DockerSuite) TestBuildCopyFromWindowsIsCaseInsensitive(c *check.C) {
}
// #33176
func (s *DockerSuite) TestBuildCopyFromResetScratch(c *check.C) {
func (s *DockerSuite) TestBuildMulitStageResetScratch(c *check.C) {
testRequires(c, DaemonIsLinux)
dockerfile := `

View File

@ -81,50 +81,6 @@ func (s *DockerSuite) TestEventsUntag(c *check.C) {
}
}
func (s *DockerSuite) TestEventsLimit(c *check.C) {
// Windows: Limit to 4 goroutines creating containers in order to prevent
// timeouts creating so many containers simultaneously. This is a due to
// a bug in the Windows platform. It will be fixed in a Windows Update.
numContainers := 17
eventPerContainer := 7 // create, attach, network connect, start, die, network disconnect, destroy
numConcurrentContainers := numContainers
if testEnv.DaemonPlatform() == "windows" {
numConcurrentContainers = 4
}
sem := make(chan bool, numConcurrentContainers)
errChan := make(chan error, numContainers)
startTime := daemonUnixTime(c)
args := []string{"run", "--rm", "busybox", "true"}
for i := 0; i < numContainers; i++ {
sem <- true
go func(i int) {
defer func() { <-sem }()
out, err := exec.Command(dockerBinary, args...).CombinedOutput()
if err != nil {
err = fmt.Errorf("%v: %s", err, string(out))
}
errChan <- err
}(i)
}
// 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="+startTime, "--until", daemonUnixTime(c))
events := strings.Split(out, "\n")
nEvents := len(events) - 1
c.Assert(nEvents, checker.Equals, numContainers*eventPerContainer, check.Commentf("events should be limited to 256, but received %d", nEvents))
}
func (s *DockerSuite) TestEventsContainerEvents(c *check.C) {
dockerCmd(c, "run", "--rm", "--name", "container-events-test", "busybox", "true")

View File

@ -197,3 +197,73 @@ func TestBuildWithEmptyLayers(t *testing.T) {
resp.Body.Close()
require.NoError(t, err)
}
// TestBuildMultiStageOnBuild checks that ONBUILD commands are applied to
// multiple subsequent stages
// #35652
func TestBuildMultiStageOnBuild(t *testing.T) {
defer setupTest(t)()
// test both metadata and layer based commands as they may be implemented differently
dockerfile := `FROM busybox AS stage1
ONBUILD RUN echo 'foo' >somefile
ONBUILD ENV bar=baz
FROM stage1
RUN cat somefile # fails if ONBUILD RUN fails
FROM stage1
RUN cat somefile`
ctx := context.Background()
source := fakecontext.New(t, "",
fakecontext.WithDockerfile(dockerfile))
defer source.Close()
apiclient := testEnv.APIClient()
resp, err := apiclient.ImageBuild(ctx,
source.AsTarReader(t),
types.ImageBuildOptions{
Remove: true,
ForceRemove: true,
})
out := bytes.NewBuffer(nil)
require.NoError(t, err)
_, err = io.Copy(out, resp.Body)
resp.Body.Close()
require.NoError(t, err)
assert.Contains(t, out.String(), "Successfully built")
imageIDs, err := getImageIDsFromBuild(out.Bytes())
require.NoError(t, err)
assert.Equal(t, 3, len(imageIDs))
image, _, err := apiclient.ImageInspectWithRaw(context.Background(), imageIDs[2])
require.NoError(t, err)
assert.Contains(t, image.Config.Env, "bar=baz")
}
type buildLine struct {
Stream string
Aux struct {
ID string
}
}
func getImageIDsFromBuild(output []byte) ([]string, error) {
ids := []string{}
for _, line := range bytes.Split(output, []byte("\n")) {
if len(line) == 0 {
continue
}
entry := buildLine{}
if err := json.Unmarshal(line, &entry); err != nil {
return nil, err
}
if entry.Aux.ID != "" {
ids = append(ids, entry.Aux.ID)
}
}
return ids, nil
}