From c6358b0475ce051fd185bacbab8ed97c2b58b0f6 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 24 Jul 2013 15:41:49 -0500 Subject: [PATCH] builder/amazon/instance: ec2-bundle-vol is called --- builder/amazon/instance/builder.go | 24 +++++++++++-- builder/amazon/instance/builder_test.go | 28 +++++++++++++++ builder/amazon/instance/step_bundle_volume.go | 36 +++++++++++++++++++ .../amazon/instance/step_upload_x509_cert.go | 3 ++ 4 files changed, 88 insertions(+), 3 deletions(-) diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 196907698..be2ea3dd3 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -13,6 +13,7 @@ import ( "github.com/mitchellh/packer/packer" "log" "os" + "strings" ) // The unique ID for this builder @@ -25,9 +26,11 @@ type Config struct { awscommon.AccessConfig `mapstructure:",squash"` awscommon.RunConfig `mapstructure:",squash"` - X509CertPath string `mapstructure:"x509_cert_path"` - X509KeyPath string `mapstructure:"x509_key_path"` - X509UploadPath string `mapstructure:"x509_upload_path"` + AccountId string `mapstructure:"account_id"` + BundleVolCommand string `mapstructure:"bundle_vol_command"` + X509CertPath string `mapstructure:"x509_cert_path"` + X509KeyPath string `mapstructure:"x509_key_path"` + X509UploadPath string `mapstructure:"x509_upload_path"` } type Builder struct { @@ -46,6 +49,21 @@ func (b *Builder) Prepare(raws ...interface{}) error { errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare()...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare()...) + if b.config.AccountId == "" { + errs = packer.MultiErrorAppend(errs, errors.New("account_id is required")) + } else { + b.config.AccountId = strings.Replace(b.config.AccountId, "-", "", -1) + } + + if b.config.BundleVolCommand == "" { + b.config.BundleVolCommand = "ec2-bundle-vol " + + "-k {{.KeyPath}} " + + "-u {{.AccountId}} " + + "-c {{.CertPath}} " + + "-r {{.Architecture}} " + + "-e {{.PrivatePath}}" + } + if b.config.X509CertPath == "" { errs = packer.MultiErrorAppend(errs, errors.New("x509_cert_path is required")) } else if _, err := os.Stat(b.config.X509CertPath); err != nil { diff --git a/builder/amazon/instance/builder_test.go b/builder/amazon/instance/builder_test.go index d83ee9c33..5b3a560a5 100644 --- a/builder/amazon/instance/builder_test.go +++ b/builder/amazon/instance/builder_test.go @@ -14,6 +14,7 @@ func testConfig() map[string]interface{} { } return map[string]interface{}{ + "account_id": "foo", "instance_type": "m1.small", "region": "us-east-1", "source_ami": "foo", @@ -32,6 +33,33 @@ func TestBuilder_ImplementsBuilder(t *testing.T) { } } +func TestBuilderPrepare_AccountId(t *testing.T) { + b := &Builder{} + config := testConfig() + + config["account_id"] = "" + err := b.Prepare(config) + if err == nil { + t.Fatal("should have error") + } + + config["account_id"] = "foo" + err = b.Prepare(config) + if err != nil { + t.Errorf("err: %s", err) + } + + config["account_id"] = "0123-0456-7890" + err = b.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } + + if b.config.AccountId != "012304567890" { + t.Errorf("should strip hyphens: %s", b.config.AccountId) + } +} + func TestBuilderPrepare_InvalidKey(t *testing.T) { var b Builder config := testConfig() diff --git a/builder/amazon/instance/step_bundle_volume.go b/builder/amazon/instance/step_bundle_volume.go index a0142991c..7851f687a 100644 --- a/builder/amazon/instance/step_bundle_volume.go +++ b/builder/amazon/instance/step_bundle_volume.go @@ -1,16 +1,31 @@ package instance import ( + "bytes" "fmt" + "github.com/mitchellh/goamz/ec2" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" + "text/template" ) +type bundleCmdData struct { + AccountId string + Architecture string + CertPath string + KeyPath string + PrivatePath string +} + type StepBundleVolume struct{} func (s *StepBundleVolume) Run(state map[string]interface{}) multistep.StepAction { comm := state["communicator"].(packer.Communicator) + config := state["config"].(*Config) + instance := state["instance"].(*ec2.Instance) ui := state["ui"].(packer.Ui) + x509RemoteCertPath := state["x509RemoteCertPath"].(string) + x509RemoteKeyPath := state["x509RemoteKeyPath"].(string) // Verify the AMI tools are available ui.Say("Checking for EC2 AMI tools...") @@ -31,6 +46,27 @@ func (s *StepBundleVolume) Run(state map[string]interface{}) multistep.StepActio return multistep.ActionHalt } + // Bundle the volume + var bundleCmd bytes.Buffer + tData := bundleCmdData{ + AccountId: config.AccountId, + Architecture: instance.Architecture, + CertPath: x509RemoteCertPath, + KeyPath: x509RemoteKeyPath, + PrivatePath: config.X509UploadPath, + } + t := template.Must(template.New("bundleCmd").Parse(config.BundleVolCommand)) + t.Execute(&bundleCmd, tData) + + ui.Say("Bundling the volume...") + cmd = new(packer.RemoteCmd) + cmd.Command = bundleCmd.String() + if err := cmd.StartWithUi(comm, ui); err != nil { + state["error"] = fmt.Errorf("Error bundling volume: %s", err) + ui.Error(state["error"].(error).Error()) + return multistep.ActionHalt + } + return multistep.ActionContinue } diff --git a/builder/amazon/instance/step_upload_x509_cert.go b/builder/amazon/instance/step_upload_x509_cert.go index 33add850e..5660bc228 100644 --- a/builder/amazon/instance/step_upload_x509_cert.go +++ b/builder/amazon/instance/step_upload_x509_cert.go @@ -30,6 +30,9 @@ func (s *StepUploadX509Cert) Run(state map[string]interface{}) multistep.StepAct return multistep.ActionHalt } + state["x509RemoteCertPath"] = x509RemoteCertPath + state["x509RemoteKeyPath"] = x509RemoteKeyPath + return multistep.ActionContinue }