github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/post-processor/vagrant/util.go (about)

     1  package vagrant
     2  
     3  import (
     4  	"archive/tar"
     5  	"compress/gzip"
     6  	"encoding/json"
     7  	"io"
     8  	"log"
     9  	"os"
    10  	"path/filepath"
    11  )
    12  
    13  // OutputPathTemplate is the structure that is availalable within the
    14  // OutputPath variables.
    15  type OutputPathTemplate struct {
    16  	ArtifactId string
    17  	BuildName  string
    18  	Provider   string
    19  }
    20  
    21  // Copies a file by copying the contents of the file to another place.
    22  func CopyContents(dst, src string) error {
    23  	srcF, err := os.Open(src)
    24  	if err != nil {
    25  		return err
    26  	}
    27  	defer srcF.Close()
    28  
    29  	dstF, err := os.Create(dst)
    30  	if err != nil {
    31  		return err
    32  	}
    33  	defer dstF.Close()
    34  
    35  	if _, err := io.Copy(dstF, srcF); err != nil {
    36  		return err
    37  	}
    38  
    39  	return nil
    40  }
    41  
    42  // DirToBox takes the directory and compresses it into a Vagrant-compatible
    43  // box. This function does not perform checks to verify that dir is
    44  // actually a proper box. This is an expected precondition.
    45  func DirToBox(dst, dir string) error {
    46  	log.Printf("Turning dir into box: %s => %s", dir, dst)
    47  	dstF, err := os.Create(dst)
    48  	if err != nil {
    49  		return err
    50  	}
    51  	defer dstF.Close()
    52  
    53  	gzipWriter := gzip.NewWriter(dstF)
    54  	defer gzipWriter.Close()
    55  
    56  	tarWriter := tar.NewWriter(gzipWriter)
    57  	defer tarWriter.Close()
    58  
    59  	// This is the walk func that tars each of the files in the dir
    60  	tarWalk := func(path string, info os.FileInfo, prevErr error) error {
    61  		// If there was a prior error, return it
    62  		if prevErr != nil {
    63  			return prevErr
    64  		}
    65  
    66  		// Skip directories
    67  		if info.IsDir() {
    68  			log.Printf("Skipping directory '%s' for box '%s'", path, dst)
    69  			return nil
    70  		}
    71  
    72  		log.Printf("Box add: '%s' to '%s'", path, dst)
    73  		f, err := os.Open(path)
    74  		if err != nil {
    75  			return err
    76  		}
    77  		defer f.Close()
    78  
    79  		header, err := tar.FileInfoHeader(info, "")
    80  		if err != nil {
    81  			return err
    82  		}
    83  
    84  		// We have to set the Name explicitly because it is supposed to
    85  		// be a relative path to the root. Otherwise, the tar ends up
    86  		// being a bunch of files in the root, even if they're actually
    87  		// nested in a dir in the original "dir" param.
    88  		header.Name, err = filepath.Rel(dir, path)
    89  		if err != nil {
    90  			return err
    91  		}
    92  
    93  		if err := tarWriter.WriteHeader(header); err != nil {
    94  			return err
    95  		}
    96  
    97  		if _, err := io.Copy(tarWriter, f); err != nil {
    98  			return err
    99  		}
   100  
   101  		return nil
   102  	}
   103  
   104  	// Tar.gz everything up
   105  	return filepath.Walk(dir, tarWalk)
   106  }
   107  
   108  // WriteMetadata writes the "metadata.json" file for a Vagrant box.
   109  func WriteMetadata(dir string, contents interface{}) error {
   110  	f, err := os.Create(filepath.Join(dir, "metadata.json"))
   111  	if err != nil {
   112  		return err
   113  	}
   114  	defer f.Close()
   115  
   116  	enc := json.NewEncoder(f)
   117  	return enc.Encode(contents)
   118  }