func BuildFromConfig(d *daemon.Daemon, c *runconfig.Config, changes []string) (*runconfig.Config, error) { ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n"))) if err != nil { return nil, err } // ensure that the commands are valid for _, n := range ast.Children { if !validCommitCommands[n.Value] { return nil, fmt.Errorf("%s is not a valid change command", n.Value) } } builder := &Builder{ Daemon: d, Config: c, OutStream: ioutil.Discard, ErrStream: ioutil.Discard, disableCommit: true, } for i, n := range ast.Children { if err := builder.dispatch(i, n); err != nil { return nil, err } } return builder.Config, nil }
func (b *Builder) processImageFrom(img *imagepkg.Image) error { b.image = img.ID if img.Config != nil { b.Config = img.Config } if len(b.Config.Env) == 0 { b.Config.Env = append(b.Config.Env, "PATH="+daemon.DefaultPathEnv) } // Process ONBUILD triggers if they exist if nTriggers := len(b.Config.OnBuild); nTriggers != 0 { fmt.Fprintf(b.ErrStream, "# Executing %d build triggers\n", nTriggers) } // Copy the ONBUILD triggers, and remove them from the config, since the config will be committed. onBuildTriggers := b.Config.OnBuild b.Config.OnBuild = []string{} // parse the ONBUILD triggers by invoking the parser for stepN, step := range onBuildTriggers { ast, err := parser.Parse(strings.NewReader(step)) if err != nil { return err } for i, n := range ast.Children { switch strings.ToUpper(n.Value) { 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", n.Value) } fmt.Fprintf(b.OutStream, "Trigger %d, %s\n", stepN, step) if err := b.dispatch(i, n); err != nil { return err } } } return nil }