builder/amazon/instance: register the AMI
This commit is contained in:
parent
03a2cc8b22
commit
0552bc7306
|
@ -14,6 +14,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// The unique ID for this builder
|
||||
|
@ -27,6 +28,7 @@ type Config struct {
|
|||
awscommon.RunConfig `mapstructure:",squash"`
|
||||
|
||||
AccountId string `mapstructure:"account_id"`
|
||||
AMIName string `mapstructure:"ami_name"`
|
||||
BundleDestination string `mapstructure:"bundle_destination"`
|
||||
BundlePrefix string `mapstructure:"bundle_prefix"`
|
||||
BundleUploadCommand string `mapstructure:"bundle_upload_command"`
|
||||
|
@ -90,6 +92,17 @@ func (b *Builder) Prepare(raws ...interface{}) error {
|
|||
b.config.AccountId = strings.Replace(b.config.AccountId, "-", "", -1)
|
||||
}
|
||||
|
||||
if b.config.AMIName == "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("ami_name must be specified"))
|
||||
} else {
|
||||
_, err = template.New("ami").Parse(b.config.AMIName)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Failed parsing ami_name: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
if b.config.S3Bucket == "" {
|
||||
errs = packer.MultiErrorAppend(errs, errors.New("s3_bucket is required"))
|
||||
}
|
||||
|
@ -163,6 +176,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
&StepUploadX509Cert{},
|
||||
&StepBundleVolume{},
|
||||
&StepUploadBundle{},
|
||||
&StepRegisterAMI{},
|
||||
}
|
||||
|
||||
// Run!
|
||||
|
@ -187,7 +201,14 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
// Build the artifact and return it
|
||||
artifact := &awscommon.Artifact{
|
||||
Amis: state["amis"].(map[string]string),
|
||||
BuilderIdValue: BuilderId,
|
||||
Conn: ec2conn,
|
||||
}
|
||||
|
||||
return artifact, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Cancel() {
|
||||
|
|
|
@ -15,6 +15,7 @@ func testConfig() map[string]interface{} {
|
|||
|
||||
return map[string]interface{}{
|
||||
"account_id": "foo",
|
||||
"ami_name": "foo",
|
||||
"instance_type": "m1.small",
|
||||
"region": "us-east-1",
|
||||
"s3_bucket": "foo",
|
||||
|
@ -61,6 +62,34 @@ func TestBuilderPrepare_AccountId(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_AMIName(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test good
|
||||
config["ami_name"] = "foo"
|
||||
err := b.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Test bad
|
||||
config["ami_name"] = "foo {{"
|
||||
b = Builder{}
|
||||
err = b.Prepare(config)
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test bad
|
||||
delete(config, "ami_name")
|
||||
b = Builder{}
|
||||
err = b.Prepare(config)
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_BundleDestination(t *testing.T) {
|
||||
b := &Builder{}
|
||||
config := testConfig()
|
||||
|
|
|
@ -93,8 +93,10 @@ func (s *StepBundleVolume) Run(state map[string]interface{}) multistep.StepActio
|
|||
}
|
||||
|
||||
// Store the manifest path
|
||||
manifestName := bundlePrefix.String() + ".manifest.xml"
|
||||
state["manifest_name"] = manifestName
|
||||
state["manifest_path"] = fmt.Sprintf(
|
||||
"%s/%s.manifest.xml", config.BundleDestination, bundlePrefix.String())
|
||||
"%s/%s", config.BundleDestination, manifestName)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package instance
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"strconv"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
type amiNameData struct {
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
type StepRegisterAMI struct{}
|
||||
|
||||
func (s *StepRegisterAMI) Run(state map[string]interface{}) multistep.StepAction {
|
||||
comm := state["communicator"].(packer.Communicator)
|
||||
config := state["config"].(*Config)
|
||||
manifestPath := state["remote_manifest_path"].(string)
|
||||
ui := state["ui"].(packer.Ui)
|
||||
|
||||
// Parse the name of the AMI
|
||||
amiNameBuf := new(bytes.Buffer)
|
||||
tData := amiNameData{
|
||||
strconv.FormatInt(time.Now().UTC().Unix(), 10),
|
||||
}
|
||||
|
||||
t := template.Must(template.New("ami").Parse(config.AMIName))
|
||||
t.Execute(amiNameBuf, tData)
|
||||
amiName := amiNameBuf.String()
|
||||
|
||||
ui.Say("Registering the AMI...")
|
||||
cmd := &packer.RemoteCmd{
|
||||
Command: fmt.Sprintf(
|
||||
"ec2-register %s -n '%s' -O '%s' -W '%s'",
|
||||
manifestPath,
|
||||
amiName,
|
||||
config.AccessKey,
|
||||
config.SecretKey),
|
||||
}
|
||||
if err := cmd.StartWithUi(comm, ui); err != nil {
|
||||
state["error"] = fmt.Errorf("Error registering AMI: %s", err)
|
||||
ui.Error(state["error"].(error).Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
if cmd.ExitStatus != 0 {
|
||||
state["error"] = fmt.Errorf(
|
||||
"AMI registration failed. Please see the output above for more\n" +
|
||||
"details on what went wrong.")
|
||||
ui.Error(state["error"].(error).Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepRegisterAMI) Cleanup(map[string]interface{}) {}
|
|
@ -21,6 +21,7 @@ type StepUploadBundle struct{}
|
|||
func (s *StepUploadBundle) Run(state map[string]interface{}) multistep.StepAction {
|
||||
comm := state["communicator"].(packer.Communicator)
|
||||
config := state["config"].(*Config)
|
||||
manifestName := state["manifest_name"].(string)
|
||||
manifestPath := state["manifest_path"].(string)
|
||||
ui := state["ui"].(packer.Ui)
|
||||
|
||||
|
@ -51,6 +52,9 @@ func (s *StepUploadBundle) Run(state map[string]interface{}) multistep.StepActio
|
|||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
state["remote_manifest_path"] = fmt.Sprintf(
|
||||
"%s/%s", config.S3Bucket, manifestName)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue