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  }