github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/integration-cli/docker_api_build_test.go (about) 1 package main 2 3 import ( 4 "archive/tar" 5 "bytes" 6 "net/http" 7 "regexp" 8 "strings" 9 10 "github.com/docker/docker/integration-cli/checker" 11 "github.com/docker/docker/integration-cli/request" 12 "github.com/docker/docker/pkg/testutil" 13 "github.com/go-check/check" 14 ) 15 16 func (s *DockerSuite) TestBuildAPIDockerFileRemote(c *check.C) { 17 testRequires(c, NotUserNamespace) 18 var testD string 19 if testEnv.DaemonPlatform() == "windows" { 20 testD = `FROM busybox 21 COPY * /tmp/ 22 RUN find / -name ba* 23 RUN find /tmp/` 24 } else { 25 // -xdev is required because sysfs can cause EPERM 26 testD = `FROM busybox 27 COPY * /tmp/ 28 RUN find / -xdev -name ba* 29 RUN find /tmp/` 30 } 31 server := fakeStorage(c, map[string]string{"testD": testD}) 32 defer server.Close() 33 34 res, body, err := request.SockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json", daemonHost()) 35 c.Assert(err, checker.IsNil) 36 c.Assert(res.StatusCode, checker.Equals, http.StatusOK) 37 38 buf, err := testutil.ReadBody(body) 39 c.Assert(err, checker.IsNil) 40 41 // Make sure Dockerfile exists. 42 // Make sure 'baz' doesn't exist ANYWHERE despite being mentioned in the URL 43 out := string(buf) 44 c.Assert(out, checker.Contains, "/tmp/Dockerfile") 45 c.Assert(out, checker.Not(checker.Contains), "baz") 46 } 47 48 func (s *DockerSuite) TestBuildAPIRemoteTarballContext(c *check.C) { 49 buffer := new(bytes.Buffer) 50 tw := tar.NewWriter(buffer) 51 defer tw.Close() 52 53 dockerfile := []byte("FROM busybox") 54 err := tw.WriteHeader(&tar.Header{ 55 Name: "Dockerfile", 56 Size: int64(len(dockerfile)), 57 }) 58 // failed to write tar file header 59 c.Assert(err, checker.IsNil) 60 61 _, err = tw.Write(dockerfile) 62 // failed to write tar file content 63 c.Assert(err, checker.IsNil) 64 65 // failed to close tar archive 66 c.Assert(tw.Close(), checker.IsNil) 67 68 server := fakeBinaryStorage(c, map[string]*bytes.Buffer{ 69 "testT.tar": buffer, 70 }) 71 defer server.Close() 72 73 res, b, err := request.SockRequestRaw("POST", "/build?remote="+server.URL()+"/testT.tar", nil, "application/tar", daemonHost()) 74 c.Assert(err, checker.IsNil) 75 c.Assert(res.StatusCode, checker.Equals, http.StatusOK) 76 b.Close() 77 } 78 79 func (s *DockerSuite) TestBuildAPIRemoteTarballContextWithCustomDockerfile(c *check.C) { 80 buffer := new(bytes.Buffer) 81 tw := tar.NewWriter(buffer) 82 defer tw.Close() 83 84 dockerfile := []byte(`FROM busybox 85 RUN echo 'wrong'`) 86 err := tw.WriteHeader(&tar.Header{ 87 Name: "Dockerfile", 88 Size: int64(len(dockerfile)), 89 }) 90 // failed to write tar file header 91 c.Assert(err, checker.IsNil) 92 93 _, err = tw.Write(dockerfile) 94 // failed to write tar file content 95 c.Assert(err, checker.IsNil) 96 97 custom := []byte(`FROM busybox 98 RUN echo 'right' 99 `) 100 err = tw.WriteHeader(&tar.Header{ 101 Name: "custom", 102 Size: int64(len(custom)), 103 }) 104 105 // failed to write tar file header 106 c.Assert(err, checker.IsNil) 107 108 _, err = tw.Write(custom) 109 // failed to write tar file content 110 c.Assert(err, checker.IsNil) 111 112 // failed to close tar archive 113 c.Assert(tw.Close(), checker.IsNil) 114 115 server := fakeBinaryStorage(c, map[string]*bytes.Buffer{ 116 "testT.tar": buffer, 117 }) 118 defer server.Close() 119 120 url := "/build?dockerfile=custom&remote=" + server.URL() + "/testT.tar" 121 res, body, err := request.SockRequestRaw("POST", url, nil, "application/tar", daemonHost()) 122 c.Assert(err, checker.IsNil) 123 c.Assert(res.StatusCode, checker.Equals, http.StatusOK) 124 125 defer body.Close() 126 content, err := testutil.ReadBody(body) 127 c.Assert(err, checker.IsNil) 128 129 // Build used the wrong dockerfile. 130 c.Assert(string(content), checker.Not(checker.Contains), "wrong") 131 } 132 133 func (s *DockerSuite) TestBuildAPILowerDockerfile(c *check.C) { 134 git := newFakeGit(c, "repo", map[string]string{ 135 "dockerfile": `FROM busybox 136 RUN echo from dockerfile`, 137 }, false) 138 defer git.Close() 139 140 res, body, err := request.SockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json", daemonHost()) 141 c.Assert(err, checker.IsNil) 142 c.Assert(res.StatusCode, checker.Equals, http.StatusOK) 143 144 buf, err := testutil.ReadBody(body) 145 c.Assert(err, checker.IsNil) 146 147 out := string(buf) 148 c.Assert(out, checker.Contains, "from dockerfile") 149 } 150 151 func (s *DockerSuite) TestBuildAPIBuildGitWithF(c *check.C) { 152 git := newFakeGit(c, "repo", map[string]string{ 153 "baz": `FROM busybox 154 RUN echo from baz`, 155 "Dockerfile": `FROM busybox 156 RUN echo from Dockerfile`, 157 }, false) 158 defer git.Close() 159 160 // Make sure it tries to 'dockerfile' query param value 161 res, body, err := request.SockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json", daemonHost()) 162 c.Assert(err, checker.IsNil) 163 c.Assert(res.StatusCode, checker.Equals, http.StatusOK) 164 165 buf, err := testutil.ReadBody(body) 166 c.Assert(err, checker.IsNil) 167 168 out := string(buf) 169 c.Assert(out, checker.Contains, "from baz") 170 } 171 172 func (s *DockerSuite) TestBuildAPIDoubleDockerfile(c *check.C) { 173 testRequires(c, UnixCli) // dockerfile overwrites Dockerfile on Windows 174 git := newFakeGit(c, "repo", map[string]string{ 175 "Dockerfile": `FROM busybox 176 RUN echo from Dockerfile`, 177 "dockerfile": `FROM busybox 178 RUN echo from dockerfile`, 179 }, false) 180 defer git.Close() 181 182 // Make sure it tries to 'dockerfile' query param value 183 res, body, err := request.SockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json", daemonHost()) 184 c.Assert(err, checker.IsNil) 185 c.Assert(res.StatusCode, checker.Equals, http.StatusOK) 186 187 buf, err := testutil.ReadBody(body) 188 c.Assert(err, checker.IsNil) 189 190 out := string(buf) 191 c.Assert(out, checker.Contains, "from Dockerfile") 192 } 193 194 func (s *DockerSuite) TestBuildAPIUnnormalizedTarPaths(c *check.C) { 195 // Make sure that build context tars with entries of the form 196 // x/./y don't cause caching false positives. 197 198 buildFromTarContext := func(fileContents []byte) string { 199 buffer := new(bytes.Buffer) 200 tw := tar.NewWriter(buffer) 201 defer tw.Close() 202 203 dockerfile := []byte(`FROM busybox 204 COPY dir /dir/`) 205 err := tw.WriteHeader(&tar.Header{ 206 Name: "Dockerfile", 207 Size: int64(len(dockerfile)), 208 }) 209 //failed to write tar file header 210 c.Assert(err, checker.IsNil) 211 212 _, err = tw.Write(dockerfile) 213 // failed to write Dockerfile in tar file content 214 c.Assert(err, checker.IsNil) 215 216 err = tw.WriteHeader(&tar.Header{ 217 Name: "dir/./file", 218 Size: int64(len(fileContents)), 219 }) 220 //failed to write tar file header 221 c.Assert(err, checker.IsNil) 222 223 _, err = tw.Write(fileContents) 224 // failed to write file contents in tar file content 225 c.Assert(err, checker.IsNil) 226 227 // failed to close tar archive 228 c.Assert(tw.Close(), checker.IsNil) 229 230 res, body, err := request.SockRequestRaw("POST", "/build", buffer, "application/x-tar", daemonHost()) 231 c.Assert(err, checker.IsNil) 232 c.Assert(res.StatusCode, checker.Equals, http.StatusOK) 233 234 out, err := testutil.ReadBody(body) 235 c.Assert(err, checker.IsNil) 236 lines := strings.Split(string(out), "\n") 237 c.Assert(len(lines), checker.GreaterThan, 1) 238 c.Assert(lines[len(lines)-2], checker.Matches, ".*Successfully built [0-9a-f]{12}.*") 239 240 re := regexp.MustCompile("Successfully built ([0-9a-f]{12})") 241 matches := re.FindStringSubmatch(lines[len(lines)-2]) 242 return matches[1] 243 } 244 245 imageA := buildFromTarContext([]byte("abc")) 246 imageB := buildFromTarContext([]byte("def")) 247 248 c.Assert(imageA, checker.Not(checker.Equals), imageB) 249 }