Browse code

LCOW: Prefer Windows over Linux in a manifest list

When a manifest list contains both Linux and Windows images, always
prefer Windows when the platform OS is unspecified. Also, filter out any
Windows images with a higher build than the host, since they cannot run.

Signed-off-by: John Stephens <johnstep@docker.com>

John Stephens authored on 2018/06/29 12:30:41
Showing 1 changed files
... ...
@@ -74,11 +74,14 @@ func filterManifests(manifests []manifestlist.ManifestDescriptor, p specs.Platfo
74 74
 		if (manifestDescriptor.Platform.Architecture == runtime.GOARCH) &&
75 75
 			((p.OS != "" && manifestDescriptor.Platform.OS == p.OS) || // Explicit user request for an OS we know we support
76 76
 				(p.OS == "" && system.IsOSSupported(manifestDescriptor.Platform.OS))) { // No user requested OS, but one we can support
77
-			matches = append(matches, manifestDescriptor)
78
-			logrus.Debugf("found match %s/%s %s with media type %s, digest %s", manifestDescriptor.Platform.OS, runtime.GOARCH, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String())
79 77
 			if strings.EqualFold("windows", manifestDescriptor.Platform.OS) {
78
+				if err := checkImageCompatibility("windows", manifestDescriptor.Platform.OSVersion); err != nil {
79
+					continue
80
+				}
80 81
 				foundWindowsMatch = true
81 82
 			}
83
+			matches = append(matches, manifestDescriptor)
84
+			logrus.Debugf("found match %s/%s %s with media type %s, digest %s", manifestDescriptor.Platform.OS, runtime.GOARCH, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String())
82 85
 		} else {
83 86
 			logrus.Debugf("ignoring %s/%s %s with media type %s, digest %s", manifestDescriptor.Platform.OS, manifestDescriptor.Platform.Architecture, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String())
84 87
 		}
... ...
@@ -103,7 +106,8 @@ func (mbv manifestsByVersion) Less(i, j int) bool {
103 103
 	// TODO: Split version by parts and compare
104 104
 	// TODO: Prefer versions which have a greater version number
105 105
 	// Move compatible versions to the top, with no other ordering changes
106
-	return versionMatch(mbv.list[i].Platform.OSVersion, mbv.version) && !versionMatch(mbv.list[j].Platform.OSVersion, mbv.version)
106
+	return (strings.EqualFold("windows", mbv.list[i].Platform.OS) && !strings.EqualFold("windows", mbv.list[j].Platform.OS)) ||
107
+		(versionMatch(mbv.list[i].Platform.OSVersion, mbv.version) && !versionMatch(mbv.list[j].Platform.OSVersion, mbv.version))
107 108
 }
108 109
 
109 110
 func (mbv manifestsByVersion) Len() int {