github.com/jbronn/packer@v0.1.6-0.20140120165540-8a1364dbd817/builder/amazon/common/ami_config.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/mitchellh/goamz/aws"
     6  	"github.com/mitchellh/packer/packer"
     7  )
     8  
     9  // AMIConfig is for common configuration related to creating AMIs.
    10  type AMIConfig struct {
    11  	AMIName         string            `mapstructure:"ami_name"`
    12  	AMIDescription  string            `mapstructure:"ami_description"`
    13  	AMIUsers        []string          `mapstructure:"ami_users"`
    14  	AMIGroups       []string          `mapstructure:"ami_groups"`
    15  	AMIProductCodes []string          `mapstructure:"ami_product_codes"`
    16  	AMIRegions      []string          `mapstructure:"ami_regions"`
    17  	AMITags         map[string]string `mapstructure:"tags"`
    18  }
    19  
    20  func (c *AMIConfig) Prepare(t *packer.ConfigTemplate) []error {
    21  	if t == nil {
    22  		var err error
    23  		t, err = packer.NewConfigTemplate()
    24  		if err != nil {
    25  			return []error{err}
    26  		}
    27  	}
    28  
    29  	templates := map[string]*string{
    30  		"ami_name":        &c.AMIName,
    31  		"ami_description": &c.AMIDescription,
    32  	}
    33  
    34  	errs := make([]error, 0)
    35  	for n, ptr := range templates {
    36  		var err error
    37  		*ptr, err = t.Process(*ptr, nil)
    38  		if err != nil {
    39  			errs = append(
    40  				errs, fmt.Errorf("Error processing %s: %s", n, err))
    41  		}
    42  	}
    43  
    44  	sliceTemplates := map[string][]string{
    45  		"ami_users":         c.AMIUsers,
    46  		"ami_groups":        c.AMIGroups,
    47  		"ami_product_codes": c.AMIProductCodes,
    48  		"ami_regions":       c.AMIRegions,
    49  	}
    50  
    51  	for n, slice := range sliceTemplates {
    52  		for i, elem := range slice {
    53  			var err error
    54  			slice[i], err = t.Process(elem, nil)
    55  			if err != nil {
    56  				errs = append(
    57  					errs, fmt.Errorf("Error processing %s[%d]: %s", n, i, err))
    58  			}
    59  		}
    60  	}
    61  
    62  	if c.AMIName == "" {
    63  		errs = append(errs, fmt.Errorf("ami_name must be specified"))
    64  	}
    65  
    66  	if len(c.AMIRegions) > 0 {
    67  		regionSet := make(map[string]struct{})
    68  		regions := make([]string, 0, len(c.AMIRegions))
    69  
    70  		for _, region := range c.AMIRegions {
    71  			// If we already saw the region, then don't look again
    72  			if _, ok := regionSet[region]; ok {
    73  				continue
    74  			}
    75  
    76  			// Mark that we saw the region
    77  			regionSet[region] = struct{}{}
    78  
    79  			// Verify the region is real
    80  			if _, ok := aws.Regions[region]; !ok {
    81  				errs = append(errs, fmt.Errorf("Unknown region: %s", region))
    82  				continue
    83  			}
    84  
    85  			regions = append(regions, region)
    86  		}
    87  
    88  		c.AMIRegions = regions
    89  	}
    90  
    91  	newTags := make(map[string]string)
    92  	for k, v := range c.AMITags {
    93  		k, err := t.Process(k, nil)
    94  		if err != nil {
    95  			errs = append(errs,
    96  				fmt.Errorf("Error processing tag key %s: %s", k, err))
    97  			continue
    98  		}
    99  
   100  		v, err := t.Process(v, nil)
   101  		if err != nil {
   102  			errs = append(errs,
   103  				fmt.Errorf("Error processing tag value '%s': %s", v, err))
   104  			continue
   105  		}
   106  
   107  		newTags[k] = v
   108  	}
   109  
   110  	c.AMITags = newTags
   111  
   112  	if len(errs) > 0 {
   113  		return errs
   114  	}
   115  
   116  	return nil
   117  }