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