github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/builder/triton/builder.go (about)

     1  package triton
     2  
     3  import (
     4  	"log"
     5  
     6  	"github.com/hashicorp/go-multierror"
     7  	"github.com/hashicorp/packer/common"
     8  	"github.com/hashicorp/packer/helper/communicator"
     9  	"github.com/hashicorp/packer/helper/config"
    10  	"github.com/hashicorp/packer/helper/multistep"
    11  	"github.com/hashicorp/packer/packer"
    12  )
    13  
    14  const (
    15  	BuilderId = "joyent.triton"
    16  )
    17  
    18  type Builder struct {
    19  	config Config
    20  	runner multistep.Runner
    21  }
    22  
    23  func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
    24  	errs := &multierror.Error{}
    25  
    26  	err := config.Decode(&b.config, &config.DecodeOpts{
    27  		Interpolate:        true,
    28  		InterpolateContext: &b.config.ctx,
    29  	}, raws...)
    30  	if err != nil {
    31  		errs = multierror.Append(errs, err)
    32  	}
    33  
    34  	errs = multierror.Append(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...)
    35  	errs = multierror.Append(errs, b.config.SourceMachineConfig.Prepare(&b.config.ctx)...)
    36  	errs = multierror.Append(errs, b.config.Comm.Prepare(&b.config.ctx)...)
    37  	errs = multierror.Append(errs, b.config.TargetImageConfig.Prepare(&b.config.ctx)...)
    38  
    39  	// If we are using an SSH agent to sign requests, and no private key has been
    40  	// specified for SSH, use the agent for connecting for provisioning.
    41  	if b.config.AccessConfig.KeyMaterial == "" && b.config.Comm.SSHPrivateKey == "" {
    42  		b.config.Comm.SSHAgentAuth = true
    43  	}
    44  
    45  	return nil, errs.ErrorOrNil()
    46  }
    47  
    48  func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
    49  	config := b.config
    50  
    51  	driver, err := NewDriverTriton(ui, config)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	state := new(multistep.BasicStateBag)
    57  	state.Put("config", b.config)
    58  	state.Put("debug", b.config.PackerDebug)
    59  	state.Put("driver", driver)
    60  	state.Put("hook", hook)
    61  	state.Put("ui", ui)
    62  
    63  	steps := []multistep.Step{
    64  		&StepCreateSourceMachine{},
    65  		&communicator.StepConnect{
    66  			Config: &config.Comm,
    67  			Host:   commHost,
    68  			SSHConfig: sshConfig(
    69  				b.config.Comm.SSHAgentAuth,
    70  				b.config.Comm.SSHUsername,
    71  				b.config.Comm.SSHPrivateKey,
    72  				b.config.Comm.SSHPassword),
    73  		},
    74  		&common.StepProvision{},
    75  		&StepStopMachine{},
    76  		&StepCreateImageFromMachine{},
    77  		&StepDeleteMachine{},
    78  	}
    79  
    80  	b.runner = common.NewRunnerWithPauseFn(steps, b.config.PackerConfig, ui, state)
    81  	b.runner.Run(state)
    82  
    83  	// If there was an error, return that
    84  	if rawErr, ok := state.GetOk("error"); ok {
    85  		return nil, rawErr.(error)
    86  	}
    87  
    88  	// If there is no image, just return
    89  	if _, ok := state.GetOk("image"); !ok {
    90  		return nil, nil
    91  	}
    92  
    93  	artifact := &Artifact{
    94  		ImageID:        state.Get("image").(string),
    95  		BuilderIDValue: BuilderId,
    96  		Driver:         driver,
    97  	}
    98  
    99  	return artifact, nil
   100  }
   101  
   102  // Cancel cancels a possibly running Builder. This should block until
   103  // the builder actually cancels and cleans up after itself.
   104  func (b *Builder) Cancel() {
   105  	if b.runner != nil {
   106  		log.Println("Cancelling the step runner...")
   107  		b.runner.Cancel()
   108  	}
   109  }