github.com/tonnydourado/packer@v0.6.1-0.20140701134019-5d0cd9676a37/builder/amazon/common/run_config.go (about) 1 package common 2 3 import ( 4 "errors" 5 "fmt" 6 "github.com/mitchellh/packer/packer" 7 "os" 8 "time" 9 ) 10 11 // RunConfig contains configuration for running an instance from a source 12 // AMI and details on how to access that launched image. 13 type RunConfig struct { 14 AssociatePublicIpAddress bool `mapstructure:"associate_public_ip_address"` 15 AvailabilityZone string `mapstructure:"availability_zone"` 16 IamInstanceProfile string `mapstructure:"iam_instance_profile"` 17 InstanceType string `mapstructure:"instance_type"` 18 RunTags map[string]string `mapstructure:"run_tags"` 19 SourceAmi string `mapstructure:"source_ami"` 20 RawSSHTimeout string `mapstructure:"ssh_timeout"` 21 SSHUsername string `mapstructure:"ssh_username"` 22 SSHPrivateKeyFile string `mapstructure:"ssh_private_key_file"` 23 SSHPort int `mapstructure:"ssh_port"` 24 SecurityGroupId string `mapstructure:"security_group_id"` 25 SecurityGroupIds []string `mapstructure:"security_group_ids"` 26 SubnetId string `mapstructure:"subnet_id"` 27 TemporaryKeyPairName string `mapstructure:"temporary_key_pair_name"` 28 UserData string `mapstructure:"user_data"` 29 UserDataFile string `mapstructure:"user_data_file"` 30 VpcId string `mapstructure:"vpc_id"` 31 32 // Unexported fields that are calculated from others 33 sshTimeout time.Duration 34 } 35 36 func (c *RunConfig) Prepare(t *packer.ConfigTemplate) []error { 37 if t == nil { 38 var err error 39 t, err = packer.NewConfigTemplate() 40 if err != nil { 41 return []error{err} 42 } 43 } 44 45 // Defaults 46 if c.SSHPort == 0 { 47 c.SSHPort = 22 48 } 49 50 if c.RawSSHTimeout == "" { 51 c.RawSSHTimeout = "5m" 52 } 53 54 if c.TemporaryKeyPairName == "" { 55 c.TemporaryKeyPairName = "packer {{uuid}}" 56 } 57 58 // Validation 59 var err error 60 errs := make([]error, 0) 61 if c.SourceAmi == "" { 62 errs = append(errs, errors.New("A source_ami must be specified")) 63 } 64 65 if c.InstanceType == "" { 66 errs = append(errs, errors.New("An instance_type must be specified")) 67 } 68 69 if c.SSHUsername == "" { 70 errs = append(errs, errors.New("An ssh_username must be specified")) 71 } 72 73 if c.UserData != "" && c.UserDataFile != "" { 74 errs = append(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) 75 } else if c.UserDataFile != "" { 76 if _, err := os.Stat(c.UserDataFile); err != nil { 77 errs = append(errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile)) 78 } 79 } 80 81 if c.SecurityGroupId != "" { 82 if len(c.SecurityGroupIds) > 0 { 83 errs = append(errs, fmt.Errorf("Only one of security_group_id or security_group_ids can be specified.")) 84 } else { 85 c.SecurityGroupIds = []string{c.SecurityGroupId} 86 c.SecurityGroupId = "" 87 } 88 } 89 90 templates := map[string]*string{ 91 "iam_instance_profile": &c.IamInstanceProfile, 92 "instance_type": &c.InstanceType, 93 "ssh_timeout": &c.RawSSHTimeout, 94 "ssh_username": &c.SSHUsername, 95 "ssh_private_key_file": &c.SSHPrivateKeyFile, 96 "source_ami": &c.SourceAmi, 97 "subnet_id": &c.SubnetId, 98 "temporary_key_pair_name": &c.TemporaryKeyPairName, 99 "vpc_id": &c.VpcId, 100 "availability_zone": &c.AvailabilityZone, 101 } 102 103 for n, ptr := range templates { 104 var err error 105 *ptr, err = t.Process(*ptr, nil) 106 if err != nil { 107 errs = append( 108 errs, fmt.Errorf("Error processing %s: %s", n, err)) 109 } 110 } 111 112 sliceTemplates := map[string][]string{ 113 "security_group_ids": c.SecurityGroupIds, 114 } 115 116 for n, slice := range sliceTemplates { 117 for i, elem := range slice { 118 var err error 119 slice[i], err = t.Process(elem, nil) 120 if err != nil { 121 errs = append( 122 errs, fmt.Errorf("Error processing %s[%d]: %s", n, i, err)) 123 } 124 } 125 } 126 127 newTags := make(map[string]string) 128 for k, v := range c.RunTags { 129 k, err := t.Process(k, nil) 130 if err != nil { 131 errs = append(errs, 132 fmt.Errorf("Error processing tag key %s: %s", k, err)) 133 continue 134 } 135 136 v, err := t.Process(v, nil) 137 if err != nil { 138 errs = append(errs, 139 fmt.Errorf("Error processing tag value '%s': %s", v, err)) 140 continue 141 } 142 143 newTags[k] = v 144 } 145 146 c.RunTags = newTags 147 148 c.sshTimeout, err = time.ParseDuration(c.RawSSHTimeout) 149 if err != nil { 150 errs = append(errs, fmt.Errorf("Failed parsing ssh_timeout: %s", err)) 151 } 152 153 return errs 154 } 155 156 func (c *RunConfig) SSHTimeout() time.Duration { 157 return c.sshTimeout 158 }