|
|
|
|
@ -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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
image := imageResp.Images[0]
|
|
|
|
|
ui.Say(fmt.Sprintf("Got Image %v", image))
|
|
|
|
|
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
|
|
|
|
|
|