While working on the fix for #8330 I noticed a few things:
1 - the split() call for the .dockerignore process will generate a blank
"exclude". While this isn't causing an issue right now, I got worried
that in the future some code later on might interpret "" as something bad,
like "everything" or ".". So I added a check for an empty "exclude"
and skipped it
2 - if someone puts "foo" in their .dockerignore then we'll skip "foo".
However, if they put "./foo" then we won't due to the painfully
simplistic logic of go's filepath.Match algorithm. To help things
a little (and to treat ./Dockerfile just like Dockerfile) I added
code to filepath.Clean() each entry in .dockerignore. It should
result in the same semantic path but ensure that no matter how the
user expresses the path, we'll match it.
Signed-off-by: Doug Davis <dug@us.ibm.com>
... | ... |
@@ -143,6 +143,11 @@ func (cli *DockerCli) CmdBuild(args ...string) error { |
143 | 143 |
return fmt.Errorf("Error reading .dockerignore: '%s'", err) |
144 | 144 |
} |
145 | 145 |
for _, pattern := range strings.Split(string(ignore), "\n") { |
146 |
+ pattern = strings.TrimSpace(pattern) |
|
147 |
+ if pattern == "" { |
|
148 |
+ continue |
|
149 |
+ } |
|
150 |
+ pattern = filepath.Clean(pattern) |
|
146 | 151 |
ok, err := filepath.Match(pattern, "Dockerfile") |
147 | 152 |
if err != nil { |
148 | 153 |
return fmt.Errorf("Bad .dockerignore pattern: '%s', error: %s", pattern, err) |
... | ... |
@@ -2325,6 +2325,29 @@ func TestBuildDockerignore(t *testing.T) { |
2325 | 2325 |
logDone("build - test .dockerignore") |
2326 | 2326 |
} |
2327 | 2327 |
|
2328 |
+func TestBuildDockerignoreCleanPaths(t *testing.T) { |
|
2329 |
+ name := "testbuilddockerignorecleanpaths" |
|
2330 |
+ defer deleteImages(name) |
|
2331 |
+ dockerfile := ` |
|
2332 |
+ FROM busybox |
|
2333 |
+ ADD . /tmp/ |
|
2334 |
+ RUN (! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)` |
|
2335 |
+ ctx, err := fakeContext(dockerfile, map[string]string{ |
|
2336 |
+ "foo": "foo", |
|
2337 |
+ "foo2": "foo2", |
|
2338 |
+ "dir1/foo": "foo in dir1", |
|
2339 |
+ ".dockerignore": "./foo\ndir1//foo\n./dir1/../foo2", |
|
2340 |
+ }) |
|
2341 |
+ if err != nil { |
|
2342 |
+ t.Fatal(err) |
|
2343 |
+ } |
|
2344 |
+ defer ctx.Close() |
|
2345 |
+ if _, err := buildImageFromContext(name, ctx, true); err != nil { |
|
2346 |
+ t.Fatal(err) |
|
2347 |
+ } |
|
2348 |
+ logDone("build - test .dockerignore with clean paths") |
|
2349 |
+} |
|
2350 |
+ |
|
2328 | 2351 |
func TestBuildDockerignoringDockerfile(t *testing.T) { |
2329 | 2352 |
name := "testbuilddockerignoredockerfile" |
2330 | 2353 |
defer deleteImages(name) |
... | ... |
@@ -2334,13 +2357,20 @@ func TestBuildDockerignoringDockerfile(t *testing.T) { |
2334 | 2334 |
"Dockerfile": "FROM scratch", |
2335 | 2335 |
".dockerignore": "Dockerfile\n", |
2336 | 2336 |
}) |
2337 |
- defer ctx.Close() |
|
2338 | 2337 |
if err != nil { |
2339 | 2338 |
t.Fatal(err) |
2340 | 2339 |
} |
2340 |
+ defer ctx.Close() |
|
2341 | 2341 |
if _, err = buildImageFromContext(name, ctx, true); err == nil { |
2342 | 2342 |
t.Fatalf("Didn't get expected error from ignoring Dockerfile") |
2343 | 2343 |
} |
2344 |
+ |
|
2345 |
+ // now try it with ./Dockerfile |
|
2346 |
+ ctx.Add(".dockerignore", "./Dockerfile\n") |
|
2347 |
+ if _, err = buildImageFromContext(name, ctx, true); err == nil { |
|
2348 |
+ t.Fatalf("Didn't get expected error from ignoring ./Dockerfile") |
|
2349 |
+ } |
|
2350 |
+ |
|
2344 | 2351 |
logDone("build - test .dockerignore of Dockerfile") |
2345 | 2352 |
} |
2346 | 2353 |
|