github.com/rothwerx/packer@v0.9.0/builder/parallels/pvm/builder.go (about) 1 package pvm 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 8 "github.com/mitchellh/multistep" 9 parallelscommon "github.com/mitchellh/packer/builder/parallels/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 Parallels 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 Parallels 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 Parallels 37 driver, err := parallelscommon.NewDriver() 38 if err != nil { 39 return nil, fmt.Errorf("Failed creating Paralles 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("hook", hook) 47 state.Put("ui", ui) 48 state.Put("http_port", uint(0)) 49 50 // Build the steps. 51 steps := []multistep.Step{ 52 ¶llelscommon.StepPrepareParallelsTools{ 53 ParallelsToolsMode: b.config.ParallelsToolsMode, 54 ParallelsToolsFlavor: b.config.ParallelsToolsFlavor, 55 }, 56 ¶llelscommon.StepOutputDir{ 57 Force: b.config.PackerForce, 58 Path: b.config.OutputDir, 59 }, 60 &common.StepCreateFloppy{ 61 Files: b.config.FloppyFiles, 62 }, 63 &StepImport{ 64 Name: b.config.VMName, 65 SourcePath: b.config.SourcePath, 66 }, 67 ¶llelscommon.StepAttachParallelsTools{ 68 ParallelsToolsMode: b.config.ParallelsToolsMode, 69 }, 70 new(parallelscommon.StepAttachFloppy), 71 ¶llelscommon.StepPrlctl{ 72 Commands: b.config.Prlctl, 73 Ctx: b.config.ctx, 74 }, 75 ¶llelscommon.StepRun{ 76 BootWait: b.config.BootWait, 77 }, 78 ¶llelscommon.StepTypeBootCommand{ 79 BootCommand: b.config.BootCommand, 80 HostInterfaces: []string{}, 81 VMName: b.config.VMName, 82 Ctx: b.config.ctx, 83 }, 84 &communicator.StepConnect{ 85 Config: &b.config.SSHConfig.Comm, 86 Host: parallelscommon.CommHost, 87 SSHConfig: parallelscommon.SSHConfigFunc(b.config.SSHConfig), 88 }, 89 ¶llelscommon.StepUploadVersion{ 90 Path: b.config.PrlctlVersionFile, 91 }, 92 ¶llelscommon.StepUploadParallelsTools{ 93 ParallelsToolsFlavor: b.config.ParallelsToolsFlavor, 94 ParallelsToolsGuestPath: b.config.ParallelsToolsGuestPath, 95 ParallelsToolsMode: b.config.ParallelsToolsMode, 96 Ctx: b.config.ctx, 97 }, 98 new(common.StepProvision), 99 ¶llelscommon.StepShutdown{ 100 Command: b.config.ShutdownCommand, 101 Timeout: b.config.ShutdownTimeout, 102 }, 103 ¶llelscommon.StepPrlctl{ 104 Commands: b.config.PrlctlPost, 105 Ctx: b.config.ctx, 106 }, 107 } 108 109 // Run the steps. 110 if b.config.PackerDebug { 111 b.runner = &multistep.DebugRunner{ 112 Steps: steps, 113 PauseFn: common.MultistepDebugFn(ui), 114 } 115 } else { 116 b.runner = &multistep.BasicRunner{Steps: steps} 117 } 118 b.runner.Run(state) 119 120 // Report any errors. 121 if rawErr, ok := state.GetOk("error"); ok { 122 return nil, rawErr.(error) 123 } 124 125 // If we were interrupted or cancelled, then just exit. 126 if _, ok := state.GetOk(multistep.StateCancelled); ok { 127 return nil, errors.New("Build was cancelled.") 128 } 129 130 if _, ok := state.GetOk(multistep.StateHalted); ok { 131 return nil, errors.New("Build was halted.") 132 } 133 134 return parallelscommon.NewArtifact(b.config.OutputDir) 135 } 136 137 // Cancel. 138 func (b *Builder) Cancel() { 139 if b.runner != nil { 140 log.Println("Cancelling the step runner...") 141 b.runner.Cancel() 142 } 143 }