Jelajahi Sumber

graph: preserve tar archive entries

Preserve the entries from the tar archive for layers added to the graph.

With these entries and relative filesystem path, the tar archives can be
reassembled later.

Signed-off-by: Vincent Batts <vbatts@redhat.com>
Vincent Batts 10 tahun lalu
induk
melakukan
5d9f06599c
2 mengubah file dengan 49 tambahan dan 2 penghapusan
  1. 24 1
      graph/graph_unix.go
  2. 25 1
      graph/graph_windows.go

+ 24 - 1
graph/graph_unix.go

@@ -3,6 +3,7 @@
 package graph
 package graph
 
 
 import (
 import (
+	"compress/gzip"
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
 	"os"
 	"os"
@@ -90,7 +91,29 @@ func (graph *Graph) restoreBaseImages() ([]string, error) {
 func (graph *Graph) storeImage(img *image.Image, layerData archive.ArchiveReader, root string) (err error) {
 func (graph *Graph) storeImage(img *image.Image, layerData archive.ArchiveReader, root string) (err error) {
 	// Store the layer. If layerData is not nil, unpack it into the new layer
 	// Store the layer. If layerData is not nil, unpack it into the new layer
 	if layerData != nil {
 	if layerData != nil {
-		if img.Size, err = graph.driver.ApplyDiff(img.ID, img.Parent, layerData); err != nil {
+		// this is saving the tar-split metadata
+		mf, err := os.OpenFile(filepath.Join(root, "tar-data.json.gz"), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600))
+		if err != nil {
+			return err
+		}
+		defer mf.Close()
+		mfz := gzip.NewWriter(mf)
+		defer mfz.Close()
+		metaPacker := storage.NewJSONPacker(mf)
+
+		inflatedLayerData, err := archive.DecompressStream(layerData)
+		if err != nil {
+			return err
+		}
+
+		// we're passing nil here for the file putter, because the ApplyDiff will
+		// handle the extraction of the archive
+		its, err := asm.NewInputTarStream(inflatedLayerData, metaPacker, nil)
+		if err != nil {
+			return err
+		}
+
+		if img.Size, err = graph.driver.ApplyDiff(img.ID, img.Parent, archive.ArchiveReader(its)); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}

+ 25 - 1
graph/graph_windows.go

@@ -3,9 +3,11 @@
 package graph
 package graph
 
 
 import (
 import (
+	"compress/gzip"
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
 	"os"
 	"os"
+	"path/filepath"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver/windows"
 	"github.com/docker/docker/daemon/graphdriver/windows"
@@ -115,7 +117,29 @@ func (graph *Graph) storeImage(img *image.Image, layerData archive.ArchiveReader
 
 
 		// Store the layer. If layerData is not nil, unpack it into the new layer
 		// Store the layer. If layerData is not nil, unpack it into the new layer
 		if layerData != nil {
 		if layerData != nil {
-			if img.Size, err = graph.driver.ApplyDiff(img.ID, img.Parent, layerData); err != nil {
+			// this is saving the tar-split metadata
+			mf, err := os.OpenFile(filepath.Join(root, "tar-data.json.gz"), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600))
+			if err != nil {
+				return err
+			}
+			defer mf.Close()
+			mfz := gzip.NewWriter(mf)
+			defer mfz.Close()
+			metaPacker := storage.NewJSONPacker(mf)
+
+			inflatedLayerData, err := archive.DecompressStream(layerData)
+			if err != nil {
+				return err
+			}
+
+			// we're passing nil here for the file putter, because the ApplyDiff will
+			// handle the extraction of the archive
+			its, err := asm.NewInputTarStream(inflatedLayerData, metaPacker, nil)
+			if err != nil {
+				return err
+			}
+
+			if img.Size, err = graph.driver.ApplyDiff(img.ID, img.Parent, archive.ArchiveReader(its)); err != nil {
 				return err
 				return err
 			}
 			}
 		}
 		}