github.com/emate/packer@v0.8.1-0.20150625195101-fe0fde195dc6/builder/digitalocean/config.go (about) 1 package digitalocean 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/mitchellh/mapstructure" 10 "github.com/mitchellh/packer/common" 11 "github.com/mitchellh/packer/common/uuid" 12 "github.com/mitchellh/packer/helper/communicator" 13 "github.com/mitchellh/packer/helper/config" 14 "github.com/mitchellh/packer/packer" 15 "github.com/mitchellh/packer/template/interpolate" 16 ) 17 18 type Config struct { 19 common.PackerConfig `mapstructure:",squash"` 20 Comm communicator.Config `mapstructure:",squash"` 21 22 APIToken string `mapstructure:"api_token"` 23 24 Region string `mapstructure:"region"` 25 Size string `mapstructure:"size"` 26 Image string `mapstructure:"image"` 27 28 PrivateNetworking bool `mapstructure:"private_networking"` 29 SnapshotName string `mapstructure:"snapshot_name"` 30 StateTimeout time.Duration `mapstructure:"state_timeout"` 31 DropletName string `mapstructure:"droplet_name"` 32 UserData string `mapstructure:"user_data"` 33 34 ctx interpolate.Context 35 } 36 37 func NewConfig(raws ...interface{}) (*Config, []string, error) { 38 c := new(Config) 39 40 var md mapstructure.Metadata 41 err := config.Decode(c, &config.DecodeOpts{ 42 Metadata: &md, 43 Interpolate: true, 44 InterpolateContext: &c.ctx, 45 InterpolateFilter: &interpolate.RenderFilter{ 46 Exclude: []string{ 47 "run_command", 48 }, 49 }, 50 }, raws...) 51 if err != nil { 52 return nil, nil, err 53 } 54 55 // Defaults 56 if c.APIToken == "" { 57 // Default to environment variable for api_token, if it exists 58 c.APIToken = os.Getenv("DIGITALOCEAN_API_TOKEN") 59 } 60 61 if c.SnapshotName == "" { 62 def, err := interpolate.Render("packer-{{timestamp}}", nil) 63 if err != nil { 64 panic(err) 65 } 66 67 // Default to packer-{{ unix timestamp (utc) }} 68 c.SnapshotName = def 69 } 70 71 if c.DropletName == "" { 72 // Default to packer-[time-ordered-uuid] 73 c.DropletName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) 74 } 75 76 if c.Comm.SSHUsername == "" { 77 // Default to "root". You can override this if your 78 // SourceImage has a different user account then the DO default 79 c.Comm.SSHUsername = "root" 80 } 81 82 if c.StateTimeout == 0 { 83 // Default to 6 minute timeouts waiting for 84 // desired state. i.e waiting for droplet to become active 85 c.StateTimeout = 6 * time.Minute 86 } 87 88 var errs *packer.MultiError 89 if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { 90 errs = packer.MultiErrorAppend(errs, es...) 91 } 92 if c.APIToken == "" { 93 // Required configurations that will display errors if not set 94 errs = packer.MultiErrorAppend( 95 errs, errors.New("api_token for auth must be specified")) 96 } 97 98 if c.Region == "" { 99 errs = packer.MultiErrorAppend( 100 errs, errors.New("region is required")) 101 } 102 103 if c.Size == "" { 104 errs = packer.MultiErrorAppend( 105 errs, errors.New("size is required")) 106 } 107 108 if c.Image == "" { 109 errs = packer.MultiErrorAppend( 110 errs, errors.New("image is required")) 111 } 112 113 if errs != nil && len(errs.Errors) > 0 { 114 return nil, nil, errs 115 } 116 117 common.ScrubConfig(c, c.APIToken) 118 return c, nil, nil 119 }