Skip to content

Commit 1a3fa0d

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Workaround for container registry push/pull errors (go-gitea#21862) Fix scroll over mermaid frame (go-gitea#21925) Add support for HEAD requests in Maven registry (go-gitea#21834) Fix button in branch list, avoid unexpected page jump before restore branch actually done (go-gitea#21562) Fix typo in sidebar (go-gitea#21922) Fix table misalignments and tweak webhook and githook lists (go-gitea#21917)
2 parents 490381a + a1ae83f commit 1a3fa0d

File tree

30 files changed

+294
-69
lines changed

30 files changed

+294
-69
lines changed

docs/content/doc/packages/vagrant.en-us.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ toc: false
77
menu:
88
sidebar:
99
parent: "packages"
10-
name: "vagrant"
10+
name: "Vagrant"
1111
weight: 120
1212
identifier: "vagrant"
1313
---

modules/context/context.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,11 @@ func (ctx *Context) RespHeader() http.Header {
349349
type ServeHeaderOptions struct {
350350
ContentType string // defaults to "application/octet-stream"
351351
ContentTypeCharset string
352+
ContentLength *int64
352353
Disposition string // defaults to "attachment"
353354
Filename string
354355
CacheDuration time.Duration // defaults to 5 minutes
356+
LastModified time.Time
355357
}
356358

357359
// SetServeHeaders sets necessary content serve headers
@@ -369,6 +371,10 @@ func (ctx *Context) SetServeHeaders(opts *ServeHeaderOptions) {
369371
header.Set("Content-Type", contentType)
370372
header.Set("X-Content-Type-Options", "nosniff")
371373

374+
if opts.ContentLength != nil {
375+
header.Set("Content-Length", strconv.FormatInt(*opts.ContentLength, 10))
376+
}
377+
372378
if opts.Filename != "" {
373379
disposition := opts.Disposition
374380
if disposition == "" {
@@ -385,14 +391,16 @@ func (ctx *Context) SetServeHeaders(opts *ServeHeaderOptions) {
385391
duration = 5 * time.Minute
386392
}
387393
httpcache.AddCacheControlToHeader(header, duration)
394+
395+
if !opts.LastModified.IsZero() {
396+
header.Set("Last-Modified", opts.LastModified.UTC().Format(http.TimeFormat))
397+
}
388398
}
389399

390400
// ServeContent serves content to http request
391-
func (ctx *Context) ServeContent(name string, r io.ReadSeeker, modTime time.Time) {
392-
ctx.SetServeHeaders(&ServeHeaderOptions{
393-
Filename: name,
394-
})
395-
http.ServeContent(ctx.Resp, ctx.Req, name, modTime, r)
401+
func (ctx *Context) ServeContent(r io.ReadSeeker, opts *ServeHeaderOptions) {
402+
ctx.SetServeHeaders(opts)
403+
http.ServeContent(ctx.Resp, ctx.Req, opts.Filename, opts.LastModified, r)
396404
}
397405

398406
// UploadStream returns the request body or the first form file

modules/packages/content_store.go

Lines changed: 7 additions & 0 deletions
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/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ func CommonRoutes(ctx gocontext.Context) *web.Route {
181181
r.Group("/maven", func() {
182182
r.Put("/*", reqPackageAccess(perm.AccessModeWrite), maven.UploadPackageFile)
183183
r.Get("/*", maven.DownloadPackageFile)
184+
r.Head("/*", maven.ProvidePackageFileHeader)
184185
}, reqPackageAccess(perm.AccessModeRead))
185186
r.Group("/nuget", func() {
186187
r.Group("", func() { // Needs to be unauthenticated for the NuGet client.

routers/api/packages/composer/composer.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,10 @@ func DownloadPackageFile(ctx *context.Context) {
184184
}
185185
defer s.Close()
186186

187-
ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime())
187+
ctx.ServeContent(s, &context.ServeHeaderOptions{
188+
Filename: pf.Name,
189+
LastModified: pf.CreatedUnix.AsLocalTime(),
190+
})
188191
}
189192

190193
// UploadPackage creates a new package

routers/api/packages/conan/conan.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,10 @@ func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKe
477477
}
478478
defer s.Close()
479479

480-
ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime())
480+
ctx.ServeContent(s, &context.ServeHeaderOptions{
481+
Filename: pf.Name,
482+
LastModified: pf.CreatedUnix.AsLocalTime(),
483+
})
481484
}
482485

483486
// DeleteRecipeV1 deletes the requested recipe(s)

routers/api/packages/container/blob.go

Lines changed: 31 additions & 1 deletion
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,11 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic
2834

2935
contentStore := packages_module.NewContentStore()
3036

37+
var uploadVersion *packages_model.PackageVersion
38+
39+
// FIXME: Replace usage of mutex with database transaction
40+
// https://github.com/go-gitea/gitea/pull/21862
41+
uploadVersionMutex.Lock()
3142
err := db.WithTx(db.DefaultContext, func(ctx context.Context) error {
3243
created := true
3344
p := &packages_model.Package{
@@ -68,11 +79,30 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic
6879
}
6980
}
7081

82+
uploadVersion = pv
83+
84+
return nil
85+
})
86+
uploadVersionMutex.Unlock()
87+
if err != nil {
88+
return nil, err
89+
}
90+
91+
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
7192
pb, exists, err = packages_model.GetOrInsertBlob(ctx, pb)
7293
if err != nil {
7394
log.Error("Error inserting package blob: %v", err)
7495
return err
7596
}
97+
// FIXME: Workaround to be removed in v1.20
98+
// https://github.com/go-gitea/gitea/issues/19586
99+
if exists {
100+
err = contentStore.Has(packages_module.BlobHash256Key(pb.HashSHA256))
101+
if err != nil && (errors.Is(err, util.ErrNotExist) || errors.Is(err, os.ErrNotExist)) {
102+
log.Debug("Package registry inconsistent: blob %s does not exist on file system", pb.HashSHA256)
103+
exists = false
104+
}
105+
}
76106
if !exists {
77107
if err := contentStore.Save(packages_module.BlobHash256Key(pb.HashSHA256), hsr, hsr.Size()); err != nil {
78108
log.Error("Error saving package blob in content store: %v", err)
@@ -83,7 +113,7 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic
83113
filename := strings.ToLower(fmt.Sprintf("sha256_%s", pb.HashSHA256))
84114

85115
pf := &packages_model.PackageFile{
86-
VersionID: pv.ID,
116+
VersionID: uploadVersion.ID,
87117
BlobID: pb.ID,
88118
Name: filename,
89119
LowerName: filename,

routers/api/packages/container/container.go

Lines changed: 25 additions & 3 deletions
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,23 @@ 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+
blob, err := container_model.GetContainerBlob(ctx, opts)
698+
if err != nil {
699+
return nil, err
700+
}
701+
702+
err = packages_module.NewContentStore().Has(packages_module.BlobHash256Key(blob.Blob.HashSHA256))
703+
if err != nil {
704+
if errors.Is(err, util.ErrNotExist) || errors.Is(err, os.ErrNotExist) {
705+
log.Debug("Package registry inconsistent: blob %s does not exist on file system", blob.Blob.HashSHA256)
706+
return nil, container_model.ErrContainerBlobNotExist
707+
}
708+
return nil, err
709+
}
710+
711+
return blob, nil
712+
}

routers/api/packages/container/manifest.go

Lines changed: 12 additions & 0 deletions
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 {

routers/api/packages/generic/generic.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ func DownloadPackageFile(ctx *context.Context) {
5353
}
5454
defer s.Close()
5555

56-
ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime())
56+
ctx.ServeContent(s, &context.ServeHeaderOptions{
57+
Filename: pf.Name,
58+
LastModified: pf.CreatedUnix.AsLocalTime(),
59+
})
5760
}
5861

5962
// UploadPackage uploads the specific generic package.

0 commit comments

Comments
 (0)