github.com/mitchellh/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  }