|
@@ -42,7 +42,7 @@ type v2Pusher struct {
|
|
|
config *ImagePushConfig
|
|
|
repo distribution.Repository
|
|
|
|
|
|
- // pushState is state built by the Download functions.
|
|
|
+ // pushState is state built by the Upload functions.
|
|
|
pushState pushState
|
|
|
}
|
|
|
|
|
@@ -224,6 +224,7 @@ type v2PushDescriptor struct {
|
|
|
repoInfo reference.Named
|
|
|
repo distribution.Repository
|
|
|
pushState *pushState
|
|
|
+ remoteDescriptor distribution.Descriptor
|
|
|
}
|
|
|
|
|
|
func (pd *v2PushDescriptor) Key() string {
|
|
@@ -238,16 +239,16 @@ func (pd *v2PushDescriptor) DiffID() layer.DiffID {
|
|
|
return pd.layer.DiffID()
|
|
|
}
|
|
|
|
|
|
-func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.Output) error {
|
|
|
+func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.Output) (distribution.Descriptor, error) {
|
|
|
diffID := pd.DiffID()
|
|
|
|
|
|
pd.pushState.Lock()
|
|
|
- if _, ok := pd.pushState.remoteLayers[diffID]; ok {
|
|
|
+ if descriptor, ok := pd.pushState.remoteLayers[diffID]; ok {
|
|
|
// it is already known that the push is not needed and
|
|
|
// therefore doing a stat is unnecessary
|
|
|
pd.pushState.Unlock()
|
|
|
progress.Update(progressOutput, pd.ID(), "Layer already exists")
|
|
|
- return nil
|
|
|
+ return descriptor, nil
|
|
|
}
|
|
|
pd.pushState.Unlock()
|
|
|
|
|
@@ -257,14 +258,14 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
|
descriptor, exists, err := layerAlreadyExists(ctx, v2Metadata, pd.repoInfo, pd.repo, pd.pushState)
|
|
|
if err != nil {
|
|
|
progress.Update(progressOutput, pd.ID(), "Image push failed")
|
|
|
- return retryOnError(err)
|
|
|
+ return distribution.Descriptor{}, retryOnError(err)
|
|
|
}
|
|
|
if exists {
|
|
|
progress.Update(progressOutput, pd.ID(), "Layer already exists")
|
|
|
pd.pushState.Lock()
|
|
|
pd.pushState.remoteLayers[diffID] = descriptor
|
|
|
pd.pushState.Unlock()
|
|
|
- return nil
|
|
|
+ return descriptor, nil
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -328,9 +329,9 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
|
|
|
|
// Cache mapping from this layer's DiffID to the blobsum
|
|
|
if err := pd.v2MetadataService.Add(diffID, metadata.V2Metadata{Digest: mountFrom.Digest, SourceRepository: pd.repoInfo.FullName()}); err != nil {
|
|
|
- return xfer.DoNotRetry{Err: err}
|
|
|
+ return distribution.Descriptor{}, xfer.DoNotRetry{Err: err}
|
|
|
}
|
|
|
- return nil
|
|
|
+ return err.Descriptor, nil
|
|
|
case nil:
|
|
|
// blob upload session created successfully, so begin the upload
|
|
|
mountAttemptsRemaining = 0
|
|
@@ -345,14 +346,14 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
|
if layerUpload == nil {
|
|
|
layerUpload, err = bs.Create(ctx)
|
|
|
if err != nil {
|
|
|
- return retryOnError(err)
|
|
|
+ return distribution.Descriptor{}, retryOnError(err)
|
|
|
}
|
|
|
}
|
|
|
defer layerUpload.Close()
|
|
|
|
|
|
arch, err := pd.layer.TarStream()
|
|
|
if err != nil {
|
|
|
- return xfer.DoNotRetry{Err: err}
|
|
|
+ return distribution.Descriptor{}, xfer.DoNotRetry{Err: err}
|
|
|
}
|
|
|
|
|
|
// don't care if this fails; best effort
|
|
@@ -371,12 +372,12 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
|
nn, err := layerUpload.ReadFrom(tee)
|
|
|
compressedReader.Close()
|
|
|
if err != nil {
|
|
|
- return retryOnError(err)
|
|
|
+ return distribution.Descriptor{}, retryOnError(err)
|
|
|
}
|
|
|
|
|
|
pushDigest := digester.Digest()
|
|
|
if _, err := layerUpload.Commit(ctx, distribution.Descriptor{Digest: pushDigest}); err != nil {
|
|
|
- return retryOnError(err)
|
|
|
+ return distribution.Descriptor{}, retryOnError(err)
|
|
|
}
|
|
|
|
|
|
logrus.Debugf("uploaded layer %s (%s), %d bytes", diffID, pushDigest, nn)
|
|
@@ -384,7 +385,7 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
|
|
|
|
// Cache mapping from this layer's DiffID to the blobsum
|
|
|
if err := pd.v2MetadataService.Add(diffID, metadata.V2Metadata{Digest: pushDigest, SourceRepository: pd.repoInfo.FullName()}); err != nil {
|
|
|
- return xfer.DoNotRetry{Err: err}
|
|
|
+ return distribution.Descriptor{}, xfer.DoNotRetry{Err: err}
|
|
|
}
|
|
|
|
|
|
pd.pushState.Lock()
|
|
@@ -393,23 +394,24 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
|
// speaks the v2 protocol.
|
|
|
pd.pushState.confirmedV2 = true
|
|
|
|
|
|
- pd.pushState.remoteLayers[diffID] = distribution.Descriptor{
|
|
|
+ descriptor := distribution.Descriptor{
|
|
|
Digest: pushDigest,
|
|
|
MediaType: schema2.MediaTypeLayer,
|
|
|
Size: nn,
|
|
|
}
|
|
|
+ pd.pushState.remoteLayers[diffID] = descriptor
|
|
|
|
|
|
pd.pushState.Unlock()
|
|
|
|
|
|
- return nil
|
|
|
+ return descriptor, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (pd *v2PushDescriptor) SetRemoteDescriptor(descriptor distribution.Descriptor) {
|
|
|
+ pd.remoteDescriptor = descriptor
|
|
|
}
|
|
|
|
|
|
func (pd *v2PushDescriptor) Descriptor() distribution.Descriptor {
|
|
|
- // Not necessary to lock pushStatus because this is always
|
|
|
- // called after all the mutation in pushStatus.
|
|
|
- // By the time this function is called, every layer will have
|
|
|
- // an entry in remoteLayers.
|
|
|
- return pd.pushState.remoteLayers[pd.DiffID()]
|
|
|
+ return pd.remoteDescriptor
|
|
|
}
|
|
|
|
|
|
// layerAlreadyExists checks if the registry already know about any of the
|