Merge pull request #5207 from sandersaares/hyperv-vagrant-hardlink

Link VHD instead of copy where allowed by OS
This commit is contained in:
Matthew Hooker 2017-10-09 15:08:16 -07:00 committed by GitHub
commit 4d3a762e85
2 changed files with 31 additions and 5 deletions

View File

@ -2,10 +2,11 @@ package vagrant
import ( import (
"fmt" "fmt"
"github.com/hashicorp/packer/packer"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/hashicorp/packer/packer"
) )
type HypervProvider struct{} type HypervProvider struct{}
@ -55,10 +56,18 @@ func (p *HypervProvider) Process(ui packer.Ui, artifact packer.Artifact, dir str
dstPath := filepath.Join(dstDir, filepath.Base(path)) dstPath := filepath.Join(dstDir, filepath.Base(path))
if err = CopyContents(dstPath, path); err != nil { // We prefer to link the files where possible because they are often very huge.
ui.Message(fmt.Sprintf("err in copying: %s to %s", path, dstPath)) // Some filesystem configurations do not allow hardlinks. As the possibilities
return // of mounting different devices in different paths are flexible, we just try to
// link the file and copy if the link fails, thereby automatically optimizing with a safe fallback.
if err = LinkFile(dstPath, path); err != nil {
// ui.Message(fmt.Sprintf("err in linking: %s to %s", path, dstPath))
if err = CopyContents(dstPath, path); err != nil {
ui.Message(fmt.Sprintf("err in copying: %s to %s", path, dstPath))
return
}
} }
ui.Message(fmt.Sprintf("Copyed %s to %s", path, dstPath)) ui.Message(fmt.Sprintf("Copyed %s to %s", path, dstPath))
} }

View File

@ -32,7 +32,7 @@ func CopyContents(dst, src string) error {
dstDir, _ := filepath.Split(dst) dstDir, _ := filepath.Split(dst)
if dstDir != "" { if dstDir != "" {
err := os.MkdirAll(dstDir, os.ModePerm) err := os.MkdirAll(dstDir, 0755)
if err != nil { if err != nil {
return err return err
} }
@ -51,6 +51,23 @@ func CopyContents(dst, src string) error {
return nil return nil
} }
// Creates a (hard) link to a file, ensuring that all parent directories also exist.
func LinkFile(dst, src string) error {
dstDir, _ := filepath.Split(dst)
if dstDir != "" {
err := os.MkdirAll(dstDir, 0755)
if err != nil {
return err
}
}
if err := os.Link(src, dst); err != nil {
return err
}
return nil
}
// DirToBox takes the directory and compresses it into a Vagrant-compatible // DirToBox takes the directory and compresses it into a Vagrant-compatible
// box. This function does not perform checks to verify that dir is // box. This function does not perform checks to verify that dir is
// actually a proper box. This is an expected precondition. // actually a proper box. This is an expected precondition.