From 9ce5e092f3f0e0048c49419c4ccd886e817a764f Mon Sep 17 00:00:00 2001 From: silverwind Date: Thu, 24 Nov 2022 21:56:57 +0100 Subject: [PATCH 1/6] Fix scroll over mermaid frame (#21925) When starting a scroll while the mouse is over a mermaid diagram, the scroll sometimes propagates to the iframe, preventing the parent page from scrolling. Fix this by disabling scroll inside the iframe. This is not a problem because those frames are never meant to scroll. Bug seems to affect Firefox only. ![scroll](https://user-images.githubusercontent.com/115237/203847578-6831e3c8-9df4-4577-8501-822fb9ea1278.gif) --- web_src/js/markup/mermaid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/js/markup/mermaid.js b/web_src/js/markup/mermaid.js index 984946045d..efd9abbb56 100644 --- a/web_src/js/markup/mermaid.js +++ b/web_src/js/markup/mermaid.js @@ -3,7 +3,7 @@ const {mermaidMaxSourceCharacters} = window.config; const iframeCss = ` :root {color-scheme: normal} - body {margin: 0; padding: 0} + body {margin: 0; padding: 0; overflow: hidden} #mermaid {display: block; margin: 0 auto} `; From a1ae83f36ece5e37c738bd796227cf5990ccc030 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Fri, 25 Nov 2022 06:47:46 +0100 Subject: [PATCH 2/6] Workaround for container registry push/pull errors (#21862) This PR addresses #19586 I added a mutex to the upload version creation which will prevent the push errors when two requests try to create these database entries. I'm not sure if this should be the final solution for this problem. I added a workaround to allow a reupload of missing blobs. Normally a reupload is skipped because the database knows the blob is already present. The workaround checks if the blob exists on the file system. This should not be needed anymore with the above fix so I marked this code to be removed with Gitea v1.20. Co-authored-by: Lunny Xiao --- modules/packages/content_store.go | 7 ++++ routers/api/packages/container/blob.go | 32 ++++++++++++++++++- routers/api/packages/container/container.go | 28 ++++++++++++++-- routers/api/packages/container/manifest.go | 12 +++++++ .../api_packages_container_test.go | 28 ++++++++++++++++ 5 files changed, 103 insertions(+), 4 deletions(-) diff --git a/modules/packages/content_store.go b/modules/packages/content_store.go index be416ac269..13763db986 100644 --- a/modules/packages/content_store.go +++ b/modules/packages/content_store.go @@ -32,6 +32,13 @@ func (s *ContentStore) Get(key BlobHash256Key) (storage.Object, error) { return s.store.Open(KeyToRelativePath(key)) } +// FIXME: Workaround to be removed in v1.20 +// https://github.com/go-gitea/gitea/issues/19586 +func (s *ContentStore) Has(key BlobHash256Key) error { + _, err := s.store.Stat(KeyToRelativePath(key)) + return err +} + // Save stores a package blob func (s *ContentStore) Save(key BlobHash256Key, r io.Reader, size int64) error { _, err := s.store.Save(KeyToRelativePath(key), r, size) diff --git a/routers/api/packages/container/blob.go b/routers/api/packages/container/blob.go index df6b7aed92..06b450de02 100644 --- a/routers/api/packages/container/blob.go +++ b/routers/api/packages/container/blob.go @@ -7,8 +7,11 @@ package container import ( "context" "encoding/hex" + "errors" "fmt" + "os" "strings" + "sync" "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" @@ -16,9 +19,12 @@ import ( "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" container_module "code.gitea.io/gitea/modules/packages/container" + "code.gitea.io/gitea/modules/util" packages_service "code.gitea.io/gitea/services/packages" ) +var uploadVersionMutex sync.Mutex + // saveAsPackageBlob creates a package blob from an upload // The uploaded blob gets stored in a special upload version to link them to the package/image 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 contentStore := packages_module.NewContentStore() + var uploadVersion *packages_model.PackageVersion + + // FIXME: Replace usage of mutex with database transaction + // https://github.com/go-gitea/gitea/pull/21862 + uploadVersionMutex.Lock() err := db.WithTx(db.DefaultContext, func(ctx context.Context) error { created := true p := &packages_model.Package{ @@ -68,11 +79,30 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic } } + uploadVersion = pv + + 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) @@ -83,7 +113,7 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic filename := strings.ToLower(fmt.Sprintf("sha256_%s", pb.HashSHA256)) pf := &packages_model.PackageFile{ - VersionID: pv.ID, + VersionID: uploadVersion.ID, BlobID: pb.ID, Name: filename, LowerName: filename, diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 5bc64e1b29..7af06a9171 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -10,6 +10,7 @@ import ( "io" "net/http" "net/url" + "os" "regexp" "strconv" "strings" @@ -24,6 +25,7 @@ import ( container_module "code.gitea.io/gitea/modules/packages/container" "code.gitea.io/gitea/modules/packages/container/oci" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" container_service "code.gitea.io/gitea/services/packages/container" @@ -193,7 +195,7 @@ func InitiateUploadBlob(ctx *context.Context) { mount := ctx.FormTrim("mount") from := ctx.FormTrim("from") if mount != "" { - blob, _ := container_model.GetContainerBlob(ctx, &container_model.BlobSearchOptions{ + blob, _ := workaroundGetContainerBlob(ctx, &container_model.BlobSearchOptions{ Image: from, Digest: mount, }) @@ -406,7 +408,7 @@ func getBlobFromContext(ctx *context.Context) (*packages_model.PackageFileDescri return nil, container_model.ErrContainerBlobNotExist } - return container_model.GetContainerBlob(ctx, &container_model.BlobSearchOptions{ + return workaroundGetContainerBlob(ctx, &container_model.BlobSearchOptions{ OwnerID: ctx.Package.Owner.ID, Image: ctx.Params("image"), Digest: digest, @@ -548,7 +550,7 @@ func getManifestFromContext(ctx *context.Context) (*packages_model.PackageFileDe return nil, container_model.ErrContainerBlobNotExist } - return container_model.GetContainerBlob(ctx, opts) + return workaroundGetContainerBlob(ctx, opts) } // 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) { Tags: tags, }) } + +// FIXME: Workaround to be removed in v1.20 +// https://github.com/go-gitea/gitea/issues/19586 +func workaroundGetContainerBlob(ctx *context.Context, opts *container_model.BlobSearchOptions) (*packages_model.PackageFileDescriptor, error) { + blob, err := container_model.GetContainerBlob(ctx, opts) + if err != nil { + return nil, err + } + + err = packages_module.NewContentStore().Has(packages_module.BlobHash256Key(blob.Blob.HashSHA256)) + if err != nil { + if errors.Is(err, util.ErrNotExist) || errors.Is(err, os.ErrNotExist) { + log.Debug("Package registry inconsistent: blob %s does not exist on file system", blob.Blob.HashSHA256) + return nil, container_model.ErrContainerBlobNotExist + } + return nil, err + } + + return blob, nil +} diff --git a/routers/api/packages/container/manifest.go b/routers/api/packages/container/manifest.go index a48b1de3b2..64c958c2d0 100644 --- a/routers/api/packages/container/manifest.go +++ b/routers/api/packages/container/manifest.go @@ -6,8 +6,10 @@ package container import ( "context" + "errors" "fmt" "io" + "os" "strings" "code.gitea.io/gitea/models/db" @@ -19,6 +21,7 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" container_module "code.gitea.io/gitea/modules/packages/container" "code.gitea.io/gitea/modules/packages/container/oci" + "code.gitea.io/gitea/modules/util" packages_service "code.gitea.io/gitea/services/packages" ) @@ -403,6 +406,15 @@ func createManifestBlob(ctx context.Context, mci *manifestCreationInfo, pv *pack log.Error("Error inserting package blob: %v", err) return nil, false, "", err } + // FIXME: Workaround to be removed in v1.20 + // https://github.com/go-gitea/gitea/issues/19586 + if exists { + err = packages_module.NewContentStore().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 { contentStore := packages_module.NewContentStore() if err := contentStore.Save(packages_module.BlobHash256Key(pb.HashSHA256), buf, buf.Size()); err != nil { diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go index ba76ee4baa..60cbecd067 100644 --- a/tests/integration/api_packages_container_test.go +++ b/tests/integration/api_packages_container_test.go @@ -6,10 +6,12 @@ package integration import ( "bytes" + "crypto/sha256" "encoding/base64" "fmt" "net/http" "strings" + "sync" "testing" "code.gitea.io/gitea/models/db" @@ -594,6 +596,32 @@ func TestPackageContainer(t *testing.T) { }) } + // https://github.com/go-gitea/gitea/issues/19586 + t.Run("ParallelUpload", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + url := fmt.Sprintf("%sv2/%s/parallel", setting.AppURL, user.Name) + + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + + content := []byte{byte(i)} + digest := fmt.Sprintf("sha256:%x", sha256.Sum256(content)) + + go func() { + defer wg.Done() + + req := NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, digest), bytes.NewReader(content)) + addTokenAuthHeader(req, userToken) + resp := MakeRequest(t, req, http.StatusCreated) + + assert.Equal(t, digest, resp.Header().Get("Docker-Content-Digest")) + }() + } + wg.Wait() + }) + t.Run("OwnerNameChange", func(t *testing.T) { defer tests.PrintCurrentTest(t)() From b91167b77230b891a38e21f83926341b641ca525 Mon Sep 17 00:00:00 2001 From: Percy Ma Date: Fri, 25 Nov 2022 14:37:02 +0800 Subject: [PATCH 3/6] fix(web): keep the pages of the navigation in the center (#21867) Keep the pages of the navigation in the center
Before After
image image
Co-authored-by: Lunny Xiao Co-authored-by: John Olheiser --- templates/base/paginate.tmpl | 2 +- web_src/less/helpers.less | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/base/paginate.tmpl b/templates/base/paginate.tmpl index ebca1b2be4..1ed6970983 100644 --- a/templates/base/paginate.tmpl +++ b/templates/base/paginate.tmpl @@ -15,7 +15,7 @@ {{if eq .Num -1}} ... {{else}} - {{.Num}} + {{.Num}} {{end}} {{end}} diff --git a/web_src/less/helpers.less b/web_src/less/helpers.less index f475693926..46284811ee 100644 --- a/web_src/less/helpers.less +++ b/web_src/less/helpers.less @@ -172,6 +172,8 @@ .py-4 { padding-top: 1rem !important; padding-bottom: 1rem !important; } .py-5 { padding-top: 2rem !important; padding-bottom: 2rem !important; } +.content-center { align-content: center !important; } + @media @mediaSm { .db-small { display: block !important; } .w-100-small { width: 100% !important; } From 7a4f7b35e341218015f8b09d2a8e960839409265 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Fri, 25 Nov 2022 10:52:23 +0100 Subject: [PATCH 4/6] Fix typo in sidebar (#21934) Same as #21922 I used the npm file as template which was a bad idea to spot these casing errors... --- docs/content/doc/packages/storage.en-us.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/doc/packages/storage.en-us.md b/docs/content/doc/packages/storage.en-us.md index c922496a99..b04a7595f7 100644 --- a/docs/content/doc/packages/storage.en-us.md +++ b/docs/content/doc/packages/storage.en-us.md @@ -7,7 +7,7 @@ toc: false menu: sidebar: parent: "packages" - name: "storage" + name: "Storage" weight: 5 identifier: "storage" --- From abecf632d2886149474471a0e41e14dc3e15340e Mon Sep 17 00:00:00 2001 From: Meisam <39205857+MFTabriz@users.noreply.github.com> Date: Fri, 25 Nov 2022 16:33:37 +0100 Subject: [PATCH 5/6] add rel="me" to org.website link (#21941) This lets organizations verify their link on 3rd party websites. --- templates/org/home.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl index 358f045bc6..6474204493 100644 --- a/templates/org/home.tmpl +++ b/templates/org/home.tmpl @@ -16,7 +16,7 @@ {{if $.RenderedDescription}}

{{$.RenderedDescription|Str2html}}

{{end}}
From d7f12af805e33e327ec0c7a250ad8ed09a88e8fd Mon Sep 17 00:00:00 2001 From: zeripath Date: Fri, 25 Nov 2022 20:58:20 +0000 Subject: [PATCH 6/6] Prevent NPE if trying to restore an already restored deleted branch (#21940) If a deleted-branch has already been restored, a request to restore it again will cause a NPE. This PR adds detection for this case, but also disables buttons when they're clicked in order to help prevent accidental repeat requests. Fix #21930 Signed-off-by: Andrew Thornton --- routers/web/repo/branch.go | 4 ++++ web_src/js/features/common-global.js | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index a7588d275d..43e6d43134 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -126,6 +126,10 @@ func RestoreBranchPost(ctx *context.Context) { log.Error("GetDeletedBranchByID: %v", err) ctx.Flash.Error(ctx.Tr("repo.branch.restore_failed", branchName)) return + } else if deletedBranch == nil { + log.Debug("RestoreBranch: Can't restore branch[%d] '%s', as it does not exist", branchID, branchName) + ctx.Flash.Error(ctx.Tr("repo.branch.restore_failed", branchName)) + return } if err := git.Push(ctx, ctx.Repo.Repository.RepoPath(), git.PushOptions{ diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js index b00b4aea9c..7efefd7084 100644 --- a/web_src/js/features/common-global.js +++ b/web_src/js/features/common-global.js @@ -260,6 +260,7 @@ export function initGlobalLinkActions() { e.preventDefault(); const $this = $(this); const redirect = $this.data('redirect'); + $this.prop('disabled', true); $.post($this.data('url'), { _csrf: csrfToken }).done((data) => { @@ -270,6 +271,8 @@ export function initGlobalLinkActions() { } else { window.location.reload(); } + }).always(() => { + $this.prop('disabled', false); }); } @@ -283,11 +286,14 @@ export function initGlobalLinkActions() { // FIXME: this is only used once, and should be replace with `link-action` instead $('.undo-button').on('click', function () { const $this = $(this); + $this.prop('disabled', true); $.post($this.data('url'), { _csrf: csrfToken, id: $this.data('id') }).done((data) => { window.location.href = data.redirect; + }).always(() => { + $this.prop('disabled', false); }); }); }