github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/builder/cloudstack/builder.go (about) 1 package cloudstack 2 3 import ( 4 "github.com/mitchellh/multistep" 5 "github.com/mitchellh/packer/common" 6 "github.com/mitchellh/packer/helper/communicator" 7 "github.com/mitchellh/packer/packer" 8 "github.com/xanzy/go-cloudstack/cloudstack" 9 ) 10 11 const BuilderId = "packer.cloudstack" 12 13 // Builder represents the CloudStack builder. 14 type Builder struct { 15 config *Config 16 runner multistep.Runner 17 ui packer.Ui 18 } 19 20 // Prepare implements the packer.Builder interface. 21 func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 22 config, errs := NewConfig(raws...) 23 if errs != nil { 24 return nil, errs 25 } 26 b.config = config 27 28 return nil, nil 29 } 30 31 // Run implements the packer.Builder interface. 32 func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 33 b.ui = ui 34 35 // Create a CloudStack API client. 36 client := cloudstack.NewAsyncClient( 37 b.config.APIURL, 38 b.config.APIKey, 39 b.config.SecretKey, 40 !b.config.SSLNoVerify, 41 ) 42 43 // Set the time to wait before timing out 44 client.AsyncTimeout(int64(b.config.AsyncTimeout.Seconds())) 45 46 // Some CloudStack service providers only allow HTTP GET calls. 47 client.HTTPGETOnly = b.config.HTTPGetOnly 48 49 // Set up the state. 50 state := new(multistep.BasicStateBag) 51 state.Put("client", client) 52 state.Put("config", b.config) 53 state.Put("hook", hook) 54 state.Put("ui", ui) 55 56 // Build the steps. 57 steps := []multistep.Step{ 58 &stepPrepareConfig{}, 59 &stepCreateInstance{}, 60 &stepSetupNetworking{}, 61 &communicator.StepConnect{ 62 Config: &b.config.Comm, 63 Host: commHost, 64 SSHConfig: sshConfig, 65 }, 66 &common.StepProvision{}, 67 &stepShutdownInstance{}, 68 &stepCreateTemplate{}, 69 } 70 71 // Configure the runner. 72 if b.config.PackerDebug { 73 b.runner = &multistep.DebugRunner{ 74 Steps: steps, 75 PauseFn: common.MultistepDebugFn(ui), 76 } 77 } else { 78 b.runner = &multistep.BasicRunner{Steps: steps} 79 } 80 81 // Run the steps. 82 b.runner.Run(state) 83 84 // If there are no templates, then just return 85 template, ok := state.Get("template").(*cloudstack.CreateTemplateResponse) 86 if !ok || template == nil { 87 return nil, nil 88 } 89 90 // Build the artifact and return it 91 artifact := &Artifact{ 92 client: client, 93 config: b.config, 94 template: template, 95 } 96 97 return artifact, nil 98 } 99 100 // Cancel the step runner. 101 func (b *Builder) Cancel() { 102 if b.runner != nil { 103 b.ui.Say("Cancelling the step runner...") 104 b.runner.Cancel() 105 } 106 }