Browse code

Windows: Fix regression pulling linux images

Signed-off-by: John Howard <jhoward@microsoft.com>

John Howard authored on 2016/09/09 08:28:23
Showing 2 changed files
... ...
@@ -550,15 +550,36 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
550 550
 	)
551 551
 
552 552
 	// https://github.com/docker/docker/issues/24766 - Err on the side of caution,
553
-	// explicitly blocking images intended for linux from the Windows daemon
554
-	if runtime.GOOS == "windows" && unmarshalledConfig.OS == "linux" {
555
-		return "", "", fmt.Errorf("image operating system %q cannot be used on this platform", unmarshalledConfig.OS)
553
+	// explicitly blocking images intended for linux from the Windows daemon. On
554
+	// Windows, we do this before the attempt to download, effectively serialising
555
+	// the download slightly slowing it down. We have to do it this way, as
556
+	// chances are the download of layers itself would fail due to file names
557
+	// which aren't suitable for NTFS. At some point in the future, if a similar
558
+	// check to block Windows images being pulled on Linux is implemented, it
559
+	// may be necessary to perform the same type of serialisation.
560
+	if runtime.GOOS == "windows" {
561
+		configJSON, unmarshalledConfig, err = receiveConfig(configChan, errChan)
562
+		if err != nil {
563
+			return "", "", err
564
+		}
565
+
566
+		if unmarshalledConfig.RootFS == nil {
567
+			return "", "", errRootFSInvalid
568
+		}
569
+
570
+		if unmarshalledConfig.OS == "linux" {
571
+			return "", "", fmt.Errorf("image operating system %q cannot be used on this platform", unmarshalledConfig.OS)
572
+		}
556 573
 	}
557 574
 
558 575
 	downloadRootFS = *image.NewRootFS()
559 576
 
560 577
 	rootFS, release, err := p.config.DownloadManager.Download(ctx, downloadRootFS, descriptors, p.config.ProgressOutput)
561 578
 	if err != nil {
579
+		if configJSON != nil {
580
+			// Already received the config
581
+			return "", "", err
582
+		}
562 583
 		select {
563 584
 		case err = <-errChan:
564 585
 			return "", "", err
... ...
@@ -573,13 +594,15 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
573 573
 	}
574 574
 	defer release()
575 575
 
576
-	configJSON, unmarshalledConfig, err = receiveConfig(configChan, errChan)
577
-	if err != nil {
578
-		return "", "", err
579
-	}
576
+	if configJSON == nil {
577
+		configJSON, unmarshalledConfig, err = receiveConfig(configChan, errChan)
578
+		if err != nil {
579
+			return "", "", err
580
+		}
580 581
 
581
-	if unmarshalledConfig.RootFS == nil {
582
-		return "", "", errRootFSInvalid
582
+		if unmarshalledConfig.RootFS == nil {
583
+			return "", "", errRootFSInvalid
584
+		}
583 585
 	}
584 586
 
585 587
 	// The DiffIDs returned in rootFS MUST match those in the config.
... ...
@@ -272,3 +272,10 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullNoCredentialsNotFound(c *check
272 272
 	c.Assert(err, check.NotNil, check.Commentf(out))
273 273
 	c.Assert(out, checker.Contains, "Error: image busybox:latest not found")
274 274
 }
275
+
276
+// Regression test for https://github.com/docker/docker/issues/26429
277
+func (s *DockerSuite) TestPullLinuxImageFailsOnWindows(c *check.C) {
278
+	testRequires(c, DaemonIsWindows, Network)
279
+	_, _, err := dockerCmdWithError("pull", "ubuntu")
280
+	c.Assert(err.Error(), checker.Contains, "cannot be used on this platform")
281
+}