github.phpd.cn/hashicorp/packer@v1.3.2/builder/virtualbox/ovf/builder.go (about) 1 package ovf 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 8 vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" 9 "github.com/hashicorp/packer/common" 10 "github.com/hashicorp/packer/helper/communicator" 11 "github.com/hashicorp/packer/helper/multistep" 12 "github.com/hashicorp/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("debug", b.config.PackerDebug) 46 state.Put("driver", driver) 47 state.Put("cache", cache) 48 state.Put("hook", hook) 49 state.Put("ui", ui) 50 51 // Build the steps. 52 steps := []multistep.Step{ 53 &vboxcommon.StepOutputDir{ 54 Force: b.config.PackerForce, 55 Path: b.config.OutputDir, 56 }, 57 new(vboxcommon.StepSuppressMessages), 58 &common.StepCreateFloppy{ 59 Files: b.config.FloppyConfig.FloppyFiles, 60 Directories: b.config.FloppyConfig.FloppyDirectories, 61 }, 62 &common.StepHTTPServer{ 63 HTTPDir: b.config.HTTPDir, 64 HTTPPortMin: b.config.HTTPPortMin, 65 HTTPPortMax: b.config.HTTPPortMax, 66 }, 67 &vboxcommon.StepDownloadGuestAdditions{ 68 GuestAdditionsMode: b.config.GuestAdditionsMode, 69 GuestAdditionsURL: b.config.GuestAdditionsURL, 70 GuestAdditionsSHA256: b.config.GuestAdditionsSHA256, 71 Ctx: b.config.ctx, 72 }, 73 &common.StepDownload{ 74 Checksum: b.config.Checksum, 75 ChecksumType: b.config.ChecksumType, 76 Description: "OVF/OVA", 77 Extension: "ova", 78 ResultKey: "vm_path", 79 TargetPath: b.config.TargetPath, 80 Url: []string{b.config.SourcePath}, 81 }, 82 &StepImport{ 83 Name: b.config.VMName, 84 ImportFlags: b.config.ImportFlags, 85 }, 86 &vboxcommon.StepAttachGuestAdditions{ 87 GuestAdditionsMode: b.config.GuestAdditionsMode, 88 }, 89 &vboxcommon.StepConfigureVRDP{ 90 VRDPBindAddress: b.config.VRDPBindAddress, 91 VRDPPortMin: b.config.VRDPPortMin, 92 VRDPPortMax: b.config.VRDPPortMax, 93 }, 94 new(vboxcommon.StepAttachFloppy), 95 &vboxcommon.StepForwardSSH{ 96 CommConfig: &b.config.SSHConfig.Comm, 97 HostPortMin: b.config.SSHHostPortMin, 98 HostPortMax: b.config.SSHHostPortMax, 99 SkipNatMapping: b.config.SSHSkipNatMapping, 100 }, 101 &vboxcommon.StepVBoxManage{ 102 Commands: b.config.VBoxManage, 103 Ctx: b.config.ctx, 104 }, 105 &vboxcommon.StepRun{ 106 Headless: b.config.Headless, 107 }, 108 &vboxcommon.StepTypeBootCommand{ 109 BootWait: b.config.BootWait, 110 BootCommand: b.config.FlatBootCommand(), 111 VMName: b.config.VMName, 112 Ctx: b.config.ctx, 113 GroupInterval: b.config.BootConfig.BootGroupInterval, 114 }, 115 &communicator.StepConnect{ 116 Config: &b.config.SSHConfig.Comm, 117 Host: vboxcommon.CommHost(b.config.SSHConfig.Comm.SSHHost), 118 SSHConfig: b.config.SSHConfig.Comm.SSHConfigFunc(), 119 SSHPort: vboxcommon.SSHPort, 120 WinRMPort: vboxcommon.SSHPort, 121 }, 122 &vboxcommon.StepUploadVersion{ 123 Path: *b.config.VBoxVersionFile, 124 }, 125 &vboxcommon.StepUploadGuestAdditions{ 126 GuestAdditionsMode: b.config.GuestAdditionsMode, 127 GuestAdditionsPath: b.config.GuestAdditionsPath, 128 Ctx: b.config.ctx, 129 }, 130 new(common.StepProvision), 131 &common.StepCleanupTempKeys{ 132 Comm: &b.config.SSHConfig.Comm, 133 }, 134 &vboxcommon.StepShutdown{ 135 Command: b.config.ShutdownCommand, 136 Timeout: b.config.ShutdownTimeout, 137 Delay: b.config.PostShutdownDelay, 138 }, 139 new(vboxcommon.StepRemoveDevices), 140 &vboxcommon.StepVBoxManage{ 141 Commands: b.config.VBoxManagePost, 142 Ctx: b.config.ctx, 143 }, 144 &vboxcommon.StepExport{ 145 Format: b.config.Format, 146 OutputDir: b.config.OutputDir, 147 ExportOpts: b.config.ExportOpts.ExportOpts, 148 SkipNatMapping: b.config.SSHSkipNatMapping, 149 SkipExport: b.config.SkipExport, 150 }, 151 } 152 153 // Run the steps. 154 b.runner = common.NewRunnerWithPauseFn(steps, b.config.PackerConfig, ui, state) 155 b.runner.Run(state) 156 157 // Report any errors. 158 if rawErr, ok := state.GetOk("error"); ok { 159 return nil, rawErr.(error) 160 } 161 162 // If we were interrupted or cancelled, then just exit. 163 if _, ok := state.GetOk(multistep.StateCancelled); ok { 164 return nil, errors.New("Build was cancelled.") 165 } 166 167 if _, ok := state.GetOk(multistep.StateHalted); ok { 168 return nil, errors.New("Build was halted.") 169 } 170 171 return vboxcommon.NewArtifact(b.config.OutputDir) 172 } 173 174 // Cancel. 175 func (b *Builder) Cancel() { 176 if b.runner != nil { 177 log.Println("Cancelling the step runner...") 178 b.runner.Cancel() 179 } 180 }