From aa2cc18745cbe0231c33782f0fa764f657e3fb88 Mon Sep 17 00:00:00 2001
From: Stephen J Day <stephen.day@docker.com>
Date: Thu, 20 Oct 2016 16:40:59 -0700
Subject: [PATCH] pkg/archive: remove unnecessary Archive and Reader type

The `archive` package defines aliases for `io.ReadCloser` and
`io.Reader`. These don't seem to provide an benefit other than type
decoration. Per this change, several unnecessary type cases were
removed.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
---
 builder/remote.go                                      |  7 ++++++-
 builder/remote_test.go                                 |  7 ++++++-
 daemon/commit.go                                       |  4 ++--
 daemon/export.go                                       |  2 +-
 daemon/graphdriver/aufs/aufs.go                        |  7 ++++---
 daemon/graphdriver/driver.go                           |  5 +++--
 daemon/graphdriver/fsdiff.go                           |  6 +++---
 daemon/graphdriver/overlay/overlay.go                  |  9 ++++-----
 daemon/graphdriver/overlay2/overlay.go                 |  5 +++--
 daemon/graphdriver/proxy.go                            |  7 ++++---
 daemon/graphdriver/windows/windows.go                  | 10 +++++-----
 .../docker_cli_external_graphdriver_unix_test.go       |  2 +-
 layer/layer_store.go                                   |  3 +--
 layer/migration_test.go                                | 10 +++++-----
 pkg/archive/archive.go                                 |  7 ++-----
 pkg/archive/changes.go                                 |  2 +-
 pkg/archive/copy.go                                    | 10 +++++-----
 pkg/archive/diff.go                                    |  8 ++++----
 pkg/archive/utils_test.go                              |  2 +-
 pkg/archive/wrap.go                                    |  6 +++---
 pkg/chrootarchive/diff.go                              | 10 +++++++---
 pkg/chrootarchive/diff_unix.go                         |  3 ++-
 pkg/chrootarchive/diff_windows.go                      |  3 ++-
 23 files changed, 75 insertions(+), 60 deletions(-)

diff --git a/builder/remote.go b/builder/remote.go
index ef91dfcff5..f3a4329d16 100644
--- a/builder/remote.go
+++ b/builder/remote.go
@@ -89,7 +89,12 @@ func DetectContextFromRemoteURL(r io.ReadCloser, remoteURL string, createProgres
 				dockerfileName = DefaultDockerfileName
 
 				// TODO: return a context without tarsum
-				return archive.Generate(dockerfileName, string(dockerfile))
+				r, err := archive.Generate(dockerfileName, string(dockerfile))
+				if err != nil {
+					return nil, err
+				}
+
+				return ioutil.NopCloser(r), nil
 			},
 			// fallback handler (tar context)
 			"": func(rc io.ReadCloser) (io.ReadCloser, error) {
diff --git a/builder/remote_test.go b/builder/remote_test.go
index 20ee02a57b..691a084761 100644
--- a/builder/remote_test.go
+++ b/builder/remote_test.go
@@ -172,7 +172,12 @@ func TestMakeRemoteContext(t *testing.T) {
 			if err != nil {
 				return nil, err
 			}
-			return archive.Generate(DefaultDockerfileName, string(dockerfile))
+
+			r, err := archive.Generate(DefaultDockerfileName, string(dockerfile))
+			if err != nil {
+				return nil, err
+			}
+			return ioutil.NopCloser(r), nil
 		},
 	})
 
