|
@@ -201,3 +201,44 @@ func (b *Builder) dispatch(stepN int, stepTotal int, ast *parser.Node) error {
|
|
|
|
|
|
return fmt.Errorf("Unknown instruction: %s", upperCasedCmd)
|
|
|
}
|
|
|
+
|
|
|
+// checkDispatch does a simple check for syntax errors of the Dockerfile.
|
|
|
+// Because some of the instructions can only be validated through runtime,
|
|
|
+// arg, env, etc., this syntax check will not be complete and could not replace
|
|
|
+// the runtime check. Instead, this function is only a helper that allows
|
|
|
+// user to find out the obvious error in Dockerfile earlier on.
|
|
|
+// onbuild bool: indicate if instruction XXX is part of `ONBUILD XXX` trigger
|
|
|
+func (b *Builder) checkDispatch(ast *parser.Node, onbuild bool) error {
|
|
|
+ cmd := ast.Value
|
|
|
+ upperCasedCmd := strings.ToUpper(cmd)
|
|
|
+
|
|
|
+ // To ensure the user is given a decent error message if the platform
|
|
|
+ // on which the daemon is running does not support a builder command.
|
|
|
+ if err := platformSupports(strings.ToLower(cmd)); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ // The instruction itself is ONBUILD, we will make sure it follows with at
|
|
|
+ // least one argument
|
|
|
+ if upperCasedCmd == "ONBUILD" {
|
|
|
+ if ast.Next == nil {
|
|
|
+ return fmt.Errorf("ONBUILD requires at least one argument")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // The instruction is part of ONBUILD trigger (not the instruction itself)
|
|
|
+ if onbuild {
|
|
|
+ switch upperCasedCmd {
|
|
|
+ case "ONBUILD":
|
|
|
+ return fmt.Errorf("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
|
|
|
+ case "MAINTAINER", "FROM":
|
|
|
+ return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", upperCasedCmd)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if _, ok := evaluateTable[cmd]; ok {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ return fmt.Errorf("Unknown instruction: %s", upperCasedCmd)
|
|
|
+}
|