mirror of
https://github.com/go-gitea/gitea
synced 2024-07-27 17:17:08 +02:00
Compare commits
8 Commits
53b45a67f1
...
880a01229b
Author | SHA1 | Date | |
---|---|---|---|
|
880a01229b | ||
|
a40192dc12 | ||
|
e1cf760d2f | ||
|
4809a17acc | ||
|
f9c6d23d3f | ||
|
c1f7ad456e | ||
|
7255b500d9 | ||
|
f99db66c18 |
60
modules/lfs/errors.go
Normal file
60
modules/lfs/errors.go
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package lfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ErrLFS struct {
|
||||
OID string
|
||||
Err error
|
||||
}
|
||||
|
||||
type ErrLFSDownload struct {
|
||||
ErrLFS
|
||||
}
|
||||
|
||||
type ErrLFSUpload struct {
|
||||
ErrLFS
|
||||
}
|
||||
|
||||
type ErrLFSVerify struct {
|
||||
ErrLFS
|
||||
}
|
||||
|
||||
func (e *ErrLFS) Error() string {
|
||||
return fmt.Sprintf("LFS error for object %s: %v", e.OID, e.Err)
|
||||
}
|
||||
|
||||
func (e *ErrLFS) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
func (e *ErrLFSDownload) Error() string {
|
||||
return fmt.Sprintf("LFS error while downloading [%s]: %s", e.OID, e.Err)
|
||||
}
|
||||
|
||||
func (e *ErrLFSUpload) Error() string {
|
||||
return fmt.Sprintf("LFS error while uploading [%s]: %s", e.OID, e.Err)
|
||||
}
|
||||
|
||||
func (e *ErrLFSVerify) Error() string {
|
||||
return fmt.Sprintf("LFS error while verifying [%s]: %s", e.OID, e.Err)
|
||||
}
|
||||
|
||||
func (e *ErrLFSDownload) Is(target error) bool {
|
||||
_, ok := target.(*ErrLFSDownload)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (e *ErrLFSUpload) Is(target error) bool {
|
||||
_, ok := target.(*ErrLFSUpload)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (e *ErrLFSVerify) Is(target error) bool {
|
||||
_, ok := target.(*ErrLFSVerify)
|
||||
return ok
|
||||
}
|
|
@ -71,9 +71,12 @@ func (c *HTTPClient) batch(ctx context.Context, operation string, objects []Poin
|
|||
|
||||
url := fmt.Sprintf("%s/objects/batch", c.endpoint)
|
||||
|
||||
request := &BatchRequest{operation, c.transferNames(), nil, objects}
|
||||
payload := new(bytes.Buffer)
|
||||
err := json.NewEncoder(payload).Encode(request)
|
||||
err := json.NewEncoder(payload).Encode(&BatchRequest{
|
||||
Operation: operation,
|
||||
Transfers: c.transferNames(),
|
||||
Objects: objects,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("Error encoding json: %v", err)
|
||||
return nil, err
|
||||
|
@ -134,15 +137,19 @@ func (c *HTTPClient) performOperation(ctx context.Context, objects []Pointer, dc
|
|||
return fmt.Errorf("TransferAdapter not found: %s", result.Transfer)
|
||||
}
|
||||
|
||||
var resultErrors []error
|
||||
for _, object := range result.Objects {
|
||||
if object.Error != nil {
|
||||
objectError := errors.New(object.Error.Message)
|
||||
log.Trace("Error on object %v: %v", object.Pointer, objectError)
|
||||
log.Trace("Error on object %v: %v", object.Pointer, object.Error.Message)
|
||||
if uc != nil {
|
||||
objectError := &ErrLFSUpload{ErrLFS{OID: object.Oid, Err: object.Error}}
|
||||
resultErrors = append(resultErrors, objectError)
|
||||
if _, err := uc(object.Pointer, objectError); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
objectError := &ErrLFSDownload{ErrLFS{OID: object.Oid, Err: object.Error}}
|
||||
resultErrors = append(resultErrors, objectError)
|
||||
if err := dc(object.Pointer, nil, objectError); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -164,20 +171,35 @@ func (c *HTTPClient) performOperation(ctx context.Context, objects []Pointer, dc
|
|||
|
||||
content, err := uc(object.Pointer, nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, &ErrLFSUpload{}) {
|
||||
resultErrors = append(resultErrors, err)
|
||||
continue
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = transferAdapter.Upload(ctx, link, object.Pointer, content)
|
||||
if err != nil {
|
||||
if errors.Is(err, &ErrLFSUpload{}) {
|
||||
resultErrors = append(resultErrors, err)
|
||||
continue
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
link, ok = object.Actions["verify"]
|
||||
if ok {
|
||||
if err := transferAdapter.Verify(ctx, link, object.Pointer); err != nil {
|
||||
if errors.Is(err, &ErrLFSVerify{}) {
|
||||
resultErrors = append(resultErrors, err)
|
||||
continue
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
link, ok := object.Actions["download"]
|
||||
if !ok {
|
||||
|
@ -191,16 +213,26 @@ func (c *HTTPClient) performOperation(ctx context.Context, objects []Pointer, dc
|
|||
|
||||
content, err := transferAdapter.Download(ctx, link)
|
||||
if err != nil {
|
||||
if errors.Is(err, &ErrLFSDownload{}) {
|
||||
resultErrors = append(resultErrors, err)
|
||||
continue
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := dc(object.Pointer, content, nil); err != nil {
|
||||
if errors.Is(err, &ErrLFSDownload{}) {
|
||||
resultErrors = append(resultErrors, err)
|
||||
continue
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return errors.Join(resultErrors...)
|
||||
}
|
||||
|
||||
// createRequest creates a new request, and sets the headers.
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package lfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -64,6 +65,10 @@ type ObjectError struct {
|
|||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (oe *ObjectError) Error() string {
|
||||
return fmt.Sprintf("code: %d, message: %s", oe.Code, oe.Message)
|
||||
}
|
||||
|
||||
// PointerBlob associates a Git blob with a Pointer.
|
||||
type PointerBlob struct {
|
||||
Hash string
|
||||
|
|
|
@ -5,6 +5,7 @@ package repository
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
@ -178,9 +179,16 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re
|
|||
errChan := make(chan error, 1)
|
||||
go lfs.SearchPointerBlobs(ctx, gitRepo, pointerChan, errChan)
|
||||
|
||||
var lfsDownloadErrors []error
|
||||
|
||||
downloadObjects := func(pointers []lfs.Pointer) error {
|
||||
err := lfsClient.Download(ctx, pointers, func(p lfs.Pointer, content io.ReadCloser, objectError error) error {
|
||||
if objectError != nil {
|
||||
if errors.Is(objectError, &lfs.ErrLFSDownload{}) {
|
||||
log.Trace("Repo[%-v]: Ignoring LFS error: %v", repo, objectError)
|
||||
lfsDownloadErrors = append(lfsDownloadErrors, objectError)
|
||||
return nil
|
||||
}
|
||||
return objectError
|
||||
}
|
||||
|
||||
|
@ -208,10 +216,13 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re
|
|||
default:
|
||||
}
|
||||
}
|
||||
if errors.Is(err, &lfs.ErrLFSDownload{}) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var batch []lfs.Pointer
|
||||
var downloadBatch []lfs.Pointer
|
||||
for pointerBlob := range pointerChan {
|
||||
meta, err := git_model.GetLFSMetaObjectByOid(ctx, repo.ID, pointerBlob.Oid)
|
||||
if err != nil && err != git_model.ErrLFSObjectNotExist {
|
||||
|
@ -233,28 +244,32 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re
|
|||
|
||||
if exist {
|
||||
log.Trace("Repo[%-v]: LFS object %-v already present; creating meta object", repo, pointerBlob.Pointer)
|
||||
_, err := git_model.NewLFSMetaObject(ctx, repo.ID, pointerBlob.Pointer)
|
||||
m, err := git_model.NewLFSMetaObject(ctx, repo.ID, pointerBlob.Pointer)
|
||||
if err != nil {
|
||||
log.Error("Repo[%-v]: Error creating LFS meta object %-v: %v", repo, pointerBlob.Pointer, err)
|
||||
return err
|
||||
}
|
||||
if m.Existing {
|
||||
log.Trace("Repo[%-v]: LFS meta object %-v was already present", repo, m)
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
if setting.LFS.MaxFileSize > 0 && pointerBlob.Size > setting.LFS.MaxFileSize {
|
||||
log.Info("Repo[%-v]: LFS object %-v download denied because of LFS_MAX_FILE_SIZE=%d < size %d", repo, pointerBlob.Pointer, setting.LFS.MaxFileSize, pointerBlob.Size)
|
||||
continue
|
||||
}
|
||||
|
||||
batch = append(batch, pointerBlob.Pointer)
|
||||
if len(batch) >= lfsClient.BatchSize() {
|
||||
if err := downloadObjects(batch); err != nil {
|
||||
downloadBatch = append(downloadBatch, pointerBlob.Pointer)
|
||||
if len(downloadBatch) >= lfsClient.BatchSize() {
|
||||
if err := downloadObjects(downloadBatch); err != nil {
|
||||
return err
|
||||
}
|
||||
batch = nil
|
||||
downloadBatch = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(batch) > 0 {
|
||||
if err := downloadObjects(batch); err != nil {
|
||||
if len(downloadBatch) > 0 {
|
||||
if err := downloadObjects(downloadBatch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +280,7 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re
|
|||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return errors.Join(lfsDownloadErrors...)
|
||||
}
|
||||
|
||||
// shortRelease to reduce load memory, this struct can replace repo_model.Release
|
||||
|
|
|
@ -2981,6 +2981,10 @@ emails.not_updated=Falhou a modificação do endereço de email solicitado: %v
|
|||
emails.duplicate_active=Este endereço de email já está a ser usado por outro utilizador.
|
||||
emails.change_email_header=Modificar propriedades do email
|
||||
emails.change_email_text=Tem a certeza que quer modificar este endereço de email?
|
||||
emails.delete=Eliminar email
|
||||
emails.delete_desc=Tem a certeza que quer eliminar este endereço de email?
|
||||
emails.deletion_success=O endereço de email foi eliminado.
|
||||
emails.delete_primary_email_error=Não pode eliminar o email principal.
|
||||
|
||||
orgs.org_manage_panel=Gestão das organizações
|
||||
orgs.name=Nome
|
||||
|
|
|
@ -327,7 +327,7 @@ func getOAuthGroupsForUser(ctx go_context.Context, user *user_model.User) ([]str
|
|||
|
||||
func parseBasicAuth(ctx *context.Context) (username, password string, err error) {
|
||||
authHeader := ctx.Req.Header.Get("Authorization")
|
||||
if authType, authData, ok := strings.Cut(authHeader, " "); ok && authType == "Basic" {
|
||||
if authType, authData, ok := strings.Cut(authHeader, " "); ok && strings.EqualFold(authType, "Basic") {
|
||||
return base.BasicAuthDecode(authData)
|
||||
}
|
||||
return "", "", errors.New("invalid basic authentication")
|
||||
|
@ -661,7 +661,7 @@ func AccessTokenOAuth(ctx *context.Context) {
|
|||
// if there is no ClientID or ClientSecret in the request body, fill these fields by the Authorization header and ensure the provided field matches the Authorization header
|
||||
if form.ClientID == "" || form.ClientSecret == "" {
|
||||
authHeader := ctx.Req.Header.Get("Authorization")
|
||||
if authType, authData, ok := strings.Cut(authHeader, " "); ok && authType == "Basic" {
|
||||
if authType, authData, ok := strings.Cut(authHeader, " "); ok && strings.EqualFold(authType, "Basic") {
|
||||
clientID, clientSecret, err := base.BasicAuthDecode(authData)
|
||||
if err != nil {
|
||||
handleAccessTokenError(ctx, AccessTokenError{
|
||||
|
|
|
@ -169,6 +169,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
|||
lfsClient := lfs.NewClient(endpoint, httpTransport)
|
||||
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil {
|
||||
log.Error("Failed to store missing LFS objects for repository: %v", err)
|
||||
// TODO: check for lfs.ErrLFSDownload errors and display them
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user