Remove the block comment which is stale, and redundant now that the
function is just as readable as the comment.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
| ... | ... |
@@ -185,17 +185,6 @@ func sanitizeRepoAndTags(names []string) ([]reference.Named, error) {
|
| 185 | 185 |
|
| 186 | 186 |
// build runs the Dockerfile builder from a context and a docker object that allows to make calls |
| 187 | 187 |
// to Docker. |
| 188 |
-// |
|
| 189 |
-// This will (barring errors): |
|
| 190 |
-// |
|
| 191 |
-// * read the dockerfile from context |
|
| 192 |
-// * parse the dockerfile if not already parsed |
|
| 193 |
-// * walk the AST and execute it by dispatching to handlers. If Remove |
|
| 194 |
-// or ForceRemove is set, additional cleanup around containers happens after |
|
| 195 |
-// processing. |
|
| 196 |
-// * Tag image, if applicable. |
|
| 197 |
-// * Print a happy message and return the image ID. |
|
| 198 |
-// |
|
| 199 | 188 |
func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (string, error) {
|
| 200 | 189 |
defer b.imageContexts.unmount() |
| 201 | 190 |
|
| ... | ... |
@@ -203,7 +192,7 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri |
| 203 | 203 |
b.Stderr = stderr |
| 204 | 204 |
b.Output = out |
| 205 | 205 |
|
| 206 |
- dockerfile, err := b.readDockerfile() |
|
| 206 |
+ dockerfile, err := b.readAndParseDockerfile() |
|
| 207 | 207 |
if err != nil {
|
| 208 | 208 |
return "", err |
| 209 | 209 |
} |
| ... | ... |
@@ -215,14 +204,37 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri |
| 215 | 215 |
|
| 216 | 216 |
addNodesForLabelOption(dockerfile, b.options.Labels) |
| 217 | 217 |
|
| 218 |
- var shortImgID string |
|
| 219 |
- total := len(dockerfile.Children) |
|
| 220 |
- for _, n := range dockerfile.Children {
|
|
| 221 |
- if err := b.checkDispatch(n, false); err != nil {
|
|
| 222 |
- return "", errors.Wrapf(err, "Dockerfile parse error line %d", n.StartLine) |
|
| 218 |
+ if err := checkDispatchDockerfile(dockerfile); err != nil {
|
|
| 219 |
+ return "", err |
|
| 220 |
+ } |
|
| 221 |
+ |
|
| 222 |
+ shortImageID, err := b.dispatchDockerfileWithCancellation(dockerfile) |
|
| 223 |
+ if err != nil {
|
|
| 224 |
+ return "", err |
|
| 225 |
+ } |
|
| 226 |
+ |
|
| 227 |
+ b.warnOnUnusedBuildArgs() |
|
| 228 |
+ |
|
| 229 |
+ if b.image == "" {
|
|
| 230 |
+ return "", errors.New("No image was generated. Is your Dockerfile empty?")
|
|
| 231 |
+ } |
|
| 232 |
+ |
|
| 233 |
+ if b.options.Squash {
|
|
| 234 |
+ if err := b.squashBuild(); err != nil {
|
|
| 235 |
+ return "", err |
|
| 223 | 236 |
} |
| 224 | 237 |
} |
| 225 | 238 |
|
| 239 |
+ fmt.Fprintf(b.Stdout, "Successfully built %s\n", shortImageID) |
|
| 240 |
+ if err := b.tagImages(repoAndTags); err != nil {
|
|
| 241 |
+ return "", err |
|
| 242 |
+ } |
|
| 243 |
+ return b.image, nil |
|
| 244 |
+} |
|
| 245 |
+ |
|
| 246 |
+func (b *Builder) dispatchDockerfileWithCancellation(dockerfile *parser.Node) (string, error) {
|
|
| 247 |
+ total := len(dockerfile.Children) |
|
| 248 |
+ var shortImgID string |
|
| 226 | 249 |
for i, n := range dockerfile.Children {
|
| 227 | 250 |
select {
|
| 228 | 251 |
case <-b.clientCtx.Done(): |
| ... | ... |
@@ -255,34 +267,20 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri |
| 255 | 255 |
return "", errors.Errorf("failed to reach build target %s in Dockerfile", b.options.Target)
|
| 256 | 256 |
} |
| 257 | 257 |
|
| 258 |
- b.warnOnUnusedBuildArgs() |
|
| 259 |
- |
|
| 260 |
- if b.image == "" {
|
|
| 261 |
- return "", errors.New("No image was generated. Is your Dockerfile empty?")
|
|
| 262 |
- } |
|
| 258 |
+ return shortImgID, nil |
|
| 259 |
+} |
|
| 263 | 260 |
|
| 264 |
- if b.options.Squash {
|
|
| 265 |
- var fromID string |
|
| 266 |
- if b.from != nil {
|
|
| 267 |
- fromID = b.from.ImageID() |
|
| 268 |
- } |
|
| 269 |
- b.image, err = b.docker.SquashImage(b.image, fromID) |
|
| 270 |
- if err != nil {
|
|
| 271 |
- return "", errors.Wrap(err, "error squashing image") |
|
| 272 |
- } |
|
| 261 |
+func (b *Builder) squashBuild() error {
|
|
| 262 |
+ var fromID string |
|
| 263 |
+ var err error |
|
| 264 |
+ if b.from != nil {
|
|
| 265 |
+ fromID = b.from.ImageID() |
|
| 273 | 266 |
} |
| 274 |
- |
|
| 275 |
- fmt.Fprintf(b.Stdout, "Successfully built %s\n", shortImgID) |
|
| 276 |
- |
|
| 277 |
- imageID := image.ID(b.image) |
|
| 278 |
- for _, rt := range repoAndTags {
|
|
| 279 |
- if err := b.docker.TagImageWithReference(imageID, rt); err != nil {
|
|
| 280 |
- return "", err |
|
| 281 |
- } |
|
| 282 |
- fmt.Fprintf(b.Stdout, "Successfully tagged %s\n", reference.FamiliarString(rt)) |
|
| 267 |
+ b.image, err = b.docker.SquashImage(b.image, fromID) |
|
| 268 |
+ if err != nil {
|
|
| 269 |
+ return errors.Wrap(err, "error squashing image") |
|
| 283 | 270 |
} |
| 284 |
- |
|
| 285 |
- return b.image, nil |
|
| 271 |
+ return nil |
|
| 286 | 272 |
} |
| 287 | 273 |
|
| 288 | 274 |
func addNodesForLabelOption(dockerfile *parser.Node, labels map[string]string) {
|
| ... | ... |
@@ -303,6 +301,17 @@ func (b *Builder) warnOnUnusedBuildArgs() {
|
| 303 | 303 |
} |
| 304 | 304 |
} |
| 305 | 305 |
|
| 306 |
+func (b *Builder) tagImages(repoAndTags []reference.Named) error {
|
|
| 307 |
+ imageID := image.ID(b.image) |
|
| 308 |
+ for _, rt := range repoAndTags {
|
|
| 309 |
+ if err := b.docker.TagImageWithReference(imageID, rt); err != nil {
|
|
| 310 |
+ return err |
|
| 311 |
+ } |
|
| 312 |
+ fmt.Fprintf(b.Stdout, "Successfully tagged %s\n", reference.FamiliarString(rt)) |
|
| 313 |
+ } |
|
| 314 |
+ return nil |
|
| 315 |
+} |
|
| 316 |
+ |
|
| 306 | 317 |
// hasFromImage returns true if the builder has processed a `FROM <image>` line |
| 307 | 318 |
func (b *Builder) hasFromImage() bool {
|
| 308 | 319 |
return b.image != "" || b.noBaseImage |
| ... | ... |
@@ -345,18 +354,31 @@ func BuildFromConfig(config *container.Config, changes []string) (*container.Con |
| 345 | 345 |
b.Stderr = ioutil.Discard |
| 346 | 346 |
b.disableCommit = true |
| 347 | 347 |
|
| 348 |
- total := len(ast.Children) |
|
| 349 |
- for _, n := range ast.Children {
|
|
| 350 |
- if err := b.checkDispatch(n, false); err != nil {
|
|
| 351 |
- return nil, err |
|
| 348 |
+ if err := checkDispatchDockerfile(ast); err != nil {
|
|
| 349 |
+ return nil, err |
|
| 350 |
+ } |
|
| 351 |
+ |
|
| 352 |
+ if err := dispatchFromDockerfile(b, ast); err != nil {
|
|
| 353 |
+ return nil, err |
|
| 354 |
+ } |
|
| 355 |
+ return b.runConfig, nil |
|
| 356 |
+} |
|
| 357 |
+ |
|
| 358 |
+func checkDispatchDockerfile(dockerfile *parser.Node) error {
|
|
| 359 |
+ for _, n := range dockerfile.Children {
|
|
| 360 |
+ if err := checkDispatch(n); err != nil {
|
|
| 361 |
+ return errors.Wrapf(err, "Dockerfile parse error line %d", n.StartLine) |
|
| 352 | 362 |
} |
| 353 | 363 |
} |
| 364 |
+ return nil |
|
| 365 |
+} |
|
| 354 | 366 |
|
| 367 |
+func dispatchFromDockerfile(b *Builder, ast *parser.Node) error {
|
|
| 368 |
+ total := len(ast.Children) |
|
| 355 | 369 |
for i, n := range ast.Children {
|
| 356 | 370 |
if err := b.dispatch(i, total, n); err != nil {
|
| 357 |
- return nil, err |
|
| 371 |
+ return err |
|
| 358 | 372 |
} |
| 359 | 373 |
} |
| 360 |
- |
|
| 361 |
- return b.runConfig, nil |
|
| 374 |
+ return nil |
|
| 362 | 375 |
} |
| ... | ... |
@@ -206,8 +206,7 @@ func (b *Builder) runConfigEnvMapping() map[string]string {
|
| 206 | 206 |
// arg, env, etc., this syntax check will not be complete and could not replace |
| 207 | 207 |
// the runtime check. Instead, this function is only a helper that allows |
| 208 | 208 |
// user to find out the obvious error in Dockerfile earlier on. |
| 209 |
-// onbuild bool: indicate if instruction XXX is part of `ONBUILD XXX` trigger |
|
| 210 |
-func (b *Builder) checkDispatch(ast *parser.Node, onbuild bool) error {
|
|
| 209 |
+func checkDispatch(ast *parser.Node) error {
|
|
| 211 | 210 |
cmd := ast.Value |
| 212 | 211 |
upperCasedCmd := strings.ToUpper(cmd) |
| 213 | 212 |
|
| ... | ... |
@@ -225,16 +224,6 @@ func (b *Builder) checkDispatch(ast *parser.Node, onbuild bool) error {
|
| 225 | 225 |
} |
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 |
- // The instruction is part of ONBUILD trigger (not the instruction itself) |
|
| 229 |
- if onbuild {
|
|
| 230 |
- switch upperCasedCmd {
|
|
| 231 |
- case "ONBUILD": |
|
| 232 |
- return errors.New("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
|
|
| 233 |
- case "MAINTAINER", "FROM": |
|
| 234 |
- return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", upperCasedCmd)
|
|
| 235 |
- } |
|
| 236 |
- } |
|
| 237 |
- |
|
| 238 | 228 |
if _, ok := evaluateTable[cmd]; ok {
|
| 239 | 229 |
return nil |
| 240 | 230 |
} |
| ... | ... |
@@ -467,19 +467,24 @@ func (b *Builder) processImageFrom(img builder.Image) error {
|
| 467 | 467 |
return err |
| 468 | 468 |
} |
| 469 | 469 |
|
| 470 |
- total := len(ast.Children) |
|
| 471 | 470 |
for _, n := range ast.Children {
|
| 472 |
- if err := b.checkDispatch(n, true); err != nil {
|
|
| 471 |
+ if err := checkDispatch(n); err != nil {
|
|
| 473 | 472 |
return err |
| 474 | 473 |
} |
| 475 |
- } |
|
| 476 |
- for i, n := range ast.Children {
|
|
| 477 |
- if err := b.dispatch(i, total, n); err != nil {
|
|
| 478 |
- return err |
|
| 474 |
+ |
|
| 475 |
+ upperCasedCmd := strings.ToUpper(n.Value) |
|
| 476 |
+ switch upperCasedCmd {
|
|
| 477 |
+ case "ONBUILD": |
|
| 478 |
+ return errors.New("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
|
|
| 479 |
+ case "MAINTAINER", "FROM": |
|
| 480 |
+ return errors.Errorf("%s isn't allowed as an ONBUILD trigger", upperCasedCmd)
|
|
| 479 | 481 |
} |
| 480 | 482 |
} |
| 481 |
- } |
|
| 482 | 483 |
|
| 484 |
+ if err := dispatchFromDockerfile(b, ast); err != nil {
|
|
| 485 |
+ return err |
|
| 486 |
+ } |
|
| 487 |
+ } |
|
| 483 | 488 |
return nil |
| 484 | 489 |
} |
| 485 | 490 |
|
| ... | ... |
@@ -644,8 +649,8 @@ func (b *Builder) clearTmp() {
|
| 644 | 644 |
} |
| 645 | 645 |
} |
| 646 | 646 |
|
| 647 |
-// readDockerfile reads a Dockerfile from the current context. |
|
| 648 |
-func (b *Builder) readDockerfile() (*parser.Node, error) {
|
|
| 647 |
+// readAndParseDockerfile reads a Dockerfile from the current context. |
|
| 648 |
+func (b *Builder) readAndParseDockerfile() (*parser.Node, error) {
|
|
| 649 | 649 |
// If no -f was specified then look for 'Dockerfile'. If we can't find |
| 650 | 650 |
// that then look for 'dockerfile'. If neither are found then default |
| 651 | 651 |
// back to 'Dockerfile' and use that in the error message. |