github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/builder/cloudstack/builder.go (about)

     1  package cloudstack
     2  
     3  import (
     4  	"github.com/mitchellh/multistep"
     5  	"github.com/mitchellh/packer/common"
     6  	"github.com/mitchellh/packer/helper/communicator"
     7  	"github.com/mitchellh/packer/packer"
     8  	"github.com/xanzy/go-cloudstack/cloudstack"
     9  )
    10  
    11  const BuilderId = "packer.cloudstack"
    12  
    13  // Builder represents the CloudStack builder.
    14  type Builder struct {
    15  	config *Config
    16  	runner multistep.Runner
    17  	ui     packer.Ui
    18  }
    19  
    20  // Prepare implements the packer.Builder interface.
    21  func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
    22  	config, errs := NewConfig(raws...)
    23  	if errs != nil {
    24  		return nil, errs
    25  	}
    26  	b.config = config
    27  
    28  	return nil, nil
    29  }
    30  
    31  // Run implements the packer.Builder interface.
    32  func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
    33  	b.ui = ui
    34  
    35  	// Create a CloudStack API client.
    36  	client := cloudstack.NewAsyncClient(
    37  		b.config.APIURL,
    38  		b.config.APIKey,
    39  		b.config.SecretKey,
    40  		!b.config.SSLNoVerify,
    41  	)
    42  
    43  	// Set the time to wait before timing out
    44  	client.AsyncTimeout(int64(b.config.AsyncTimeout.Seconds()))
    45  
    46  	// Some CloudStack service providers only allow HTTP GET calls.
    47  	client.HTTPGETOnly = b.config.HTTPGetOnly
    48  
    49  	// Set up the state.
    50  	state := new(multistep.BasicStateBag)
    51  	state.Put("client", client)
    52  	state.Put("config", b.config)
    53  	state.Put("hook", hook)
    54  	state.Put("ui", ui)
    55  
    56  	// Build the steps.
    57  	steps := []multistep.Step{
    58  		&stepPrepareConfig{},
    59  		&stepCreateInstance{},
    60  		&stepSetupNetworking{},
    61  		&communicator.StepConnect{
    62  			Config:    &b.config.Comm,
    63  			Host:      commHost,
    64  			SSHConfig: sshConfig,
    65  		},
    66  		&common.StepProvision{},
    67  		&stepShutdownInstance{},
    68  		&stepCreateTemplate{},
    69  	}
    70  
    71  	// Configure the runner.
    72  	if b.config.PackerDebug {
    73  		b.runner = &multistep.DebugRunner{
    74  			Steps:   steps,
    75  			PauseFn: common.MultistepDebugFn(ui),
    76  		}
    77  	} else {
    78  		b.runner = &multistep.BasicRunner{Steps: steps}
    79  	}
    80  
    81  	// Run the steps.
    82  	b.runner.Run(state)
    83  
    84  	// If there are no templates, then just return
    85  	template, ok := state.Get("template").(*cloudstack.CreateTemplateResponse)
    86  	if !ok || template == nil {
    87  		return nil, nil
    88  	}
    89  
    90  	// Build the artifact and return it
    91  	artifact := &Artifact{
    92  		client:   client,
    93  		config:   b.config,
    94  		template: template,
    95  	}
    96  
    97  	return artifact, nil
    98  }
    99  
   100  // Cancel the step runner.
   101  func (b *Builder) Cancel() {
   102  	if b.runner != nil {
   103  		b.ui.Say("Cancelling the step runner...")
   104  		b.runner.Cancel()
   105  	}
   106  }