github.com/tonnydourado/packer@v0.6.1-0.20140701134019-5d0cd9676a37/builder/vmware/vmx/builder.go (about) 1 package vmx 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 "time" 8 9 "github.com/mitchellh/multistep" 10 vmwcommon "github.com/mitchellh/packer/builder/vmware/common" 11 "github.com/mitchellh/packer/common" 12 "github.com/mitchellh/packer/packer" 13 ) 14 15 // Builder implements packer.Builder and builds the actual VirtualBox 16 // images. 17 type Builder struct { 18 config *Config 19 runner multistep.Runner 20 } 21 22 // Prepare processes the build configuration parameters. 23 func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 24 c, warnings, errs := NewConfig(raws...) 25 if errs != nil { 26 return warnings, errs 27 } 28 b.config = c 29 30 return warnings, nil 31 } 32 33 // Run executes a Packer build and returns a packer.Artifact representing 34 // a VirtualBox appliance. 35 func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 36 driver, err := vmwcommon.NewDriver(&b.config.DriverConfig, &b.config.SSHConfig) 37 if err != nil { 38 return nil, fmt.Errorf("Failed creating VMware driver: %s", err) 39 } 40 41 // Setup the directory 42 dir := new(vmwcommon.LocalOutputDir) 43 dir.SetOutputDir(b.config.OutputDir) 44 45 // Set up the state. 46 state := new(multistep.BasicStateBag) 47 state.Put("config", b.config) 48 state.Put("dir", dir) 49 state.Put("driver", driver) 50 state.Put("hook", hook) 51 state.Put("ui", ui) 52 53 // Build the steps. 54 steps := []multistep.Step{ 55 &vmwcommon.StepPrepareTools{ 56 RemoteType: b.config.RemoteType, 57 ToolsUploadFlavor: b.config.ToolsUploadFlavor, 58 }, 59 &vmwcommon.StepOutputDir{ 60 Force: b.config.PackerForce, 61 }, 62 &common.StepCreateFloppy{ 63 Files: b.config.FloppyFiles, 64 }, 65 &StepCloneVMX{ 66 OutputDir: b.config.OutputDir, 67 Path: b.config.SourcePath, 68 VMName: b.config.VMName, 69 }, 70 &vmwcommon.StepConfigureVMX{ 71 CustomData: b.config.VMXData, 72 }, 73 &vmwcommon.StepSuppressMessages{}, 74 &vmwcommon.StepRun{ 75 BootWait: b.config.BootWait, 76 DurationBeforeStop: 5 * time.Second, 77 Headless: b.config.Headless, 78 }, 79 &common.StepConnectSSH{ 80 SSHAddress: driver.SSHAddress, 81 SSHConfig: vmwcommon.SSHConfigFunc(&b.config.SSHConfig), 82 SSHWaitTimeout: b.config.SSHWaitTimeout, 83 NoPty: b.config.SSHSkipRequestPty, 84 }, 85 &vmwcommon.StepUploadTools{ 86 RemoteType: b.config.RemoteType, 87 ToolsUploadFlavor: b.config.ToolsUploadFlavor, 88 ToolsUploadPath: b.config.ToolsUploadPath, 89 Tpl: b.config.tpl, 90 }, 91 &common.StepProvision{}, 92 &vmwcommon.StepShutdown{ 93 Command: b.config.ShutdownCommand, 94 Timeout: b.config.ShutdownTimeout, 95 }, 96 &vmwcommon.StepCleanFiles{}, 97 &vmwcommon.StepCleanVMX{}, 98 &vmwcommon.StepConfigureVMX{ 99 CustomData: b.config.VMXDataPost, 100 }, 101 &vmwcommon.StepCompactDisk{ 102 Skip: b.config.SkipCompaction, 103 }, 104 } 105 106 // Run the steps. 107 if b.config.PackerDebug { 108 b.runner = &multistep.DebugRunner{ 109 Steps: steps, 110 PauseFn: common.MultistepDebugFn(ui), 111 } 112 } else { 113 b.runner = &multistep.BasicRunner{Steps: steps} 114 } 115 b.runner.Run(state) 116 117 // Report any errors. 118 if rawErr, ok := state.GetOk("error"); ok { 119 return nil, rawErr.(error) 120 } 121 122 // If we were interrupted or cancelled, then just exit. 123 if _, ok := state.GetOk(multistep.StateCancelled); ok { 124 return nil, errors.New("Build was cancelled.") 125 } 126 127 if _, ok := state.GetOk(multistep.StateHalted); ok { 128 return nil, errors.New("Build was halted.") 129 } 130 131 return vmwcommon.NewLocalArtifact(b.config.OutputDir) 132 } 133 134 // Cancel. 135 func (b *Builder) Cancel() { 136 if b.runner != nil { 137 log.Println("Cancelling the step runner...") 138 b.runner.Cancel() 139 } 140 }