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. |