76 lines
1.7 KiB
Go
76 lines
1.7 KiB
Go
|
package vagrant
|
||
|
|
||
|
import (
|
||
|
"archive/tar"
|
||
|
"compress/gzip"
|
||
|
"encoding/json"
|
||
|
"io"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
)
|
||
|
|
||
|
// DirToBox takes the directory and compresses it into a Vagrant-compatible
|
||
|
// box. This function does not perform checks to verify that dir is
|
||
|
// actually a proper box. This is an expected precondition.
|
||
|
func DirToBox(dst, dir string) error {
|
||
|
dstF, err := os.Create(dst)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer dstF.Close()
|
||
|
|
||
|
gzipWriter := gzip.NewWriter(dstF)
|
||
|
defer gzipWriter.Close()
|
||
|
|
||
|
tarWriter := tar.NewWriter(gzipWriter)
|
||
|
defer tarWriter.Close()
|
||
|
|
||
|
// This is the walk func that tars each of the files in the dir
|
||
|
tarWalk := func(path string, info os.FileInfo, prevErr error) error {
|
||
|
f, err := os.Open(path)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
|
||
|
header, err := tar.FileInfoHeader(info, "")
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// We have to set the Name explicitly because it is supposed to
|
||
|
// be a relative path to the root. Otherwise, the tar ends up
|
||
|
// being a bunch of files in the root, even if they're actually
|
||
|
// nested in a dir in the original "dir" param.
|
||
|
header.Name, err = filepath.Rel(dir, path)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if err := tarWriter.WriteHeader(header); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if _, err := io.Copy(tarWriter, f); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Tar.gz everything up
|
||
|
return filepath.Walk(dir, tarWalk)
|
||
|
}
|
||
|
|
||
|
// WriteMetadata writes the "metadata.json" file for a Vagrant box.
|
||
|
func WriteMetadata(dir string, contents interface{}) error {
|
||
|
f, err := os.Create(filepath.Join(dir, "metadata.json"))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
|
||
|
enc := json.NewEncoder(f)
|
||
|
return enc.Encode(contents)
|
||
|
}
|