Skip to content

Commit 02f9dd4

Browse files
rremerRoyce Remer
authored and
Royce Remer
committed
Add new [lfs_client].BATCH_SIZE and [server].LFS_MAX_BATCH_SIZE config settings.
This contains two backwards-compatible changes: * in the lfs http_client, the number of lfs oids requested per batch is loaded from lfs_client#BATCH_SIZE and defaulted to the previous value of 20 * in the lfs server/service, the max number of lfs oids allowed in a batch api request is loaded from server#LFS_MAX_BATCH_SIZE and defaults to 'nil' which equates to the previous behavior of 'infinite' This fixes #32306 Signed-off-by: Royce Remer <[email protected]>
1 parent feca880 commit 02f9dd4

File tree

5 files changed

+51
-8
lines changed

5 files changed

+51
-8
lines changed

custom/conf/app.example.ini

+8
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ RUN_USER = ; git
324324
;; Maximum number of locks returned per page
325325
;LFS_LOCKS_PAGING_NUM = 50
326326
;;
327+
;; When clients make lfs batch requests, reject them if there are more pointers than this number
328+
;; zero means 'unlimited'
329+
;LFS_MAX_BATCH_SIZE = 0
330+
;;
327331
;; Allow graceful restarts using SIGHUP to fork
328332
;ALLOW_GRACEFUL_RESTARTS = true
329333
;;
@@ -2638,6 +2642,10 @@ LEVEL = Info
26382642
;; override the azure blob base path if storage type is azureblob
26392643
;AZURE_BLOB_BASE_PATH = lfs/
26402644

2645+
;[lfs_client]
2646+
;; When mirroring an upstream lfs endpoint, limit the number of pointers in each batch request to this number
2647+
;BATCH_SIZE = 20
2648+
26412649
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26422650
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26432651
;; settings for packages, will override storage setting

modules/lfs/http_client.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ import (
1616
"code.gitea.io/gitea/modules/json"
1717
"code.gitea.io/gitea/modules/log"
1818
"code.gitea.io/gitea/modules/proxy"
19+
"code.gitea.io/gitea/modules/setting"
1920
)
2021

21-
const httpBatchSize = 20
22-
2322
// HTTPClient is used to communicate with the LFS server
2423
// https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md
2524
type HTTPClient struct {
@@ -30,7 +29,7 @@ type HTTPClient struct {
3029

3130
// BatchSize returns the preferred size of batchs to process
3231
func (c *HTTPClient) BatchSize() int {
33-
return httpBatchSize
32+
return setting.LFSClient.BatchSize
3433
}
3534

3635
func newHTTPClient(endpoint *url.URL, httpTransport *http.Transport) *HTTPClient {

modules/setting/lfs.go

+20-5
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,34 @@ import (
1010
"code.gitea.io/gitea/modules/generate"
1111
)
1212

13-
// LFS represents the configuration for Git LFS
13+
const (
14+
LFSConfigSectionServer = "server"
15+
LFSConfigSectionClient = "lfs_client"
16+
)
17+
18+
// LFS represents the legacy configuration for Git LFS, to be migrated to LFSServer
1419
var LFS = struct {
1520
StartServer bool `ini:"LFS_START_SERVER"`
1621
AllowPureSSH bool `ini:"LFS_ALLOW_PURE_SSH"`
1722
JWTSecretBytes []byte `ini:"-"`
1823
HTTPAuthExpiry time.Duration `ini:"LFS_HTTP_AUTH_EXPIRY"`
1924
MaxFileSize int64 `ini:"LFS_MAX_FILE_SIZE"`
2025
LocksPagingNum int `ini:"LFS_LOCKS_PAGING_NUM"`
26+
MaxBatchSize int `ini:"LFS_MAX_BATCH_SIZE"`
2127

2228
Storage *Storage
2329
}{}
2430

31+
// LFSClient represents configuration for mirroring upstream Git LFS
32+
var LFSClient = struct {
33+
BatchSize int `ini:"BATCH_SIZE"`
34+
}{}
35+
2536
func loadLFSFrom(rootCfg ConfigProvider) error {
26-
sec := rootCfg.Section("server")
27-
if err := sec.MapTo(&LFS); err != nil {
28-
return fmt.Errorf("failed to map LFS settings: %v", err)
29-
}
37+
mustMapSetting(rootCfg, LFSConfigSectionClient, &LFSClient)
38+
mustMapSetting(rootCfg, LFSConfigSectionServer, &LFS)
39+
40+
sec := rootCfg.Section(LFSConfigSectionServer)
3041

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

@@ -53,6 +64,10 @@ func loadLFSFrom(rootCfg ConfigProvider) error {
5364
LFS.LocksPagingNum = 50
5465
}
5566

67+
if LFSClient.BatchSize < 1 {
68+
LFSClient.BatchSize = 20
69+
}
70+
5671
LFS.HTTPAuthExpiry = sec.Key("LFS_HTTP_AUTH_EXPIRY").MustDuration(24 * time.Hour)
5772

5873
if !LFS.StartServer || !InstallLock {

modules/setting/lfs_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,19 @@ STORAGE_TYPE = minio
9999
assert.EqualValues(t, "gitea", LFS.Storage.MinioConfig.Bucket)
100100
assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
101101
}
102+
103+
func Test_LFSClientServerConfigs(t *testing.T) {
104+
iniStr := `
105+
[server]
106+
LFS_MAX_BATCH_SIZE = 100
107+
[lfs_client]
108+
# will default to 20
109+
BATCH_SIZE = 0
110+
`
111+
cfg, err := NewConfigProviderFromData(iniStr)
112+
assert.NoError(t, err)
113+
114+
assert.NoError(t, loadLFSFrom(cfg))
115+
assert.EqualValues(t, 100, LFS.MaxBatchSize)
116+
assert.EqualValues(t, 20, LFSClient.BatchSize)
117+
}

services/lfs/server.go

+5
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ func BatchHandler(ctx *context.Context) {
179179
return
180180
}
181181

182+
if setting.LFS.MaxBatchSize != 0 && len(br.Objects) > setting.LFS.MaxBatchSize {
183+
writeStatus(ctx, http.StatusRequestEntityTooLarge)
184+
return
185+
}
186+
182187
contentStore := lfs_module.NewContentStore()
183188

184189
var responseObjects []*lfs_module.ObjectResponse

0 commit comments

Comments
 (0)