2018-03-30 07:10:02 -04:00
|
|
|
package build
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"context"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/docker/docker/api/types"
|
2018-12-24 10:55:22 -05:00
|
|
|
dclient "github.com/docker/docker/client"
|
2018-03-30 07:10:02 -04:00
|
|
|
"github.com/docker/docker/integration/internal/container"
|
2018-04-19 05:14:15 -04:00
|
|
|
"github.com/docker/docker/internal/test/daemon"
|
2018-04-16 08:39:13 -04:00
|
|
|
"github.com/docker/docker/internal/test/fakecontext"
|
2018-03-30 07:10:02 -04:00
|
|
|
"github.com/docker/docker/pkg/stdcopy"
|
2018-06-11 09:32:11 -04:00
|
|
|
"gotest.tools/assert"
|
|
|
|
is "gotest.tools/assert/cmp"
|
|
|
|
"gotest.tools/skip"
|
2018-03-30 07:10:02 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestBuildSquashParent(t *testing.T) {
|
2018-04-19 05:14:15 -04:00
|
|
|
skip.If(t, testEnv.DaemonInfo.OSType == "windows")
|
2018-03-30 07:10:02 -04:00
|
|
|
|
2018-12-24 10:55:22 -05:00
|
|
|
var client dclient.APIClient
|
|
|
|
if !testEnv.DaemonInfo.ExperimentalBuild {
|
|
|
|
skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon")
|
|
|
|
|
|
|
|
d := daemon.New(t, daemon.WithExperimental)
|
|
|
|
d.StartWithBusybox(t)
|
|
|
|
defer d.Stop(t)
|
|
|
|
client = d.NewClientT(t)
|
|
|
|
} else {
|
|
|
|
client = testEnv.APIClient()
|
|
|
|
}
|
2018-03-30 07:10:02 -04:00
|
|
|
|
|
|
|
dockerfile := `
|
|
|
|
FROM busybox
|
|
|
|
RUN echo hello > /hello
|
|
|
|
RUN echo world >> /hello
|
|
|
|
RUN echo hello > /remove_me
|
|
|
|
ENV HELLO world
|
|
|
|
RUN rm /remove_me
|
|
|
|
`
|
|
|
|
|
|
|
|
// build and get the ID that we can use later for history comparison
|
|
|
|
ctx := context.Background()
|
|
|
|
source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile))
|
|
|
|
defer source.Close()
|
|
|
|
|
|
|
|
name := "test"
|
|
|
|
resp, err := client.ImageBuild(ctx,
|
|
|
|
source.AsTarReader(t),
|
|
|
|
types.ImageBuildOptions{
|
|
|
|
Remove: true,
|
|
|
|
ForceRemove: true,
|
|
|
|
Tags: []string{name},
|
|
|
|
})
|
|
|
|
assert.NilError(t, err)
|
|
|
|
_, err = io.Copy(ioutil.Discard, resp.Body)
|
|
|
|
resp.Body.Close()
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
inspect, _, err := client.ImageInspectWithRaw(ctx, name)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
origID := inspect.ID
|
|
|
|
|
|
|
|
// build with squash
|
|
|
|
resp, err = client.ImageBuild(ctx,
|
|
|
|
source.AsTarReader(t),
|
|
|
|
types.ImageBuildOptions{
|
|
|
|
Remove: true,
|
|
|
|
ForceRemove: true,
|
|
|
|
Squash: true,
|
|
|
|
Tags: []string{name},
|
|
|
|
})
|
|
|
|
assert.NilError(t, err)
|
|
|
|
_, err = io.Copy(ioutil.Discard, resp.Body)
|
|
|
|
resp.Body.Close()
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
2019-06-06 07:15:31 -04:00
|
|
|
cid := container.Run(ctx, t, client,
|
2018-03-30 07:10:02 -04:00
|
|
|
container.WithImage(name),
|
|
|
|
container.WithCmd("/bin/sh", "-c", "cat /hello"),
|
|
|
|
)
|
|
|
|
reader, err := client.ContainerLogs(ctx, cid, types.ContainerLogsOptions{
|
|
|
|
ShowStdout: true,
|
|
|
|
})
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
actualStdout := new(bytes.Buffer)
|
|
|
|
actualStderr := ioutil.Discard
|
|
|
|
_, err = stdcopy.StdCopy(actualStdout, actualStderr, reader)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
assert.Check(t, is.Equal(strings.TrimSpace(actualStdout.String()), "hello\nworld"))
|
|
|
|
|
2019-06-06 07:15:31 -04:00
|
|
|
container.Run(ctx, t, client,
|
2018-03-30 07:10:02 -04:00
|
|
|
container.WithImage(name),
|
|
|
|
container.WithCmd("/bin/sh", "-c", "[ ! -f /remove_me ]"),
|
|
|
|
)
|
2019-06-06 07:15:31 -04:00
|
|
|
container.Run(ctx, t, client,
|
2018-03-30 07:10:02 -04:00
|
|
|
container.WithImage(name),
|
|
|
|
container.WithCmd("/bin/sh", "-c", `[ "$(echo $HELLO)" == "world" ]`),
|
|
|
|
)
|
|
|
|
|
|
|
|
origHistory, err := client.ImageHistory(ctx, origID)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
testHistory, err := client.ImageHistory(ctx, name)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
inspect, _, err = client.ImageInspectWithRaw(ctx, name)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
assert.Check(t, is.Len(testHistory, len(origHistory)+1))
|
|
|
|
assert.Check(t, is.Len(inspect.RootFS.Layers, 2))
|
|
|
|
}
|