github.phpd.cn/hashicorp/packer@v1.3.2/builder/parallels/common/step_output_dir.go (about) 1 package common 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "os" 8 "path/filepath" 9 "time" 10 11 "github.com/hashicorp/packer/helper/multistep" 12 "github.com/hashicorp/packer/packer" 13 ) 14 15 // StepOutputDir sets up the output directory by creating it if it does 16 // not exist, deleting it if it does exist and we're forcing, and cleaning 17 // it up when we're done with it. 18 type StepOutputDir struct { 19 Force bool 20 Path string 21 success bool 22 } 23 24 // Run sets up the output directory. 25 func (s *StepOutputDir) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 26 ui := state.Get("ui").(packer.Ui) 27 28 if _, err := os.Stat(s.Path); err == nil && s.Force { 29 ui.Say("Deleting previous output directory...") 30 os.RemoveAll(s.Path) 31 } 32 33 // Create the directory 34 if err := os.MkdirAll(s.Path, 0755); err != nil { 35 state.Put("error", err) 36 return multistep.ActionHalt 37 } 38 39 // Make sure we can write in the directory 40 f, err := os.Create(filepath.Join(s.Path, "_packer_perm_check")) 41 if err != nil { 42 err = fmt.Errorf("Couldn't write to output directory: %s", err) 43 state.Put("error", err) 44 return multistep.ActionHalt 45 } 46 f.Close() 47 os.Remove(f.Name()) 48 49 s.success = true 50 return multistep.ActionContinue 51 } 52 53 // Cleanup deletes the output directory. 54 func (s *StepOutputDir) Cleanup(state multistep.StateBag) { 55 _, cancelled := state.GetOk(multistep.StateCancelled) 56 _, halted := state.GetOk(multistep.StateHalted) 57 58 if !s.success { 59 return 60 } 61 62 if cancelled || halted { 63 ui := state.Get("ui").(packer.Ui) 64 65 ui.Say("Deleting output directory...") 66 for i := 0; i < 5; i++ { 67 err := os.RemoveAll(s.Path) 68 if err == nil { 69 break 70 } 71 72 log.Printf("Error removing output dir: %s", err) 73 time.Sleep(2 * time.Second) 74 } 75 } 76 }