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