From 5ad4b0e97e186f5414045c1aa42b313fb3e6df65 Mon Sep 17 00:00:00 2001 From: Chris Bednarski Date: Wed, 12 Aug 2015 12:16:26 -0700 Subject: [PATCH] Added tests and handle the tar format from docker cp - --- builder/docker/communicator.go | 12 +++++++++++- builder/docker/communicator_test.go | 22 +++++++++++++--------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/builder/docker/communicator.go b/builder/docker/communicator.go index 8af54bdfe..fb88a4491 100644 --- a/builder/docker/communicator.go +++ b/builder/docker/communicator.go @@ -1,6 +1,7 @@ package docker import ( + "archive/tar" "bytes" "fmt" "io" @@ -210,7 +211,16 @@ func (c *Communicator) Download(src string, dst io.Writer) error { return fmt.Errorf("Failed to start download: %s", err) } - numBytes, err := io.Copy(dst, pipe) + // When you use - to send docker cp to stdout it is streamed as a tar; this + // enables it to work with directories. We don't actually support + // directories in Download() but we still need to handle the tar format. + archive := tar.NewReader(pipe) + _, err = archive.Next() + if err != nil { + return fmt.Errorf("Failed to read header from tar stream: %s", err) + } + + numBytes, err := io.Copy(dst, archive) if err != nil { return fmt.Errorf("Failed to pipe download: %s", err) } diff --git a/builder/docker/communicator_test.go b/builder/docker/communicator_test.go index 221356723..db0bfcfe8 100644 --- a/builder/docker/communicator_test.go +++ b/builder/docker/communicator_test.go @@ -61,8 +61,10 @@ func TestUploadDownload(t *testing.T) { if err != nil { t.Fatalf("Error preparing download: %s", err) } - // Preemptive cleanup - defer os.Remove("delicious-cake") + // Preemptive cleanup. Honestly I don't know why you would want to get rid + // of my strawberry cake. It's so tasty! Do you not like cake? Are you a + // cake-hater? Or are you keeping all the cake all for yourself? So selfish! + defer os.Remove("my-strawberry-cake") // Add hooks so the provisioners run during the build hooks := map[string][]packer.Hook{} @@ -85,16 +87,18 @@ func TestUploadDownload(t *testing.T) { defer artifact.Destroy() // Verify that the thing we downloaded is the same thing we sent up. - inputFile, err := ioutil.ReadFile("test-fixtures/cake") + // Complain loudly if it isn't. + inputFile, err := ioutil.ReadFile("test-fixtures/onecakes/strawberry") if err != nil { t.Fatalf("Unable to read input file: %s", err) } - outputFile, err := ioutil.ReadFile("delicious-cake") + outputFile, err := ioutil.ReadFile("my-strawberry-cake") if err != nil { t.Fatalf("Unable to read output file: %s", err) } if sha256.Sum256(inputFile) != sha256.Sum256(outputFile) { - t.Fatalf("Input and output files do not match\nInput:\n%s\nOutput:\n%s\n", inputFile, outputFile) + t.Fatalf("Input and output files do not match\n"+ + "Input:\n%s\nOutput:\n%s\n", inputFile, outputFile) } } @@ -111,13 +115,13 @@ const dockerBuilderConfig = ` "provisioners": [ { "type": "file", - "source": "test-fixtures/cake", - "destination": "/chocolate-cake" + "source": "test-fixtures/onecakes/strawberry", + "destination": "/strawberry-cake" }, { "type": "file", - "source": "/chocolate-cake", - "destination": "delicious-cake", + "source": "/strawberry-cake", + "destination": "my-strawberry-cake", "direction": "download" } ]