builder/amazonebs: Can make an AMI. WHAT!
This commit is contained in:
parent
185d2765be
commit
e071739cd8
|
@ -7,8 +7,12 @@ package amazonebs
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/mitchellh/goamz/aws"
|
||||
"github.com/mitchellh/goamz/ec2"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
|
@ -43,6 +47,93 @@ func (b *Builder) Prepare(raw interface{}) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (*Builder) Run(b packer.Build, ui packer.Ui) {
|
||||
ui.Say("Building an AWS image...\n")
|
||||
func (b *Builder) Run(build packer.Build, ui packer.Ui) {
|
||||
auth := aws.Auth{b.config.AccessKey, b.config.SecretKey}
|
||||
region := aws.Regions[b.config.Region]
|
||||
ec2conn := ec2.New(auth, region)
|
||||
|
||||
runOpts := &ec2.RunInstances{
|
||||
ImageId: b.config.SourceAmi,
|
||||
InstanceType: "m1.small",
|
||||
MinCount: 0,
|
||||
MaxCount: 0,
|
||||
}
|
||||
|
||||
ui.Say("Launching a source AWS instance...\n")
|
||||
runResp, err := ec2conn.RunInstances(runOpts)
|
||||
if err != nil {
|
||||
ui.Error("%s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
instance := &runResp.Instances[0]
|
||||
log.Printf("instance id: %s\n", instance.InstanceId)
|
||||
ui.Say("Waiting for instance to become ready...\n")
|
||||
err = waitForState(ec2conn, instance, "running")
|
||||
if err != nil {
|
||||
ui.Error("%s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Stop the instance so we can create an AMI from it
|
||||
_, err = ec2conn.StopInstances(instance.InstanceId)
|
||||
if err != nil {
|
||||
ui.Error("%s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Wait for the instance to actual stop
|
||||
// TODO: Handle diff source states, i.e. this force state sucks
|
||||
ui.Say("Waiting for the instance to stop...\n")
|
||||
instance.State.Name = "stopping"
|
||||
err = waitForState(ec2conn, instance, "stopped")
|
||||
if err != nil {
|
||||
ui.Error("%s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Create the image
|
||||
ui.Say("Creating the AMI...\n")
|
||||
createOpts := &ec2.CreateImage{
|
||||
InstanceId: instance.InstanceId,
|
||||
Name: "ZIMAGINE",
|
||||
}
|
||||
|
||||
createResp, err := ec2conn.CreateImage(createOpts)
|
||||
if err != nil {
|
||||
ui.Error("%s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ui.Say("AMI: %s\n", createResp.ImageId)
|
||||
|
||||
// Make sure we clean up the instance by terminating it, no matter what
|
||||
defer func() {
|
||||
// TODO: error handling
|
||||
ui.Say("Terminating the source AWS instance...\n")
|
||||
ec2conn.TerminateInstances([]string{instance.InstanceId})
|
||||
}()
|
||||
}
|
||||
|
||||
func waitForState(ec2conn *ec2.EC2, i *ec2.Instance, target string) (err error) {
|
||||
log.Printf("Waiting for instance state to become: %s\n", target)
|
||||
|
||||
original := i.State.Name
|
||||
for i.State.Name == original {
|
||||
var resp *ec2.InstancesResp
|
||||
resp, err = ec2conn.Instances([]string{i.InstanceId}, ec2.NewFilter())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
i = &resp.Reservations[0].Instances[0]
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
||||
if i.State.Name != target {
|
||||
return fmt.Errorf("unexpected target state '%s', wanted '%s'", i.State.Name, target)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue