diff --git a/builder/digitalocean/builder.go b/builder/digitalocean/builder.go index cf76f6970..57e6018a1 100644 --- a/builder/digitalocean/builder.go +++ b/builder/digitalocean/builder.go @@ -13,7 +13,9 @@ import ( "github.com/mitchellh/multistep" "github.com/mitchellh/packer/common" "github.com/mitchellh/packer/common/uuid" + "github.com/mitchellh/packer/helper/config" "github.com/mitchellh/packer/packer" + "github.com/mitchellh/packer/template/interpolate" ) // see https://api.digitalocean.com/images/?client_id=[client_id]&api_key=[api_key] @@ -34,7 +36,7 @@ const BuilderId = "pearkes.digitalocean" // Configuration tells the builder the credentials // to use while communicating with DO and describes the image // you are creating -type config struct { +type Config struct { common.PackerConfig `mapstructure:",squash"` ClientID string `mapstructure:"client_id"` @@ -63,29 +65,23 @@ type config struct { sshTimeout time.Duration stateTimeout time.Duration + ctx *interpolate.Context tpl *packer.ConfigTemplate } type Builder struct { - config config + config Config runner multistep.Runner } func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { - md, err := common.DecodeConfig(&b.config, raws...) + err := config.Decode(&b.config, &config.DecodeOpts{ + Interpolate: true, + }, raws...) if err != nil { return nil, err } - b.config.tpl, err = packer.NewConfigTemplate() - if err != nil { - return nil, err - } - b.config.tpl.UserVars = b.config.PackerUserVars - - // Accumulate any errors - errs := common.CheckUnusedConfig(md) - // Optional configuration with defaults if b.config.APIKey == "" { // Default to environment variable for api_key, if it exists @@ -163,30 +159,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.RawStateTimeout = "6m" } - templates := map[string]*string{ - "region": &b.config.Region, - "size": &b.config.Size, - "image": &b.config.Image, - "client_id": &b.config.ClientID, - "api_key": &b.config.APIKey, - "api_url": &b.config.APIURL, - "api_token": &b.config.APIToken, - "snapshot_name": &b.config.SnapshotName, - "droplet_name": &b.config.DropletName, - "ssh_username": &b.config.SSHUsername, - "ssh_timeout": &b.config.RawSSHTimeout, - "state_timeout": &b.config.RawStateTimeout, - } - - for n, ptr := range templates { - var err error - *ptr, err = b.config.tpl.Process(*ptr, nil) - if err != nil { - errs = packer.MultiErrorAppend( - errs, fmt.Errorf("Error processing %s: %s", n, err)) - } - } - + var errs *packer.MultiError if b.config.APIToken == "" { // Required configurations that will display errors if not set if b.config.ClientID == "" { diff --git a/builder/digitalocean/ssh.go b/builder/digitalocean/ssh.go index 2e9afcf7a..c53262ccc 100644 --- a/builder/digitalocean/ssh.go +++ b/builder/digitalocean/ssh.go @@ -7,13 +7,13 @@ import ( ) func sshAddress(state multistep.StateBag) (string, error) { - config := state.Get("config").(config) + config := state.Get("config").(Config) ipAddress := state.Get("droplet_ip").(string) return fmt.Sprintf("%s:%d", ipAddress, config.SSHPort), nil } func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) { - config := state.Get("config").(config) + config := state.Get("config").(Config) privateKey := state.Get("privateKey").(string) signer, err := ssh.ParsePrivateKey([]byte(privateKey)) diff --git a/builder/digitalocean/step_create_droplet.go b/builder/digitalocean/step_create_droplet.go index 85164abaf..afb3e5814 100644 --- a/builder/digitalocean/step_create_droplet.go +++ b/builder/digitalocean/step_create_droplet.go @@ -14,7 +14,7 @@ type stepCreateDroplet struct { func (s *stepCreateDroplet) Run(state multistep.StateBag) multistep.StepAction { client := state.Get("client").(DigitalOceanClient) ui := state.Get("ui").(packer.Ui) - c := state.Get("config").(config) + c := state.Get("config").(Config) sshKeyId := state.Get("ssh_key_id").(uint) ui.Say("Creating droplet...") @@ -46,7 +46,7 @@ func (s *stepCreateDroplet) Cleanup(state multistep.StateBag) { client := state.Get("client").(DigitalOceanClient) ui := state.Get("ui").(packer.Ui) - c := state.Get("config").(config) + c := state.Get("config").(Config) // Destroy the droplet we just created ui.Say("Destroying droplet...") diff --git a/builder/digitalocean/step_create_ssh_key.go b/builder/digitalocean/step_create_ssh_key.go index 78bb474c1..db1ad9c16 100644 --- a/builder/digitalocean/step_create_ssh_key.go +++ b/builder/digitalocean/step_create_ssh_key.go @@ -73,7 +73,7 @@ func (s *stepCreateSSHKey) Cleanup(state multistep.StateBag) { client := state.Get("client").(DigitalOceanClient) ui := state.Get("ui").(packer.Ui) - c := state.Get("config").(config) + c := state.Get("config").(Config) ui.Say("Deleting temporary ssh key...") err := client.DestroyKey(s.keyId) diff --git a/builder/digitalocean/step_droplet_info.go b/builder/digitalocean/step_droplet_info.go index ea08599ce..8e9b69927 100644 --- a/builder/digitalocean/step_droplet_info.go +++ b/builder/digitalocean/step_droplet_info.go @@ -12,7 +12,7 @@ type stepDropletInfo struct{} func (s *stepDropletInfo) Run(state multistep.StateBag) multistep.StepAction { client := state.Get("client").(DigitalOceanClient) ui := state.Get("ui").(packer.Ui) - c := state.Get("config").(config) + c := state.Get("config").(Config) dropletId := state.Get("droplet_id").(uint) ui.Say("Waiting for droplet to become active...") diff --git a/builder/digitalocean/step_power_off.go b/builder/digitalocean/step_power_off.go index efead2d8a..d6ef49a22 100644 --- a/builder/digitalocean/step_power_off.go +++ b/builder/digitalocean/step_power_off.go @@ -12,7 +12,7 @@ type stepPowerOff struct{} func (s *stepPowerOff) Run(state multistep.StateBag) multistep.StepAction { client := state.Get("client").(DigitalOceanClient) - c := state.Get("config").(config) + c := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) dropletId := state.Get("droplet_id").(uint) diff --git a/builder/digitalocean/step_snapshot.go b/builder/digitalocean/step_snapshot.go index 4fdf20bc1..1903c1a34 100644 --- a/builder/digitalocean/step_snapshot.go +++ b/builder/digitalocean/step_snapshot.go @@ -14,7 +14,7 @@ type stepSnapshot struct{} func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { client := state.Get("client").(DigitalOceanClient) ui := state.Get("ui").(packer.Ui) - c := state.Get("config").(config) + c := state.Get("config").(Config) dropletId := state.Get("droplet_id").(uint) ui.Say(fmt.Sprintf("Creating snapshot: %v", c.SnapshotName))