github.com/daniellockard/packer@v0.7.6-0.20141210173435-5a9390934716/builder/googlecompute/builder.go (about) 1 // The googlecompute package contains a packer.Builder implementation that 2 // builds images for Google Compute Engine. 3 package googlecompute 4 5 import ( 6 "fmt" 7 "github.com/mitchellh/multistep" 8 "github.com/mitchellh/packer/common" 9 "github.com/mitchellh/packer/packer" 10 "log" 11 "time" 12 ) 13 14 // The unique ID for this builder. 15 const BuilderId = "packer.googlecompute" 16 17 // Builder represents a Packer Builder. 18 type Builder struct { 19 config *Config 20 runner multistep.Runner 21 } 22 23 // Prepare processes the build configuration parameters. 24 func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 25 c, warnings, errs := NewConfig(raws...) 26 if errs != nil { 27 return warnings, errs 28 } 29 b.config = c 30 31 return warnings, nil 32 } 33 34 // Run executes a googlecompute Packer build and returns a packer.Artifact 35 // representing a GCE machine image. 36 func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 37 driver, err := NewDriverGCE( 38 ui, b.config.ProjectId, &b.config.account) 39 if err != nil { 40 return nil, err 41 } 42 43 // Set up the state. 44 state := new(multistep.BasicStateBag) 45 state.Put("config", b.config) 46 state.Put("driver", driver) 47 state.Put("hook", hook) 48 state.Put("ui", ui) 49 50 // Build the steps. 51 steps := []multistep.Step{ 52 new(StepCheckExistingImage), 53 &StepCreateSSHKey{ 54 Debug: b.config.PackerDebug, 55 DebugKeyPath: fmt.Sprintf("gce_%s.pem", b.config.PackerBuildName), 56 }, 57 &StepCreateInstance{ 58 Debug: b.config.PackerDebug, 59 }, 60 &StepInstanceInfo{ 61 Debug: b.config.PackerDebug, 62 }, 63 &common.StepConnectSSH{ 64 SSHAddress: sshAddress, 65 SSHConfig: sshConfig, 66 SSHWaitTimeout: 5 * time.Minute, 67 }, 68 new(common.StepProvision), 69 new(StepTeardownInstance), 70 new(StepCreateImage), 71 } 72 73 // Run the steps. 74 if b.config.PackerDebug { 75 b.runner = &multistep.DebugRunner{ 76 Steps: steps, 77 PauseFn: common.MultistepDebugFn(ui), 78 } 79 } else { 80 b.runner = &multistep.BasicRunner{Steps: steps} 81 } 82 b.runner.Run(state) 83 84 // Report any errors. 85 if rawErr, ok := state.GetOk("error"); ok { 86 return nil, rawErr.(error) 87 } 88 if _, ok := state.GetOk("image_name"); !ok { 89 log.Println("Failed to find image_name in state. Bug?") 90 return nil, nil 91 } 92 93 artifact := &Artifact{ 94 imageName: state.Get("image_name").(string), 95 driver: driver, 96 } 97 return artifact, nil 98 } 99 100 // Cancel. 101 func (b *Builder) Cancel() { 102 if b.runner != nil { 103 log.Println("Cancelling the step runner...") 104 b.runner.Cancel() 105 } 106 }