diff --git a/daemon/commit.go b/daemon/commit.go
index 3db3ea0070..56352d9e29 100644
--- a/daemon/commit.go
+++ b/daemon/commit.go
@@ -3,6 +3,7 @@ package daemon
 import (
 	"encoding/json"
 	"fmt"
+	"io"
 	"runtime"
 	"strings"
 	"time"
@@ -14,7 +15,6 @@ import (
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
-	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/reference"
 	"github.com/docker/go-connections/nat"
@@ -247,7 +247,7 @@ func (daemon *Daemon) Commit(name string, c *backend.ContainerCommitConfig) (str
 	return id.String(), nil
 }
 
-func (daemon *Daemon) exportContainerRw(container *container.Container) (archive.Archive, error) {
+func (daemon *Daemon) exportContainerRw(container *container.Container) (io.ReadCloser, error) {
 	if err := daemon.Mount(container); err != nil {
 		return nil, err
 	}
diff --git a/daemon/export.go b/daemon/export.go
index 602ebc2054..5ef6dbb0e5 100644
--- a/daemon/export.go
+++ b/daemon/export.go
@@ -35,7 +35,7 @@ func (daemon *Daemon) ContainerExport(name string, out io.Writer) error {
 	return nil
 }
 
-func (daemon *Daemon) containerExport(container *container.Container) (archive.Archive, error) {
+func (daemon *Daemon) containerExport(container *container.Container) (io.ReadCloser, error) {
 	if err := daemon.Mount(container); err != nil {
 		return nil, err
 	}
diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go
index 95daeb7caf..c59cac019e 100644
--- a/daemon/graphdriver/aufs/aufs.go
+++ b/daemon/graphdriver/aufs/aufs.go
@@ -25,6 +25,7 @@ package aufs
 import (
 	"bufio"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -428,7 +429,7 @@ func (a *Driver) Put(id string) error {
 
 // Diff produces an archive of the changes between the specified
 // layer and its parent layer which may be "".
-func (a *Driver) Diff(id, parent string) (archive.Archive, error) {
+func (a *Driver) Diff(id, parent string) (io.ReadCloser, error) {
 	// AUFS doesn't need the parent layer to produce a diff.
 	return archive.TarWithOptions(path.Join(a.rootPath(), "diff", id), &archive.TarOptions{
 		Compression:     archive.Uncompressed,
@@ -453,7 +454,7 @@ func (a *Driver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
 	return fileGetNilCloser{storage.NewPathFileGetter(p)}, nil
 }
 
-func (a *Driver) applyDiff(id string, diff archive.Reader) error {
+func (a *Driver) applyDiff(id string, diff io.Reader) error {
 	return chrootarchive.UntarUncompressed(diff, path.Join(a.rootPath(), "diff", id), &archive.TarOptions{
 		UIDMaps: a.uidMaps,
 		GIDMaps: a.gidMaps,
@@ -471,7 +472,7 @@ func (a *Driver) DiffSize(id, parent string) (size int64, err error) {
 // ApplyDiff extracts the changeset from the given diff into the
 // layer with the specified id and parent, returning the size of the
 // new layer in bytes.
-func (a *Driver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) {
+func (a *Driver) ApplyDiff(id, parent string, diff io.Reader) (size int64, err error) {
 	// AUFS doesn't need the parent id to apply the diff.
 	if err = a.applyDiff(id, diff); err != nil {
 		return
diff --git a/daemon/graphdriver/driver.go b/daemon/graphdriver/driver.go
index 0c0b383a44..f6434ef24b 100644
--- a/daemon/graphdriver/driver.go
+++ b/daemon/graphdriver/driver.go
@@ -3,6 +3,7 @@ package graphdriver
 import (
 	"errors"
 	"fmt"
+	"io"
 	"os"
 	"path/filepath"
 	"strings"
@@ -82,7 +83,7 @@ type Driver interface {
 	ProtoDriver
 	// Diff produces an archive of the changes between the specified
 	// layer and its parent layer which may be "".
-	Diff(id, parent string) (archive.Archive, error)
+	Diff(id, parent string) (io.ReadCloser, error)
 	// Changes produces a list of changes between the specified layer
 	// and its parent layer. If parent is "", then all changes will be ADD changes.
 	Changes(id, parent string) ([]archive.Change, error)
@@ -90,7 +91,7 @@ type Driver interface {
 	// layer with the specified id and parent, returning the size of the
 	// new layer in bytes.
 	// The archive.Reader must be an uncompressed stream.
-	ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error)
+	ApplyDiff(id, parent string, diff io.Reader) (size int64, err error)
 	// DiffSize calculates the changes between the specified id
 	// and its parent and returns the size in bytes of the changes
 	// relative to its base filesystem directory.
diff --git a/daemon/graphdriver/fsdiff.go b/daemon/graphdriver/fsdiff.go
index 6e26f7a7f8..20826cd7d2 100644
--- a/daemon/graphdriver/fsdiff.go
+++ b/daemon/graphdriver/fsdiff.go
@@ -1,10 +1,10 @@
 package graphdriver
 
 import (
+	"io"
 	"time"
 
 	"github.com/Sirupsen/logrus"
-
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/pkg/idtools"
@@ -43,7 +43,7 @@ func NewNaiveDiffDriver(driver ProtoDriver, uidMaps, gidMaps []idtools.IDMap) Dr
 
 // Diff produces an archive of the changes between the specified
 // layer and its parent layer which may be "".
-func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch archive.Archive, err error) {
+func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch io.ReadCloser, err error) {
 	startTime := time.Now()
 	driver := gdw.ProtoDriver
 
@@ -126,7 +126,7 @@ func (gdw *NaiveDiffDriver) Changes(id, parent string) ([]archive.Change, error)
 // ApplyDiff extracts the changeset from the given diff into the
 // layer with the specified id and parent, returning the size of the
 // new layer in bytes.
-func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) {
+func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, diff io.Reader) (size int64, err error) {
 	driver := gdw.ProtoDriver
 
 	// Mount the root filesystem so we can apply the diff/layer.
diff --git a/daemon/graphdriver/overlay/overlay.go b/daemon/graphdriver/overlay/overlay.go
index 16fcd785ff..ec3979d4bd 100644
--- a/daemon/graphdriver/overlay/overlay.go
+++ b/daemon/graphdriver/overlay/overlay.go
@@ -5,6 +5,7 @@ package overlay
 import (
 	"bufio"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -12,11 +13,9 @@ import (
 	"syscall"
 
 	"github.com/Sirupsen/logrus"
-
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/idtools"
-
 	"github.com/docker/docker/pkg/mount"
 	"github.com/opencontainers/runc/libcontainer/label"
 )
@@ -35,7 +34,7 @@ type ApplyDiffProtoDriver interface {
 	graphdriver.ProtoDriver
 	// ApplyDiff writes the diff to the archive for the given id and parent id.
 	// It returns the size in bytes written if successful, an error ErrApplyDiffFallback is returned otherwise.
-	ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error)
+	ApplyDiff(id, parent string, diff io.Reader) (size int64, err error)
 }
 
 type naiveDiffDriverWithApply struct {
@@ -52,7 +51,7 @@ func NaiveDiffDriverWithApply(driver ApplyDiffProtoDriver, uidMaps, gidMaps []id
 }
 
 // ApplyDiff creates a diff layer with either the NaiveDiffDriver or with a fallback.
-func (d *naiveDiffDriverWithApply) ApplyDiff(id, parent string, diff archive.Reader) (int64, error) {
+func (d *naiveDiffDriverWithApply) ApplyDiff(id, parent string, diff io.Reader) (int64, error) {
 	b, err := d.applyDiff.ApplyDiff(id, parent, diff)
 	if err == ErrApplyDiffFallback {
 		return d.Driver.ApplyDiff(id, parent, diff)
@@ -386,7 +385,7 @@ func (d *Driver) Put(id string) error {
 }
 
 // ApplyDiff applies the new layer on top of the root, if parent does not exist with will return an ErrApplyDiffFallback error.
-func (d *Driver) ApplyDiff(id string, parent string, diff archive.Reader) (size int64, err error) {
+func (d *Driver) ApplyDiff(id string, parent string, diff io.Reader) (size int64, err error) {
 	dir := d.dir(id)
 
 	if parent == "" {
diff --git a/daemon/graphdriver/overlay2/overlay.go b/daemon/graphdriver/overlay2/overlay.go
index 074551b77e..7d3c7b3ab8 100644
--- a/daemon/graphdriver/overlay2/overlay.go
+++ b/daemon/graphdriver/overlay2/overlay.go
@@ -6,6 +6,7 @@ import (
 	"bufio"
 	"errors"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -536,7 +537,7 @@ func (d *Driver) Exists(id string) bool {
 }
 
 // ApplyDiff applies the new layer into a root
-func (d *Driver) ApplyDiff(id string, parent string, diff archive.Reader) (size int64, err error) {
+func (d *Driver) ApplyDiff(id string, parent string, diff io.Reader) (size int64, err error) {
 	applyDir := d.getDiffPath(id)
 
 	logrus.Debugf("Applying tar in %s", applyDir)
@@ -567,7 +568,7 @@ func (d *Driver) DiffSize(id, parent string) (size int64, err error) {
 
 // Diff produces an archive of the changes between the specified
 // layer and its parent layer which may be "".
-func (d *Driver) Diff(id, parent string) (archive.Archive, error) {
+func (d *Driver) Diff(id, parent string) (io.ReadCloser, error) {
 	diffPath := d.getDiffPath(id)
 	logrus.Debugf("Tar with options on %s", diffPath)
 	return archive.TarWithOptions(diffPath, &archive.TarOptions{
diff --git a/daemon/graphdriver/proxy.go b/daemon/graphdriver/proxy.go
index 3a8d599cb6..7fc8fe0de4 100644
--- a/daemon/graphdriver/proxy.go
+++ b/daemon/graphdriver/proxy.go
@@ -5,6 +5,7 @@ package graphdriver
 import (
 	"errors"
 	"fmt"
+	"io"
 
 	"github.com/docker/docker/pkg/archive"
 )
@@ -170,7 +171,7 @@ func (d *graphDriverProxy) Cleanup() error {
 	return nil
 }
 
-func (d *graphDriverProxy) Diff(id, parent string) (archive.Archive, error) {
+func (d *graphDriverProxy) Diff(id, parent string) (io.ReadCloser, error) {
 	args := &graphDriverRequest{
 		ID:     id,
 		Parent: parent,
@@ -179,7 +180,7 @@ func (d *graphDriverProxy) Diff(id, parent string) (archive.Archive, error) {
 	if err != nil {
 		return nil, err
 	}
-	return archive.Archive(body), nil
+	return body, nil
 }
 
 func (d *graphDriverProxy) Changes(id, parent string) ([]archive.Change, error) {
@@ -198,7 +199,7 @@ func (d *graphDriverProxy) Changes(id, parent string) ([]archive.Change, error)
 	return ret.Changes, nil
 }
 
-func (d *graphDriverProxy) ApplyDiff(id, parent string, diff archive.Reader) (int64, error) {
+func (d *graphDriverProxy) ApplyDiff(id, parent string, diff io.Reader) (int64, error) {
 	var ret graphDriverResponse
 	if err := d.client.SendFile(fmt.Sprintf("GraphDriver.ApplyDiff?id=%s&parent=%s", id, parent), diff, &ret); err != nil {
 		return -1, err
diff --git a/daemon/graphdriver/windows/windows.go b/daemon/graphdriver/windows/windows.go
index 3cb09fdf00..f41f2d0227 100644
--- a/daemon/graphdriver/windows/windows.go
+++ b/daemon/graphdriver/windows/windows.go
@@ -331,7 +331,7 @@ func (d *Driver) Cleanup() error {
 // Diff produces an archive of the changes between the specified
 // layer and its parent layer which may be "".
 // The layer should be mounted when calling this function
-func (d *Driver) Diff(id, parent string) (_ archive.Archive, err error) {
+func (d *Driver) Diff(id, parent string) (_ io.ReadCloser, err error) {
 	rID, err := d.resolveID(id)
 	if err != nil {
 		return
@@ -423,7 +423,7 @@ func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
 // layer with the specified id and parent, returning the size of the
 // new layer in bytes.
 // The layer should not be mounted when calling this function
-func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (int64, error) {
+func (d *Driver) ApplyDiff(id, parent string, diff io.Reader) (int64, error) {
 	var layerChain []string
 	if parent != "" {
 		rPId, err := d.resolveID(parent)
@@ -514,7 +514,7 @@ func writeTarFromLayer(r hcsshim.LayerReader, w io.Writer) error {
 }
 
 // exportLayer generates an archive from a layer based on the given ID.
-func (d *Driver) exportLayer(id string, parentLayerPaths []string) (archive.Archive, error) {
+func (d *Driver) exportLayer(id string, parentLayerPaths []string) (io.ReadCloser, error) {
 	archive, w := io.Pipe()
 	go func() {
 		err := winio.RunWithPrivilege(winio.SeBackupPrivilege, func() error {
@@ -577,7 +577,7 @@ func writeBackupStreamFromTarAndSaveMutatedFiles(buf *bufio.Writer, w io.Writer,
 	return backuptar.WriteBackupStreamFromTarFile(buf, t, hdr)
 }
 
-func writeLayerFromTar(r archive.Reader, w hcsshim.LayerWriter, root string) (int64, error) {
+func writeLayerFromTar(r io.Reader, w hcsshim.LayerWriter, root string) (int64, error) {
 	t := tar.NewReader(r)
 	hdr, err := t.Next()
 	totalSize := int64(0)
@@ -622,7 +622,7 @@ func writeLayerFromTar(r archive.Reader, w hcsshim.LayerWriter, root string) (in
 }
 
 // importLayer adds a new layer to the tag and graph store based on the given data.
-func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPaths []string) (size int64, err error) {
+func (d *Driver) importLayer(id string, layerData io.Reader, parentLayerPaths []string) (size int64, err error) {
 	cmd := reexec.Command(append([]string{"docker-windows-write-layer", d.info.HomeDir, id}, parentLayerPaths...)...)
 	output := bytes.NewBuffer(nil)
 	cmd.Stdin = layerData
diff --git a/integration-cli/docker_cli_external_graphdriver_unix_test.go b/integration-cli/docker_cli_external_graphdriver_unix_test.go
index c4a7281cc1..1b0ec9147c 100644
--- a/integration-cli/docker_cli_external_graphdriver_unix_test.go
+++ b/integration-cli/docker_cli_external_graphdriver_unix_test.go
@@ -287,7 +287,7 @@ func (s *DockerExternalGraphdriverSuite) setUpPlugin(c *check.C, name string, ex
 
 	mux.HandleFunc("/GraphDriver.ApplyDiff", func(w http.ResponseWriter, r *http.Request) {
 		s.ec[ext].applydiff++
-		var diff archive.Reader = r.Body
+		var diff io.Reader = r.Body
 		defer r.Body.Close()
 
 		id := r.URL.Query().Get("id")
diff --git a/layer/layer_store.go b/layer/layer_store.go
index 8c7bd7526b..4fbf3961b1 100644
--- a/layer/layer_store.go
+++ b/layer/layer_store.go
@@ -11,7 +11,6 @@ import (
 	"github.com/docker/distribution"
 	"github.com/docker/distribution/digest"
 	"github.com/docker/docker/daemon/graphdriver"
-	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/stringid"
@@ -221,7 +220,7 @@ func (ls *layerStore) applyTar(tx MetadataTransaction, ts io.Reader, parent stri
 		return err
 	}
 
-	applySize, err := ls.driver.ApplyDiff(layer.cacheID, parent, archive.Reader(rdr))
+	applySize, err := ls.driver.ApplyDiff(layer.cacheID, parent, rdr)
 	if err != nil {
 		return err
 	}
diff --git a/layer/migration_test.go b/layer/migration_test.go
index 50ea6407bb..e73caf97ad 100644
--- a/layer/migration_test.go
+++ b/layer/migration_test.go
@@ -81,7 +81,7 @@ func TestLayerMigration(t *testing.T) {
 	if err := graph.Create(graphID1, "", "", nil); err != nil {
 		t.Fatal(err)
 	}
-	if _, err := graph.ApplyDiff(graphID1, "", archive.Reader(bytes.NewReader(tar1))); err != nil {
+	if _, err := graph.ApplyDiff(graphID1, "", bytes.NewReader(tar1)); err != nil {
 		t.Fatal(err)
 	}
 
@@ -126,7 +126,7 @@ func TestLayerMigration(t *testing.T) {
 	if err := graph.Create(graphID2, graphID1, "", nil); err != nil {
 		t.Fatal(err)
 	}
-	if _, err := graph.ApplyDiff(graphID2, graphID1, archive.Reader(bytes.NewReader(tar2))); err != nil {
+	if _, err := graph.ApplyDiff(graphID2, graphID1, bytes.NewReader(tar2)); err != nil {
 		t.Fatal(err)
 	}
 
@@ -168,7 +168,7 @@ func tarFromFilesInGraph(graph graphdriver.Driver, graphID, parentID string, fil
 	if err := graph.Create(graphID, parentID, "", nil); err != nil {
 		return nil, err
 	}
-	if _, err := graph.ApplyDiff(graphID, parentID, archive.Reader(bytes.NewReader(t))); err != nil {
+	if _, err := graph.ApplyDiff(graphID, parentID, bytes.NewReader(t)); err != nil {
 		return nil, err
 	}
 
@@ -323,14 +323,14 @@ func TestMountMigration(t *testing.T) {
 	if err := graph.Create(containerInit, graphID1, "", nil); err != nil {
 		t.Fatal(err)
 	}
-	if _, err := graph.ApplyDiff(containerInit, graphID1, archive.Reader(bytes.NewReader(initTar))); err != nil {
+	if _, err := graph.ApplyDiff(containerInit, graphID1, bytes.NewReader(initTar)); err != nil {
 		t.Fatal(err)
 	}
 
 	if err := graph.Create(containerID, containerInit, "", nil); err != nil {
 		t.Fatal(err)
 	}
-	if _, err := graph.ApplyDiff(containerID, containerInit, archive.Reader(bytes.NewReader(mountTar))); err != nil {
+	if _, err := graph.ApplyDiff(containerID, containerInit, bytes.NewReader(mountTar)); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go
index d8e9f70c05..46edecfee2 100644
--- a/pkg/archive/archive.go
+++ b/pkg/archive/archive.go
@@ -27,10 +27,6 @@ import (
 )
 
 type (
-	// Archive is a type of io.ReadCloser which has two interfaces Read and Closer.
-	Archive io.ReadCloser
-	// Reader is a type of io.Reader.
-	Reader io.Reader
 	// Compression is the state represents if compressed or not.
 	Compression int
 	// WhiteoutFormat is the format of whiteouts unpacked
@@ -39,6 +35,7 @@ type (
 	TarChownOptions struct {
 		UID, GID int
 	}
+
 	// TarOptions wraps the tar options.
 	TarOptions struct {
 		IncludeFiles     []string
@@ -1106,7 +1103,7 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, <-chan struct{},
 // NewTempArchive reads the content of src into a temporary file, and returns the contents
 // of that file as an archive. The archive can only be read once - as soon as reading completes,
 // the file will be deleted.
-func NewTempArchive(src Archive, dir string) (*TempArchive, error) {
+func NewTempArchive(src io.Reader, dir string) (*TempArchive, error) {
 	f, err := ioutil.TempFile(dir, "")
 	if err != nil {
 		return nil, err
diff --git a/pkg/archive/changes.go b/pkg/archive/changes.go
index 4e2d8e54f7..c07d55cbd9 100644
--- a/pkg/archive/changes.go
+++ b/pkg/archive/changes.go
@@ -391,7 +391,7 @@ func ChangesSize(newDir string, changes []Change) int64 {
 }
 
 // ExportChanges produces an Archive from the provided changes, relative to dir.
-func ExportChanges(dir string, changes []Change, uidMaps, gidMaps []idtools.IDMap) (Archive, error) {
+func ExportChanges(dir string, changes []Change, uidMaps, gidMaps []idtools.IDMap) (io.ReadCloser, error) {
 	reader, writer := io.Pipe()
 	go func() {
 		ta := &tarAppender{
diff --git a/pkg/archive/copy.go b/pkg/archive/copy.go
index a60c948d0d..0614c67cec 100644
--- a/pkg/archive/copy.go
+++ b/pkg/archive/copy.go
@@ -88,13 +88,13 @@ func SplitPathDirEntry(path string) (dir, base string) {
 // This function acts as a convenient wrapper around TarWithOptions, which
 // requires a directory as the source path. TarResource accepts either a
 // directory or a file path and correctly sets the Tar options.
-func TarResource(sourceInfo CopyInfo) (content Archive, err error) {
+func TarResource(sourceInfo CopyInfo) (content io.ReadCloser, err error) {
 	return TarResourceRebase(sourceInfo.Path, sourceInfo.RebaseName)
 }
 
 // TarResourceRebase is like TarResource but renames the first path element of
 // items in the resulting tar archive to match the given rebaseName if not "".
-func TarResourceRebase(sourcePath, rebaseName string) (content Archive, err error) {
+func TarResourceRebase(sourcePath, rebaseName string) (content io.ReadCloser, err error) {
 	sourcePath = normalizePath(sourcePath)
 	if _, err = os.Lstat(sourcePath); err != nil {
 		// Catches the case where the source does not exist or is not a
@@ -241,7 +241,7 @@ func CopyInfoDestinationPath(path string) (info CopyInfo, err error) {
 // contain the archived resource described by srcInfo, to the destination
 // described by dstInfo. Returns the possibly modified content archive along
 // with the path to the destination directory which it should be extracted to.
-func PrepareArchiveCopy(srcContent Reader, srcInfo, dstInfo CopyInfo) (dstDir string, content Archive, err error) {
+func PrepareArchiveCopy(srcContent io.Reader, srcInfo, dstInfo CopyInfo) (dstDir string, content io.ReadCloser, err error) {
 	// Ensure in platform semantics
 	srcInfo.Path = normalizePath(srcInfo.Path)
 	dstInfo.Path = normalizePath(dstInfo.Path)
@@ -304,7 +304,7 @@ func PrepareArchiveCopy(srcContent Reader, srcInfo, dstInfo CopyInfo) (dstDir st
 
 // RebaseArchiveEntries rewrites the given srcContent archive replacing
 // an occurrence of oldBase with newBase at the beginning of entry names.
-func RebaseArchiveEntries(srcContent Reader, oldBase, newBase string) Archive {
+func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.ReadCloser {
 	if oldBase == string(os.PathSeparator) {
 		// If oldBase specifies the root directory, use an empty string as
 		// oldBase instead so that newBase doesn't replace the path separator
@@ -380,7 +380,7 @@ func CopyResource(srcPath, dstPath string, followLink bool) error {
 
 // CopyTo handles extracting the given content whose
 // entries should be sourced from srcInfo to dstPath.
-func CopyTo(content Reader, srcInfo CopyInfo, dstPath string) error {
+func CopyTo(content io.Reader, srcInfo CopyInfo, dstPath string) error {
 	// The destination path need not exist, but CopyInfoDestinationPath will
 	// ensure that at least the parent directory exists.
 	dstInfo, err := CopyInfoDestinationPath(normalizePath(dstPath))
diff --git a/pkg/archive/diff.go b/pkg/archive/diff.go
index 26da677c1f..9e1a58c499 100644
--- a/pkg/archive/diff.go
+++ b/pkg/archive/diff.go
@@ -19,7 +19,7 @@ import (
 // UnpackLayer unpack `layer` to a `dest`. The stream `layer` can be
 // compressed or uncompressed.
 // Returns the size in bytes of the contents of the layer.
-func UnpackLayer(dest string, layer Reader, options *TarOptions) (size int64, err error) {
+func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, err error) {
 	tr := tar.NewReader(layer)
 	trBuf := pools.BufioReader32KPool.Get(tr)
 	defer pools.BufioReader32KPool.Put(trBuf)
@@ -246,7 +246,7 @@ func UnpackLayer(dest string, layer Reader, options *TarOptions) (size int64, er
 // and applies it to the directory `dest`. The stream `layer` can be
 // compressed or uncompressed.
 // Returns the size in bytes of the contents of the layer.
-func ApplyLayer(dest string, layer Reader) (int64, error) {
+func ApplyLayer(dest string, layer io.Reader) (int64, error) {
 	return applyLayerHandler(dest, layer, &TarOptions{}, true)
 }
 
@@ -254,12 +254,12 @@ func ApplyLayer(dest string, layer Reader) (int64, error) {
 // `layer`, and applies it to the directory `dest`. The stream `layer`
 // can only be uncompressed.
 // Returns the size in bytes of the contents of the layer.
-func ApplyUncompressedLayer(dest string, layer Reader, options *TarOptions) (int64, error) {
+func ApplyUncompressedLayer(dest string, layer io.Reader, options *TarOptions) (int64, error) {
 	return applyLayerHandler(dest, layer, options, false)
 }
 
 // do the bulk load of ApplyLayer, but allow for not calling DecompressStream
-func applyLayerHandler(dest string, layer Reader, options *TarOptions, decompress bool) (int64, error) {
+func applyLayerHandler(dest string, layer io.Reader, options *TarOptions, decompress bool) (int64, error) {
 	dest = filepath.Clean(dest)
 
 	// We need to be able to set any perms
diff --git a/pkg/archive/utils_test.go b/pkg/archive/utils_test.go
index 98719032f3..01b9e92d1c 100644
--- a/pkg/archive/utils_test.go
+++ b/pkg/archive/utils_test.go
@@ -16,7 +16,7 @@ var testUntarFns = map[string]func(string, io.Reader) error{
 		return Untar(r, dest, nil)
 	},
 	"applylayer": func(dest string, r io.Reader) error {
-		_, err := ApplyLayer(dest, Reader(r))
+		_, err := ApplyLayer(dest, r)
 		return err
 	},
 }
diff --git a/pkg/archive/wrap.go b/pkg/archive/wrap.go
index dfb335c0b6..b39d12c878 100644
--- a/pkg/archive/wrap.go
+++ b/pkg/archive/wrap.go
@@ -3,7 +3,7 @@ package archive
 import (
 	"archive/tar"
 	"bytes"
-	"io/ioutil"
+	"io"
 )
 
 // Generate generates a new archive from the content provided
@@ -22,7 +22,7 @@ import (
 //
 // FIXME: stream content instead of buffering
 // FIXME: specify permissions and other archive metadata
-func Generate(input ...string) (Archive, error) {
+func Generate(input ...string) (io.Reader, error) {
 	files := parseStringPairs(input...)
 	buf := new(bytes.Buffer)
 	tw := tar.NewWriter(buf)
@@ -42,7 +42,7 @@ func Generate(input ...string) (Archive, error) {
 	if err := tw.Close(); err != nil {
 		return nil, err
 	}
-	return ioutil.NopCloser(buf), nil
+	return buf, nil
 }
 
 func parseStringPairs(input ...string) (output [][2]string) {
diff --git a/pkg/chrootarchive/diff.go b/pkg/chrootarchive/diff.go
index 94131a6eb8..49acad79ff 100644
--- a/pkg/chrootarchive/diff.go
+++ b/pkg/chrootarchive/diff.go
@@ -1,12 +1,16 @@
 package chrootarchive
 
-import "github.com/docker/docker/pkg/archive"
+import (
+	"io"
+
+	"github.com/docker/docker/pkg/archive"
+)
 
 // ApplyLayer parses a diff in the standard layer format from `layer`,
 // and applies it to the directory `dest`. The stream `layer` can only be
 // uncompressed.
 // Returns the size in bytes of the contents of the layer.
-func ApplyLayer(dest string, layer archive.Reader) (size int64, err error) {
+func ApplyLayer(dest string, layer io.Reader) (size int64, err error) {
 	return applyLayerHandler(dest, layer, &archive.TarOptions{}, true)
 }
 
@@ -14,6 +18,6 @@ func ApplyLayer(dest string, layer archive.Reader) (size int64, err error) {
 // `layer`, and applies it to the directory `dest`. The stream `layer`
 // can only be uncompressed.
 // Returns the size in bytes of the contents of the layer.
-func ApplyUncompressedLayer(dest string, layer archive.Reader, options *archive.TarOptions) (int64, error) {
+func ApplyUncompressedLayer(dest string, layer io.Reader, options *archive.TarOptions) (int64, error) {
 	return applyLayerHandler(dest, layer, options, false)
 }
diff --git a/pkg/chrootarchive/diff_unix.go b/pkg/chrootarchive/diff_unix.go
index 066eda5fa7..eb0aacc3ab 100644
--- a/pkg/chrootarchive/diff_unix.go
+++ b/pkg/chrootarchive/diff_unix.go
@@ -7,6 +7,7 @@ import (
 	"encoding/json"
 	"flag"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -81,7 +82,7 @@ func applyLayer() {
 // applyLayerHandler parses a diff in the standard layer format from `layer`, and
 // applies it to the directory `dest`. Returns the size in bytes of the
 // contents of the layer.
-func applyLayerHandler(dest string, layer archive.Reader, options *archive.TarOptions, decompress bool) (size int64, err error) {
+func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions, decompress bool) (size int64, err error) {
 	dest = filepath.Clean(dest)
 	if decompress {
 		decompressed, err := archive.DecompressStream(layer)
diff --git a/pkg/chrootarchive/diff_windows.go b/pkg/chrootarchive/diff_windows.go
index 8e1830cb83..9dd9988de0 100644
--- a/pkg/chrootarchive/diff_windows.go
+++ b/pkg/chrootarchive/diff_windows.go
@@ -2,6 +2,7 @@ package chrootarchive
 
 import (
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -13,7 +14,7 @@ import (
 // applyLayerHandler parses a diff in the standard layer format from `layer`, and
 // applies it to the directory `dest`. Returns the size in bytes of the
 // contents of the layer.
-func applyLayerHandler(dest string, layer archive.Reader, options *archive.TarOptions, decompress bool) (size int64, err error) {
+func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions, decompress bool) (size int64, err error) {
 	dest = filepath.Clean(dest)
 
 	// Ensure it is a Windows-style volume path