github.com/emate/packer@v0.8.1-0.20150625195101-fe0fde195dc6/builder/digitalocean/builder.go (about) 1 // The digitalocean package contains a packer.Builder implementation 2 // that builds DigitalOcean images (snapshots). 3 4 package digitalocean 5 6 import ( 7 "fmt" 8 "log" 9 10 "github.com/digitalocean/godo" 11 "github.com/mitchellh/multistep" 12 "github.com/mitchellh/packer/common" 13 "github.com/mitchellh/packer/helper/communicator" 14 "github.com/mitchellh/packer/packer" 15 "golang.org/x/oauth2" 16 ) 17 18 // The unique id for the builder 19 const BuilderId = "pearkes.digitalocean" 20 21 type Builder struct { 22 config Config 23 runner multistep.Runner 24 } 25 26 func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 27 c, warnings, errs := NewConfig(raws...) 28 if errs != nil { 29 return warnings, errs 30 } 31 b.config = *c 32 33 return nil, nil 34 } 35 36 func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 37 client := godo.NewClient(oauth2.NewClient(oauth2.NoContext, &apiTokenSource{ 38 AccessToken: b.config.APIToken, 39 })) 40 41 // Set up the state 42 state := new(multistep.BasicStateBag) 43 state.Put("config", b.config) 44 state.Put("client", client) 45 state.Put("hook", hook) 46 state.Put("ui", ui) 47 48 // Build the steps 49 steps := []multistep.Step{ 50 &stepCreateSSHKey{ 51 Debug: b.config.PackerDebug, 52 DebugKeyPath: fmt.Sprintf("do_%s.pem", b.config.PackerBuildName), 53 }, 54 new(stepCreateDroplet), 55 new(stepDropletInfo), 56 &communicator.StepConnect{ 57 Config: &b.config.Comm, 58 Host: commHost, 59 SSHConfig: sshConfig, 60 }, 61 new(common.StepProvision), 62 new(stepShutdown), 63 new(stepPowerOff), 64 new(stepSnapshot), 65 } 66 67 // Run the steps 68 if b.config.PackerDebug { 69 b.runner = &multistep.DebugRunner{ 70 Steps: steps, 71 PauseFn: common.MultistepDebugFn(ui), 72 } 73 } else { 74 b.runner = &multistep.BasicRunner{Steps: steps} 75 } 76 77 b.runner.Run(state) 78 79 // If there was an error, return that 80 if rawErr, ok := state.GetOk("error"); ok { 81 return nil, rawErr.(error) 82 } 83 84 if _, ok := state.GetOk("snapshot_name"); !ok { 85 log.Println("Failed to find snapshot_name in state. Bug?") 86 return nil, nil 87 } 88 89 artifact := &Artifact{ 90 snapshotName: state.Get("snapshot_name").(string), 91 snapshotId: state.Get("snapshot_image_id").(int), 92 regionName: state.Get("region").(string), 93 client: client, 94 } 95 96 return artifact, nil 97 } 98 99 func (b *Builder) Cancel() { 100 if b.runner != nil { 101 log.Println("Cancelling the step runner...") 102 b.runner.Cancel() 103 } 104 }