func()

in ecr/layer_writer.go [157:203]


func (lw *layerWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
	log.G(lw.ctx).WithField("size", size).WithField("expected", expected).Debug("ecr.layer.commit")
	lw.buf.Close()
	select {
	case err := <-lw.err:
		if err != nil {
			log.G(lw.ctx).
				WithError(err).
				WithField("expected", expected).
				Error("ecr.layer.commit: error while uploading parts")
			return err
		}
	case <-lw.ctx.Done():
	}

	completeLayerUploadInput := &ecr.CompleteLayerUploadInput{
		RegistryId:     aws.String(lw.base.ecrSpec.Registry()),
		RepositoryName: aws.String(lw.base.ecrSpec.Repository),
		UploadId:       aws.String(lw.uploadID),
		LayerDigests:   []*string{aws.String(expected.String())},
	}

	completeLayerUploadOutput, err := lw.base.client.CompleteLayerUpload(completeLayerUploadInput)
	if err != nil {
		// If the layer that is being uploaded already exists then return successfully instead of failing. Unfortunately
		// in this case we do not get the digest back from ECR, but if the client-provided digest starts with a
		// "sha256:" then the ECR has validated that the digest provided matches ours. If the expected digest uses a
		// different algorithm we have to fail as we do not know the digest ECR calculated and the expected digest
		// has not been validated.
		awsErr, ok := err.(awserr.Error)
		if ok && awsErr.Code() == "LayerAlreadyExistsException" && strings.HasPrefix(expected.String(), "sha256:") {
			log.G(lw.ctx).Debug("ecr.layer.commit: layer already exists")
			return nil
		} else {
			return err
		}
	}
	actualDigest := aws.StringValue(completeLayerUploadOutput.LayerDigest)
	if actualDigest != expected.String() {
		return errors.New("ecr: failed to validate uploaded digest")
	}
	log.G(ctx).
		WithField("expected", expected).
		WithField("actual", actualDigest).
		Debug("ecr.layer.commit: complete")
	return nil
}