Windows base layers are no longer the special "layers+base" type, so we can remove all the special handling for that.
Signed-off-by: Stefan J. Wernli <swernli@microsoft.com>
| ... | ... |
@@ -426,9 +426,8 @@ func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
|
| 426 | 426 |
layers = append(layers, l.String()) |
| 427 | 427 |
} |
| 428 | 428 |
return types.RootFS{
|
| 429 |
- Type: rootfs.Type, |
|
| 430 |
- Layers: layers, |
|
| 431 |
- BaseLayer: rootfs.BaseLayer, |
|
| 429 |
+ Type: rootfs.Type, |
|
| 430 |
+ Layers: layers, |
|
| 432 | 431 |
} |
| 433 | 432 |
} |
| 434 | 433 |
|
| ... | ... |
@@ -89,15 +89,10 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e |
| 89 | 89 |
|
| 90 | 90 |
// s.Windows.LayerPaths |
| 91 | 91 |
var layerPaths []string |
| 92 |
- if img.RootFS != nil && (img.RootFS.Type == image.TypeLayers || img.RootFS.Type == image.TypeLayersWithBase) {
|
|
| 92 |
+ if img.RootFS != nil && img.RootFS.Type == image.TypeLayers {
|
|
| 93 | 93 |
// Get the layer path for each layer. |
| 94 |
- start := 1 |
|
| 95 |
- if img.RootFS.Type == image.TypeLayersWithBase {
|
|
| 96 |
- // Include an empty slice to get the base layer ID. |
|
| 97 |
- start = 0 |
|
| 98 |
- } |
|
| 99 | 94 |
max := len(img.RootFS.DiffIDs) |
| 100 |
- for i := start; i <= max; i++ {
|
|
| 95 |
+ for i := 1; i <= max; i++ {
|
|
| 101 | 96 |
img.RootFS.DiffIDs = img.RootFS.DiffIDs[:i] |
| 102 | 97 |
path, err := layer.GetLayerPath(daemon.layerStore, img.RootFS.ChainID()) |
| 103 | 98 |
if err != nil {
|
| ... | ... |
@@ -423,10 +423,6 @@ func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Named, unverif |
| 423 | 423 |
|
| 424 | 424 |
rootFS := image.NewRootFS() |
| 425 | 425 |
|
| 426 |
- if err := detectBaseLayer(p.config.ImageStore, verifiedManifest, rootFS); err != nil {
|
|
| 427 |
- return "", "", err |
|
| 428 |
- } |
|
| 429 |
- |
|
| 430 | 426 |
// remove duplicate layers and check parent chain validity |
| 431 | 427 |
err = fixManifestLayers(verifiedManifest) |
| 432 | 428 |
if err != nil {
|
| ... | ... |
@@ -542,25 +538,15 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s |
| 542 | 542 |
unmarshalledConfig image.Image // deserialized image config |
| 543 | 543 |
downloadRootFS image.RootFS // rootFS to use for registering layers. |
| 544 | 544 |
) |
| 545 |
- if runtime.GOOS == "windows" {
|
|
| 546 |
- configJSON, unmarshalledConfig, err = receiveConfig(configChan, errChan) |
|
| 547 |
- if err != nil {
|
|
| 548 |
- return "", "", err |
|
| 549 |
- } |
|
| 550 |
- if unmarshalledConfig.RootFS == nil {
|
|
| 551 |
- return "", "", errors.New("image config has no rootfs section")
|
|
| 552 |
- } |
|
| 553 |
- // https://github.com/docker/docker/issues/24766 - Err on the side of caution, |
|
| 554 |
- // explicitly blocking images intended for linux from the Windows daemon |
|
| 555 |
- if unmarshalledConfig.OS == "linux" {
|
|
| 556 |
- return "", "", fmt.Errorf("image operating system %q cannot be used on this platform", unmarshalledConfig.OS)
|
|
| 557 |
- } |
|
| 558 |
- downloadRootFS = *unmarshalledConfig.RootFS |
|
| 559 |
- downloadRootFS.DiffIDs = []layer.DiffID{}
|
|
| 560 |
- } else {
|
|
| 561 |
- downloadRootFS = *image.NewRootFS() |
|
| 545 |
+ |
|
| 546 |
+ // https://github.com/docker/docker/issues/24766 - Err on the side of caution, |
|
| 547 |
+ // explicitly blocking images intended for linux from the Windows daemon |
|
| 548 |
+ if runtime.GOOS == "windows" && unmarshalledConfig.OS == "linux" {
|
|
| 549 |
+ return "", "", fmt.Errorf("image operating system %q cannot be used on this platform", unmarshalledConfig.OS)
|
|
| 562 | 550 |
} |
| 563 | 551 |
|
| 552 |
+ downloadRootFS = *image.NewRootFS() |
|
| 553 |
+ |
|
| 564 | 554 |
rootFS, release, err := p.config.DownloadManager.Download(ctx, downloadRootFS, descriptors, p.config.ProgressOutput) |
| 565 | 555 |
if err != nil {
|
| 566 | 556 |
if configJSON != nil {
|
| ... | ... |
@@ -5,14 +5,8 @@ package distribution |
| 5 | 5 |
import ( |
| 6 | 6 |
"github.com/docker/distribution" |
| 7 | 7 |
"github.com/docker/distribution/context" |
| 8 |
- "github.com/docker/distribution/manifest/schema1" |
|
| 9 |
- "github.com/docker/docker/image" |
|
| 10 | 8 |
) |
| 11 | 9 |
|
| 12 |
-func detectBaseLayer(is image.Store, m *schema1.Manifest, rootFS *image.RootFS) error {
|
|
| 13 |
- return nil |
|
| 14 |
-} |
|
| 15 |
- |
|
| 16 | 10 |
func (ld *v2LayerDescriptor) open(ctx context.Context) (distribution.ReadSeekCloser, error) {
|
| 17 | 11 |
blobs := ld.repo.Blobs(ctx) |
| 18 | 12 |
return blobs.Open(ctx, ld.digest) |
| ... | ... |
@@ -3,38 +3,15 @@ |
| 3 | 3 |
package distribution |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
- "encoding/json" |
|
| 7 |
- "fmt" |
|
| 8 | 6 |
"net/http" |
| 9 | 7 |
"os" |
| 10 | 8 |
|
| 11 | 9 |
"github.com/docker/distribution" |
| 12 | 10 |
"github.com/docker/distribution/context" |
| 13 |
- "github.com/docker/distribution/manifest/schema1" |
|
| 14 | 11 |
"github.com/docker/distribution/manifest/schema2" |
| 15 | 12 |
"github.com/docker/distribution/registry/client/transport" |
| 16 |
- "github.com/docker/docker/image" |
|
| 17 | 13 |
) |
| 18 | 14 |
|
| 19 |
-func detectBaseLayer(is image.Store, m *schema1.Manifest, rootFS *image.RootFS) error {
|
|
| 20 |
- v1img := &image.V1Image{}
|
|
| 21 |
- if err := json.Unmarshal([]byte(m.History[len(m.History)-1].V1Compatibility), v1img); err != nil {
|
|
| 22 |
- return err |
|
| 23 |
- } |
|
| 24 |
- if v1img.Parent == "" {
|
|
| 25 |
- return fmt.Errorf("Last layer %q does not have a base layer reference", v1img.ID)
|
|
| 26 |
- } |
|
| 27 |
- // There must be an image that already references the baselayer. |
|
| 28 |
- for _, img := range is.Map() {
|
|
| 29 |
- if img.RootFS.Type == image.TypeLayersWithBase && img.RootFS.BaseLayerID() == v1img.Parent {
|
|
| 30 |
- rootFS.BaseLayer = img.RootFS.BaseLayer |
|
| 31 |
- rootFS.Type = image.TypeLayersWithBase |
|
| 32 |
- return nil |
|
| 33 |
- } |
|
| 34 |
- } |
|
| 35 |
- return fmt.Errorf("Invalid base layer %q", v1img.Parent)
|
|
| 36 |
-} |
|
| 37 |
- |
|
| 38 | 15 |
var _ distribution.Describable = &v2LayerDescriptor{}
|
| 39 | 16 |
|
| 40 | 17 |
func (ld *v2LayerDescriptor) Descriptor() distribution.Descriptor {
|
| ... | ... |
@@ -5,6 +5,14 @@ import "github.com/docker/docker/layer" |
| 5 | 5 |
// TypeLayers is used for RootFS.Type for filesystems organized into layers. |
| 6 | 6 |
const TypeLayers = "layers" |
| 7 | 7 |
|
| 8 |
+// RootFS describes images root filesystem |
|
| 9 |
+// This is currently a placeholder that only supports layers. In the future |
|
| 10 |
+// this can be made into an interface that supports different implementations. |
|
| 11 |
+type RootFS struct {
|
|
| 12 |
+ Type string `json:"type"` |
|
| 13 |
+ DiffIDs []layer.DiffID `json:"diff_ids,omitempty"` |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 8 | 16 |
// NewRootFS returns empty RootFS struct |
| 9 | 17 |
func NewRootFS() *RootFS {
|
| 10 | 18 |
return &RootFS{Type: TypeLayers}
|
| ... | ... |
@@ -14,3 +22,8 @@ func NewRootFS() *RootFS {
|
| 14 | 14 |
func (r *RootFS) Append(id layer.DiffID) {
|
| 15 | 15 |
r.DiffIDs = append(r.DiffIDs, id) |
| 16 | 16 |
} |
| 17 |
+ |
|
| 18 |
+// ChainID returns the ChainID for the top layer in RootFS. |
|
| 19 |
+func (r *RootFS) ChainID() layer.ChainID {
|
|
| 20 |
+ return layer.CreateChainID(r.DiffIDs) |
|
| 21 |
+} |
| 17 | 22 |
deleted file mode 100644 |
| ... | ... |
@@ -1,18 +0,0 @@ |
| 1 |
-// +build !windows |
|
| 2 |
- |
|
| 3 |
-package image |
|
| 4 |
- |
|
| 5 |
-import "github.com/docker/docker/layer" |
|
| 6 |
- |
|
| 7 |
-// RootFS describes images root filesystem |
|
| 8 |
-// This is currently a placeholder that only supports layers. In the future |
|
| 9 |
-// this can be made into an interface that supports different implementations. |
|
| 10 |
-type RootFS struct {
|
|
| 11 |
- Type string `json:"type"` |
|
| 12 |
- DiffIDs []layer.DiffID `json:"diff_ids,omitempty"` |
|
| 13 |
-} |
|
| 14 |
- |
|
| 15 |
-// ChainID returns the ChainID for the top layer in RootFS. |
|
| 16 |
-func (r *RootFS) ChainID() layer.ChainID {
|
|
| 17 |
- return layer.CreateChainID(r.DiffIDs) |
|
| 18 |
-} |
| 19 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,48 +0,0 @@ |
| 1 |
-// +build windows |
|
| 2 |
- |
|
| 3 |
-package image |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "crypto/sha512" |
|
| 7 |
- "fmt" |
|
| 8 |
- |
|
| 9 |
- "github.com/docker/distribution/digest" |
|
| 10 |
- "github.com/docker/docker/layer" |
|
| 11 |
-) |
|
| 12 |
- |
|
| 13 |
-// TypeLayersWithBase is used for RootFS.Type for Windows filesystems that have layers and a centrally-stored base layer. |
|
| 14 |
-const TypeLayersWithBase = "layers+base" |
|
| 15 |
- |
|
| 16 |
-// RootFS describes images root filesystem |
|
| 17 |
-// This is currently a placeholder that only supports layers. In the future |
|
| 18 |
-// this can be made into an interface that supports different implementations. |
|
| 19 |
-type RootFS struct {
|
|
| 20 |
- Type string `json:"type"` |
|
| 21 |
- DiffIDs []layer.DiffID `json:"diff_ids,omitempty"` |
|
| 22 |
- BaseLayer string `json:"base_layer,omitempty"` |
|
| 23 |
-} |
|
| 24 |
- |
|
| 25 |
-// BaseLayerID returns the 64 byte hex ID for the baselayer name. |
|
| 26 |
-func (r *RootFS) BaseLayerID() string {
|
|
| 27 |
- if r.Type != TypeLayersWithBase {
|
|
| 28 |
- panic("tried to get base layer ID without a base layer")
|
|
| 29 |
- } |
|
| 30 |
- baseID := sha512.Sum384([]byte(r.BaseLayer)) |
|
| 31 |
- return fmt.Sprintf("%x", baseID[:32])
|
|
| 32 |
-} |
|
| 33 |
- |
|
| 34 |
-// ChainID returns the ChainID for the top layer in RootFS. |
|
| 35 |
-func (r *RootFS) ChainID() layer.ChainID {
|
|
| 36 |
- ids := r.DiffIDs |
|
| 37 |
- if r.Type == TypeLayersWithBase {
|
|
| 38 |
- // Add an extra ID for the base. |
|
| 39 |
- baseDiffID := layer.DiffID(digest.FromBytes([]byte(r.BaseLayerID()))) |
|
| 40 |
- ids = append([]layer.DiffID{baseDiffID}, ids...)
|
|
| 41 |
- } |
|
| 42 |
- return layer.CreateChainID(ids) |
|
| 43 |
-} |
|
| 44 |
- |
|
| 45 |
-// NewRootFSWithBaseLayer returns a RootFS struct with a base layer |
|
| 46 |
-func NewRootFSWithBaseLayer(baseLayer string) *RootFS {
|
|
| 47 |
- return &RootFS{Type: TypeLayersWithBase, BaseLayer: baseLayer}
|
|
| 48 |
-} |
| ... | ... |
@@ -370,10 +370,7 @@ whitespace. It has been added to this example for clarity. |
| 370 | 370 |
|
| 371 | 371 |
<ul> |
| 372 | 372 |
<li> |
| 373 |
- <code>type</code> is usually set to <code>layers</code>. There is |
|
| 374 |
- also a Windows-specific value <code>layers+base</code> that allows |
|
| 375 |
- a base layer to be specified in a field of <code>rootfs</code> |
|
| 376 |
- called <code>base_layer</code>. |
|
| 373 |
+ <code>type</code> is usually set to <code>layers</code>. |
|
| 377 | 374 |
</li> |
| 378 | 375 |
<li> |
| 379 | 376 |
<code>diff_ids</code> is an array of layer content hashes (<code>DiffIDs</code>), in order from bottom-most to top-most. |