github.com/rothwerx/packer@v0.9.0/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/helper/communicator" 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 // Create the driver that we'll use to communicate with VirtualBox 37 driver, err := vboxcommon.NewDriver() 38 if err != nil { 39 return nil, fmt.Errorf("Failed creating VirtualBox driver: %s", err) 40 } 41 42 // Set up the state. 43 state := new(multistep.BasicStateBag) 44 state.Put("config", b.config) 45 state.Put("driver", driver) 46 state.Put("cache", cache) 47 state.Put("hook", hook) 48 state.Put("ui", ui) 49 50 // Build the steps. 51 steps := []multistep.Step{ 52 &vboxcommon.StepOutputDir{ 53 Force: b.config.PackerForce, 54 Path: b.config.OutputDir, 55 }, 56 new(vboxcommon.StepSuppressMessages), 57 &common.StepCreateFloppy{ 58 Files: b.config.FloppyFiles, 59 }, 60 &common.StepHTTPServer{ 61 HTTPDir: b.config.HTTPDir, 62 HTTPPortMin: b.config.HTTPPortMin, 63 HTTPPortMax: b.config.HTTPPortMax, 64 }, 65 &vboxcommon.StepDownloadGuestAdditions{ 66 GuestAdditionsMode: b.config.GuestAdditionsMode, 67 GuestAdditionsURL: b.config.GuestAdditionsURL, 68 GuestAdditionsSHA256: b.config.GuestAdditionsSHA256, 69 Ctx: b.config.ctx, 70 }, 71 &StepImport{ 72 Name: b.config.VMName, 73 SourcePath: b.config.SourcePath, 74 ImportFlags: b.config.ImportFlags, 75 }, 76 &vboxcommon.StepAttachGuestAdditions{ 77 GuestAdditionsMode: b.config.GuestAdditionsMode, 78 }, 79 &vboxcommon.StepConfigureVRDP{ 80 VRDPPortMin: b.config.VRDPPortMin, 81 VRDPPortMax: b.config.VRDPPortMax, 82 }, 83 new(vboxcommon.StepAttachFloppy), 84 &vboxcommon.StepForwardSSH{ 85 CommConfig: &b.config.SSHConfig.Comm, 86 HostPortMin: b.config.SSHHostPortMin, 87 HostPortMax: b.config.SSHHostPortMax, 88 SkipNatMapping: b.config.SSHSkipNatMapping, 89 }, 90 &vboxcommon.StepVBoxManage{ 91 Commands: b.config.VBoxManage, 92 Ctx: b.config.ctx, 93 }, 94 &vboxcommon.StepRun{ 95 BootWait: b.config.BootWait, 96 Headless: b.config.Headless, 97 }, 98 &vboxcommon.StepTypeBootCommand{ 99 BootCommand: b.config.BootCommand, 100 VMName: b.config.VMName, 101 Ctx: b.config.ctx, 102 }, 103 &communicator.StepConnect{ 104 Config: &b.config.SSHConfig.Comm, 105 Host: vboxcommon.CommHost, 106 SSHConfig: vboxcommon.SSHConfigFunc(b.config.SSHConfig), 107 SSHPort: vboxcommon.SSHPort, 108 }, 109 &vboxcommon.StepUploadVersion{ 110 Path: b.config.VBoxVersionFile, 111 }, 112 &vboxcommon.StepUploadGuestAdditions{ 113 GuestAdditionsMode: b.config.GuestAdditionsMode, 114 GuestAdditionsPath: b.config.GuestAdditionsPath, 115 Ctx: b.config.ctx, 116 }, 117 new(common.StepProvision), 118 &vboxcommon.StepShutdown{ 119 Command: b.config.ShutdownCommand, 120 Timeout: b.config.ShutdownTimeout, 121 }, 122 new(vboxcommon.StepRemoveDevices), 123 &vboxcommon.StepVBoxManage{ 124 Commands: b.config.VBoxManagePost, 125 Ctx: b.config.ctx, 126 }, 127 &vboxcommon.StepExport{ 128 Format: b.config.Format, 129 OutputDir: b.config.OutputDir, 130 ExportOpts: b.config.ExportOpts.ExportOpts, 131 SkipNatMapping: b.config.SSHSkipNatMapping, 132 }, 133 } 134 135 // Run the steps. 136 if b.config.PackerDebug { 137 b.runner = &multistep.DebugRunner{ 138 Steps: steps, 139 PauseFn: common.MultistepDebugFn(ui), 140 } 141 } else { 142 b.runner = &multistep.BasicRunner{Steps: steps} 143 } 144 b.runner.Run(state) 145 146 // Report any errors. 147 if rawErr, ok := state.GetOk("error"); ok { 148 return nil, rawErr.(error) 149 } 150 151 // If we were interrupted or cancelled, then just exit. 152 if _, ok := state.GetOk(multistep.StateCancelled); ok { 153 return nil, errors.New("Build was cancelled.") 154 } 155 156 if _, ok := state.GetOk(multistep.StateHalted); ok { 157 return nil, errors.New("Build was halted.") 158 } 159 160 return vboxcommon.NewArtifact(b.config.OutputDir) 161 } 162 163 // Cancel. 164 func (b *Builder) Cancel() { 165 if b.runner != nil { 166 log.Println("Cancelling the step runner...") 167 b.runner.Cancel() 168 } 169 }