|
@@ -42,7 +42,7 @@ type v2Pusher struct {
|
|
config *ImagePushConfig
|
|
config *ImagePushConfig
|
|
repo distribution.Repository
|
|
repo distribution.Repository
|
|
|
|
|
|
- // pushState is state built by the Download functions.
|
|
|
|
|
|
+ // pushState is state built by the Upload functions.
|
|
pushState pushState
|
|
pushState pushState
|
|
}
|
|
}
|
|
|
|
|
|
@@ -216,6 +216,7 @@ type v2PushDescriptor struct {
|
|
repoInfo reference.Named
|
|
repoInfo reference.Named
|
|
repo distribution.Repository
|
|
repo distribution.Repository
|
|
pushState *pushState
|
|
pushState *pushState
|
|
|
|
+ remoteDescriptor distribution.Descriptor
|
|
}
|
|
}
|
|
|
|
|
|
func (pd *v2PushDescriptor) Key() string {
|
|
func (pd *v2PushDescriptor) Key() string {
|
|
@@ -230,16 +231,16 @@ func (pd *v2PushDescriptor) DiffID() layer.DiffID {
|
|
return pd.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()
|
|
diffID := pd.DiffID()
|
|
|
|
|
|
pd.pushState.Lock()
|
|
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
|
|
// it is already known that the push is not needed and
|
|
// therefore doing a stat is unnecessary
|
|
// therefore doing a stat is unnecessary
|
|
pd.pushState.Unlock()
|
|
pd.pushState.Unlock()
|
|
progress.Update(progressOutput, pd.ID(), "Layer already exists")
|
|
progress.Update(progressOutput, pd.ID(), "Layer already exists")
|
|
- return nil
|
|
|
|
|
|
+ return descriptor, nil
|
|
}
|
|
}
|
|
pd.pushState.Unlock()
|
|
pd.pushState.Unlock()
|
|
|
|
|
|
@@ -249,14 +250,14 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
descriptor, exists, err := layerAlreadyExists(ctx, v2Metadata, pd.repoInfo, pd.repo, pd.pushState)
|
|
descriptor, exists, err := layerAlreadyExists(ctx, v2Metadata, pd.repoInfo, pd.repo, pd.pushState)
|
|
if err != nil {
|
|
if err != nil {
|
|
progress.Update(progressOutput, pd.ID(), "Image push failed")
|
|
progress.Update(progressOutput, pd.ID(), "Image push failed")
|
|
- return retryOnError(err)
|
|
|
|
|
|
+ return distribution.Descriptor{}, retryOnError(err)
|
|
}
|
|
}
|
|
if exists {
|
|
if exists {
|
|
progress.Update(progressOutput, pd.ID(), "Layer already exists")
|
|
progress.Update(progressOutput, pd.ID(), "Layer already exists")
|
|
pd.pushState.Lock()
|
|
pd.pushState.Lock()
|
|
pd.pushState.remoteLayers[diffID] = descriptor
|
|
pd.pushState.remoteLayers[diffID] = descriptor
|
|
pd.pushState.Unlock()
|
|
pd.pushState.Unlock()
|
|
- return nil
|
|
|
|
|
|
+ return descriptor, nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -286,7 +287,7 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
if mountFrom.SourceRepository != "" {
|
|
if mountFrom.SourceRepository != "" {
|
|
namedRef, err := reference.WithName(mountFrom.SourceRepository)
|
|
namedRef, err := reference.WithName(mountFrom.SourceRepository)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return err
|
|
|
|
|
|
+ return distribution.Descriptor{}, err
|
|
}
|
|
}
|
|
|
|
|
|
// TODO (brianbland): We need to construct a reference where the Name is
|
|
// TODO (brianbland): We need to construct a reference where the Name is
|
|
@@ -294,12 +295,12 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
// richer reference package
|
|
// richer reference package
|
|
remoteRef, err := distreference.WithName(namedRef.RemoteName())
|
|
remoteRef, err := distreference.WithName(namedRef.RemoteName())
|
|
if err != nil {
|
|
if err != nil {
|
|
- return err
|
|
|
|
|
|
+ return distribution.Descriptor{}, err
|
|
}
|
|
}
|
|
|
|
|
|
canonicalRef, err := distreference.WithDigest(remoteRef, mountFrom.Digest)
|
|
canonicalRef, err := distreference.WithDigest(remoteRef, mountFrom.Digest)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return err
|
|
|
|
|
|
+ return distribution.Descriptor{}, err
|
|
}
|
|
}
|
|
|
|
|
|
createOpts = append(createOpts, client.WithMountFrom(canonicalRef))
|
|
createOpts = append(createOpts, client.WithMountFrom(canonicalRef))
|
|
@@ -320,10 +321,10 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
|
|
|
|
// Cache mapping from this layer's DiffID to the blobsum
|
|
// 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 {
|
|
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
|
|
}
|
|
}
|
|
if mountFrom.SourceRepository != "" {
|
|
if mountFrom.SourceRepository != "" {
|
|
// unable to mount layer from this repository, so this source mapping is no longer valid
|
|
// unable to mount layer from this repository, so this source mapping is no longer valid
|
|
@@ -332,13 +333,13 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
}
|
|
}
|
|
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
- return retryOnError(err)
|
|
|
|
|
|
+ return distribution.Descriptor{}, retryOnError(err)
|
|
}
|
|
}
|
|
defer layerUpload.Close()
|
|
defer layerUpload.Close()
|
|
|
|
|
|
arch, err := pd.layer.TarStream()
|
|
arch, err := pd.layer.TarStream()
|
|
if err != nil {
|
|
if err != nil {
|
|
- return xfer.DoNotRetry{Err: err}
|
|
|
|
|
|
+ return distribution.Descriptor{}, xfer.DoNotRetry{Err: err}
|
|
}
|
|
}
|
|
|
|
|
|
// don't care if this fails; best effort
|
|
// don't care if this fails; best effort
|
|
@@ -357,12 +358,12 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
nn, err := layerUpload.ReadFrom(tee)
|
|
nn, err := layerUpload.ReadFrom(tee)
|
|
compressedReader.Close()
|
|
compressedReader.Close()
|
|
if err != nil {
|
|
if err != nil {
|
|
- return retryOnError(err)
|
|
|
|
|
|
+ return distribution.Descriptor{}, retryOnError(err)
|
|
}
|
|
}
|
|
|
|
|
|
pushDigest := digester.Digest()
|
|
pushDigest := digester.Digest()
|
|
if _, err := layerUpload.Commit(ctx, distribution.Descriptor{Digest: pushDigest}); err != nil {
|
|
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)
|
|
logrus.Debugf("uploaded layer %s (%s), %d bytes", diffID, pushDigest, nn)
|
|
@@ -370,7 +371,7 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
|
|
|
|
// Cache mapping from this layer's DiffID to the blobsum
|
|
// 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 {
|
|
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()
|
|
pd.pushState.Lock()
|
|
@@ -379,23 +380,24 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
|
|
// speaks the v2 protocol.
|
|
// speaks the v2 protocol.
|
|
pd.pushState.confirmedV2 = true
|
|
pd.pushState.confirmedV2 = true
|
|
|
|
|
|
- pd.pushState.remoteLayers[diffID] = distribution.Descriptor{
|
|
|
|
|
|
+ descriptor := distribution.Descriptor{
|
|
Digest: pushDigest,
|
|
Digest: pushDigest,
|
|
MediaType: schema2.MediaTypeLayer,
|
|
MediaType: schema2.MediaTypeLayer,
|
|
Size: nn,
|
|
Size: nn,
|
|
}
|
|
}
|
|
|
|
+ pd.pushState.remoteLayers[diffID] = descriptor
|
|
|
|
|
|
pd.pushState.Unlock()
|
|
pd.pushState.Unlock()
|
|
|
|
|
|
- return nil
|
|
|
|
|
|
+ return descriptor, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (pd *v2PushDescriptor) SetRemoteDescriptor(descriptor distribution.Descriptor) {
|
|
|
|
+ pd.remoteDescriptor = descriptor
|
|
}
|
|
}
|
|
|
|
|
|
func (pd *v2PushDescriptor) Descriptor() distribution.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
|
|
// layerAlreadyExists checks if the registry already know about any of the
|