Переглянути джерело

Merge pull request #15543 from icecrime/15536_partial_manifest

Fix partial manifest push
Jessie Frazelle 10 роки тому
батько
коміт
30cf473f26
3 змінених файлів з 39 додано та 34 видалено
  1. 6 7
      graph/push.go
  2. 4 7
      graph/push_v2.go
  3. 29 20
      integration-cli/docker_cli_push_test.go

+ 6 - 7
graph/push.go

@@ -44,13 +44,12 @@ func (s *TagStore) NewPusher(endpoint registry.APIEndpoint, localRepo Repository
 	switch endpoint.Version {
 	switch endpoint.Version {
 	case registry.APIVersion2:
 	case registry.APIVersion2:
 		return &v2Pusher{
 		return &v2Pusher{
-			TagStore:   s,
-			endpoint:   endpoint,
-			localRepo:  localRepo,
-			repoInfo:   repoInfo,
-			config:     imagePushConfig,
-			sf:         sf,
-			layersSeen: make(map[string]bool),
+			TagStore:  s,
+			endpoint:  endpoint,
+			localRepo: localRepo,
+			repoInfo:  repoInfo,
+			config:    imagePushConfig,
+			sf:        sf,
 		}, nil
 		}, nil
 	case registry.APIVersion1:
 	case registry.APIVersion1:
 		return &v1Pusher{
 		return &v1Pusher{

+ 4 - 7
graph/push_v2.go

@@ -27,11 +27,6 @@ type v2Pusher struct {
 	config    *ImagePushConfig
 	config    *ImagePushConfig
 	sf        *streamformatter.StreamFormatter
 	sf        *streamformatter.StreamFormatter
 	repo      distribution.Repository
 	repo      distribution.Repository
-
-	// layersSeen is the set of layers known to exist on the remote side.
-	// This avoids redundant queries when pushing multiple tags that
-	// involve the same layers.
-	layersSeen map[string]bool
 }
 }
 
 
 func (p *v2Pusher) Push() (fallback bool, err error) {
 func (p *v2Pusher) Push() (fallback bool, err error) {
@@ -92,6 +87,8 @@ func (p *v2Pusher) pushV2Tag(tag string) error {
 		return fmt.Errorf("tag does not exist: %s", tag)
 		return fmt.Errorf("tag does not exist: %s", tag)
 	}
 	}
 
 
+	layersSeen := make(map[string]bool)
+
 	layer, err := p.graph.Get(layerID)
 	layer, err := p.graph.Get(layerID)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -120,7 +117,7 @@ func (p *v2Pusher) pushV2Tag(tag string) error {
 			return err
 			return err
 		}
 		}
 
 
-		if p.layersSeen[layer.ID] {
+		if layersSeen[layer.ID] {
 			break
 			break
 		}
 		}
 
 
@@ -175,7 +172,7 @@ func (p *v2Pusher) pushV2Tag(tag string) error {
 		m.FSLayers = append(m.FSLayers, manifest.FSLayer{BlobSum: dgst})
 		m.FSLayers = append(m.FSLayers, manifest.FSLayer{BlobSum: dgst})
 		m.History = append(m.History, manifest.History{V1Compatibility: string(jsonData)})
 		m.History = append(m.History, manifest.History{V1Compatibility: string(jsonData)})
 
 
-		p.layersSeen[layer.ID] = true
+		layersSeen[layer.ID] = true
 	}
 	}
 
 
 	logrus.Infof("Signed manifest for %s:%s using daemon's key: %s", p.repo.Name(), tag, p.trustKey.KeyID())
 	logrus.Infof("Signed manifest for %s:%s using daemon's key: %s", p.repo.Name(), tag, p.trustKey.KeyID())

+ 29 - 20
integration-cli/docker_cli_push_test.go

@@ -60,31 +60,40 @@ func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) {
 
 
 	dockerCmd(c, "tag", "busybox", repoTag2)
 	dockerCmd(c, "tag", "busybox", repoTag2)
 
 
-	out, _ := dockerCmd(c, "push", repoName)
+	dockerCmd(c, "push", repoName)
 
 
-	// There should be no duplicate hashes in the output
-	imageSuccessfullyPushed := ": Image successfully pushed"
+	// Ensure layer list is equivalent for repoTag1 and repoTag2
+	out1, _ := dockerCmd(c, "pull", repoTag1)
+	if strings.Contains(out1, "Tag t1 not found") {
+		c.Fatalf("Unable to pull pushed image: %s", out1)
+	}
 	imageAlreadyExists := ": Image already exists"
 	imageAlreadyExists := ": Image already exists"
-	imagePushHashes := make(map[string]struct{})
-	outputLines := strings.Split(out, "\n")
-	for _, outputLine := range outputLines {
-		if strings.Contains(outputLine, imageSuccessfullyPushed) {
-			hash := strings.TrimSuffix(outputLine, imageSuccessfullyPushed)
-			if _, present := imagePushHashes[hash]; present {
-				c.Fatalf("Duplicate image push: %s", outputLine)
-			}
-			imagePushHashes[hash] = struct{}{}
-		} else if strings.Contains(outputLine, imageAlreadyExists) {
-			hash := strings.TrimSuffix(outputLine, imageAlreadyExists)
-			if _, present := imagePushHashes[hash]; present {
-				c.Fatalf("Duplicate image push: %s", outputLine)
-			}
-			imagePushHashes[hash] = struct{}{}
+	var out1Lines []string
+	for _, outputLine := range strings.Split(out1, "\n") {
+		if strings.Contains(outputLine, imageAlreadyExists) {
+			out1Lines = append(out1Lines, outputLine)
 		}
 		}
 	}
 	}
 
 
-	if len(imagePushHashes) == 0 {
-		c.Fatal(`Expected at least one line containing "Image successfully pushed"`)
+	out2, _ := dockerCmd(c, "pull", repoTag2)
+	if strings.Contains(out2, "Tag t2 not found") {
+		c.Fatalf("Unable to pull pushed image: %s", out1)
+	}
+	var out2Lines []string
+	for _, outputLine := range strings.Split(out2, "\n") {
+		if strings.Contains(outputLine, imageAlreadyExists) {
+			out1Lines = append(out1Lines, outputLine)
+		}
+	}
+
+	if len(out1Lines) != len(out2Lines) {
+		c.Fatalf("Mismatched output length:\n%s\n%s", out1, out2)
+	}
+
+	for i := range out1Lines {
+		if out1Lines[i] != out2Lines[i] {
+			c.Fatalf("Mismatched output line:\n%s\n%s", out1Lines[i], out2Lines[i])
+		}
 	}
 	}
 }
 }