github.com/askholme/packer@v0.7.2-0.20140924152349-70d9566a6852/builder/virtualbox/ovf/builder.go (about) 1 package ovf 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 "math/rand" 8 "time" 9 10 "github.com/mitchellh/multistep" 11 vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common" 12 "github.com/mitchellh/packer/common" 13 "github.com/mitchellh/packer/packer" 14 ) 15 16 // Builder implements packer.Builder and builds the actual VirtualBox 17 // images. 18 type Builder struct { 19 config *Config 20 runner multistep.Runner 21 } 22 23 // Prepare processes the build configuration parameters. 24 func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 25 c, warnings, errs := NewConfig(raws...) 26 if errs != nil { 27 return warnings, errs 28 } 29 b.config = c 30 31 return warnings, nil 32 } 33 34 // Run executes a Packer build and returns a packer.Artifact representing 35 // a VirtualBox appliance. 36 func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 37 // Seed the random number generator 38 rand.Seed(time.Now().UTC().UnixNano()) 39 40 // Create the driver that we'll use to communicate with VirtualBox 41 driver, err := vboxcommon.NewDriver() 42 if err != nil { 43 return nil, fmt.Errorf("Failed creating VirtualBox driver: %s", err) 44 } 45 46 // Set up the state. 47 state := new(multistep.BasicStateBag) 48 state.Put("config", b.config) 49 state.Put("driver", driver) 50 state.Put("cache", cache) 51 state.Put("hook", hook) 52 state.Put("ui", ui) 53 54 // Build the steps. 55 steps := []multistep.Step{ 56 &vboxcommon.StepOutputDir{ 57 Force: b.config.PackerForce, 58 Path: b.config.OutputDir, 59 }, 60 new(vboxcommon.StepSuppressMessages), 61 &common.StepCreateFloppy{ 62 Files: b.config.FloppyFiles, 63 }, 64 &vboxcommon.StepHTTPServer{ 65 HTTPDir: b.config.HTTPDir, 66 HTTPPortMin: b.config.HTTPPortMin, 67 HTTPPortMax: b.config.HTTPPortMax, 68 }, 69 &vboxcommon.StepDownloadGuestAdditions{ 70 GuestAdditionsMode: b.config.GuestAdditionsMode, 71 GuestAdditionsURL: b.config.GuestAdditionsURL, 72 GuestAdditionsSHA256: b.config.GuestAdditionsSHA256, 73 Tpl: b.config.tpl, 74 }, 75 &StepImport{ 76 Name: b.config.VMName, 77 SourcePath: b.config.SourcePath, 78 ImportFlags: b.config.ImportFlags, 79 }, 80 &vboxcommon.StepAttachGuestAdditions{ 81 GuestAdditionsMode: b.config.GuestAdditionsMode, 82 }, 83 new(vboxcommon.StepAttachFloppy), 84 &vboxcommon.StepForwardSSH{ 85 GuestPort: b.config.SSHPort, 86 HostPortMin: b.config.SSHHostPortMin, 87 HostPortMax: b.config.SSHHostPortMax, 88 }, 89 &vboxcommon.StepVBoxManage{ 90 Commands: b.config.VBoxManage, 91 Tpl: b.config.tpl, 92 }, 93 &vboxcommon.StepRun{ 94 BootWait: b.config.BootWait, 95 Headless: b.config.Headless, 96 }, 97 &vboxcommon.StepTypeBootCommand{ 98 BootCommand: b.config.BootCommand, 99 VMName: b.config.VMName, 100 Tpl: b.config.tpl, 101 }, 102 &common.StepConnectSSH{ 103 SSHAddress: vboxcommon.SSHAddress, 104 SSHConfig: vboxcommon.SSHConfigFunc(b.config.SSHConfig), 105 SSHWaitTimeout: b.config.SSHWaitTimeout, 106 }, 107 &vboxcommon.StepUploadVersion{ 108 Path: b.config.VBoxVersionFile, 109 }, 110 &vboxcommon.StepUploadGuestAdditions{ 111 GuestAdditionsMode: b.config.GuestAdditionsMode, 112 GuestAdditionsPath: b.config.GuestAdditionsPath, 113 Tpl: b.config.tpl, 114 }, 115 new(common.StepProvision), 116 &vboxcommon.StepShutdown{ 117 Command: b.config.ShutdownCommand, 118 Timeout: b.config.ShutdownTimeout, 119 }, 120 new(vboxcommon.StepRemoveDevices), 121 &vboxcommon.StepVBoxManage{ 122 Commands: b.config.VBoxManagePost, 123 Tpl: b.config.tpl, 124 }, 125 &vboxcommon.StepExport{ 126 Format: b.config.Format, 127 OutputDir: b.config.OutputDir, 128 ExportOpts: b.config.ExportOpts.ExportOpts, 129 }, 130 } 131 132 // Run the steps. 133 if b.config.PackerDebug { 134 b.runner = &multistep.DebugRunner{ 135 Steps: steps, 136 PauseFn: common.MultistepDebugFn(ui), 137 } 138 } else { 139 b.runner = &multistep.BasicRunner{Steps: steps} 140 } 141 b.runner.Run(state) 142 143 // Report any errors. 144 if rawErr, ok := state.GetOk("error"); ok { 145 return nil, rawErr.(error) 146 } 147 148 // If we were interrupted or cancelled, then just exit. 149 if _, ok := state.GetOk(multistep.StateCancelled); ok { 150 return nil, errors.New("Build was cancelled.") 151 } 152 153 if _, ok := state.GetOk(multistep.StateHalted); ok { 154 return nil, errors.New("Build was halted.") 155 } 156 157 return vboxcommon.NewArtifact(b.config.OutputDir) 158 } 159 160 // Cancel. 161 func (b *Builder) Cancel() { 162 if b.runner != nil { 163 log.Println("Cancelling the step runner...") 164 b.runner.Cancel() 165 } 166 }