github.com/jbronn/packer@v0.1.6-0.20140120165540-8a1364dbd817/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  	"log"
     7  	"time"
     8  
     9  	"github.com/mitchellh/multistep"
    10  	"github.com/mitchellh/packer/common"
    11  	"github.com/mitchellh/packer/packer"
    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.clientSecrets, b.config.privateKeyBytes)
    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(StepCreateSSHKey),
    53  		new(StepCreateInstance),
    54  		new(StepInstanceInfo),
    55  		&common.StepConnectSSH{
    56  			SSHAddress:     sshAddress,
    57  			SSHConfig:      sshConfig,
    58  			SSHWaitTimeout: 5 * time.Minute,
    59  		},
    60  		new(common.StepProvision),
    61  		new(StepUpdateGsutil),
    62  		new(StepCreateImage),
    63  		new(StepUploadImage),
    64  		new(StepRegisterImage),
    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  	b.runner.Run(state)
    77  
    78  	// Report any errors.
    79  	if rawErr, ok := state.GetOk("error"); ok {
    80  		return nil, rawErr.(error)
    81  	}
    82  	if _, ok := state.GetOk("image_name"); !ok {
    83  		log.Println("Failed to find image_name in state. Bug?")
    84  		return nil, nil
    85  	}
    86  
    87  	artifact := &Artifact{
    88  		imageName: state.Get("image_name").(string),
    89  		driver:    driver,
    90  	}
    91  	return artifact, nil
    92  }
    93  
    94  // Cancel.
    95  func (b *Builder) Cancel() {
    96  	if b.runner != nil {
    97  		log.Println("Cancelling the step runner...")
    98  		b.runner.Cancel()
    99  	}
   100  }