[dynamic-source-ami] make most_recent work
This commit is contained in:
parent
ec1abb9448
commit
0e248f1516
|
@ -15,13 +15,13 @@ import (
|
|||
var reShutdownBehavior = regexp.MustCompile("^(stop|terminate)$")
|
||||
|
||||
type DynamicAmiOptions struct {
|
||||
Filters map[*string]*string
|
||||
Owners []*string
|
||||
Most_recent bool
|
||||
Filters map[*string]*string
|
||||
Owners []*string
|
||||
MostRecent bool `mapstructure:"most_recent"`
|
||||
}
|
||||
|
||||
func (d *DynamicAmiOptions) Validate() bool {
|
||||
return true
|
||||
func (d *DynamicAmiOptions) Empty() bool {
|
||||
return len(d.Owners) == 0 && len(d.Filters) == 0
|
||||
}
|
||||
|
||||
// RunConfig contains configuration for running an instance from a source
|
||||
|
@ -67,7 +67,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
|
||||
// Validation
|
||||
errs := c.Comm.Prepare(ctx)
|
||||
if c.SourceAmi == "" {
|
||||
if c.SourceAmi == "" && c.DynamicSourceAmi.Empty() {
|
||||
errs = append(errs, errors.New("A source_ami or dynamic_source_ami must be specified"))
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@ package common
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/mitchellh/multistep"
|
||||
|
@ -23,11 +26,6 @@ type StepSourceAMIInfo struct {
|
|||
func buildAmiFilters(input map[*string]*string) []*ec2.Filter {
|
||||
var filters []*ec2.Filter
|
||||
for k, v := range input {
|
||||
/*m := v.(map[string]interface{})
|
||||
var filterValues []*string
|
||||
for _, e := range m["values"].([]interface{}) {
|
||||
filterValues = append(filterValues, aws.String(e.(string)))
|
||||
}*/
|
||||
filters = append(filters, &ec2.Filter{
|
||||
Name: k,
|
||||
Values: []*string{v},
|
||||
|
@ -36,17 +34,40 @@ func buildAmiFilters(input map[*string]*string) []*ec2.Filter {
|
|||
return filters
|
||||
}
|
||||
|
||||
type imageSort []*ec2.Image
|
||||
|
||||
func (a imageSort) Len() int { return len(a) }
|
||||
func (a imageSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a imageSort) Less(i, j int) bool {
|
||||
itime, _ := time.Parse(time.RFC3339, *a[i].CreationDate)
|
||||
jtime, _ := time.Parse(time.RFC3339, *a[j].CreationDate)
|
||||
return itime.Unix() < jtime.Unix()
|
||||
}
|
||||
|
||||
// Returns the most recent AMI out of a slice of images.
|
||||
func mostRecentAmi(images []*ec2.Image) *ec2.Image {
|
||||
sortedImages := images
|
||||
sort.Sort(imageSort(sortedImages))
|
||||
return sortedImages[len(sortedImages)-1]
|
||||
}
|
||||
|
||||
func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
|
||||
ec2conn := state.Get("ec2").(*ec2.EC2)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
params := &ec2.DescribeImagesInput{}
|
||||
params.Filters = buildAmiFilters(s.AmiFilters.Filters)
|
||||
params.Owners = s.AmiFilters.Owners
|
||||
ui.Say(fmt.Sprintf("Using AMI Filters %v", params))
|
||||
|
||||
if s.SourceAmi != "" {
|
||||
params.ImageIds = []*string{&s.SourceAmi}
|
||||
}
|
||||
|
||||
// We have filters to apply
|
||||
if len(s.AmiFilters.Filters) > 0 {
|
||||
params.Filters = buildAmiFilters(s.AmiFilters.Filters)
|
||||
}
|
||||
|
||||
log.Printf("Using AMI Filters %v", params)
|
||||
imageResp, err := ec2conn.DescribeImages(params)
|
||||
//ui.Say(fmt.Sprintf("Inspecting the source AMI (%s)...", s.SourceAmi))
|
||||
//imageResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{&s.SourceAmi}})
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error querying AMI: %s", err)
|
||||
state.Put("error", err)
|
||||
|
@ -55,14 +76,27 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
|
|||
}
|
||||
|
||||
if len(imageResp.Images) == 0 {
|
||||
err := fmt.Errorf("Source AMI '%s' was not found!", s.SourceAmi)
|
||||
err := fmt.Errorf("No AMI was found matching filters: %v", params)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
image := imageResp.Images[0]
|
||||
ui.Say(fmt.Sprintf("Got Image %v", image))
|
||||
if len(imageResp.Images) > 1 && s.AmiFilters.MostRecent == false {
|
||||
err := fmt.Errorf("Your query returned more than one result. Please try a more specific search, or set most_recent to true.")
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
var image *ec2.Image
|
||||
if s.AmiFilters.MostRecent {
|
||||
image = mostRecentAmi(imageResp.Images)
|
||||
} else {
|
||||
image = imageResp.Images[0]
|
||||
}
|
||||
|
||||
log.Printf(fmt.Sprintf("Got Image %v", image))
|
||||
|
||||
// Enhanced Networking (SriovNetSupport) can only be enabled on HVM AMIs.
|
||||
// See http://goo.gl/icuXh5
|
||||
|
|
Loading…
Reference in New Issue