Forráskód Böngészése

Windows: Support non-base-layered images

Previously, Windows only supported running with a OS-managed base image.
With this change, Windows supports normal, Linux-like layered images, too.

Signed-off-by: John Starks <jostarks@microsoft.com>
John Starks 9 éve
szülő
commit
d45a26d7e2

+ 1 - 2
daemon/daemon_windows.go

@@ -373,8 +373,7 @@ func restoreCustomImage(is image.Store, ls layer.Store, rs reference.Store) erro
 		}
 		// layer is intentionally not released
 
-		rootFS := image.NewRootFS()
-		rootFS.BaseLayer = filepath.Base(info.Path)
+		rootFS := image.NewRootFSWithBaseLayer(filepath.Base(info.Path))
 
 		// Create history for base layer
 		config, err := json.Marshal(&image.Image{

+ 9 - 2
daemon/oci_windows.go

@@ -5,6 +5,7 @@ import (
 	"syscall"
 
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/libcontainerd/windowsoci"
@@ -88,9 +89,15 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
 
 	// s.Windows.LayerPaths
 	var layerPaths []string
-	if img.RootFS != nil && img.RootFS.Type == "layers+base" {
+	if img.RootFS != nil && (img.RootFS.Type == image.TypeLayers || img.RootFS.Type == image.TypeLayersWithBase) {
+		// Get the layer path for each layer.
+		start := 1
+		if img.RootFS.Type == image.TypeLayersWithBase {
+			// Include an empty slice to get the base layer ID.
+			start = 0
+		}
 		max := len(img.RootFS.DiffIDs)
-		for i := 0; i <= max; i++ {
+		for i := start; i <= max; i++ {
 			img.RootFS.DiffIDs = img.RootFS.DiffIDs[:i]
 			path, err := layer.GetLayerPath(daemon.layerStore, img.RootFS.ChainID())
 			if err != nil {

+ 2 - 1
distribution/pull_v2_windows.go

@@ -20,8 +20,9 @@ func detectBaseLayer(is image.Store, m *schema1.Manifest, rootFS *image.RootFS)
 	}
 	// There must be an image that already references the baselayer.
 	for _, img := range is.Map() {
-		if img.RootFS.BaseLayerID() == v1img.Parent {
+		if img.RootFS.Type == image.TypeLayersWithBase && img.RootFS.BaseLayerID() == v1img.Parent {
 			rootFS.BaseLayer = img.RootFS.BaseLayer
+			rootFS.Type = image.TypeLayersWithBase
 			return nil
 		}
 	}

+ 8 - 0
image/rootfs.go

@@ -2,6 +2,14 @@ package image
 
 import "github.com/docker/docker/layer"
 
+// TypeLayers is used for RootFS.Type for filesystems organized into layers.
+const TypeLayers = "layers"
+
+// NewRootFS returns empty RootFS struct
+func NewRootFS() *RootFS {
+	return &RootFS{Type: TypeLayers}
+}
+
 // Append appends a new diffID to rootfs
 func (r *RootFS) Append(id layer.DiffID) {
 	r.DiffIDs = append(r.DiffIDs, id)

+ 0 - 5
image/rootfs_unix.go

@@ -16,8 +16,3 @@ type RootFS struct {
 func (r *RootFS) ChainID() layer.ChainID {
 	return layer.CreateChainID(r.DiffIDs)
 }
-
-// NewRootFS returns empty RootFS struct
-func NewRootFS() *RootFS {
-	return &RootFS{Type: "layers"}
-}

+ 16 - 5
image/rootfs_windows.go

@@ -10,6 +10,9 @@ import (
 	"github.com/docker/docker/layer"
 )
 
+// TypeLayersWithBase is used for RootFS.Type for Windows filesystems that have layers and a centrally-stored base layer.
+const TypeLayersWithBase = "layers+base"
+
 // RootFS describes images root filesystem
 // This is currently a placeholder that only supports layers. In the future
 // this can be made into an interface that supports different implementations.
@@ -21,17 +24,25 @@ type RootFS struct {
 
 // BaseLayerID returns the 64 byte hex ID for the baselayer name.
 func (r *RootFS) BaseLayerID() string {
+	if r.Type != TypeLayersWithBase {
+		panic("tried to get base layer ID without a base layer")
+	}
 	baseID := sha512.Sum384([]byte(r.BaseLayer))
 	return fmt.Sprintf("%x", baseID[:32])
 }
 
 // ChainID returns the ChainID for the top layer in RootFS.
 func (r *RootFS) ChainID() layer.ChainID {
-	baseDiffID := digest.FromBytes([]byte(r.BaseLayerID()))
-	return layer.CreateChainID(append([]layer.DiffID{layer.DiffID(baseDiffID)}, r.DiffIDs...))
+	ids := r.DiffIDs
+	if r.Type == TypeLayersWithBase {
+		// Add an extra ID for the base.
+		baseDiffID := layer.DiffID(digest.FromBytes([]byte(r.BaseLayerID())))
+		ids = append([]layer.DiffID{baseDiffID}, ids...)
+	}
+	return layer.CreateChainID(ids)
 }
 
-// NewRootFS returns empty RootFS struct
-func NewRootFS() *RootFS {
-	return &RootFS{Type: "layers+base"}
+// NewRootFSWithBaseLayer returns a RootFS struct with a base layer
+func NewRootFSWithBaseLayer(baseLayer string) *RootFS {
+	return &RootFS{Type: TypeLayersWithBase, BaseLayer: baseLayer}
 }