github.phpd.cn/hashicorp/packer@v1.3.2/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/hashicorp/packer/common" 10 "github.com/hashicorp/packer/helper/communicator" 11 "github.com/hashicorp/packer/helper/multistep" 12 "github.com/hashicorp/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 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 &StepCreateWindowsPassword{ 61 Debug: b.config.PackerDebug, 62 DebugKeyPath: fmt.Sprintf("gce_windows_%s.pem", b.config.PackerBuildName), 63 }, 64 &StepInstanceInfo{ 65 Debug: b.config.PackerDebug, 66 }, 67 &communicator.StepConnect{ 68 Config: &b.config.Comm, 69 Host: commHost, 70 SSHConfig: b.config.Comm.SSHConfigFunc(), 71 WinRMConfig: winrmConfig, 72 }, 73 new(common.StepProvision), 74 &common.StepCleanupTempKeys{ 75 Comm: &b.config.Comm, 76 }, 77 } 78 if _, exists := b.config.Metadata[StartupScriptKey]; exists || b.config.StartupScriptFile != "" { 79 steps = append(steps, new(StepWaitStartupScript)) 80 } 81 steps = append(steps, new(StepTeardownInstance), new(StepCreateImage)) 82 83 // Run the steps. 84 b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) 85 b.runner.Run(state) 86 87 // Report any errors. 88 if rawErr, ok := state.GetOk("error"); ok { 89 return nil, rawErr.(error) 90 } 91 if _, ok := state.GetOk("image"); !ok { 92 log.Println("Failed to find image in state. Bug?") 93 return nil, nil 94 } 95 96 artifact := &Artifact{ 97 image: state.Get("image").(*Image), 98 driver: driver, 99 config: b.config, 100 } 101 return artifact, nil 102 } 103 104 // Cancel. 105 func (b *Builder) Cancel() { 106 if b.runner != nil { 107 log.Println("Cancelling the step runner...") 108 b.runner.Cancel() 109 } 110 }