From b04cff5a9e1a823fc7a073f0e3750e4fd9278959 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 31 Aug 2013 13:00:43 -0700 Subject: [PATCH] builder/amazon/ebs: new multistep API --- builder/amazon/common/ssh.go | 15 ++++++++------- builder/amazon/ebs/builder.go | 16 ++++++++-------- builder/amazon/ebs/step_create_ami.go | 18 +++++++++--------- builder/amazon/ebs/step_stop_instance.go | 14 +++++++------- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/builder/amazon/common/ssh.go b/builder/amazon/common/ssh.go index eb87767cb..5e7d8872d 100644 --- a/builder/amazon/common/ssh.go +++ b/builder/amazon/common/ssh.go @@ -5,17 +5,18 @@ import ( "errors" "fmt" "github.com/mitchellh/goamz/ec2" + "github.com/mitchellh/multistep" "github.com/mitchellh/packer/communicator/ssh" "time" ) // SSHAddress returns a function that can be given to the SSH communicator // for determining the SSH address based on the instance DNS name. -func SSHAddress(e *ec2.EC2, port int) func(map[string]interface{}) (string, error) { - return func(state map[string]interface{}) (string, error) { +func SSHAddress(e *ec2.EC2, port int) func(multistep.StateBag) (string, error) { + return func(state multistep.StateBag) (string, error) { for j := 0; j < 2; j++ { var host string - i := state["instance"].(*ec2.Instance) + i := state.Get("instance").(*ec2.Instance) if i.DNSName != "" { host = i.DNSName } else if i.VpcId != "" { @@ -35,7 +36,7 @@ func SSHAddress(e *ec2.EC2, port int) func(map[string]interface{}) (string, erro return "", fmt.Errorf("instance not found: %s", i.InstanceId) } - state["instance"] = &r.Reservations[0].Instances[0] + state.Put("instance", &r.Reservations[0].Instances[0]) time.Sleep(1 * time.Second) } @@ -46,9 +47,9 @@ func SSHAddress(e *ec2.EC2, port int) func(map[string]interface{}) (string, erro // SSHConfig returns a function that can be used for the SSH communicator // config for connecting to the instance created over SSH using the generated // private key. -func SSHConfig(username string) func(map[string]interface{}) (*gossh.ClientConfig, error) { - return func(state map[string]interface{}) (*gossh.ClientConfig, error) { - privateKey := state["privateKey"].(string) +func SSHConfig(username string) func(multistep.StateBag) (*gossh.ClientConfig, error) { + return func(state multistep.StateBag) (*gossh.ClientConfig, error) { + privateKey := state.Get("privateKey").(string) keyring := new(ssh.SimpleKeychain) if err := keyring.AddPEMKey(privateKey); err != nil { diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 837fcdc68..5c6cd16dd 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -73,11 +73,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ec2conn := ec2.New(auth, region) // Setup the state bag and initial state for the steps - state := make(map[string]interface{}) - state["config"] = b.config - state["ec2"] = ec2conn - state["hook"] = hook - state["ui"] = ui + state := new(multistep.BasicStateBag) + state.Put("config", b.config) + state.Put("ec2", ec2conn) + state.Put("hook", hook) + state.Put("ui", ui) // Build the steps steps := []multistep.Step{ @@ -136,18 +136,18 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe b.runner.Run(state) // If there was an error, return that - if rawErr, ok := state["error"]; ok { + if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } // If there are no AMIs, then just return - if _, ok := state["amis"]; !ok { + if _, ok := state.GetOk("amis"); !ok { return nil, nil } // Build the artifact and return it artifact := &awscommon.Artifact{ - Amis: state["amis"].(map[string]string), + Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, } diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index b6fc70ff1..ec89827a0 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -10,11 +10,11 @@ import ( type stepCreateAMI struct{} -func (s *stepCreateAMI) Run(state map[string]interface{}) multistep.StepAction { - config := state["config"].(config) - ec2conn := state["ec2"].(*ec2.EC2) - instance := state["instance"].(*ec2.Instance) - ui := state["ui"].(packer.Ui) +func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(config) + ec2conn := state.Get("ec2").(*ec2.EC2) + instance := state.Get("instance").(*ec2.Instance) + ui := state.Get("ui").(packer.Ui) // Create the image ui.Say(fmt.Sprintf("Creating the AMI: %s", config.AMIName)) @@ -27,7 +27,7 @@ func (s *stepCreateAMI) Run(state map[string]interface{}) multistep.StepAction { createResp, err := ec2conn.CreateImage(createOpts) if err != nil { err := fmt.Errorf("Error creating AMI: %s", err) - state["error"] = err + state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } @@ -36,13 +36,13 @@ func (s *stepCreateAMI) Run(state map[string]interface{}) multistep.StepAction { ui.Say(fmt.Sprintf("AMI: %s", createResp.ImageId)) amis := make(map[string]string) amis[ec2conn.Region.Name] = createResp.ImageId - state["amis"] = amis + state.Put("amis", amis) // Wait for the image to become ready ui.Say("Waiting for AMI to become ready...") if err := awscommon.WaitForAMI(ec2conn, createResp.ImageId); err != nil { err := fmt.Errorf("Error waiting for AMI: %s", err) - state["error"] = err + state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } @@ -50,6 +50,6 @@ func (s *stepCreateAMI) Run(state map[string]interface{}) multistep.StepAction { return multistep.ActionContinue } -func (s *stepCreateAMI) Cleanup(map[string]interface{}) { +func (s *stepCreateAMI) Cleanup(multistep.StateBag) { // No cleanup... } diff --git a/builder/amazon/ebs/step_stop_instance.go b/builder/amazon/ebs/step_stop_instance.go index 8aa4385e8..058c61983 100644 --- a/builder/amazon/ebs/step_stop_instance.go +++ b/builder/amazon/ebs/step_stop_instance.go @@ -10,17 +10,17 @@ import ( type stepStopInstance struct{} -func (s *stepStopInstance) Run(state map[string]interface{}) multistep.StepAction { - ec2conn := state["ec2"].(*ec2.EC2) - instance := state["instance"].(*ec2.Instance) - ui := state["ui"].(packer.Ui) +func (s *stepStopInstance) Run(state multistep.StateBag) multistep.StepAction { + ec2conn := state.Get("ec2").(*ec2.EC2) + instance := state.Get("instance").(*ec2.Instance) + ui := state.Get("ui").(packer.Ui) // Stop the instance so we can create an AMI from it ui.Say("Stopping the source instance...") _, err := ec2conn.StopInstances(instance.InstanceId) if err != nil { err := fmt.Errorf("Error stopping instance: %s", err) - state["error"] = err + state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } @@ -37,7 +37,7 @@ func (s *stepStopInstance) Run(state map[string]interface{}) multistep.StepActio _, err = awscommon.WaitForState(&stateChange) if err != nil { err := fmt.Errorf("Error waiting for instance to stop: %s", err) - state["error"] = err + state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } @@ -45,6 +45,6 @@ func (s *stepStopInstance) Run(state map[string]interface{}) multistep.StepActio return multistep.ActionContinue } -func (s *stepStopInstance) Cleanup(map[string]interface{}) { +func (s *stepStopInstance) Cleanup(multistep.StateBag) { // No cleanup... }