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