Skip to content

Commit a76aa77

Browse files
committed
Allow reupload of inconsistent layers.
Prevent multiple upload version creation.
1 parent 20385b5 commit a76aa77

File tree

4 files changed

+79
-4
lines changed

4 files changed

+79
-4
lines changed

modules/packages/content_store.go

+7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ func (s *ContentStore) Get(key BlobHash256Key) (storage.Object, error) {
3232
return s.store.Open(KeyToRelativePath(key))
3333
}
3434

35+
// FIXME: Workaround to be removed in v1.20
36+
// https://github.com/go-gitea/gitea/issues/19586
37+
func (s *ContentStore) Has(key BlobHash256Key) error {
38+
_, err := s.store.Stat(KeyToRelativePath(key))
39+
return err
40+
}
41+
3542
// Save stores a package blob
3643
func (s *ContentStore) Save(key BlobHash256Key, r io.Reader, size int64) error {
3744
_, err := s.store.Save(KeyToRelativePath(key), r, size)

routers/api/packages/container/blob.go

+29-1
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,24 @@ package container
77
import (
88
"context"
99
"encoding/hex"
10+
"errors"
1011
"fmt"
12+
"os"
1113
"strings"
14+
"sync"
1215

1316
"code.gitea.io/gitea/models/db"
1417
packages_model "code.gitea.io/gitea/models/packages"
1518
container_model "code.gitea.io/gitea/models/packages/container"
1619
"code.gitea.io/gitea/modules/log"
1720
packages_module "code.gitea.io/gitea/modules/packages"
1821
container_module "code.gitea.io/gitea/modules/packages/container"
22+
"code.gitea.io/gitea/modules/util"
1923
packages_service "code.gitea.io/gitea/services/packages"
2024
)
2125

26+
var uploadVersionMutex sync.Mutex
27+
2228
// saveAsPackageBlob creates a package blob from an upload
2329
// The uploaded blob gets stored in a special upload version to link them to the package/image
2430
func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_service.PackageInfo) (*packages_model.PackageBlob, error) {
@@ -28,6 +34,9 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic
2834

2935
contentStore := packages_module.NewContentStore()
3036

37+
var uploadVersion *packages_model.PackageVersion
38+
39+
uploadVersionMutex.Lock()
3140
err := db.WithTx(db.DefaultContext, func(ctx context.Context) error {
3241
created := true
3342
p := &packages_model.Package{
@@ -68,11 +77,30 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic
6877
}
6978
}
7079

80+
uploadVersion = pv
81+
82+
return nil
83+
})
84+
uploadVersionMutex.Unlock()
85+
if err != nil {
86+
return nil, err
87+
}
88+
89+
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
7190
pb, exists, err = packages_model.GetOrInsertBlob(ctx, pb)
7291
if err != nil {
7392
log.Error("Error inserting package blob: %v", err)
7493
return err
7594
}
95+
// FIXME: Workaround to be removed in v1.20
96+
// https://github.com/go-gitea/gitea/issues/19586
97+
if exists {
98+
err = contentStore.Has(packages_module.BlobHash256Key(pb.HashSHA256))
99+
if err != nil && (errors.Is(err, util.ErrNotExist) || errors.Is(err, os.ErrNotExist)) {
100+
log.Debug("Package registry inconsistent: blob %s does not exist on file system", pb.HashSHA256)
101+
exists = false
102+
}
103+
}
76104
if !exists {
77105
if err := contentStore.Save(packages_module.BlobHash256Key(pb.HashSHA256), hsr, hsr.Size()); err != nil {
78106
log.Error("Error saving package blob in content store: %v", err)
@@ -83,7 +111,7 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic
83111
filename := strings.ToLower(fmt.Sprintf("sha256_%s", pb.HashSHA256))
84112

85113
pf := &packages_model.PackageFile{
86-
VersionID: pv.ID,
114+
VersionID: uploadVersion.ID,
87115
BlobID: pb.ID,
88116
Name: filename,
89117
LowerName: filename,

routers/api/packages/container/container.go

+31-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"io"
1111
"net/http"
1212
"net/url"
13+
"os"
1314
"regexp"
1415
"strconv"
1516
"strings"
@@ -24,6 +25,7 @@ import (
2425
container_module "code.gitea.io/gitea/modules/packages/container"
2526
"code.gitea.io/gitea/modules/packages/container/oci"
2627
"code.gitea.io/gitea/modules/setting"
28+
"code.gitea.io/gitea/modules/util"
2729
"code.gitea.io/gitea/routers/api/packages/helper"
2830
packages_service "code.gitea.io/gitea/services/packages"
2931
container_service "code.gitea.io/gitea/services/packages/container"
@@ -193,7 +195,7 @@ func InitiateUploadBlob(ctx *context.Context) {
193195
mount := ctx.FormTrim("mount")
194196
from := ctx.FormTrim("from")
195197
if mount != "" {
196-
blob, _ := container_model.GetContainerBlob(ctx, &container_model.BlobSearchOptions{
198+
blob, _ := workaroundGetContainerBlob(ctx, &container_model.BlobSearchOptions{
197199
Image: from,
198200
Digest: mount,
199201
})
@@ -406,7 +408,7 @@ func getBlobFromContext(ctx *context.Context) (*packages_model.PackageFileDescri
406408
return nil, container_model.ErrContainerBlobNotExist
407409
}
408410

409-
return container_model.GetContainerBlob(ctx, &container_model.BlobSearchOptions{
411+
return workaroundGetContainerBlob(ctx, &container_model.BlobSearchOptions{
410412
OwnerID: ctx.Package.Owner.ID,
411413
Image: ctx.Params("image"),
412414
Digest: digest,
@@ -548,7 +550,7 @@ func getManifestFromContext(ctx *context.Context) (*packages_model.PackageFileDe
548550
return nil, container_model.ErrContainerBlobNotExist
549551
}
550552

551-
return container_model.GetContainerBlob(ctx, opts)
553+
return workaroundGetContainerBlob(ctx, opts)
552554
}
553555

554556
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#checking-if-content-exists-in-the-registry
@@ -688,3 +690,29 @@ func GetTagList(ctx *context.Context) {
688690
Tags: tags,
689691
})
690692
}
693+
694+
// FIXME: Workaround to be removed in v1.20
695+
// https://github.com/go-gitea/gitea/issues/19586
696+
func workaroundGetContainerBlob(ctx *context.Context, opts *container_model.BlobSearchOptions) (*packages_model.PackageFileDescriptor, error) {
697+
log.Error("workaroundGetContainerBlob")
698+
blob, err := container_model.GetContainerBlob(ctx, opts)
699+
if err != nil {
700+
return nil, err
701+
}
702+
703+
log.Error("%#v %v", blob, err)
704+
705+
err = packages_module.NewContentStore().Has(packages_module.BlobHash256Key(blob.Blob.HashSHA256))
706+
log.Error("stat %#v", err)
707+
if err != nil {
708+
if errors.Is(err, util.ErrNotExist) || errors.Is(err, os.ErrNotExist) {
709+
log.Error("jup")
710+
log.Debug("Package registry inconsistent: blob %s does not exist on file system", blob.Blob.HashSHA256)
711+
return nil, container_model.ErrContainerBlobNotExist
712+
}
713+
return nil, err
714+
}
715+
716+
log.Error("ok")
717+
return blob, nil
718+
}

routers/api/packages/container/manifest.go

+12
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ package container
66

77
import (
88
"context"
9+
"errors"
910
"fmt"
1011
"io"
12+
"os"
1113
"strings"
1214

1315
"code.gitea.io/gitea/models/db"
@@ -19,6 +21,7 @@ import (
1921
packages_module "code.gitea.io/gitea/modules/packages"
2022
container_module "code.gitea.io/gitea/modules/packages/container"
2123
"code.gitea.io/gitea/modules/packages/container/oci"
24+
"code.gitea.io/gitea/modules/util"
2225
packages_service "code.gitea.io/gitea/services/packages"
2326
)
2427

@@ -403,6 +406,15 @@ func createManifestBlob(ctx context.Context, mci *manifestCreationInfo, pv *pack
403406
log.Error("Error inserting package blob: %v", err)
404407
return nil, false, "", err
405408
}
409+
// FIXME: Workaround to be removed in v1.20
410+
// https://github.com/go-gitea/gitea/issues/19586
411+
if exists {
412+
err = packages_module.NewContentStore().Has(packages_module.BlobHash256Key(pb.HashSHA256))
413+
if err != nil && (errors.Is(err, util.ErrNotExist) || errors.Is(err, os.ErrNotExist)) {
414+
log.Debug("Package registry inconsistent: blob %s does not exist on file system", pb.HashSHA256)
415+
exists = false
416+
}
417+
}
406418
if !exists {
407419
contentStore := packages_module.NewContentStore()
408420
if err := contentStore.Save(packages_module.BlobHash256Key(pb.HashSHA256), buf, buf.Size()); err != nil {

0 commit comments

Comments
 (0)