diff --git a/command/push.go b/command/push.go index 95e50597f..6c04917dd 100644 --- a/command/push.go +++ b/command/push.go @@ -11,7 +11,6 @@ import ( "github.com/hashicorp/atlas-go/archive" "github.com/hashicorp/atlas-go/v1" "github.com/mitchellh/packer/template" - "github.com/mitchellh/packer/template/interpolate" ) // archiveTemplateEntry is the name the template always takes within the slug. @@ -73,13 +72,7 @@ func (c *PushCommand) Run(args []string) int { c.Ui.Error(err.Error()) return 1 } - push := tpl.Push - pushRaw, err := interpolate.RenderInterface(&push, core.Context()) - if err != nil { - c.Ui.Error(err.Error()) - return 1 - } - push = *pushRaw.(*template.Push) + push := core.Template.Push // If we didn't pass name from the CLI, use the template if name == "" { diff --git a/packer/core.go b/packer/core.go index bdf9cb65a..3bc5d295e 100644 --- a/packer/core.go +++ b/packer/core.go @@ -12,8 +12,9 @@ import ( // Core is the main executor of Packer. If Packer is being used as a // library, this is the struct you'll want to instantiate to get anything done. type Core struct { + Template *template.Template + components ComponentFinder - template *template.Template variables map[string]string builds map[string]*template.Builder } @@ -51,8 +52,8 @@ type ComponentFinder struct { // NewCore creates a new Core. func NewCore(c *CoreConfig) (*Core, error) { result := &Core{ + Template: c.Template, components: c.Components, - template: c.Template, variables: c.Variables, } if err := result.validate(); err != nil { @@ -112,8 +113,8 @@ func (c *Core) Build(n string) (Build, error) { rawName := configBuilder.Name // Setup the provisioners for this build - provisioners := make([]coreBuildProvisioner, 0, len(c.template.Provisioners)) - for _, rawP := range c.template.Provisioners { + provisioners := make([]coreBuildProvisioner, 0, len(c.Template.Provisioners)) + for _, rawP := range c.Template.Provisioners { // If we're skipping this, then ignore it if rawP.Skip(rawName) { continue @@ -155,8 +156,8 @@ func (c *Core) Build(n string) (Build, error) { } // Setup the post-processors - postProcessors := make([][]coreBuildPostProcessor, 0, len(c.template.PostProcessors)) - for _, rawPs := range c.template.PostProcessors { + postProcessors := make([][]coreBuildPostProcessor, 0, len(c.Template.PostProcessors)) + for _, rawPs := range c.Template.PostProcessors { current := make([]coreBuildPostProcessor, 0, len(rawPs)) for _, rawP := range rawPs { // If we skip, ignore @@ -201,7 +202,7 @@ func (c *Core) Build(n string) (Build, error) { builderType: configBuilder.Type, postProcessors: postProcessors, provisioners: provisioners, - templatePath: c.template.Path, + templatePath: c.Template.Path, variables: c.variables, }, nil } @@ -209,7 +210,7 @@ func (c *Core) Build(n string) (Build, error) { // Context returns an interpolation context. func (c *Core) Context() *interpolate.Context { return &interpolate.Context{ - TemplatePath: c.template.Path, + TemplatePath: c.Template.Path, UserVariables: c.variables, } } @@ -221,13 +222,13 @@ func (c *Core) Context() *interpolate.Context { func (c *Core) validate() error { // First validate the template in general, we can't do anything else // unless the template itself is valid. - if err := c.template.Validate(); err != nil { + if err := c.Template.Validate(); err != nil { return err } // Validate variables are set var err error - for n, v := range c.template.Variables { + for n, v := range c.Template.Variables { if v.Required { if _, ok := c.variables[n]; !ok { err = multierror.Append(err, fmt.Errorf( @@ -252,7 +253,7 @@ func (c *Core) init() error { ctx := c.Context() ctx.EnableEnv = true ctx.UserVariables = nil - for k, v := range c.template.Variables { + for k, v := range c.Template.Variables { // Ignore variables that are required if v.Required { continue @@ -274,5 +275,10 @@ func (c *Core) init() error { c.variables[k] = def } + // Interpolate the push configuration + if _, err := interpolate.RenderInterface(&c.Template.Push, c.Context()); err != nil { + return fmt.Errorf("Error interpolating 'push': %s", err) + } + return nil } diff --git a/packer/core_test.go b/packer/core_test.go index cc03574ed..f11242d0c 100644 --- a/packer/core_test.go +++ b/packer/core_test.go @@ -368,6 +368,40 @@ func TestCoreBuild_templatePath(t *testing.T) { } } +func TestCore_pushInterpolate(t *testing.T) { + cases := []struct { + File string + Vars map[string]string + Result template.Push + }{ + { + "push-vars.json", + map[string]string{"foo": "bar"}, + template.Push{Name: "bar"}, + }, + } + + for _, tc := range cases { + tpl, err := template.ParseFile(fixtureDir(tc.File)) + if err != nil { + t.Fatalf("err: %s\n\n%s", tc.File, err) + } + + core, err := NewCore(&CoreConfig{ + Template: tpl, + Variables: tc.Vars, + }) + if err != nil { + t.Fatalf("err: %s\n\n%s", tc.File, err) + } + + expected := core.Template.Push + if !reflect.DeepEqual(expected, tc.Result) { + t.Fatalf("err: %s\n\n%#v", tc.File, expected) + } + } +} + func TestCoreValidate(t *testing.T) { cases := []struct { File string diff --git a/packer/test-fixtures/push-vars.json b/packer/test-fixtures/push-vars.json new file mode 100644 index 000000000..b5f518100 --- /dev/null +++ b/packer/test-fixtures/push-vars.json @@ -0,0 +1,11 @@ +{ + "variables": { + "foo": null + }, + + "builders": [{"type": "test"}], + + "push": { + "name": "{{user `foo`}}" + } +}