github.phpd.cn/hashicorp/packer@v1.3.2/builder/amazon/chroot/step_flock.go (about) 1 package chroot 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "os" 8 "path/filepath" 9 10 "github.com/hashicorp/packer/helper/multistep" 11 "github.com/hashicorp/packer/packer" 12 ) 13 14 // StepFlock provisions the instance within a chroot. 15 // 16 // Produces: 17 // flock_cleanup Cleanup - To perform early cleanup 18 type StepFlock struct { 19 fh *os.File 20 } 21 22 func (s *StepFlock) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 23 ui := state.Get("ui").(packer.Ui) 24 25 lockfile := "/var/lock/packer-chroot/lock" 26 if err := os.MkdirAll(filepath.Dir(lockfile), 0755); err != nil { 27 err := fmt.Errorf("Error creating lock: %s", err) 28 state.Put("error", err) 29 ui.Error(err.Error()) 30 return multistep.ActionHalt 31 } 32 33 log.Printf("Obtaining lock: %s", lockfile) 34 f, err := os.Create(lockfile) 35 if err != nil { 36 err := fmt.Errorf("Error creating lock: %s", err) 37 state.Put("error", err) 38 ui.Error(err.Error()) 39 return multistep.ActionHalt 40 } 41 42 // LOCK! 43 if err := lockFile(f); err != nil { 44 err := fmt.Errorf("Error obtaining lock: %s", err) 45 state.Put("error", err) 46 ui.Error(err.Error()) 47 return multistep.ActionHalt 48 } 49 50 // Set the file handle, we can't close it because we need to hold 51 // the lock. 52 s.fh = f 53 54 state.Put("flock_cleanup", s) 55 return multistep.ActionContinue 56 } 57 58 func (s *StepFlock) Cleanup(state multistep.StateBag) { 59 s.CleanupFunc(state) 60 } 61 62 func (s *StepFlock) CleanupFunc(state multistep.StateBag) error { 63 if s.fh == nil { 64 return nil 65 } 66 67 log.Printf("Unlocking: %s", s.fh.Name()) 68 if err := unlockFile(s.fh); err != nil { 69 return err 70 } 71 72 s.fh = nil 73 return nil 74 }