github.com/homburg/packer@v0.6.1-0.20140528012651-1dcaf1716848/builder/googlecompute/config.go (about) 1 package googlecompute 2 3 import ( 4 "errors" 5 "fmt" 6 "time" 7 8 "github.com/mitchellh/packer/common" 9 "github.com/mitchellh/packer/common/uuid" 10 "github.com/mitchellh/packer/packer" 11 ) 12 13 // Config is the configuration structure for the GCE builder. It stores 14 // both the publicly settable state as well as the privately generated 15 // state of the config object. 16 type Config struct { 17 common.PackerConfig `mapstructure:",squash"` 18 19 BucketName string `mapstructure:"bucket_name"` 20 ClientSecretsFile string `mapstructure:"client_secrets_file"` 21 ImageName string `mapstructure:"image_name"` 22 ImageDescription string `mapstructure:"image_description"` 23 InstanceName string `mapstructure:"instance_name"` 24 MachineType string `mapstructure:"machine_type"` 25 Metadata map[string]string `mapstructure:"metadata"` 26 Network string `mapstructure:"network"` 27 Passphrase string `mapstructure:"passphrase"` 28 PrivateKeyFile string `mapstructure:"private_key_file"` 29 ProjectId string `mapstructure:"project_id"` 30 SourceImage string `mapstructure:"source_image"` 31 SSHUsername string `mapstructure:"ssh_username"` 32 SSHPort uint `mapstructure:"ssh_port"` 33 RawSSHTimeout string `mapstructure:"ssh_timeout"` 34 RawStateTimeout string `mapstructure:"state_timeout"` 35 Tags []string `mapstructure:"tags"` 36 Zone string `mapstructure:"zone"` 37 38 clientSecrets *clientSecrets 39 instanceName string 40 privateKeyBytes []byte 41 sshTimeout time.Duration 42 stateTimeout time.Duration 43 tpl *packer.ConfigTemplate 44 } 45 46 func NewConfig(raws ...interface{}) (*Config, []string, error) { 47 c := new(Config) 48 md, err := common.DecodeConfig(c, raws...) 49 if err != nil { 50 return nil, nil, err 51 } 52 53 c.tpl, err = packer.NewConfigTemplate() 54 if err != nil { 55 return nil, nil, err 56 } 57 c.tpl.UserVars = c.PackerUserVars 58 59 // Prepare the errors 60 errs := common.CheckUnusedConfig(md) 61 62 // Set defaults. 63 if c.Network == "" { 64 c.Network = "default" 65 } 66 67 if c.ImageDescription == "" { 68 c.ImageDescription = "Created by Packer" 69 } 70 71 if c.ImageName == "" { 72 c.ImageName = "packer-{{timestamp}}" 73 } 74 75 if c.InstanceName == "" { 76 c.InstanceName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) 77 } 78 79 if c.MachineType == "" { 80 c.MachineType = "n1-standard-1" 81 } 82 83 if c.RawSSHTimeout == "" { 84 c.RawSSHTimeout = "5m" 85 } 86 87 if c.RawStateTimeout == "" { 88 c.RawStateTimeout = "5m" 89 } 90 91 if c.SSHUsername == "" { 92 c.SSHUsername = "root" 93 } 94 95 if c.SSHPort == 0 { 96 c.SSHPort = 22 97 } 98 99 // Process Templates 100 templates := map[string]*string{ 101 "bucket_name": &c.BucketName, 102 "client_secrets_file": &c.ClientSecretsFile, 103 "image_name": &c.ImageName, 104 "image_description": &c.ImageDescription, 105 "instance_name": &c.InstanceName, 106 "machine_type": &c.MachineType, 107 "network": &c.Network, 108 "passphrase": &c.Passphrase, 109 "private_key_file": &c.PrivateKeyFile, 110 "project_id": &c.ProjectId, 111 "source_image": &c.SourceImage, 112 "ssh_username": &c.SSHUsername, 113 "ssh_timeout": &c.RawSSHTimeout, 114 "state_timeout": &c.RawStateTimeout, 115 "zone": &c.Zone, 116 } 117 118 for n, ptr := range templates { 119 var err error 120 *ptr, err = c.tpl.Process(*ptr, nil) 121 if err != nil { 122 errs = packer.MultiErrorAppend( 123 errs, fmt.Errorf("Error processing %s: %s", n, err)) 124 } 125 } 126 127 // Process required parameters. 128 if c.BucketName == "" { 129 errs = packer.MultiErrorAppend( 130 errs, errors.New("a bucket_name must be specified")) 131 } 132 133 if c.ClientSecretsFile == "" { 134 errs = packer.MultiErrorAppend( 135 errs, errors.New("a client_secrets_file must be specified")) 136 } 137 138 if c.PrivateKeyFile == "" { 139 errs = packer.MultiErrorAppend( 140 errs, errors.New("a private_key_file must be specified")) 141 } 142 143 if c.ProjectId == "" { 144 errs = packer.MultiErrorAppend( 145 errs, errors.New("a project_id must be specified")) 146 } 147 148 if c.SourceImage == "" { 149 errs = packer.MultiErrorAppend( 150 errs, errors.New("a source_image must be specified")) 151 } 152 153 if c.Zone == "" { 154 errs = packer.MultiErrorAppend( 155 errs, errors.New("a zone must be specified")) 156 } 157 158 // Process timeout settings. 159 sshTimeout, err := time.ParseDuration(c.RawSSHTimeout) 160 if err != nil { 161 errs = packer.MultiErrorAppend( 162 errs, fmt.Errorf("Failed parsing ssh_timeout: %s", err)) 163 } 164 c.sshTimeout = sshTimeout 165 166 stateTimeout, err := time.ParseDuration(c.RawStateTimeout) 167 if err != nil { 168 errs = packer.MultiErrorAppend( 169 errs, fmt.Errorf("Failed parsing state_timeout: %s", err)) 170 } 171 c.stateTimeout = stateTimeout 172 173 if c.ClientSecretsFile != "" { 174 // Load the client secrets file. 175 cs, err := loadClientSecrets(c.ClientSecretsFile) 176 if err != nil { 177 errs = packer.MultiErrorAppend( 178 errs, fmt.Errorf("Failed parsing client secrets file: %s", err)) 179 } 180 c.clientSecrets = cs 181 } 182 183 if c.PrivateKeyFile != "" { 184 // Load the private key. 185 c.privateKeyBytes, err = processPrivateKeyFile(c.PrivateKeyFile, c.Passphrase) 186 if err != nil { 187 errs = packer.MultiErrorAppend( 188 errs, fmt.Errorf("Failed loading private key file: %s", err)) 189 } 190 } 191 192 // Check for any errors. 193 if errs != nil && len(errs.Errors) > 0 { 194 return nil, nil, errs 195 } 196 197 return c, nil, nil 198 }