Track the import task and report AMIs created from it

This commit is contained in:
David Zanetti 2015-11-23 15:55:09 +13:00
parent 439d1b1788
commit 418da16991
2 changed files with 72 additions and 4 deletions

View File

@ -8,6 +8,7 @@ import (
"os"
"strconv"
"time"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/ec2"
@ -128,6 +129,34 @@ func SpotRequestStateRefreshFunc(conn *ec2.EC2, spotRequestId string) StateRefre
}
}
func ImportImageRefreshFunc(conn *ec2.EC2, importTaskId string) StateRefreshFunc {
return func() (interface{}, string, error) {
resp, err := conn.DescribeImportImageTasks(&ec2.DescribeImportImageTasksInput{
ImportTaskIds: []*string{
&importTaskId,
},
},
)
if err != nil {
if ec2err, ok := err.(awserr.Error); ok && strings.HasPrefix(ec2err.Code(),"InvalidConversionTaskId") {
resp = nil
} else if isTransientNetworkError(err) {
resp = nil
} else {
log.Printf("Error on ImportImageRefresh: %s", err)
return nil, "", err
}
}
if resp == nil || len(resp.ImportImageTasks) == 0 {
return nil, "", nil
}
i := resp.ImportImageTasks[0]
return i, *i.Status, nil
}
}
// WaitForState watches an object and waits for it to achieve a certain
// state.
func WaitForState(conf *StateChangeConf) (i interface{}, err error) {

View File

@ -17,10 +17,12 @@ import (
"github.com/mitchellh/packer/template/interpolate"
)
const BuilderId = "packer.post-processor.amazon-import"
// We accept the output from vmware or vmware-esx
var builtins = map[string]string{
"mitchellh.vmware": "amazon-ova",
"mitchellh.vmware-esx": "amazon-ova",
"mitchellh.vmware": "amazon-import",
"mitchellh.vmware-esx": "amazon-import",
}
// Configuration of this post processor
@ -141,7 +143,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
// Call EC2 image import process
ec2conn := ec2.New(session)
impres, err := ec2conn.ImportImage(&ec2.ImportImageInput{
import_start, err := ec2conn.ImportImage(&ec2.ImportImageInput{
Description: &p.config.ImportTaskDesc,
DiskContainers: []*ec2.ImageDiskContainer{
{
@ -158,7 +160,44 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
return nil, false, fmt.Errorf("Failed to start import from s3://%s/%s: %s", p.config.S3Bucket, p.config.S3Key, err)
}
ui.Message(fmt.Sprintf("Started import of s3://%s/%s, task id %s", p.config.S3Bucket, p.config.S3Key, *impres.ImportTaskId))
ui.Message(fmt.Sprintf("Started import of s3://%s/%s, task id %s", p.config.S3Bucket, p.config.S3Key, *import_start.ImportTaskId))
// Wait for import process to complete, this takess a while
ui.Message(fmt.Sprintf("Waiting for task %s to complete (may take a while)", *import_start.ImportTaskId))
stateChange := awscommon.StateChangeConf{
Pending: []string{"pending","active"},
Refresh: awscommon.ImportImageRefreshFunc(ec2conn, *import_start.ImportTaskId),
Target: "completed",
}
_, err = awscommon.WaitForState(&stateChange)
if err != nil {
return nil, false, fmt.Errorf("Import task %s failed: %s", *import_start.ImportTaskId, err)
}
// Extract the AMI ID and return this as the artifact of the
// post processor
import_result, err := ec2conn.DescribeImportImageTasks(&ec2.DescribeImportImageTasksInput{
ImportTaskIds: []*string{
import_start.ImportTaskId,
},
})
if err != nil {
return nil, false, fmt.Errorf("API error for import task id %s: %s", *import_start.ImportTaskId, err)
}
// Add the discvered AMI ID to the artifact list
artifact = &awscommon.Artifact{
Amis: map[string]string{
*config.Region: *import_result.ImportImageTasks[0].ImageId,
},
BuilderIdValue: BuilderId,
Conn: ec2conn,
}
return artifact, false, nil
}