diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go new file mode 100644 index 000000000..2ef4a418b --- /dev/null +++ b/builder/vmware/vmx/builder.go @@ -0,0 +1,83 @@ +package vmx + +import ( + "errors" + "fmt" + "github.com/mitchellh/multistep" + vmwcommon "github.com/mitchellh/packer/builder/vmware/common" + "github.com/mitchellh/packer/common" + "github.com/mitchellh/packer/packer" + "log" +) + +// Builder implements packer.Builder and builds the actual VirtualBox +// images. +type Builder struct { + config *Config + runner multistep.Runner +} + +// Prepare processes the build configuration parameters. +func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + c, warnings, errs := NewConfig(raws...) + if errs != nil { + return warnings, errs + } + b.config = c + + return warnings, nil +} + +// Run executes a Packer build and returns a packer.Artifact representing +// a VirtualBox appliance. +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + driver, err := vmwcommon.NewDriver(&b.config.SSHConfig) + if err != nil { + return nil, fmt.Errorf("Failed creating VMware driver: %s", err) + } + + // Set up the state. + state := new(multistep.BasicStateBag) + state.Put("config", b.config) + state.Put("driver", driver) + state.Put("hook", hook) + state.Put("ui", ui) + + // Build the steps. + steps := []multistep.Step{} + + // Run the steps. + if b.config.PackerDebug { + b.runner = &multistep.DebugRunner{ + Steps: steps, + PauseFn: common.MultistepDebugFn(ui), + } + } else { + b.runner = &multistep.BasicRunner{Steps: steps} + } + b.runner.Run(state) + + // Report any errors. + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + + // If we were interrupted or cancelled, then just exit. + if _, ok := state.GetOk(multistep.StateCancelled); ok { + return nil, errors.New("Build was cancelled.") + } + + if _, ok := state.GetOk(multistep.StateHalted); ok { + return nil, errors.New("Build was halted.") + } + + return nil, nil +} + +// Cancel. +func (b *Builder) Cancel() { + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } +} diff --git a/builder/vmware/vmx/builder_test.go b/builder/vmware/vmx/builder_test.go new file mode 100644 index 000000000..e6b128721 --- /dev/null +++ b/builder/vmware/vmx/builder_test.go @@ -0,0 +1 @@ +package vmx diff --git a/builder/vmware/vmx/config.go b/builder/vmware/vmx/config.go new file mode 100644 index 000000000..c31b7d11d --- /dev/null +++ b/builder/vmware/vmx/config.go @@ -0,0 +1,58 @@ +package vmx + +import ( + "fmt" + + vmwcommon "github.com/mitchellh/packer/builder/vmware/common" + "github.com/mitchellh/packer/common" + "github.com/mitchellh/packer/packer" +) + +// Config is the configuration structure for the builder. +type Config struct { + common.PackerConfig `mapstructure:",squash"` + vmwcommon.SSHConfig `mapstructure:",squash"` + + tpl *packer.ConfigTemplate +} + +func NewConfig(raws ...interface{}) (*Config, []string, error) { + c := new(Config) + md, err := common.DecodeConfig(c, raws...) + if err != nil { + return nil, nil, err + } + + c.tpl, err = packer.NewConfigTemplate() + if err != nil { + return nil, nil, err + } + c.tpl.UserVars = c.PackerUserVars + + // Defaults + + // Prepare the errors + errs := common.CheckUnusedConfig(md) + errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...) + + templates := map[string]*string{} + + for n, ptr := range templates { + var err error + *ptr, err = c.tpl.Process(*ptr, nil) + if err != nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("Error processing %s: %s", n, err)) + } + } + + // Warnings + var warnings []string + + // Check for any errors. + if errs != nil && len(errs.Errors) > 0 { + return nil, warnings, errs + } + + return c, warnings, nil +}