Browse Source

Ignore ping errors in notary repository setup

Notary is capable of acting in offline mode, making use of cache TUF data.
When ping is not successful, notary should still be attempted without error.

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Derek McGowan 9 years ago
parent
commit
5e11cd43aa

+ 14 - 6
api/client/trust.go

@@ -144,15 +144,21 @@ func (cli *DockerCli) getNotaryRepository(repoInfo *registry.RepositoryInfo, aut
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
+
+	challengeManager := auth.NewSimpleChallengeManager()
+
 	resp, err := pingClient.Do(req)
 	resp, err := pingClient.Do(req)
 	if err != nil {
 	if err != nil {
-		return nil, err
-	}
-	defer resp.Body.Close()
+		// Ignore error on ping to operate in offline mode
+		logrus.Debugf("Error pinging notary server %q: %s", endpointStr, err)
+	} else {
+		defer resp.Body.Close()
 
 
-	challengeManager := auth.NewSimpleChallengeManager()
-	if err := challengeManager.AddResponse(resp); err != nil {
-		return nil, err
+		// Add response to the challenge manager to parse out
+		// authentication header and register authentication method
+		if err := challengeManager.AddResponse(resp); err != nil {
+			return nil, err
+		}
 	}
 	}
 
 
 	creds := simpleCredentialStore{auth: authConfig}
 	creds := simpleCredentialStore{auth: authConfig}
@@ -248,6 +254,8 @@ func notaryError(err error) error {
 		return fmt.Errorf("remote repository out-of-date: %v", err)
 		return fmt.Errorf("remote repository out-of-date: %v", err)
 	case trustmanager.ErrKeyNotFound:
 	case trustmanager.ErrKeyNotFound:
 		return fmt.Errorf("signing keys not found: %v", err)
 		return fmt.Errorf("signing keys not found: %v", err)
+	case *net.OpError:
+		return fmt.Errorf("error contacting notary server: %v", err)
 	}
 	}
 
 
 	return err
 	return err

+ 41 - 0
integration-cli/docker_cli_pull_trusted_test.go

@@ -223,3 +223,44 @@ func (s *DockerTrustSuite) TestTrustedPullWithExpiredSnapshot(c *check.C) {
 		}
 		}
 	})
 	})
 }
 }
+
+func (s *DockerTrustSuite) TestTrustedOfflinePull(c *check.C) {
+	repoName := s.setupTrustedImage(c, "trusted-offline-pull")
+
+	pullCmd := exec.Command(dockerBinary, "pull", repoName)
+	s.trustedCmdWithServer(pullCmd, "https://invalidnotaryserver")
+	out, _, err := runCommandWithOutput(pullCmd)
+	if err == nil {
+		c.Fatalf("Expected error pulling with invalid notary server:\n%s", out)
+	}
+
+	if !strings.Contains(string(out), "error contacting notary server") {
+		c.Fatalf("Missing expected output on trusted pull:\n%s", out)
+	}
+
+	// Do valid trusted pull to warm cache
+	pullCmd = exec.Command(dockerBinary, "pull", repoName)
+	s.trustedCmd(pullCmd)
+	out, _, err = runCommandWithOutput(pullCmd)
+	if err != nil {
+		c.Fatalf("Error running trusted pull: %s\n%s", err, out)
+	}
+
+	if !strings.Contains(string(out), "Tagging") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	dockerCmd(c, "rmi", repoName)
+
+	// Try pull again with invalid notary server, should use cache
+	pullCmd = exec.Command(dockerBinary, "pull", repoName)
+	s.trustedCmdWithServer(pullCmd, "https://invalidnotaryserver")
+	out, _, err = runCommandWithOutput(pullCmd)
+	if err != nil {
+		c.Fatalf("Error running trusted pull: %s\n%s", err, out)
+	}
+
+	if !strings.Contains(string(out), "Tagging") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+}

+ 1 - 1
integration-cli/docker_cli_push_test.go

@@ -154,7 +154,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithFaillingServer(c *check.C) {
 		c.Fatalf("Missing error while running trusted push w/ no server")
 		c.Fatalf("Missing error while running trusted push w/ no server")
 	}
 	}
 
 
-	if !strings.Contains(string(out), "Error establishing connection to notary repository") {
+	if !strings.Contains(string(out), "error contacting notary server") {
 		c.Fatalf("Missing expected output on trusted push:\n%s", out)
 		c.Fatalf("Missing expected output on trusted push:\n%s", out)
 	}
 	}
 }
 }