From 141cfeb4bbadfcca4d926be363db8d7ff591837e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 25 Dec 2013 16:01:57 -0700 Subject: [PATCH] builder/vmware/vmx: outputdir --- builder/vmware/common/output_config.go | 40 +++++++++++++ builder/vmware/common/output_config_test.go | 65 +++++++++++++++++++++ builder/vmware/iso/builder.go | 21 ++----- builder/vmware/vmx/builder.go | 11 +++- builder/vmware/vmx/config.go | 6 +- builder/vmware/vmx/config_test.go | 27 +++++++++ 6 files changed, 151 insertions(+), 19 deletions(-) create mode 100644 builder/vmware/common/output_config.go create mode 100644 builder/vmware/common/output_config_test.go create mode 100644 builder/vmware/vmx/config_test.go diff --git a/builder/vmware/common/output_config.go b/builder/vmware/common/output_config.go new file mode 100644 index 000000000..19be1ba00 --- /dev/null +++ b/builder/vmware/common/output_config.go @@ -0,0 +1,40 @@ +package common + +import ( + "fmt" + "github.com/mitchellh/packer/common" + "github.com/mitchellh/packer/packer" + "os" +) + +type OutputConfig struct { + OutputDir string `mapstructure:"output_directory"` +} + +func (c *OutputConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig) []error { + if c.OutputDir == "" { + c.OutputDir = fmt.Sprintf("output-%s", pc.PackerBuildName) + } + + templates := map[string]*string{ + "output_directory": &c.OutputDir, + } + + errs := make([]error, 0) + for n, ptr := range templates { + var err error + *ptr, err = t.Process(*ptr, nil) + if err != nil { + errs = append(errs, fmt.Errorf("Error processing %s: %s", n, err)) + } + } + + if !pc.PackerForce { + if _, err := os.Stat(c.OutputDir); err == nil { + errs = append(errs, fmt.Errorf( + "Output directory '%s' already exists. It must not exist.", c.OutputDir)) + } + } + + return errs +} diff --git a/builder/vmware/common/output_config_test.go b/builder/vmware/common/output_config_test.go new file mode 100644 index 000000000..7fa039a16 --- /dev/null +++ b/builder/vmware/common/output_config_test.go @@ -0,0 +1,65 @@ +package common + +import ( + "github.com/mitchellh/packer/common" + "io/ioutil" + "os" + "testing" +) + +func TestOutputConfigPrepare(t *testing.T) { + c := new(OutputConfig) + if c.OutputDir != "" { + t.Fatalf("what: %s", c.OutputDir) + } + + pc := &common.PackerConfig{PackerBuildName: "foo"} + errs := c.Prepare(testConfigTemplate(t), pc) + if len(errs) > 0 { + t.Fatalf("err: %#v", errs) + } + + if c.OutputDir == "" { + t.Fatal("should have output dir") + } +} + +func TestOutputConfigPrepare_exists(t *testing.T) { + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + + c := new(OutputConfig) + c.OutputDir = td + + pc := &common.PackerConfig{ + PackerBuildName: "foo", + PackerForce: false, + } + errs := c.Prepare(testConfigTemplate(t), pc) + if len(errs) == 0 { + t.Fatal("should have errors") + } +} + +func TestOutputConfigPrepare_forceExists(t *testing.T) { + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + + c := new(OutputConfig) + c.OutputDir = td + + pc := &common.PackerConfig{ + PackerBuildName: "foo", + PackerForce: true, + } + errs := c.Prepare(testConfigTemplate(t), pc) + if len(errs) > 0 { + t.Fatal("should not have errors") + } +} diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 52bf48daa..3272d0036 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -24,8 +24,9 @@ type Builder struct { } type config struct { - common.PackerConfig `mapstructure:",squash"` - vmwcommon.SSHConfig `mapstructure:",squash"` + common.PackerConfig `mapstructure:",squash"` + vmwcommon.OutputConfig `mapstructure:",squash"` + vmwcommon.SSHConfig `mapstructure:",squash"` DiskName string `mapstructure:"vmdk_name"` DiskSize uint `mapstructure:"disk_size"` @@ -36,7 +37,6 @@ type config struct { ISOChecksumType string `mapstructure:"iso_checksum_type"` ISOUrls []string `mapstructure:"iso_urls"` VMName string `mapstructure:"vm_name"` - OutputDir string `mapstructure:"output_directory"` Headless bool `mapstructure:"headless"` HTTPDir string `mapstructure:"http_directory"` HTTPPortMin uint `mapstructure:"http_port_min"` @@ -81,6 +81,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { // Accumulate any errors errs := common.CheckUnusedConfig(md) + errs = packer.MultiErrorAppend(errs, + b.config.OutputConfig.Prepare(b.config.tpl, &b.config.PackerConfig)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(b.config.tpl)...) warnings := make([]string, 0) @@ -133,10 +135,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.VNCPortMax = 6000 } - if b.config.OutputDir == "" { - b.config.OutputDir = fmt.Sprintf("output-%s", b.config.PackerBuildName) - } - if b.config.RemoteUser == "" { b.config.RemoteUser = "root" } @@ -161,7 +159,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "iso_checksum": &b.config.ISOChecksum, "iso_checksum_type": &b.config.ISOChecksumType, "iso_url": &b.config.RawSingleISOUrl, - "output_directory": &b.config.OutputDir, "shutdown_command": &b.config.ShutdownCommand, "tools_upload_flavor": &b.config.ToolsUploadFlavor, "vm_name": &b.config.VMName, @@ -273,14 +270,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } - if !b.config.PackerForce { - if _, err := os.Stat(b.config.OutputDir); err == nil { - errs = packer.MultiErrorAppend( - errs, - fmt.Errorf("Output directory '%s' already exists. It must not exist.", b.config.OutputDir)) - } - } - if b.config.RawBootWait != "" { b.config.bootWait, err = time.ParseDuration(b.config.RawBootWait) if err != nil { diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index 2ef4a418b..c401e0a9e 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -36,15 +36,24 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, fmt.Errorf("Failed creating VMware driver: %s", err) } + // Setup the directory + dir := new(vmwcommon.LocalOutputDir) + dir.SetOutputDir(b.config.OutputDir) + // Set up the state. state := new(multistep.BasicStateBag) state.Put("config", b.config) + state.Put("dir", dir) state.Put("driver", driver) state.Put("hook", hook) state.Put("ui", ui) // Build the steps. - steps := []multistep.Step{} + steps := []multistep.Step{ + &vmwcommon.StepOutputDir{ + Force: b.config.PackerForce, + }, + } // Run the steps. if b.config.PackerDebug { diff --git a/builder/vmware/vmx/config.go b/builder/vmware/vmx/config.go index c31b7d11d..b4f45c4af 100644 --- a/builder/vmware/vmx/config.go +++ b/builder/vmware/vmx/config.go @@ -10,8 +10,9 @@ import ( // Config is the configuration structure for the builder. type Config struct { - common.PackerConfig `mapstructure:",squash"` - vmwcommon.SSHConfig `mapstructure:",squash"` + common.PackerConfig `mapstructure:",squash"` + vmwcommon.OutputConfig `mapstructure:",squash"` + vmwcommon.SSHConfig `mapstructure:",squash"` tpl *packer.ConfigTemplate } @@ -33,6 +34,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { // Prepare the errors errs := common.CheckUnusedConfig(md) + errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(c.tpl, &c.PackerConfig)...) errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...) templates := map[string]*string{} diff --git a/builder/vmware/vmx/config_test.go b/builder/vmware/vmx/config_test.go new file mode 100644 index 000000000..7128d8a71 --- /dev/null +++ b/builder/vmware/vmx/config_test.go @@ -0,0 +1,27 @@ +package vmx + +import ( + "testing" +) + +func testConfig(t *testing.T) map[string]interface{} { + return map[string]interface{}{} +} + +func testConfigErr(t *testing.T, warns []string, err error) { + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should error") + } +} + +func testConfigOk(t *testing.T, warns []string, err error) { + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("bad: %s", err) + } +}