Remove unused arguments to commit.
This will allow us to remove all the runConfig mutate+revert code that
is scattered around builder dispatchers/internals
Signed-off-by: Daniel Nephin <dnephin@docker.com>
... | ... |
@@ -73,7 +73,7 @@ func env(req dispatchRequest) error { |
73 | 73 |
} |
74 | 74 |
} |
75 | 75 |
|
76 |
- return req.builder.commit("", req.runConfig.Cmd, commitMessage.String()) |
|
76 |
+ return req.builder.commit(commitMessage.String()) |
|
77 | 77 |
} |
78 | 78 |
|
79 | 79 |
// MAINTAINER some text <maybe@an.email.address> |
... | ... |
@@ -90,7 +90,7 @@ func maintainer(req dispatchRequest) error { |
90 | 90 |
|
91 | 91 |
maintainer := req.args[0] |
92 | 92 |
req.builder.maintainer = maintainer |
93 |
- return req.builder.commit("", req.runConfig.Cmd, "MAINTAINER "+maintainer) |
|
93 |
+ return req.builder.commit("MAINTAINER " + maintainer) |
|
94 | 94 |
} |
95 | 95 |
|
96 | 96 |
// LABEL some json data describing the image |
... | ... |
@@ -130,7 +130,7 @@ func label(req dispatchRequest) error { |
130 | 130 |
req.runConfig.Labels[req.args[j]] = req.args[j+1] |
131 | 131 |
j++ |
132 | 132 |
} |
133 |
- return req.builder.commit("", req.runConfig.Cmd, commitStr) |
|
133 |
+ return req.builder.commit(commitStr) |
|
134 | 134 |
} |
135 | 135 |
|
136 | 136 |
// ADD foo /path |
... | ... |
@@ -281,7 +281,7 @@ func onbuild(req dispatchRequest) error { |
281 | 281 |
|
282 | 282 |
original := regexp.MustCompile(`(?i)^\s*ONBUILD\s*`).ReplaceAllString(req.original, "") |
283 | 283 |
req.runConfig.OnBuild = append(req.runConfig.OnBuild, original) |
284 |
- return req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("ONBUILD %s", original)) |
|
284 |
+ return req.builder.commit("ONBUILD " + original) |
|
285 | 285 |
} |
286 | 286 |
|
287 | 287 |
// WORKDIR /tmp |
... | ... |
@@ -321,10 +321,9 @@ func workdir(req dispatchRequest) error { |
321 | 321 |
req.runConfig.Cmd = strslice.StrSlice(append(getShell(req.runConfig), "#(nop) "+comment)) |
322 | 322 |
defer func(cmd strslice.StrSlice) { req.runConfig.Cmd = cmd }(cmd) |
323 | 323 |
|
324 |
- if hit, err := req.builder.probeCache(); err != nil { |
|
324 |
+ // TODO: this should pass a copy of runConfig |
|
325 |
+ if hit, err := req.builder.probeCache(req.builder.image, req.runConfig); err != nil || hit { |
|
325 | 326 |
return err |
326 |
- } else if hit { |
|
327 |
- return nil |
|
328 | 327 |
} |
329 | 328 |
|
330 | 329 |
req.runConfig.Image = req.builder.image |
... | ... |
@@ -341,7 +340,7 @@ func workdir(req dispatchRequest) error { |
341 | 341 |
return err |
342 | 342 |
} |
343 | 343 |
|
344 |
- return req.builder.commit(container.ID, cmd, comment) |
|
344 |
+ return req.builder.commitContainer(container.ID, copyRunConfig(req.runConfig, withCmd(cmd))) |
|
345 | 345 |
} |
346 | 346 |
|
347 | 347 |
// RUN some command yo |
... | ... |
@@ -402,13 +401,10 @@ func run(req dispatchRequest) error { |
402 | 402 |
} |
403 | 403 |
|
404 | 404 |
req.runConfig.Cmd = saveCmd |
405 |
- hit, err := req.builder.probeCache() |
|
406 |
- if err != nil { |
|
405 |
+ hit, err := req.builder.probeCache(req.builder.image, req.runConfig) |
|
406 |
+ if err != nil || hit { |
|
407 | 407 |
return err |
408 | 408 |
} |
409 |
- if hit { |
|
410 |
- return nil |
|
411 |
- } |
|
412 | 409 |
|
413 | 410 |
// set Cmd manually, this is special case only for Dockerfiles |
414 | 411 |
req.runConfig.Cmd = config.Cmd |
... | ... |
@@ -419,7 +415,11 @@ func run(req dispatchRequest) error { |
419 | 419 |
|
420 | 420 |
logrus.Debugf("[BUILDER] Command to be executed: %v", req.runConfig.Cmd) |
421 | 421 |
|
422 |
- cID, err := req.builder.create() |
|
422 |
+ // TODO: this was previously in b.create(), why is it necessary? |
|
423 |
+ req.builder.runConfig.Image = req.builder.image |
|
424 |
+ |
|
425 |
+ // TODO: should pass a copy of runConfig |
|
426 |
+ cID, err := req.builder.create(req.runConfig) |
|
423 | 427 |
if err != nil { |
424 | 428 |
return err |
425 | 429 |
} |
... | ... |
@@ -451,7 +451,7 @@ func run(req dispatchRequest) error { |
451 | 451 |
saveCmd = strslice.StrSlice(append(tmpEnv, saveCmd...)) |
452 | 452 |
} |
453 | 453 |
req.runConfig.Cmd = saveCmd |
454 |
- return req.builder.commit(cID, cmd, "run") |
|
454 |
+ return req.builder.commitContainer(cID, copyRunConfig(req.runConfig, withCmd(cmd))) |
|
455 | 455 |
} |
456 | 456 |
|
457 | 457 |
// CMD foo |
... | ... |
@@ -474,7 +474,7 @@ func cmd(req dispatchRequest) error { |
474 | 474 |
// set config as already being escaped, this prevents double escaping on windows |
475 | 475 |
req.runConfig.ArgsEscaped = true |
476 | 476 |
|
477 |
- if err := req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("CMD %q", cmdSlice)); err != nil { |
|
477 |
+ if err := req.builder.commit(fmt.Sprintf("CMD %q", cmdSlice)); err != nil { |
|
478 | 478 |
return err |
479 | 479 |
} |
480 | 480 |
|
... | ... |
@@ -590,7 +590,7 @@ func healthcheck(req dispatchRequest) error { |
590 | 590 |
req.runConfig.Healthcheck = &healthcheck |
591 | 591 |
} |
592 | 592 |
|
593 |
- return req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("HEALTHCHECK %q", req.runConfig.Healthcheck)) |
|
593 |
+ return req.builder.commit(fmt.Sprintf("HEALTHCHECK %q", req.runConfig.Healthcheck)) |
|
594 | 594 |
} |
595 | 595 |
|
596 | 596 |
// ENTRYPOINT /usr/sbin/nginx |
... | ... |
@@ -626,11 +626,7 @@ func entrypoint(req dispatchRequest) error { |
626 | 626 |
req.runConfig.Cmd = nil |
627 | 627 |
} |
628 | 628 |
|
629 |
- if err := req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("ENTRYPOINT %q", req.runConfig.Entrypoint)); err != nil { |
|
630 |
- return err |
|
631 |
- } |
|
632 |
- |
|
633 |
- return nil |
|
629 |
+ return req.builder.commit(fmt.Sprintf("ENTRYPOINT %q", req.runConfig.Entrypoint)) |
|
634 | 630 |
} |
635 | 631 |
|
636 | 632 |
// EXPOSE 6667/tcp 7000/tcp |
... | ... |
@@ -671,7 +667,7 @@ func expose(req dispatchRequest) error { |
671 | 671 |
i++ |
672 | 672 |
} |
673 | 673 |
sort.Strings(portList) |
674 |
- return req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("EXPOSE %s", strings.Join(portList, " "))) |
|
674 |
+ return req.builder.commit("EXPOSE " + strings.Join(portList, " ")) |
|
675 | 675 |
} |
676 | 676 |
|
677 | 677 |
// USER foo |
... | ... |
@@ -689,7 +685,7 @@ func user(req dispatchRequest) error { |
689 | 689 |
} |
690 | 690 |
|
691 | 691 |
req.runConfig.User = req.args[0] |
692 |
- return req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("USER %v", req.args)) |
|
692 |
+ return req.builder.commit(fmt.Sprintf("USER %v", req.args)) |
|
693 | 693 |
} |
694 | 694 |
|
695 | 695 |
// VOLUME /foo |
... | ... |
@@ -715,10 +711,7 @@ func volume(req dispatchRequest) error { |
715 | 715 |
} |
716 | 716 |
req.runConfig.Volumes[v] = struct{}{} |
717 | 717 |
} |
718 |
- if err := req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("VOLUME %v", req.args)); err != nil { |
|
719 |
- return err |
|
720 |
- } |
|
721 |
- return nil |
|
718 |
+ return req.builder.commit(fmt.Sprintf("VOLUME %v", req.args)) |
|
722 | 719 |
} |
723 | 720 |
|
724 | 721 |
// STOPSIGNAL signal |
... | ... |
@@ -736,7 +729,7 @@ func stopSignal(req dispatchRequest) error { |
736 | 736 |
} |
737 | 737 |
|
738 | 738 |
req.runConfig.StopSignal = sig |
739 |
- return req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("STOPSIGNAL %v", req.args)) |
|
739 |
+ return req.builder.commit(fmt.Sprintf("STOPSIGNAL %v", req.args)) |
|
740 | 740 |
} |
741 | 741 |
|
742 | 742 |
// ARG name[=value] |
... | ... |
@@ -786,7 +779,7 @@ func arg(req dispatchRequest) error { |
786 | 786 |
req.builder.buildArgs.AddMetaArg(name, value) |
787 | 787 |
return nil |
788 | 788 |
} |
789 |
- return req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("ARG %s", arg)) |
|
789 |
+ return req.builder.commit("ARG " + arg) |
|
790 | 790 |
} |
791 | 791 |
|
792 | 792 |
// SHELL powershell -command |
... | ... |
@@ -808,7 +801,7 @@ func shell(req dispatchRequest) error { |
808 | 808 |
// SHELL powershell -command - not JSON |
809 | 809 |
return errNotJSON("SHELL", req.original) |
810 | 810 |
} |
811 |
- return req.builder.commit("", req.runConfig.Cmd, fmt.Sprintf("SHELL %v", shellSlice)) |
|
811 |
+ return req.builder.commit(fmt.Sprintf("SHELL %v", shellSlice)) |
|
812 | 812 |
} |
813 | 813 |
|
814 | 814 |
func errAtLeastOneArgument(command string) error { |
... | ... |
@@ -831,15 +824,6 @@ func errTooManyArguments(command string) error { |
831 | 831 |
return fmt.Errorf("Bad input to %s, too many arguments", command) |
832 | 832 |
} |
833 | 833 |
|
834 |
-// getShell is a helper function which gets the right shell for prefixing the |
|
835 |
-// shell-form of RUN, ENTRYPOINT and CMD instructions |
|
836 |
-func getShell(c *container.Config) []string { |
|
837 |
- if 0 == len(c.Shell) { |
|
838 |
- return append([]string{}, defaultShell[:]...) |
|
839 |
- } |
|
840 |
- return append([]string{}, c.Shell[:]...) |
|
841 |
-} |
|
842 |
- |
|
843 | 834 |
// mountByRef creates an imageMount from a reference. pulling the image if needed. |
844 | 835 |
func mountByRef(b *Builder, name string) (*imageMount, error) { |
845 | 836 |
image, err := pullOrGetImage(b, name) |
... | ... |
@@ -36,41 +36,39 @@ import ( |
36 | 36 |
"github.com/pkg/errors" |
37 | 37 |
) |
38 | 38 |
|
39 |
-func (b *Builder) commit(id string, autoCmd strslice.StrSlice, comment string) error { |
|
39 |
+func (b *Builder) commit(comment string) error { |
|
40 | 40 |
if b.disableCommit { |
41 | 41 |
return nil |
42 | 42 |
} |
43 | 43 |
if !b.hasFromImage() { |
44 | 44 |
return errors.New("Please provide a source image with `from` prior to commit") |
45 | 45 |
} |
46 |
+ // TODO: why is this set here? |
|
46 | 47 |
b.runConfig.Image = b.image |
47 | 48 |
|
48 |
- if id == "" { |
|
49 |
- cmd := b.runConfig.Cmd |
|
50 |
- b.runConfig.Cmd = strslice.StrSlice(append(getShell(b.runConfig), "#(nop) ", comment)) |
|
51 |
- defer func(cmd strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd) |
|
52 |
- |
|
53 |
- hit, err := b.probeCache() |
|
54 |
- if err != nil { |
|
55 |
- return err |
|
56 |
- } else if hit { |
|
57 |
- return nil |
|
58 |
- } |
|
59 |
- id, err = b.create() |
|
60 |
- if err != nil { |
|
61 |
- return err |
|
62 |
- } |
|
49 |
+ runConfigWithCommentCmd := copyRunConfig(b.runConfig, withCmdComment(comment)) |
|
50 |
+ hit, err := b.probeCache(b.image, runConfigWithCommentCmd) |
|
51 |
+ if err != nil || hit { |
|
52 |
+ return err |
|
53 |
+ } |
|
54 |
+ id, err := b.create(runConfigWithCommentCmd) |
|
55 |
+ if err != nil { |
|
56 |
+ return err |
|
63 | 57 |
} |
64 | 58 |
|
65 |
- // Note: Actually copy the struct |
|
66 |
- autoConfig := *b.runConfig |
|
67 |
- autoConfig.Cmd = autoCmd |
|
59 |
+ return b.commitContainer(id, b.runConfig) |
|
60 |
+} |
|
61 |
+ |
|
62 |
+func (b *Builder) commitContainer(id string, runConfig *container.Config) error { |
|
63 |
+ if b.disableCommit { |
|
64 |
+ return nil |
|
65 |
+ } |
|
68 | 66 |
|
69 | 67 |
commitCfg := &backend.ContainerCommitConfig{ |
70 | 68 |
ContainerCommitConfig: types.ContainerCommitConfig{ |
71 | 69 |
Author: b.maintainer, |
72 | 70 |
Pause: true, |
73 |
- Config: &autoConfig, |
|
71 |
+ Config: runConfig, |
|
74 | 72 |
}, |
75 | 73 |
} |
76 | 74 |
|
... | ... |
@@ -80,8 +78,10 @@ func (b *Builder) commit(id string, autoCmd strslice.StrSlice, comment string) e |
80 | 80 |
return err |
81 | 81 |
} |
82 | 82 |
|
83 |
+ // TODO: this function should return imageID and runConfig instead of setting |
|
84 |
+ // then on the builder |
|
83 | 85 |
b.image = imageID |
84 |
- b.imageContexts.update(imageID, &autoConfig) |
|
86 |
+ b.imageContexts.update(imageID, runConfig) |
|
85 | 87 |
return nil |
86 | 88 |
} |
87 | 89 |
|
... | ... |
@@ -148,11 +148,9 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD |
148 | 148 |
// For backwards compat, if there's just one info then use it as the |
149 | 149 |
// cache look-up string, otherwise hash 'em all into one |
150 | 150 |
var srcHash string |
151 |
- var origPaths string |
|
152 | 151 |
|
153 | 152 |
if len(infos) == 1 { |
154 | 153 |
info := infos[0] |
155 |
- origPaths = info.path |
|
156 | 154 |
srcHash = info.hash |
157 | 155 |
} else { |
158 | 156 |
var hashs []string |
... | ... |
@@ -164,17 +162,16 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD |
164 | 164 |
hasher := sha256.New() |
165 | 165 |
hasher.Write([]byte(strings.Join(hashs, ","))) |
166 | 166 |
srcHash = "multi:" + hex.EncodeToString(hasher.Sum(nil)) |
167 |
- origPaths = strings.Join(origs, " ") |
|
168 | 167 |
} |
169 | 168 |
|
170 | 169 |
cmd := b.runConfig.Cmd |
170 |
+ // TODO: should this have been using origPaths instead of srcHash in the comment? |
|
171 | 171 |
b.runConfig.Cmd = strslice.StrSlice(append(getShell(b.runConfig), fmt.Sprintf("#(nop) %s %s in %s ", cmdName, srcHash, dest))) |
172 | 172 |
defer func(cmd strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd) |
173 | 173 |
|
174 |
- if hit, err := b.probeCache(); err != nil { |
|
174 |
+ // TODO: this should pass a copy of runConfig |
|
175 |
+ if hit, err := b.probeCache(b.image, b.runConfig); err != nil || hit { |
|
175 | 176 |
return err |
176 |
- } else if hit { |
|
177 |
- return nil |
|
178 | 177 |
} |
179 | 178 |
|
180 | 179 |
container, err := b.docker.ContainerCreate(types.ContainerCreateConfig{ |
... | ... |
@@ -187,8 +184,6 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD |
187 | 187 |
} |
188 | 188 |
b.tmpContainers[container.ID] = struct{}{} |
189 | 189 |
|
190 |
- comment := fmt.Sprintf("%s %s in %s", cmdName, origPaths, dest) |
|
191 |
- |
|
192 | 190 |
// Twiddle the destination when it's a relative path - meaning, make it |
193 | 191 |
// relative to the WORKINGDIR |
194 | 192 |
if dest, err = normaliseDest(cmdName, b.runConfig.WorkingDir, dest); err != nil { |
... | ... |
@@ -201,7 +196,44 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD |
201 | 201 |
} |
202 | 202 |
} |
203 | 203 |
|
204 |
- return b.commit(container.ID, cmd, comment) |
|
204 |
+ return b.commitContainer(container.ID, copyRunConfig(b.runConfig, withCmd(cmd))) |
|
205 |
+} |
|
206 |
+ |
|
207 |
+type runConfigModifier func(*container.Config) |
|
208 |
+ |
|
209 |
+func copyRunConfig(runConfig *container.Config, modifiers ...runConfigModifier) *container.Config { |
|
210 |
+ copy := *runConfig |
|
211 |
+ for _, modifier := range modifiers { |
|
212 |
+ modifier(©) |
|
213 |
+ } |
|
214 |
+ return © |
|
215 |
+} |
|
216 |
+ |
|
217 |
+func withCmd(cmd []string) runConfigModifier { |
|
218 |
+ return func(runConfig *container.Config) { |
|
219 |
+ runConfig.Cmd = cmd |
|
220 |
+ } |
|
221 |
+} |
|
222 |
+ |
|
223 |
+func withCmdComment(comment string) runConfigModifier { |
|
224 |
+ return func(runConfig *container.Config) { |
|
225 |
+ runConfig.Cmd = append(getShell(runConfig), "#(nop) ", comment) |
|
226 |
+ } |
|
227 |
+} |
|
228 |
+ |
|
229 |
+func withEnv(env []string) runConfigModifier { |
|
230 |
+ return func(runConfig *container.Config) { |
|
231 |
+ runConfig.Env = env |
|
232 |
+ } |
|
233 |
+} |
|
234 |
+ |
|
235 |
+// getShell is a helper function which gets the right shell for prefixing the |
|
236 |
+// shell-form of RUN, ENTRYPOINT and CMD instructions |
|
237 |
+func getShell(c *container.Config) []string { |
|
238 |
+ if 0 == len(c.Shell) { |
|
239 |
+ return append([]string{}, defaultShell[:]...) |
|
240 |
+ } |
|
241 |
+ return append([]string{}, c.Shell[:]...) |
|
205 | 242 |
} |
206 | 243 |
|
207 | 244 |
func (b *Builder) download(srcURL string) (remote builder.Source, p string, err error) { |
... | ... |
@@ -498,35 +530,33 @@ func (b *Builder) processImageFrom(img builder.Image) error { |
498 | 498 |
// If an image is found, probeCache returns `(true, nil)`. |
499 | 499 |
// If no image is found, it returns `(false, nil)`. |
500 | 500 |
// If there is any error, it returns `(false, err)`. |
501 |
-func (b *Builder) probeCache() (bool, error) { |
|
501 |
+func (b *Builder) probeCache(imageID string, runConfig *container.Config) (bool, error) { |
|
502 | 502 |
c := b.imageCache |
503 | 503 |
if c == nil || b.options.NoCache || b.cacheBusted { |
504 | 504 |
return false, nil |
505 | 505 |
} |
506 |
- cache, err := c.GetCache(b.image, b.runConfig) |
|
506 |
+ cache, err := c.GetCache(imageID, runConfig) |
|
507 | 507 |
if err != nil { |
508 | 508 |
return false, err |
509 | 509 |
} |
510 | 510 |
if len(cache) == 0 { |
511 |
- logrus.Debugf("[BUILDER] Cache miss: %s", b.runConfig.Cmd) |
|
511 |
+ logrus.Debugf("[BUILDER] Cache miss: %s", runConfig.Cmd) |
|
512 | 512 |
b.cacheBusted = true |
513 | 513 |
return false, nil |
514 | 514 |
} |
515 | 515 |
|
516 | 516 |
fmt.Fprint(b.Stdout, " ---> Using cache\n") |
517 |
- logrus.Debugf("[BUILDER] Use cached version: %s", b.runConfig.Cmd) |
|
517 |
+ logrus.Debugf("[BUILDER] Use cached version: %s", runConfig.Cmd) |
|
518 | 518 |
b.image = string(cache) |
519 |
- b.imageContexts.update(b.image, b.runConfig) |
|
519 |
+ b.imageContexts.update(b.image, runConfig) |
|
520 | 520 |
|
521 | 521 |
return true, nil |
522 | 522 |
} |
523 | 523 |
|
524 |
-func (b *Builder) create() (string, error) { |
|
524 |
+func (b *Builder) create(runConfig *container.Config) (string, error) { |
|
525 | 525 |
if !b.hasFromImage() { |
526 | 526 |
return "", errors.New("Please provide a source image with `from` prior to run") |
527 | 527 |
} |
528 |
- b.runConfig.Image = b.image |
|
529 |
- |
|
530 | 528 |
resources := container.Resources{ |
531 | 529 |
CgroupParent: b.options.CgroupParent, |
532 | 530 |
CPUShares: b.options.CPUShares, |
... | ... |
@@ -551,11 +581,9 @@ func (b *Builder) create() (string, error) { |
551 | 551 |
ExtraHosts: b.options.ExtraHosts, |
552 | 552 |
} |
553 | 553 |
|
554 |
- config := *b.runConfig |
|
555 |
- |
|
556 | 554 |
// Create the container |
557 | 555 |
c, err := b.docker.ContainerCreate(types.ContainerCreateConfig{ |
558 |
- Config: b.runConfig, |
|
556 |
+ Config: runConfig, |
|
559 | 557 |
HostConfig: hostConfig, |
560 | 558 |
}) |
561 | 559 |
if err != nil { |
... | ... |
@@ -569,7 +597,7 @@ func (b *Builder) create() (string, error) { |
569 | 569 |
fmt.Fprintf(b.Stdout, " ---> Running in %s\n", stringid.TruncateID(c.ID)) |
570 | 570 |
|
571 | 571 |
// override the entry point that may have been picked up from the base image |
572 |
- if err := b.docker.ContainerUpdateCmdOnBuild(c.ID, config.Cmd); err != nil { |
|
572 |
+ if err := b.docker.ContainerUpdateCmdOnBuild(c.ID, runConfig.Cmd); err != nil { |
|
573 | 573 |
return "", err |
574 | 574 |
} |
575 | 575 |
|
... | ... |
@@ -5,6 +5,7 @@ import ( |
5 | 5 |
"fmt" |
6 | 6 |
"testing" |
7 | 7 |
|
8 |
+ "github.com/docker/docker/api/types/container" |
|
8 | 9 |
"github.com/docker/docker/builder" |
9 | 10 |
"github.com/docker/docker/builder/remotecontext" |
10 | 11 |
"github.com/docker/docker/pkg/archive" |
... | ... |
@@ -71,3 +72,54 @@ func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, |
71 | 71 |
_, _, err = remotecontext.Detect(context.Background(), "", dockerfilePath, tarStream, nil) |
72 | 72 |
assert.EqualError(t, err, expectedError) |
73 | 73 |
} |
74 |
+ |
|
75 |
+func TestCopyRunConfig(t *testing.T) { |
|
76 |
+ defaultEnv := []string{"foo=1"} |
|
77 |
+ defaultCmd := []string{"old"} |
|
78 |
+ |
|
79 |
+ var testcases = []struct { |
|
80 |
+ doc string |
|
81 |
+ modifiers []runConfigModifier |
|
82 |
+ expected *container.Config |
|
83 |
+ }{ |
|
84 |
+ { |
|
85 |
+ doc: "Set the command", |
|
86 |
+ modifiers: []runConfigModifier{withCmd([]string{"new"})}, |
|
87 |
+ expected: &container.Config{ |
|
88 |
+ Cmd: []string{"new"}, |
|
89 |
+ Env: defaultEnv, |
|
90 |
+ }, |
|
91 |
+ }, |
|
92 |
+ { |
|
93 |
+ doc: "Set the command to a comment", |
|
94 |
+ modifiers: []runConfigModifier{withCmdComment("comment")}, |
|
95 |
+ expected: &container.Config{ |
|
96 |
+ Cmd: append(defaultShell, "#(nop) ", "comment"), |
|
97 |
+ Env: defaultEnv, |
|
98 |
+ }, |
|
99 |
+ }, |
|
100 |
+ { |
|
101 |
+ doc: "Set the command and env", |
|
102 |
+ modifiers: []runConfigModifier{ |
|
103 |
+ withCmd([]string{"new"}), |
|
104 |
+ withEnv([]string{"one", "two"}), |
|
105 |
+ }, |
|
106 |
+ expected: &container.Config{ |
|
107 |
+ Cmd: []string{"new"}, |
|
108 |
+ Env: []string{"one", "two"}, |
|
109 |
+ }, |
|
110 |
+ }, |
|
111 |
+ } |
|
112 |
+ |
|
113 |
+ for _, testcase := range testcases { |
|
114 |
+ runConfig := &container.Config{ |
|
115 |
+ Cmd: defaultCmd, |
|
116 |
+ Env: defaultEnv, |
|
117 |
+ } |
|
118 |
+ runConfigCopy := copyRunConfig(runConfig, testcase.modifiers...) |
|
119 |
+ assert.Equal(t, testcase.expected, runConfigCopy, testcase.doc) |
|
120 |
+ // Assert the original was not modified |
|
121 |
+ assert.NotEqual(t, runConfig, runConfigCopy, testcase.doc) |
|
122 |
+ } |
|
123 |
+ |
|
124 |
+} |