Explorar o código

Try to cross-repo mount until success

Don't fallback back immediately to blob upload if the cross-repo mount
fails and layer upload is initiated by registry.

Instead cancel the upload and re-try cross-repo mount from different
source repository before doing full re-upload.

Signed-off-by: Michal Minář <miminar@redhat.com>
Michal Minář %!s(int64=9) %!d(string=hai) anos
pai
achega
c6dd51c32c
Modificáronse 1 ficheiros con 15 adicións e 4 borrados
  1. 15 4
      distribution/push_v2.go

+ 15 - 4
distribution/push_v2.go

@@ -29,7 +29,7 @@ import (
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/registry"
 )
 )
 
 
-const maxRepositoryMountAttempts = 3
+const maxRepositoryMountAttempts = 4
 
 
 // PushResult contains the tag, manifest digest, and manifest size from the
 // PushResult contains the tag, manifest digest, and manifest size from the
 // push. It's used to signal this information to the trust code in the client
 // push. It's used to signal this information to the trust code in the client
@@ -379,9 +379,10 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
 			pd.v2MetadataService.Remove(mountCandidate)
 			pd.v2MetadataService.Remove(mountCandidate)
 		}
 		}
 
 
-		layerUpload = lu
-		if layerUpload != nil {
-			break
+		if lu != nil {
+			// cancel previous upload
+			cancelLayerUpload(ctx, mountCandidate.Digest, layerUpload)
+			layerUpload = lu
 		}
 		}
 	}
 	}
 
 
@@ -583,3 +584,13 @@ func getPathComponents(path string) []string {
 	}
 	}
 	return strings.Split(path, "/")
 	return strings.Split(path, "/")
 }
 }
+
+func cancelLayerUpload(ctx context.Context, dgst digest.Digest, layerUpload distribution.BlobWriter) {
+	if layerUpload != nil {
+		logrus.Debugf("cancelling upload of blob %s", dgst)
+		err := layerUpload.Cancel(ctx)
+		if err != nil {
+			logrus.Warnf("failed to cancel upload: %v", err)
+		}
+	}
+}