Skip to content

Commit 39ba0d2

Browse files
committed
fix
1 parent bbee652 commit 39ba0d2

File tree

6 files changed

+118
-64
lines changed

6 files changed

+118
-64
lines changed

models/packages/container/search.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,33 +70,34 @@ func (opts *BlobSearchOptions) toConds() builder.Cond {
7070
// GetContainerBlob gets the container blob matching the blob search options
7171
// If multiple matching blobs are found (manifests with the same digest) the first (according to the database) is selected.
7272
func GetContainerBlob(ctx context.Context, opts *BlobSearchOptions) (*packages.PackageFileDescriptor, error) {
73-
pfds, err := getContainerBlobsLimit(ctx, opts, 1)
73+
pfds, err := GetContainerBlobs(ctx, opts)
7474
if err != nil {
7575
return nil, err
7676
}
77-
if len(pfds) != 1 {
77+
if len(pfds) == 0 {
7878
return nil, ErrContainerBlobNotExist
7979
}
80-
81-
return pfds[0], nil
80+
pfd := pfds[0]
81+
if opts.IsManifest {
82+
// FIXME: old data doesn't have IsLead set, so we try to find the lead manifest, otherwise we just return the first one
83+
for _, v := range pfds {
84+
if v.File.IsLead {
85+
pfd = v
86+
break
87+
}
88+
}
89+
}
90+
return pfd, nil
8291
}
8392

8493
// GetContainerBlobs gets the container blobs matching the blob search options
8594
func GetContainerBlobs(ctx context.Context, opts *BlobSearchOptions) ([]*packages.PackageFileDescriptor, error) {
86-
return getContainerBlobsLimit(ctx, opts, 0)
87-
}
88-
89-
func getContainerBlobsLimit(ctx context.Context, opts *BlobSearchOptions, limit int) ([]*packages.PackageFileDescriptor, error) {
90-
pfs := make([]*packages.PackageFile, 0, limit)
95+
pfs := make([]*packages.PackageFile, 0)
9196
sess := db.GetEngine(ctx).
9297
Join("INNER", "package_version", "package_version.id = package_file.version_id").
9398
Join("INNER", "package", "package.id = package_version.package_id").
9499
Where(opts.toConds())
95100

96-
if limit > 0 {
97-
sess = sess.Limit(limit)
98-
}
99-
100101
if err := sess.Find(&pfs); err != nil {
101102
return nil, err
102103
}

models/packages/package_file.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ func DeleteFileByID(ctx context.Context, fileID int64) error {
115115
return err
116116
}
117117

118+
func UpdateFile(ctx context.Context, pf *PackageFile, cols []string) error {
119+
_, err := db.GetEngine(ctx).ID(pf.ID).Cols(cols...).Update(pf)
120+
return err
121+
}
122+
118123
// PackageFileSearchOptions are options for SearchXXX methods
119124
type PackageFileSearchOptions struct {
120125
OwnerID int64

models/packages/package_property.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ func UpdateProperty(ctx context.Context, pp *PackageProperty) error {
6666
return err
6767
}
6868

69+
func InsertOrUpdateProperty(ctx context.Context, refType PropertyType, refID int64, name, value string) error {
70+
pp := PackageProperty{RefType: refType, RefID: refID, Name: name}
71+
ok, err := db.GetEngine(ctx).Get(&pp)
72+
if err != nil {
73+
return err
74+
}
75+
if ok {
76+
_, err = db.GetEngine(ctx).Where("ref_type=? AND ref_id=? AND name=?", refType, refID, name).Cols("value").Update(&PackageProperty{Value: value})
77+
return err
78+
}
79+
_, err = InsertProperty(ctx, refType, refID, name, value)
80+
return err
81+
}
82+
6983
// DeleteAllProperties deletes all properties of a ref
7084
func DeleteAllProperties(ctx context.Context, refType PropertyType, refID int64) error {
7185
_, err := db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ?", refType, refID).Delete(&PackageProperty{})

routers/api/packages/container/manifest.go

Lines changed: 74 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"io"
1111
"os"
1212
"strings"
13+
"time"
1314

1415
"code.gitea.io/gitea/models/db"
1516
packages_model "code.gitea.io/gitea/models/packages"
@@ -23,19 +24,19 @@ import (
2324
notify_service "code.gitea.io/gitea/services/notify"
2425
packages_service "code.gitea.io/gitea/services/packages"
2526

26-
digest "github.com/opencontainers/go-digest"
27+
"github.com/opencontainers/go-digest"
2728
oci "github.com/opencontainers/image-spec/specs-go/v1"
2829
)
2930

30-
func isValidMediaType(mt string) bool {
31+
func isMediaTypeValid(mt string) bool {
3132
return strings.HasPrefix(mt, "application/vnd.docker.") || strings.HasPrefix(mt, "application/vnd.oci.")
3233
}
3334

34-
func isImageManifestMediaType(mt string) bool {
35+
func isMediaTypeImageManifest(mt string) bool {
3536
return strings.EqualFold(mt, oci.MediaTypeImageManifest) || strings.EqualFold(mt, "application/vnd.docker.distribution.manifest.v2+json")
3637
}
3738

38-
func isImageIndexMediaType(mt string) bool {
39+
func isMediaTypeImageIndex(mt string) bool {
3940
return strings.EqualFold(mt, oci.MediaTypeImageIndex) || strings.EqualFold(mt, "application/vnd.docker.distribution.manifest.list.v2+json")
4041
}
4142

@@ -64,22 +65,22 @@ func processManifest(ctx context.Context, mci *manifestCreationInfo, buf *packag
6465
return "", err
6566
}
6667

67-
if !isValidMediaType(mci.MediaType) {
68+
if !isMediaTypeValid(mci.MediaType) {
6869
mci.MediaType = index.MediaType
69-
if !isValidMediaType(mci.MediaType) {
70+
if !isMediaTypeValid(mci.MediaType) {
7071
return "", errManifestInvalid.WithMessage("MediaType not recognized")
7172
}
7273
}
7374

74-
if isImageManifestMediaType(mci.MediaType) {
75-
return processImageManifest(ctx, mci, buf)
76-
} else if isImageIndexMediaType(mci.MediaType) {
77-
return processImageManifestIndex(ctx, mci, buf)
75+
if isMediaTypeImageManifest(mci.MediaType) {
76+
return processOciImageManifest(ctx, mci, buf)
77+
} else if isMediaTypeImageIndex(mci.MediaType) {
78+
return processOciImageIndex(ctx, mci, buf)
7879
}
7980
return "", errManifestInvalid
8081
}
8182

82-
func processImageManifest(ctx context.Context, mci *manifestCreationInfo, buf *packages_module.HashedBuffer) (string, error) {
83+
func processOciImageManifest(ctx context.Context, mci *manifestCreationInfo, buf *packages_module.HashedBuffer) (string, error) {
8384
manifestDigest := ""
8485

8586
err := func() error {
@@ -156,7 +157,7 @@ func processImageManifest(ctx context.Context, mci *manifestCreationInfo, buf *p
156157
}
157158

158159
for _, ref := range blobReferences {
159-
if err := createFileFromBlobReference(ctx, pv, uploadVersion, ref); err != nil {
160+
if _, err = createFileFromBlobReference(ctx, pv, uploadVersion, ref); err != nil {
160161
return err
161162
}
162163
}
@@ -196,7 +197,7 @@ func processImageManifest(ctx context.Context, mci *manifestCreationInfo, buf *p
196197
return manifestDigest, nil
197198
}
198199

199-
func processImageManifestIndex(ctx context.Context, mci *manifestCreationInfo, buf *packages_module.HashedBuffer) (string, error) {
200+
func processOciImageIndex(ctx context.Context, mci *manifestCreationInfo, buf *packages_module.HashedBuffer) (string, error) {
200201
manifestDigest := ""
201202

202203
err := func() error {
@@ -221,7 +222,7 @@ func processImageManifestIndex(ctx context.Context, mci *manifestCreationInfo, b
221222
}
222223

223224
for _, manifest := range index.Manifests {
224-
if !isImageManifestMediaType(manifest.MediaType) {
225+
if !isMediaTypeImageManifest(manifest.MediaType) {
225226
return errManifestInvalid
226227
}
227228

@@ -349,24 +350,31 @@ func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, met
349350
LowerVersion: strings.ToLower(mci.Reference),
350351
MetadataJSON: string(metadataJSON),
351352
}
352-
var pv *packages_model.PackageVersion
353-
if pv, err = packages_model.GetOrInsertVersion(ctx, _pv); err != nil {
353+
pv, err := packages_model.GetOrInsertVersion(ctx, _pv)
354+
if err != nil {
354355
if !errors.Is(err, packages_model.ErrDuplicatePackageVersion) {
355356
log.Error("Error inserting package: %v", err)
356357
return nil, err
357358
}
358359

359-
if err = packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil {
360-
return nil, err
361-
}
362-
363-
// keep download count on overwrite
364-
_pv.DownloadCount = pv.DownloadCount
365-
366-
if pv, err = packages_model.GetOrInsertVersion(ctx, _pv); err != nil {
367-
if !errors.Is(err, packages_model.ErrDuplicatePackageVersion) {
368-
log.Error("Error inserting package: %v", err)
369-
return nil, err
360+
if isMediaTypeImageIndex(mci.MediaType) {
361+
if pv.CreatedUnix.AsTime().Before(time.Now().Add(-24 * time.Hour)) {
362+
if err = packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil {
363+
return nil, err
364+
}
365+
// keep download count on overwriting
366+
_pv.DownloadCount = pv.DownloadCount
367+
if pv, err = packages_model.GetOrInsertVersion(ctx, _pv); err != nil {
368+
if !errors.Is(err, packages_model.ErrDuplicatePackageVersion) {
369+
log.Error("Error inserting package: %v", err)
370+
return nil, err
371+
}
372+
}
373+
} else {
374+
err = packages_model.UpdateVersion(ctx, &packages_model.PackageVersion{ID: pv.ID, MetadataJSON: _pv.MetadataJSON})
375+
if err != nil {
376+
return nil, err
377+
}
370378
}
371379
}
372380
}
@@ -376,14 +384,12 @@ func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, met
376384
}
377385

378386
if mci.IsTagged {
379-
if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypeVersion, pv.ID, container_module.PropertyManifestTagged, ""); err != nil {
380-
log.Error("Error setting package version property: %v", err)
387+
if err = packages_model.InsertOrUpdateProperty(ctx, packages_model.PropertyTypeVersion, pv.ID, container_module.PropertyManifestTagged, ""); err != nil {
381388
return nil, err
382389
}
383390
}
384391
for _, manifest := range metadata.Manifests {
385-
if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypeVersion, pv.ID, container_module.PropertyManifestReference, manifest.Digest); err != nil {
386-
log.Error("Error setting package version property: %v", err)
392+
if err = packages_model.InsertOrUpdateProperty(ctx, packages_model.PropertyTypeVersion, pv.ID, container_module.PropertyManifestReference, manifest.Digest); err != nil {
387393
return nil, err
388394
}
389395
}
@@ -400,30 +406,33 @@ type blobReference struct {
400406
IsLead bool
401407
}
402408

403-
func createFileFromBlobReference(ctx context.Context, pv, uploadVersion *packages_model.PackageVersion, ref *blobReference) error {
409+
func createFileFromBlobReference(ctx context.Context, pv, uploadVersion *packages_model.PackageVersion, ref *blobReference) (*packages_model.PackageFile, error) {
404410
if ref.File.Blob.Size != ref.ExpectedSize {
405-
return errSizeInvalid
411+
return nil, errSizeInvalid
406412
}
407413

408414
if ref.Name == "" {
409415
ref.Name = strings.ToLower("sha256_" + ref.File.Blob.HashSHA256)
410416
}
411417

412418
pf := &packages_model.PackageFile{
413-
VersionID: pv.ID,
414-
BlobID: ref.File.Blob.ID,
415-
Name: ref.Name,
416-
LowerName: ref.Name,
417-
IsLead: ref.IsLead,
419+
VersionID: pv.ID,
420+
BlobID: ref.File.Blob.ID,
421+
Name: ref.Name,
422+
LowerName: ref.Name,
423+
CompositeKey: string(ref.Digest),
424+
// FIXME: old data doesn't have this field set, so we can't use it unless there is a migration fix
425+
// at the moment, there is a workaround in GetContainerBlob to tolerate this
426+
IsLead: ref.IsLead,
418427
}
419428
var err error
420429
if pf, err = packages_model.TryInsertFile(ctx, pf); err != nil {
421430
if errors.Is(err, packages_model.ErrDuplicatePackageFile) {
422431
// Skip this blob because the manifest contains the same filesystem layer multiple times.
423-
return nil
432+
return pf, nil
424433
}
425434
log.Error("Error inserting package file: %v", err)
426-
return err
435+
return nil, err
427436
}
428437

429438
props := map[string]string{
@@ -433,18 +442,18 @@ func createFileFromBlobReference(ctx context.Context, pv, uploadVersion *package
433442
for name, value := range props {
434443
if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypeFile, pf.ID, name, value); err != nil {
435444
log.Error("Error setting package file property: %v", err)
436-
return err
445+
return nil, err
437446
}
438447
}
439448

440-
// Remove the file from the blob upload version
449+
// Remove the ref file (old file) from the blob upload version
441450
if uploadVersion != nil && ref.File.File != nil && uploadVersion.ID == ref.File.File.VersionID {
442451
if err := packages_service.DeletePackageFile(ctx, ref.File.File); err != nil {
443-
return err
452+
return nil, err
444453
}
445454
}
446455

447-
return nil
456+
return pf, nil
448457
}
449458

450459
func createManifestBlob(ctx context.Context, mci *manifestCreationInfo, pv *packages_model.PackageVersion, buf *packages_module.HashedBuffer) (*packages_model.PackageBlob, bool, string, error) {
@@ -471,14 +480,34 @@ func createManifestBlob(ctx context.Context, mci *manifestCreationInfo, pv *pack
471480
}
472481

473482
manifestDigest := digestFromHashSummer(buf)
474-
err = createFileFromBlobReference(ctx, pv, nil, &blobReference{
483+
pf, err := createFileFromBlobReference(ctx, pv, nil, &blobReference{
475484
Digest: digest.Digest(manifestDigest),
476485
MediaType: mci.MediaType,
477486
Name: container_model.ManifestFilename,
478487
File: &packages_model.PackageFileDescriptor{Blob: pb},
479488
ExpectedSize: pb.Size,
480489
IsLead: true,
481490
})
491+
if err != nil {
492+
return nil, false, "", err
493+
}
482494

495+
oldManifestFiles, _, err := packages_model.SearchFiles(ctx, &packages_model.PackageFileSearchOptions{
496+
OwnerID: mci.Owner.ID,
497+
PackageType: packages_model.TypeContainer,
498+
VersionID: pv.ID,
499+
Query: container_model.ManifestFilename,
500+
})
501+
if err != nil {
502+
return nil, false, "", err
503+
}
504+
for _, oldManifestFile := range oldManifestFiles {
505+
if oldManifestFile.ID != pf.ID && oldManifestFile.IsLead {
506+
err = packages_model.UpdateFile(ctx, &packages_model.PackageFile{ID: oldManifestFile.ID, IsLead: false}, []string{"is_lead"})
507+
if err != nil {
508+
return nil, false, "", err
509+
}
510+
}
511+
}
483512
return pb, !exists, manifestDigest, err
484513
}

templates/package/content/container.tmpl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,17 @@
1616
</div>
1717
<div class="field">
1818
<label>{{svg "octicon-code"}} {{ctx.Locale.Tr "packages.container.digest"}}</label>
19-
<div class="markup"><pre class="code-block"><code>{{range .PackageDescriptor.Files}}{{if eq .File.LowerName "manifest.json"}}{{.Properties.GetByName "container.digest"}}{{end}}{{end}}</code></pre></div>
19+
<div class="markup">
20+
<div class="code-block-container code-overflow-scroll">
21+
<pre class="code-block code-overflow-scroll"><code>
22+
{{- range .PackageDescriptor.Files -}}
23+
{{- if eq .File.LowerName "manifest.json" -}}
24+
{{- .Properties.GetByName "container.digest" -}}<br>
25+
{{- end -}}
26+
{{- end -}}
27+
</code></pre>
28+
</div>
29+
</div>
2030
</div>
2131
<div class="field">
2232
<label>{{ctx.Locale.Tr "packages.registry.documentation" "Container" "https://docs.gitea.com/usage/packages/container/"}}</label>

web_src/css/markup/content.css

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -446,11 +446,6 @@
446446
border-radius: var(--border-radius);
447447
}
448448

449-
.markup code br,
450-
.markup tt br {
451-
display: none;
452-
}
453-
454449
.markup del code {
455450
text-decoration: inherit;
456451
}

0 commit comments

Comments
 (0)