diff options
author | KN4CK3R <admin@oldschoolhack.me> | 2023-01-16 23:35:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-16 17:35:48 -0500 |
commit | 3510d7e33ace5302691b6e96b9bde71148ed6e4c (patch) | |
tree | 4a1b765d478092900237b00a1bcfea0818a3e89e /routers/api | |
parent | 1aba53db62275e45209210a5bf6d830dfc2010d3 (diff) | |
download | gitea-3510d7e33ace5302691b6e96b9bde71148ed6e4c.tar.gz gitea-3510d7e33ace5302691b6e96b9bde71148ed6e4c.zip |
Fix container blob mount (#22226)
Diffstat (limited to 'routers/api')
-rw-r--r-- | routers/api/packages/container/blob.go | 129 | ||||
-rw-r--r-- | routers/api/packages/container/container.go | 9 |
2 files changed, 83 insertions, 55 deletions
diff --git a/routers/api/packages/container/blob.go b/routers/api/packages/container/blob.go index fd5819d506..2e4309a2eb 100644 --- a/routers/api/packages/container/blob.go +++ b/routers/api/packages/container/blob.go @@ -33,6 +33,60 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic contentStore := packages_module.NewContentStore() + uploadVersion, err := getOrCreateUploadVersion(pi) + if err != nil { + return nil, err + } + + err = db.WithTx(db.DefaultContext, func(ctx context.Context) error { + pb, exists, err = packages_model.GetOrInsertBlob(ctx, pb) + if err != nil { + log.Error("Error inserting package blob: %v", err) + return err + } + // FIXME: Workaround to be removed in v1.20 + // https://github.com/go-gitea/gitea/issues/19586 + if exists { + err = contentStore.Has(packages_module.BlobHash256Key(pb.HashSHA256)) + if err != nil && (errors.Is(err, util.ErrNotExist) || errors.Is(err, os.ErrNotExist)) { + log.Debug("Package registry inconsistent: blob %s does not exist on file system", pb.HashSHA256) + exists = false + } + } + if !exists { + if err := contentStore.Save(packages_module.BlobHash256Key(pb.HashSHA256), hsr, hsr.Size()); err != nil { + log.Error("Error saving package blob in content store: %v", err) + return err + } + } + + return createFileForBlob(ctx, uploadVersion, pb) + }) + if err != nil { + if !exists { + if err := contentStore.Delete(packages_module.BlobHash256Key(pb.HashSHA256)); err != nil { + log.Error("Error deleting package blob from content store: %v", err) + } + } + return nil, err + } + + return pb, nil +} + +// mountBlob mounts the specific blob to a different package +func mountBlob(pi *packages_service.PackageInfo, pb *packages_model.PackageBlob) error { + uploadVersion, err := getOrCreateUploadVersion(pi) + if err != nil { + return err + } + + return db.WithTx(db.DefaultContext, func(ctx context.Context) error { + return createFileForBlob(ctx, uploadVersion, pb) + }) +} + +func getOrCreateUploadVersion(pi *packages_service.PackageInfo) (*packages_model.PackageVersion, error) { var uploadVersion *packages_model.PackageVersion // FIXME: Replace usage of mutex with database transaction @@ -83,66 +137,35 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic return nil }) uploadVersionMutex.Unlock() - if err != nil { - return nil, err - } - - err = db.WithTx(db.DefaultContext, func(ctx context.Context) error { - pb, exists, err = packages_model.GetOrInsertBlob(ctx, pb) - if err != nil { - log.Error("Error inserting package blob: %v", err) - return err - } - // FIXME: Workaround to be removed in v1.20 - // https://github.com/go-gitea/gitea/issues/19586 - if exists { - err = contentStore.Has(packages_module.BlobHash256Key(pb.HashSHA256)) - if err != nil && (errors.Is(err, util.ErrNotExist) || errors.Is(err, os.ErrNotExist)) { - log.Debug("Package registry inconsistent: blob %s does not exist on file system", pb.HashSHA256) - exists = false - } - } - if !exists { - if err := contentStore.Save(packages_module.BlobHash256Key(pb.HashSHA256), hsr, hsr.Size()); err != nil { - log.Error("Error saving package blob in content store: %v", err) - return err - } - } - filename := strings.ToLower(fmt.Sprintf("sha256_%s", pb.HashSHA256)) + return uploadVersion, err +} - pf := &packages_model.PackageFile{ - VersionID: uploadVersion.ID, - BlobID: pb.ID, - Name: filename, - LowerName: filename, - CompositeKey: packages_model.EmptyFileKey, - } - if pf, err = packages_model.TryInsertFile(ctx, pf); err != nil { - if err == packages_model.ErrDuplicatePackageFile { - return nil - } - log.Error("Error inserting package file: %v", err) - return err - } +func createFileForBlob(ctx context.Context, pv *packages_model.PackageVersion, pb *packages_model.PackageBlob) error { + filename := strings.ToLower(fmt.Sprintf("sha256_%s", pb.HashSHA256)) - if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypeFile, pf.ID, container_module.PropertyDigest, digestFromPackageBlob(pb)); err != nil { - log.Error("Error setting package file property: %v", err) - return err + pf := &packages_model.PackageFile{ + VersionID: pv.ID, + BlobID: pb.ID, + Name: filename, + LowerName: filename, + CompositeKey: packages_model.EmptyFileKey, + } + var err error + if pf, err = packages_model.TryInsertFile(ctx, pf); err != nil { + if err == packages_model.ErrDuplicatePackageFile { + return nil } + log.Error("Error inserting package file: %v", err) + return err + } - return nil - }) - if err != nil { - if !exists { - if err := contentStore.Delete(packages_module.BlobHash256Key(pb.HashSHA256)); err != nil { - log.Error("Error deleting package blob from content store: %v", err) - } - } - return nil, err + if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypeFile, pf.ID, container_module.PropertyDigest, digestFromPackageBlob(pb)); err != nil { + log.Error("Error setting package file property: %v", err) + return err } - return pb, nil + return nil } func deleteBlob(ownerID int64, image, digest string) error { diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index cbbdf8eb88..8b2c4e6bb2 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -195,10 +195,15 @@ func InitiateUploadBlob(ctx *context.Context) { from := ctx.FormTrim("from") if mount != "" { blob, _ := workaroundGetContainerBlob(ctx, &container_model.BlobSearchOptions{ - Image: from, - Digest: mount, + Repository: from, + Digest: mount, }) if blob != nil { + if err := mountBlob(&packages_service.PackageInfo{Owner: ctx.Package.Owner, Name: image}, blob.Blob); err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + setResponseHeaders(ctx.Resp, &containerHeaders{ Location: fmt.Sprintf("/v2/%s/%s/blobs/%s", ctx.Package.Owner.LowerName, image, mount), ContentDigest: mount, |