diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 4427d45aa..faeb412cb 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -160,6 +160,7 @@ func (c *comm) UploadDir(dst string, src string, excl []string) error { func (c *comm) DownloadDir(src string, dst string, excl []string) error { log.Printf("Download dir '%s' to '%s'", src, dst) scpFunc := func(w io.Writer, stdoutR *bufio.Reader) error { + dirStack := []string{dst} for { fmt.Fprint(w, "\x00") @@ -178,6 +179,13 @@ func (c *comm) DownloadDir(src string, dst string, excl []string) error { return fmt.Errorf("%s", fi[1:len(fi)]) case 'C', 'D': break + case 'E': + dirStack = dirStack[:len(dirStack)-1] + if len(dirStack) == 1 { + fmt.Fprint(w, "\x00") + return nil + } + continue default: return fmt.Errorf("unexpected server response (%x)", fi[0]) } @@ -195,14 +203,16 @@ func (c *comm) DownloadDir(src string, dst string, excl []string) error { } log.Printf("Download dir mode:%s size:%d name:%s", mode, size, name) + + dst = filepath.Join(dirStack...) switch fi[0] { case 'D': err = os.MkdirAll(filepath.Join(dst, name), os.FileMode(0755)) if err != nil { return err } - fmt.Fprint(w, "\x00") - return nil + dirStack = append(dirStack, name) + continue case 'C': fmt.Fprint(w, "\x00") err = scpDownloadFile(filepath.Join(dst, name), stdoutR, size, os.FileMode(0644)) diff --git a/provisioner/file/provisioner.go b/provisioner/file/provisioner.go index 2b9a6b5fe..49498d08d 100644 --- a/provisioner/file/provisioner.go +++ b/provisioner/file/provisioner.go @@ -109,7 +109,7 @@ func (p *Provisioner) ProvisionDownload(ui packer.Ui, comm packer.Communicator) } } // if the config.Destination was a dir, download the dir - if !strings.HasSuffix(p.config.Destination, "/") { + if strings.HasSuffix(p.config.Destination, "/") { return comm.DownloadDir(src, p.config.Destination, nil) } diff --git a/provisioner/file/provisioner_test.go b/provisioner/file/provisioner_test.go index 53dc315d4..2169c96a3 100644 --- a/provisioner/file/provisioner_test.go +++ b/provisioner/file/provisioner_test.go @@ -192,5 +192,9 @@ func TestProvisionDownloadMkdirAll(t *testing.T) { if _, err := os.Stat(path); err != nil { t.Fatalf("stat of download dir should not error: %s", err) } + + if _, err := os.Stat(config["destination"].(string)); err != nil { + t.Fatalf("stat of destination file should not error: %s", err) + } } }