From 0df18df40f4da1f9f7eded548c73329660489921 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 4 Jun 2013 10:00:06 -0700 Subject: [PATCH] builder/amazonebs: extract multistep, use that --- builder/amazonebs/builder.go | 6 ++- builder/amazonebs/step.go | 39 ------------------- builder/amazonebs/step_connect_ssh.go | 9 +++-- builder/amazonebs/step_create_ami.go | 9 +++-- builder/amazonebs/step_keypair.go | 7 ++-- builder/amazonebs/step_provision.go | 5 ++- builder/amazonebs/step_run_source_instance.go | 9 +++-- builder/amazonebs/step_stop_instance.go | 9 +++-- 8 files changed, 31 insertions(+), 62 deletions(-) delete mode 100644 builder/amazonebs/step.go diff --git a/builder/amazonebs/builder.go b/builder/amazonebs/builder.go index 69c337d16..b5ddb8ced 100644 --- a/builder/amazonebs/builder.go +++ b/builder/amazonebs/builder.go @@ -9,6 +9,7 @@ import ( "github.com/mitchellh/goamz/aws" "github.com/mitchellh/goamz/ec2" "github.com/mitchellh/mapstructure" + "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "log" ) @@ -87,7 +88,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) packer.Artifact { state["ui"] = ui // Build the steps - steps := []Step{ + steps := []multistep.Step{ &stepKeyPair{}, &stepRunSourceInstance{}, &stepConnectSSH{}, @@ -97,7 +98,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) packer.Artifact { } // Run! - RunSteps(state, steps) + runner := &multistep.BasicRunner{Steps: steps} + runner.Run(state) // Build the artifact and return it return &artifact{state["amis"].(map[string]string)} diff --git a/builder/amazonebs/step.go b/builder/amazonebs/step.go deleted file mode 100644 index 23970cca8..000000000 --- a/builder/amazonebs/step.go +++ /dev/null @@ -1,39 +0,0 @@ -package amazonebs - -// A StepAction determines the next step to take regarding multi-step actions. -type StepAction uint - -const ( - StepContinue StepAction = iota - StepHalt -) - -// Step is a single step that is part of a potentially large sequence -// of other steps, responsible for performing some specific action. -type Step interface { - // Run is called to perform the action. The parameter is a "state bag" - // of untyped things. Please be very careful about type-checking the - // items in this bag. - // - // The return value determines whether multi-step sequences continue - // or should halt. - Run(map[string]interface{}) StepAction - - // Cleanup is called in reverse order of the steps that have run - // and allow steps to clean up after themselves. - // - // The parameter is the same "state bag" as Run. - Cleanup(map[string]interface{}) -} - -// RunSteps runs a sequence of steps. -func RunSteps(state map[string]interface{}, steps []Step) { - for _, step := range steps { - action := step.Run(state) - defer step.Cleanup(state) - - if action == StepHalt { - break - } - } -} diff --git a/builder/amazonebs/step_connect_ssh.go b/builder/amazonebs/step_connect_ssh.go index 92eae374c..36b30ddc8 100644 --- a/builder/amazonebs/step_connect_ssh.go +++ b/builder/amazonebs/step_connect_ssh.go @@ -4,6 +4,7 @@ import ( gossh "code.google.com/p/go.crypto/ssh" "fmt" "github.com/mitchellh/goamz/ec2" + "github.com/mitchellh/multistep" "github.com/mitchellh/packer/communicator/ssh" "github.com/mitchellh/packer/packer" "log" @@ -15,7 +16,7 @@ type stepConnectSSH struct { conn net.Conn } -func (s *stepConnectSSH) Run(state map[string]interface{}) StepAction { +func (s *stepConnectSSH) Run(state map[string]interface{}) multistep.StepAction { config := state["config"].(config) instance := state["instance"].(*ec2.Instance) privateKey := state["privateKey"].(string) @@ -27,7 +28,7 @@ func (s *stepConnectSSH) Run(state map[string]interface{}) StepAction { err := keyring.AddPEMKey(privateKey) if err != nil { ui.Say(fmt.Sprintf("Error setting up SSH config: %s", err)) - return StepHalt + return multistep.ActionHalt } // Build the actual SSH client configuration @@ -59,13 +60,13 @@ func (s *stepConnectSSH) Run(state map[string]interface{}) StepAction { if err != nil { ui.Error(fmt.Sprintf("Error connecting to SSH: %s", err)) - return StepHalt + return multistep.ActionHalt } // Set the communicator on the state bag so it can be used later state["communicator"] = comm - return StepContinue + return multistep.ActionContinue } func (s *stepConnectSSH) Cleanup(map[string]interface{}) { diff --git a/builder/amazonebs/step_create_ami.go b/builder/amazonebs/step_create_ami.go index 60e83b60d..27d41c304 100644 --- a/builder/amazonebs/step_create_ami.go +++ b/builder/amazonebs/step_create_ami.go @@ -3,12 +3,13 @@ package amazonebs import ( "fmt" "github.com/mitchellh/goamz/ec2" + "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" ) type stepCreateAMI struct{} -func (s *stepCreateAMI) Run(state map[string]interface{}) StepAction { +func (s *stepCreateAMI) Run(state map[string]interface{}) multistep.StepAction { config := state["config"].(config) ec2conn := state["ec2"].(*ec2.EC2) instance := state["instance"].(*ec2.Instance) @@ -24,7 +25,7 @@ func (s *stepCreateAMI) Run(state map[string]interface{}) StepAction { createResp, err := ec2conn.CreateImage(createOpts) if err != nil { ui.Error(err.Error()) - return StepHalt + return multistep.ActionHalt } // Set the AMI ID in the state @@ -39,7 +40,7 @@ func (s *stepCreateAMI) Run(state map[string]interface{}) StepAction { imageResp, err := ec2conn.Images([]string{createResp.ImageId}, ec2.NewFilter()) if err != nil { ui.Error(err.Error()) - return StepHalt + return multistep.ActionHalt } if imageResp.Images[0].State == "available" { @@ -47,7 +48,7 @@ func (s *stepCreateAMI) Run(state map[string]interface{}) StepAction { } } - return StepContinue + return multistep.ActionContinue } func (s *stepCreateAMI) Cleanup(map[string]interface{}) { diff --git a/builder/amazonebs/step_keypair.go b/builder/amazonebs/step_keypair.go index 10ae3a45c..62a32f7fb 100644 --- a/builder/amazonebs/step_keypair.go +++ b/builder/amazonebs/step_keypair.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "fmt" "github.com/mitchellh/goamz/ec2" + "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "log" ) @@ -13,7 +14,7 @@ type stepKeyPair struct { keyName string } -func (s *stepKeyPair) Run(state map[string]interface{}) StepAction { +func (s *stepKeyPair) Run(state map[string]interface{}) multistep.StepAction { ec2conn := state["ec2"].(*ec2.EC2) ui := state["ui"].(packer.Ui) @@ -23,7 +24,7 @@ func (s *stepKeyPair) Run(state map[string]interface{}) StepAction { keyResp, err := ec2conn.CreateKeyPair(keyName) if err != nil { ui.Error(err.Error()) - return StepHalt + return multistep.ActionHalt } // Set the keyname so we know to delete it later @@ -33,7 +34,7 @@ func (s *stepKeyPair) Run(state map[string]interface{}) StepAction { state["keyPair"] = keyName state["privateKey"] = keyResp.KeyMaterial - return StepContinue + return multistep.ActionContinue } func (s *stepKeyPair) Cleanup(state map[string]interface{}) { diff --git a/builder/amazonebs/step_provision.go b/builder/amazonebs/step_provision.go index 87145c98f..6f46983d4 100644 --- a/builder/amazonebs/step_provision.go +++ b/builder/amazonebs/step_provision.go @@ -1,13 +1,14 @@ package amazonebs import ( + "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "log" ) type stepProvision struct{} -func (*stepProvision) Run(state map[string]interface{}) StepAction { +func (*stepProvision) Run(state map[string]interface{}) multistep.StepAction { comm := state["communicator"].(packer.Communicator) hook := state["hook"].(packer.Hook) ui := state["ui"].(packer.Ui) @@ -15,7 +16,7 @@ func (*stepProvision) Run(state map[string]interface{}) StepAction { log.Println("Running the provision hook") hook.Run(packer.HookProvision, ui, comm, nil) - return StepContinue + return multistep.ActionContinue } func (*stepProvision) Cleanup(map[string]interface{}) {} diff --git a/builder/amazonebs/step_run_source_instance.go b/builder/amazonebs/step_run_source_instance.go index 5f557232b..104ae7ce4 100644 --- a/builder/amazonebs/step_run_source_instance.go +++ b/builder/amazonebs/step_run_source_instance.go @@ -2,6 +2,7 @@ package amazonebs import ( "github.com/mitchellh/goamz/ec2" + "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "log" ) @@ -10,7 +11,7 @@ type stepRunSourceInstance struct { instance *ec2.Instance } -func (s *stepRunSourceInstance) Run(state map[string]interface{}) StepAction { +func (s *stepRunSourceInstance) Run(state map[string]interface{}) multistep.StepAction { config := state["config"].(config) ec2conn := state["ec2"].(*ec2.EC2) keyName := state["keyPair"].(string) @@ -28,7 +29,7 @@ func (s *stepRunSourceInstance) Run(state map[string]interface{}) StepAction { runResp, err := ec2conn.RunInstances(runOpts) if err != nil { ui.Error(err.Error()) - return StepHalt + return multistep.ActionHalt } s.instance = &runResp.Instances[0] @@ -38,12 +39,12 @@ func (s *stepRunSourceInstance) Run(state map[string]interface{}) StepAction { s.instance, err = waitForState(ec2conn, s.instance, "running") if err != nil { ui.Error(err.Error()) - return StepHalt + return multistep.ActionHalt } state["instance"] = s.instance - return StepContinue + return multistep.ActionContinue } func (s *stepRunSourceInstance) Cleanup(state map[string]interface{}) { diff --git a/builder/amazonebs/step_stop_instance.go b/builder/amazonebs/step_stop_instance.go index d9b876826..46d9f0daf 100644 --- a/builder/amazonebs/step_stop_instance.go +++ b/builder/amazonebs/step_stop_instance.go @@ -2,12 +2,13 @@ package amazonebs import ( "github.com/mitchellh/goamz/ec2" + "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" ) type stepStopInstance struct{} -func (s *stepStopInstance) Run(state map[string]interface{}) StepAction { +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) @@ -17,7 +18,7 @@ func (s *stepStopInstance) Run(state map[string]interface{}) StepAction { _, err := ec2conn.StopInstances(instance.InstanceId) if err != nil { ui.Error(err.Error()) - return StepHalt + return multistep.ActionHalt } // Wait for the instance to actual stop @@ -27,10 +28,10 @@ func (s *stepStopInstance) Run(state map[string]interface{}) StepAction { instance, err = waitForState(ec2conn, instance, "stopped") if err != nil { ui.Error(err.Error()) - return StepHalt + return multistep.ActionHalt } - return StepContinue + return multistep.ActionContinue } func (s *stepStopInstance) Cleanup(map[string]interface{}) {