github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/builder/amazon/chroot/step_copy_files.go (about)

     1  package chroot
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/mitchellh/multistep"
     6  	"github.com/mitchellh/packer/packer"
     7  	"io"
     8  	"log"
     9  	"os"
    10  	"path/filepath"
    11  )
    12  
    13  // StepCopyFiles copies some files from the host into the chroot environment.
    14  //
    15  // Produces:
    16  //   copy_files_cleanup CleanupFunc - A function to clean up the copied files
    17  //   early.
    18  type StepCopyFiles struct {
    19  	files []string
    20  }
    21  
    22  func (s *StepCopyFiles) Run(state map[string]interface{}) multistep.StepAction {
    23  	config := state["config"].(*Config)
    24  	mountPath := state["mount_path"].(string)
    25  	ui := state["ui"].(packer.Ui)
    26  
    27  	s.files = make([]string, 0, len(config.CopyFiles))
    28  	if len(config.CopyFiles) > 0 {
    29  		ui.Say("Copying files from host to chroot...")
    30  		for _, path := range config.CopyFiles {
    31  			ui.Message(path)
    32  			chrootPath := filepath.Join(mountPath, path)
    33  			log.Printf("Copying '%s' to '%s'", path, chrootPath)
    34  
    35  			if err := s.copySingle(chrootPath, path); err != nil {
    36  				err := fmt.Errorf("Error copying file: %s", err)
    37  				state["error"] = err
    38  				ui.Error(err.Error())
    39  				return multistep.ActionHalt
    40  			}
    41  
    42  			s.files = append(s.files, chrootPath)
    43  		}
    44  	}
    45  
    46  	state["copy_files_cleanup"] = s
    47  	return multistep.ActionContinue
    48  }
    49  
    50  func (s *StepCopyFiles) Cleanup(state map[string]interface{}) {
    51  	ui := state["ui"].(packer.Ui)
    52  	if err := s.CleanupFunc(state); err != nil {
    53  		ui.Error(err.Error())
    54  	}
    55  }
    56  
    57  func (s *StepCopyFiles) CleanupFunc(map[string]interface{}) error {
    58  	if s.files != nil {
    59  		for _, file := range s.files {
    60  			log.Printf("Removing: %s", file)
    61  			if err := os.Remove(file); err != nil {
    62  				return err
    63  			}
    64  		}
    65  	}
    66  
    67  	s.files = nil
    68  	return nil
    69  }
    70  
    71  func (s *StepCopyFiles) copySingle(dst, src string) error {
    72  	// Stat the src file so we can copy the mode later
    73  	srcInfo, err := os.Stat(src)
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	// Remove any existing destination file
    79  	if err := os.Remove(dst); err != nil {
    80  		return err
    81  	}
    82  
    83  	// Copy the files
    84  	srcF, err := os.Open(src)
    85  	if err != nil {
    86  		return err
    87  	}
    88  	defer srcF.Close()
    89  
    90  	dstF, err := os.Create(dst)
    91  	if err != nil {
    92  		return err
    93  	}
    94  	defer dstF.Close()
    95  
    96  	if _, err := io.Copy(dstF, srcF); err != nil {
    97  		return err
    98  	}
    99  	dstF.Close()
   100  
   101  	// Match the mode
   102  	if err := os.Chmod(dst, srcInfo.Mode()); err != nil {
   103  		return err
   104  	}
   105  
   106  	return nil
   107  }