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 }