Merge pull request #3933 from miry/do_user_data_file

Added UserDataFile support for DigitalOcean builder config.
This commit is contained in:
Rickard von Essen 2016-09-28 21:39:38 +02:00 committed by GitHub
commit 1dabba856e
4 changed files with 31 additions and 2 deletions

View File

@ -27,7 +27,9 @@ const testBuilderAccBasic = `
"type": "test", "type": "test",
"region": "nyc2", "region": "nyc2",
"size": "512mb", "size": "512mb",
"image": "ubuntu-12-04-x64" "image": "ubuntu-12-04-x64",
"user_date": "",
"user_date_file": ""
}] }]
} }
` `

View File

@ -31,6 +31,7 @@ type Config struct {
StateTimeout time.Duration `mapstructure:"state_timeout"` StateTimeout time.Duration `mapstructure:"state_timeout"`
DropletName string `mapstructure:"droplet_name"` DropletName string `mapstructure:"droplet_name"`
UserData string `mapstructure:"user_data"` UserData string `mapstructure:"user_data"`
UserDataFile string `mapstructure:"user_data_file"`
ctx interpolate.Context ctx interpolate.Context
} }
@ -113,6 +114,16 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
errs, errors.New("image is required")) errs, errors.New("image is required"))
} }
if c.UserData != "" && c.UserDataFile != "" {
errs = packer.MultiErrorAppend(
errs, errors.New("only one of user_data or user_data_file can be specified"))
} else if c.UserDataFile != "" {
if _, err := os.Stat(c.UserDataFile); err != nil {
errs = packer.MultiErrorAppend(
errs, errors.New(fmt.Sprintf("user_data_file not found: %s", c.UserDataFile)))
}
}
if errs != nil && len(errs.Errors) > 0 { if errs != nil && len(errs.Errors) > 0 {
return nil, nil, errs return nil, nil, errs
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/digitalocean/godo" "github.com/digitalocean/godo"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"io/ioutil"
) )
type stepCreateDroplet struct { type stepCreateDroplet struct {
@ -20,6 +21,18 @@ func (s *stepCreateDroplet) Run(state multistep.StateBag) multistep.StepAction {
// Create the droplet based on configuration // Create the droplet based on configuration
ui.Say("Creating droplet...") ui.Say("Creating droplet...")
userData := c.UserData
if c.UserDataFile != "" {
contents, err := ioutil.ReadFile(c.UserDataFile)
if err != nil {
state.Put("error", fmt.Errorf("Problem reading user data file: %s", err))
return multistep.ActionHalt
}
userData = string(contents)
}
droplet, _, err := client.Droplets.Create(&godo.DropletCreateRequest{ droplet, _, err := client.Droplets.Create(&godo.DropletCreateRequest{
Name: c.DropletName, Name: c.DropletName,
Region: c.Region, Region: c.Region,
@ -31,7 +44,7 @@ func (s *stepCreateDroplet) Run(state multistep.StateBag) multistep.StepAction {
godo.DropletCreateSSHKey{ID: int(sshKeyId)}, godo.DropletCreateSSHKey{ID: int(sshKeyId)},
}, },
PrivateNetworking: c.PrivateNetworking, PrivateNetworking: c.PrivateNetworking,
UserData: c.UserData, UserData: userData,
}) })
if err != nil { if err != nil {
err := fmt.Errorf("Error creating droplet: %s", err) err := fmt.Errorf("Error creating droplet: %s", err)

View File

@ -75,6 +75,9 @@ builder.
default state timeout is "6m". default state timeout is "6m".
- `user_data` (string) - User data to launch with the Droplet. - `user_data` (string) - User data to launch with the Droplet.
- `user_data_file` (string) - Path to a file that will be used for the user
data when launching the Droplet.
## Basic Example ## Basic Example