Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new [lfs_client].BATCH_SIZE and [server].LFS_MAX_BATCH_SIZE config settings. #32307

Merged
merged 3 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,10 @@ RUN_USER = ; git
;; Maximum number of locks returned per page
;LFS_LOCKS_PAGING_NUM = 50
;;
;; When clients make lfs batch requests, reject them if there are more pointers than this number
;; zero means 'unlimited'
;LFS_MAX_BATCH_SIZE = 0
;;
;; Allow graceful restarts using SIGHUP to fork
;ALLOW_GRACEFUL_RESTARTS = true
;;
Expand Down Expand Up @@ -2638,6 +2642,10 @@ LEVEL = Info
;; override the azure blob base path if storage type is azureblob
;AZURE_BLOB_BASE_PATH = lfs/

;[lfs_client]
;; When mirroring an upstream lfs endpoint, limit the number of pointers in each batch request to this number
;BATCH_SIZE = 20

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; settings for packages, will override storage setting
Expand Down
5 changes: 2 additions & 3 deletions modules/lfs/http_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ import (
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/proxy"
"code.gitea.io/gitea/modules/setting"
)

const httpBatchSize = 20

// HTTPClient is used to communicate with the LFS server
// https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md
type HTTPClient struct {
Expand All @@ -30,7 +29,7 @@ type HTTPClient struct {

// BatchSize returns the preferred size of batchs to process
func (c *HTTPClient) BatchSize() int {
return httpBatchSize
return setting.LFSClient.BatchSize
lunny marked this conversation as resolved.
Show resolved Hide resolved
}

func newHTTPClient(endpoint *url.URL, httpTransport *http.Transport) *HTTPClient {
Expand Down
21 changes: 17 additions & 4 deletions modules/setting/lfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,32 @@ import (
"code.gitea.io/gitea/modules/generate"
)

// LFS represents the configuration for Git LFS
// LFS represents the server-side configuration for Git LFS.
// Ideally these options should be in a section like "[lfs_server]",
// but they are in "[server]" section due to historical reasons.
// Could be refactored in the future while keeping backwards compatibility.
var LFS = struct {
StartServer bool `ini:"LFS_START_SERVER"`
AllowPureSSH bool `ini:"LFS_ALLOW_PURE_SSH"`
JWTSecretBytes []byte `ini:"-"`
HTTPAuthExpiry time.Duration `ini:"LFS_HTTP_AUTH_EXPIRY"`
MaxFileSize int64 `ini:"LFS_MAX_FILE_SIZE"`
LocksPagingNum int `ini:"LFS_LOCKS_PAGING_NUM"`
MaxBatchSize int `ini:"LFS_MAX_BATCH_SIZE"`

Storage *Storage
}{}

// LFSClient represents configuration for Gitea's LFS clients, for example: mirroring upstream Git LFS
var LFSClient = struct {
BatchSize int `ini:"BATCH_SIZE"`
}{}

func loadLFSFrom(rootCfg ConfigProvider) error {
mustMapSetting(rootCfg, "lfs_client", &LFSClient)

mustMapSetting(rootCfg, "server", &LFS)
sec := rootCfg.Section("server")
if err := sec.MapTo(&LFS); err != nil {
return fmt.Errorf("failed to map LFS settings: %v", err)
}
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved

lfsSec, _ := rootCfg.GetSection("lfs")

Expand All @@ -53,6 +62,10 @@ func loadLFSFrom(rootCfg ConfigProvider) error {
LFS.LocksPagingNum = 50
}

if LFSClient.BatchSize < 1 {
LFSClient.BatchSize = 20
}

LFS.HTTPAuthExpiry = sec.Key("LFS_HTTP_AUTH_EXPIRY").MustDuration(24 * time.Hour)

if !LFS.StartServer || !InstallLock {
Expand Down
16 changes: 16 additions & 0 deletions modules/setting/lfs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,19 @@ STORAGE_TYPE = minio
assert.EqualValues(t, "gitea", LFS.Storage.MinioConfig.Bucket)
assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
}

func Test_LFSClientServerConfigs(t *testing.T) {
iniStr := `
[server]
LFS_MAX_BATCH_SIZE = 100
[lfs_client]
# will default to 20
BATCH_SIZE = 0
`
cfg, err := NewConfigProviderFromData(iniStr)
assert.NoError(t, err)

assert.NoError(t, loadLFSFrom(cfg))
assert.EqualValues(t, 100, LFS.MaxBatchSize)
assert.EqualValues(t, 20, LFSClient.BatchSize)
}
5 changes: 5 additions & 0 deletions services/lfs/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ func BatchHandler(ctx *context.Context) {
return
}

if setting.LFS.MaxBatchSize != 0 && len(br.Objects) > setting.LFS.MaxBatchSize {
writeStatus(ctx, http.StatusRequestEntityTooLarge)
return
}

contentStore := lfs_module.NewContentStore()

var responseObjects []*lfs_module.ObjectResponse
Expand Down
Loading