From 3f9df2992cafc18ac06d9fdfaf5cb906a15b34f5 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 1 Jul 2013 15:07:09 -0700 Subject: [PATCH] post-processor/vagrant: make output contain build name by default [GH-92] --- packer/template.go | 250 +++++++++++------------ post-processor/vagrant/aws.go | 5 +- post-processor/vagrant/post-processor.go | 10 +- post-processor/vagrant/util.go | 4 +- post-processor/vagrant/virtualbox.go | 5 +- post-processor/vagrant/vmware.go | 6 +- 6 files changed, 148 insertions(+), 132 deletions(-) diff --git a/packer/template.go b/packer/template.go index c94dd8fc3..fb24df062 100644 --- a/packer/template.go +++ b/packer/template.go @@ -76,14 +76,14 @@ func ParseTemplate(data []byte) (t *Template, err error) { newline := []byte{'\x0a'} // Calculate the start/end position of the line where the error is - start := bytes.LastIndex(data[:syntaxErr.Offset], newline)+1 + start := bytes.LastIndex(data[:syntaxErr.Offset], newline) + 1 end := len(data) if idx := bytes.Index(data[start:], newline); idx >= 0 { end = start + idx } // Count the line number we're on plus the offset in the line - line := bytes.Count(data[:start], newline)+1 + line := bytes.Count(data[:start], newline) + 1 pos := int(syntaxErr.Offset) - start - 1 err = fmt.Errorf("Error in line %d, char %d: %s\n%s", @@ -230,151 +230,151 @@ func parsePostProvisioner(i int, rawV interface{}) (result []map[string]interfac errors = append( errors, fmt.Errorf("Post-processor %d.%d: sequences not allowed to be nested in sequences", i+1, j+1)) - default: - errors = append(errors, fmt.Errorf("Post-processor %d.%d is in a bad format.", i+1, j+1)) - } + default: + errors = append(errors, fmt.Errorf("Post-processor %d.%d is in a bad format.", i+1, j+1)) } - - if len(errors) == 0 { - errors = nil - } - default: - result = nil - errors = []error{fmt.Errorf("Post-processor %d is in a bad format.", i+1)} } + if len(errors) == 0 { + errors = nil + } + default: + result = nil + errors = []error{fmt.Errorf("Post-processor %d is in a bad format.", i+1)} + } + + return +} + +// BuildNames returns a slice of the available names of builds that +// this template represents. +func (t *Template) BuildNames() []string { + names := make([]string, 0, len(t.Builders)) + for name, _ := range t.Builders { + names = append(names, name) + } + + return names +} + +// Build returns a Build for the given name. +// +// If the build does not exist as part of this template, an error is +// returned. +func (t *Template) Build(name string, components *ComponentFinder) (b Build, err error) { + // Setup the Builder + builderConfig, ok := t.Builders[name] + if !ok { + err = fmt.Errorf("No such build found in template: %s", name) return } - // BuildNames returns a slice of the available names of builds that - // this template represents. - func (t *Template) BuildNames() []string { - names := make([]string, 0, len(t.Builders)) - for name, _ := range t.Builders { - names = append(names, name) - } - - return names + // We panic if there is no builder function because this is really + // an internal bug that always needs to be fixed, not an error. + if components.Builder == nil { + panic("no builder function") } - // Build returns a Build for the given name. - // - // If the build does not exist as part of this template, an error is - // returned. - func (t *Template) Build(name string, components *ComponentFinder) (b Build, err error) { - // Setup the Builder - builderConfig, ok := t.Builders[name] - if !ok { - err = fmt.Errorf("No such build found in template: %s", name) - return - } + // Panic if there are provisioners on the template but no provisioner + // component finder. This is always an internal error, so we panic. + if len(t.Provisioners) > 0 && components.Provisioner == nil { + panic("no provisioner function") + } - // We panic if there is no builder function because this is really - // an internal bug that always needs to be fixed, not an error. - if components.Builder == nil { - panic("no builder function") - } + builder, err := components.Builder(builderConfig.Type) + if err != nil { + return + } - // Panic if there are provisioners on the template but no provisioner - // component finder. This is always an internal error, so we panic. - if len(t.Provisioners) > 0 && components.Provisioner == nil { - panic("no provisioner function") - } + if builder == nil { + err = fmt.Errorf("Builder type not found: %s", builderConfig.Type) + return + } - builder, err := components.Builder(builderConfig.Type) - if err != nil { - return - } + // Gather the Hooks + hooks := make(map[string][]Hook) + for tplEvent, tplHooks := range t.Hooks { + curHooks := make([]Hook, 0, len(tplHooks)) - if builder == nil { - err = fmt.Errorf("Builder type not found: %s", builderConfig.Type) - return - } - - // Gather the Hooks - hooks := make(map[string][]Hook) - for tplEvent, tplHooks := range t.Hooks { - curHooks := make([]Hook, 0, len(tplHooks)) - - for _, hookName := range tplHooks { - var hook Hook - hook, err = components.Hook(hookName) - if err != nil { - return - } - - if hook == nil { - err = fmt.Errorf("Hook not found: %s", hookName) - return - } - - curHooks = append(curHooks, hook) - } - - hooks[tplEvent] = curHooks - } - - // Prepare the post-processors - postProcessors := make([][]coreBuildPostProcessor, 0, len(t.PostProcessors)) - for _, rawPPs := range t.PostProcessors { - current := make([]coreBuildPostProcessor, len(rawPPs)) - for i, rawPP := range rawPPs { - pp, err := components.PostProcessor(rawPP.Type) - if err != nil { - return nil, err - } - - if pp == nil { - return nil, fmt.Errorf("PostProcessor type not found: %s", rawPP.Type) - } - - current[i] = coreBuildPostProcessor{ - processor: pp, - processorType: rawPP.Type, - config: rawPP.rawConfig, - keepInputArtifact: rawPP.KeepInputArtifact, - } - } - - postProcessors = append(postProcessors, current) - } - - // Prepare the provisioners - provisioners := make([]coreBuildProvisioner, 0, len(t.Provisioners)) - for _, rawProvisioner := range t.Provisioners { - var provisioner Provisioner - provisioner, err = components.Provisioner(rawProvisioner.Type) + for _, hookName := range tplHooks { + var hook Hook + hook, err = components.Hook(hookName) if err != nil { return } - if provisioner == nil { - err = fmt.Errorf("Provisioner type not found: %s", rawProvisioner.Type) + if hook == nil { + err = fmt.Errorf("Hook not found: %s", hookName) return } - configs := make([]interface{}, 1, 2) - configs[0] = rawProvisioner.rawConfig + curHooks = append(curHooks, hook) + } - if rawProvisioner.Override != nil { - if override, ok := rawProvisioner.Override[name]; ok { - configs = append(configs, override) - } + hooks[tplEvent] = curHooks + } + + // Prepare the post-processors + postProcessors := make([][]coreBuildPostProcessor, 0, len(t.PostProcessors)) + for _, rawPPs := range t.PostProcessors { + current := make([]coreBuildPostProcessor, len(rawPPs)) + for i, rawPP := range rawPPs { + pp, err := components.PostProcessor(rawPP.Type) + if err != nil { + return nil, err } - coreProv := coreBuildProvisioner{provisioner, configs} - provisioners = append(provisioners, coreProv) + if pp == nil { + return nil, fmt.Errorf("PostProcessor type not found: %s", rawPP.Type) + } + + current[i] = coreBuildPostProcessor{ + processor: pp, + processorType: rawPP.Type, + config: rawPP.rawConfig, + keepInputArtifact: rawPP.KeepInputArtifact, + } } - b = &coreBuild{ - name: name, - builder: builder, - builderConfig: builderConfig.rawConfig, - builderType: builderConfig.Type, - hooks: hooks, - postProcessors: postProcessors, - provisioners: provisioners, - } - - return + postProcessors = append(postProcessors, current) } + + // Prepare the provisioners + provisioners := make([]coreBuildProvisioner, 0, len(t.Provisioners)) + for _, rawProvisioner := range t.Provisioners { + var provisioner Provisioner + provisioner, err = components.Provisioner(rawProvisioner.Type) + if err != nil { + return + } + + if provisioner == nil { + err = fmt.Errorf("Provisioner type not found: %s", rawProvisioner.Type) + return + } + + configs := make([]interface{}, 1, 2) + configs[0] = rawProvisioner.rawConfig + + if rawProvisioner.Override != nil { + if override, ok := rawProvisioner.Override[name]; ok { + configs = append(configs, override) + } + } + + coreProv := coreBuildProvisioner{provisioner, configs} + provisioners = append(provisioners, coreProv) + } + + b = &coreBuild{ + name: name, + builder: builder, + builderConfig: builderConfig.rawConfig, + builderType: builderConfig.Type, + hooks: hooks, + postProcessors: postProcessors, + provisioners: provisioners, + } + + return +} diff --git a/post-processor/vagrant/aws.go b/post-processor/vagrant/aws.go index c4284c3f8..9ca633f16 100644 --- a/post-processor/vagrant/aws.go +++ b/post-processor/vagrant/aws.go @@ -14,6 +14,8 @@ import ( type AWSBoxConfig struct { OutputPath string `mapstructure:"output"` VagrantfileTemplate string `mapstructure:"vagrantfile_template"` + + PackerBuildName string `mapstructure:"packer_build_name"` } type AWSVagrantfileTemplate struct { @@ -51,7 +53,8 @@ func (p *AWSBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact } // Compile the output path - outputPath, err := ProcessOutputPath(p.config.OutputPath, "aws", artifact) + outputPath, err := ProcessOutputPath(p.config.OutputPath, + p.config.PackerBuildName, "aws", artifact) if err != nil { return nil, false, err } diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index 0dd1e4bf2..3b6c8cd47 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -19,6 +19,8 @@ var builtins = map[string]string{ type Config struct { OutputPath string `mapstructure:"output"` + + PackerBuildName string `mapstructure:"packer_build_name"` } type PostProcessor struct { @@ -35,7 +37,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { } if p.config.OutputPath == "" { - p.config.OutputPath = "packer_{{.Provider}}.box" + p.config.OutputPath = "packer_{{ .BuildName }}_{{.Provider}}.box" } _, err := template.New("output").Parse(p.config.OutputPath) @@ -49,6 +51,10 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { return err } + packerConfig := map[string]interface{}{ + packer.BuildNameConfigKey: p.config.PackerBuildName, + } + p.premade = make(map[string]packer.PostProcessor) errors := make([]error, 0) for k, raw := range mapConfig { @@ -57,7 +63,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { continue } - if err := pp.Configure(raw); err != nil { + if err := pp.Configure(raw, packerConfig); err != nil { errors = append(errors, err) } diff --git a/post-processor/vagrant/util.go b/post-processor/vagrant/util.go index 515f7f3d8..5eee761a8 100644 --- a/post-processor/vagrant/util.go +++ b/post-processor/vagrant/util.go @@ -17,6 +17,7 @@ import ( // OutputPath variables. type OutputPathTemplate struct { ArtifactId string + BuildName string Provider string } @@ -83,11 +84,12 @@ func DirToBox(dst, dir string) error { // ProcessOutputPath takes an output path template and executes it, // replacing variables with their respective values. -func ProcessOutputPath(path string, provider string, artifact packer.Artifact) (string, error) { +func ProcessOutputPath(path string, buildName string, provider string, artifact packer.Artifact) (string, error) { var buf bytes.Buffer tplData := &OutputPathTemplate{ ArtifactId: artifact.Id(), + BuildName: buildName, Provider: provider, } diff --git a/post-processor/vagrant/virtualbox.go b/post-processor/vagrant/virtualbox.go index 50aad8c71..fd8b7dfce 100644 --- a/post-processor/vagrant/virtualbox.go +++ b/post-processor/vagrant/virtualbox.go @@ -18,6 +18,8 @@ import ( type VBoxBoxConfig struct { OutputPath string `mapstructure:"output"` VagrantfileTemplate string `mapstructure:"vagrantfile_template"` + + PackerBuildName string `mapstructure:"packer_build_name"` } type VBoxVagrantfileTemplate struct { @@ -48,7 +50,8 @@ func (p *VBoxBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifac } // Compile the output path - outputPath, err := ProcessOutputPath(p.config.OutputPath, "virtualbox", artifact) + outputPath, err := ProcessOutputPath(p.config.OutputPath, + p.config.PackerBuildName, "virtualbox", artifact) if err != nil { return nil, false, err } diff --git a/post-processor/vagrant/vmware.go b/post-processor/vagrant/vmware.go index 310192f39..211e6322c 100644 --- a/post-processor/vagrant/vmware.go +++ b/post-processor/vagrant/vmware.go @@ -14,6 +14,8 @@ import ( type VMwareBoxConfig struct { OutputPath string `mapstructure:"output"` VagrantfileTemplate string `mapstructure:"vagrantfile_template"` + + PackerBuildName string `mapstructure:"packer_build_name"` } type VMwareBoxPostProcessor struct { @@ -28,13 +30,13 @@ func (p *VMwareBoxPostProcessor) Configure(raws ...interface{}) error { } } - return nil } func (p *VMwareBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { // Compile the output path - outputPath, err := ProcessOutputPath(p.config.OutputPath, "vmware", artifact) + outputPath, err := ProcessOutputPath(p.config.OutputPath, + p.config.PackerBuildName, "vmware", artifact) if err != nil { return nil, false, err }