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