diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index b01a50919..3eeaa2051 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -127,6 +127,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepPrepareDevice{}, &StepCreateVolume{}, &StepAttachVolume{}, + &StepEarlyUnflock{}, &StepMountDevice{}, &StepMountExtra{}, &StepCopyFiles{}, diff --git a/builder/amazon/chroot/step_early_unflock.go b/builder/amazon/chroot/step_early_unflock.go new file mode 100644 index 000000000..d1c09008e --- /dev/null +++ b/builder/amazon/chroot/step_early_unflock.go @@ -0,0 +1,28 @@ +package chroot + +import ( + "fmt" + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" + "log" +) + +// StepEarlyUnflock unlocks the flock. +type StepEarlyUnflock struct{} + +func (s *StepEarlyUnflock) Run(state map[string]interface{}) multistep.StepAction { + cleanup := state["flock_cleanup"].(Cleanup) + ui := state["ui"].(packer.Ui) + + log.Println("Unlocking file lock...") + if err := cleanup.CleanupFunc(state); err != nil { + err := fmt.Errorf("Error unlocking file lock: %s", err) + state["error"] = err + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepEarlyUnflock) Cleanup(state map[string]interface{}) {} diff --git a/builder/amazon/chroot/step_flock.go b/builder/amazon/chroot/step_flock.go index 57c07ebba..47d168d4c 100644 --- a/builder/amazon/chroot/step_flock.go +++ b/builder/amazon/chroot/step_flock.go @@ -10,6 +10,9 @@ import ( ) // StepFlock provisions the instance within a chroot. +// +// Produces: +// flock_cleanup Cleanup - To perform early cleanup type StepFlock struct { fh *os.File } @@ -46,14 +49,24 @@ func (s *StepFlock) Run(state map[string]interface{}) multistep.StepAction { // the lock. s.fh = f + state["flock_cleanup"] = s return multistep.ActionContinue } func (s *StepFlock) Cleanup(state map[string]interface{}) { + s.CleanupFunc(state) +} + +func (s *StepFlock) CleanupFunc(state map[string]interface{}) error { if s.fh == nil { - return + return nil } log.Printf("Unlocking: %s", s.fh.Name()) - unlockFile(s.fh) + if err := unlockFile(s.fh); err != nil { + return err + } + + s.fh = nil + return nil } diff --git a/builder/amazon/chroot/step_flock_test.go b/builder/amazon/chroot/step_flock_test.go new file mode 100644 index 000000000..a50cbd93d --- /dev/null +++ b/builder/amazon/chroot/step_flock_test.go @@ -0,0 +1,11 @@ +package chroot + +import "testing" + +func TestFlockCleanupFunc_ImplementsCleanupFunc(t *testing.T) { + var raw interface{} + raw = new(StepFlock) + if _, ok := raw.(Cleanup); !ok { + t.Fatalf("cleanup func should be a CleanupFunc") + } +}