github.phpd.cn/hashicorp/packer@v1.3.2/builder/virtualbox/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 22 cleanup bool 23 } 24 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 { 29 if !s.Force { 30 err := fmt.Errorf( 31 "Output directory exists: %s\n\n"+ 32 "Use the force flag to delete it prior to building.", 33 s.Path) 34 state.Put("error", err) 35 return multistep.ActionHalt 36 } 37 38 ui.Say("Deleting previous output directory...") 39 os.RemoveAll(s.Path) 40 } 41 42 // Enable cleanup 43 s.cleanup = true 44 45 // Create the directory 46 if err := os.MkdirAll(s.Path, 0755); err != nil { 47 state.Put("error", err) 48 return multistep.ActionHalt 49 } 50 51 // Make sure we can write in the directory 52 f, err := os.Create(filepath.Join(s.Path, "_packer_perm_check")) 53 if err != nil { 54 err = fmt.Errorf("Couldn't write to output directory: %s", err) 55 state.Put("error", err) 56 return multistep.ActionHalt 57 } 58 f.Close() 59 os.Remove(f.Name()) 60 61 return multistep.ActionContinue 62 } 63 64 func (s *StepOutputDir) Cleanup(state multistep.StateBag) { 65 if !s.cleanup { 66 return 67 } 68 69 _, cancelled := state.GetOk(multistep.StateCancelled) 70 _, halted := state.GetOk(multistep.StateHalted) 71 72 if cancelled || halted { 73 ui := state.Get("ui").(packer.Ui) 74 75 ui.Say("Deleting output directory...") 76 for i := 0; i < 5; i++ { 77 err := os.RemoveAll(s.Path) 78 if err == nil { 79 break 80 } 81 82 log.Printf("Error removing output dir: %s", err) 83 time.Sleep(2 * time.Second) 84 } 85 } 86 }