From 095631107a93f67b59e93f2d7e00f2a2c29a374f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 25 Aug 2013 20:29:50 -0700 Subject: [PATCH] communicator/ssh: UploadDir works properly --- communicator/ssh/communicator.go | 56 +++++++++++----------------- provisioner/file/provisioner_test.go | 27 ++------------ 2 files changed, 25 insertions(+), 58 deletions(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 5336556b4..ec9a40724 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -313,9 +313,11 @@ func scpUploadFile(dst string, src io.Reader, w io.Writer, r *bufio.Reader) erro func scpUploadDir(root string, fs []os.FileInfo, w io.Writer, r *bufio.Reader) error { for _, fi := range fs { + realPath := filepath.Join(root, fi.Name()) + if !fi.IsDir() { // It is a regular file, just upload it - f, err := os.Open(filepath.Join(root, fi.Name())) + f, err := os.Open(realPath) if err != nil { return err } @@ -328,58 +330,44 @@ func scpUploadDir(root string, fs []os.FileInfo, w io.Writer, r *bufio.Reader) e if err != nil { return err } - } - } - return nil -} + continue + } -func scpWalkFn(cur string, dst string, src string, w io.Writer, r *bufio.Reader) filepath.WalkFunc { - return func(path string, info os.FileInfo, err error) error { + // It is a directory, recursively upload + log.Printf("SCP: starting directory upload: %s", fi.Name()) + fmt.Fprintln(w, "D0755 0", fi.Name()) + err := checkSCPStatus(r) if err != nil { return err } - if path == cur { - // Don't upload ourselves - return nil - } - - // Get the relative path so that we can check excludes and also - // so that we can build the full destination path - relPath, err := filepath.Rel(src, path) + f, err := os.Open(realPath) if err != nil { return err } - // TODO(mitchellh): Check excludes - targetPath := filepath.Base(relPath) - if info.IsDir() { - log.Printf("SCP: starting directory upload: %s", targetPath) - fmt.Fprintln(w, "D0755 0", targetPath) - err := checkSCPStatus(r) - if err != nil { - return err - } + // Execute this in a function just so that we have easy "defer" + // available because laziness. + err = func() error { + defer f.Close() - err = filepath.Walk(path, scpWalkFn(path, dst, src, w, r)) + entries, err := f.Readdir(-1) if err != nil { return err } - fmt.Fprintln(w, "E") - return checkSCPStatus(r) + return scpUploadDir(realPath, entries, w, r) + }() + if err != nil { + return err } - // Open the file for uploading - f, err := os.Open(path) + fmt.Fprintln(w, "E") if err != nil { return err } - defer f.Close() - - // Upload the file like any normal SCP operation - targetPath = filepath.Base(relPath) - return scpUploadFile(targetPath, f, w, r) } + + return nil } diff --git a/provisioner/file/provisioner_test.go b/provisioner/file/provisioner_test.go index c35f67cdb..6f7cd5ea3 100644 --- a/provisioner/file/provisioner_test.go +++ b/provisioner/file/provisioner_test.go @@ -2,7 +2,6 @@ package file import ( "github.com/mitchellh/packer/packer" - "io" "io/ioutil" "os" "strings" @@ -75,26 +74,6 @@ func TestProvisionerPrepare_EmptyDestination(t *testing.T) { } } -type stubUploadCommunicator struct { - dest string - data []byte -} - -func (suc *stubUploadCommunicator) Download(src string, data io.Writer) error { - return nil -} - -func (suc *stubUploadCommunicator) Upload(dest string, data io.Reader) error { - var err error - suc.dest = dest - suc.data, err = ioutil.ReadAll(data) - return err -} - -func (suc *stubUploadCommunicator) Start(cmd *packer.RemoteCmd) error { - return nil -} - type stubUi struct { sayMessages string } @@ -138,7 +117,7 @@ func TestProvisionerProvision_SendsFile(t *testing.T) { } ui := &stubUi{} - comm := &stubUploadCommunicator{} + comm := &packer.MockCommunicator{} err = p.Provision(ui, comm) if err != nil { t.Fatalf("should successfully provision: %s", err) @@ -152,11 +131,11 @@ func TestProvisionerProvision_SendsFile(t *testing.T) { t.Fatalf("should print destination filename") } - if comm.dest != "something" { + if comm.UploadPath != "something" { t.Fatalf("should upload to configured destination") } - if string(comm.data) != "hello" { + if comm.UploadData != "hello" { t.Fatalf("should upload with source file's data") } }