Skip to content

Commit d6dd6d6

Browse files
lunnywxiaoguang
andauthored
Fix all possible setting error related storages and added some tests (#23911)
Follow up #22405 Fix #20703 This PR rewrites storage configuration read sequences with some breaks and tests. It becomes more strict than before and also fixed some inherit problems. - Move storage's MinioConfig struct into setting, so after the configuration loading, the values will be stored into the struct but not still on some section. - All storages configurations should be stored on one section, configuration items cannot be overrided by multiple sections. The prioioty of configuration is `[attachment]` > `[storage.attachments]` | `[storage.customized]` > `[storage]` > `default` - For extra override configuration items, currently are `SERVE_DIRECT`, `MINIO_BASE_PATH`, `MINIO_BUCKET`, which could be configured in another section. The prioioty of the override configuration is `[attachment]` > `[storage.attachments]` > `default`. - Add more tests for storages configurations. - Update the storage documentations. --------- Co-authored-by: wxiaoguang <[email protected]>
1 parent dc0a716 commit d6dd6d6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1154
-454
lines changed

cmd/dump.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,9 @@ func runDump(ctx *cli.Context) error {
353353
}
354354

355355
excludes = append(excludes, setting.RepoRootPath)
356-
excludes = append(excludes, setting.LFS.Path)
357-
excludes = append(excludes, setting.Attachment.Path)
358-
excludes = append(excludes, setting.Packages.Path)
356+
excludes = append(excludes, setting.LFS.Storage.Path)
357+
excludes = append(excludes, setting.Attachment.Storage.Path)
358+
excludes = append(excludes, setting.Packages.Storage.Path)
359359
excludes = append(excludes, setting.Log.RootPath)
360360
excludes = append(excludes, absFileName)
361361
if err := addRecursiveExclude(w, "data", setting.AppDataPath, excludes, verbose); err != nil {

cmd/migrate_storage.go

+15-13
Original file line numberDiff line numberDiff line change
@@ -179,30 +179,32 @@ func runMigrateStorage(ctx *cli.Context) error {
179179
switch strings.ToLower(ctx.String("storage")) {
180180
case "":
181181
fallthrough
182-
case string(storage.LocalStorageType):
182+
case string(setting.LocalStorageType):
183183
p := ctx.String("path")
184184
if p == "" {
185185
log.Fatal("Path must be given when storage is loal")
186186
return nil
187187
}
188188
dstStorage, err = storage.NewLocalStorage(
189189
stdCtx,
190-
storage.LocalStorageConfig{
190+
&setting.Storage{
191191
Path: p,
192192
})
193-
case string(storage.MinioStorageType):
193+
case string(setting.MinioStorageType):
194194
dstStorage, err = storage.NewMinioStorage(
195195
stdCtx,
196-
storage.MinioStorageConfig{
197-
Endpoint: ctx.String("minio-endpoint"),
198-
AccessKeyID: ctx.String("minio-access-key-id"),
199-
SecretAccessKey: ctx.String("minio-secret-access-key"),
200-
Bucket: ctx.String("minio-bucket"),
201-
Location: ctx.String("minio-location"),
202-
BasePath: ctx.String("minio-base-path"),
203-
UseSSL: ctx.Bool("minio-use-ssl"),
204-
InsecureSkipVerify: ctx.Bool("minio-insecure-skip-verify"),
205-
ChecksumAlgorithm: ctx.String("minio-checksum-algorithm"),
196+
&setting.Storage{
197+
MinioConfig: setting.MinioStorageConfig{
198+
Endpoint: ctx.String("minio-endpoint"),
199+
AccessKeyID: ctx.String("minio-access-key-id"),
200+
SecretAccessKey: ctx.String("minio-secret-access-key"),
201+
Bucket: ctx.String("minio-bucket"),
202+
Location: ctx.String("minio-location"),
203+
BasePath: ctx.String("minio-base-path"),
204+
UseSSL: ctx.Bool("minio-use-ssl"),
205+
InsecureSkipVerify: ctx.Bool("minio-insecure-skip-verify"),
206+
ChecksumAlgorithm: ctx.String("minio-checksum-algorithm"),
207+
},
206208
})
207209
default:
208210
return fmt.Errorf("unsupported storage type: %s", ctx.String("storage"))

cmd/migrate_storage_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"code.gitea.io/gitea/models/unittest"
1414
user_model "code.gitea.io/gitea/models/user"
1515
packages_module "code.gitea.io/gitea/modules/packages"
16+
"code.gitea.io/gitea/modules/setting"
1617
"code.gitea.io/gitea/modules/storage"
1718
packages_service "code.gitea.io/gitea/services/packages"
1819

@@ -57,7 +58,7 @@ func TestMigratePackages(t *testing.T) {
5758

5859
dstStorage, err := storage.NewLocalStorage(
5960
ctx,
60-
storage.LocalStorageConfig{
61+
&setting.Storage{
6162
Path: p,
6263
})
6364
assert.NoError(t, err)

custom/conf/app.example.ini

+21
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,10 @@ LEVEL = Info
23922392
;; Enable/Disable package registry capabilities
23932393
;ENABLED = true
23942394
;;
2395+
;STORAGE_TYPE = local
2396+
;; override the minio base path if storage type is minio
2397+
;MINIO_BASE_PATH = packages/
2398+
;;
23952399
;; Path for chunked uploads. Defaults to APP_DATA_PATH + `tmp/package-upload`
23962400
;CHUNKED_UPLOAD_PATH = tmp/package-upload
23972401
;;
@@ -2452,6 +2456,19 @@ LEVEL = Info
24522456
;; storage type
24532457
;STORAGE_TYPE = local
24542458

2459+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2460+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2461+
;; repo-archive storage will override storage
2462+
;;
2463+
;[repo-archive]
2464+
;STORAGE_TYPE = local
2465+
;;
2466+
;; Where your lfs files reside, default is data/lfs.
2467+
;PATH = data/repo-archive
2468+
;;
2469+
;; override the minio base path if storage type is minio
2470+
;MINIO_BASE_PATH = repo-archive/
2471+
24552472
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24562473
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24572474
;; settings for repository archives, will override storage setting
@@ -2471,6 +2488,9 @@ LEVEL = Info
24712488
;;
24722489
;; Where your lfs files reside, default is data/lfs.
24732490
;PATH = data/lfs
2491+
;;
2492+
;; override the minio base path if storage type is minio
2493+
;MINIO_BASE_PATH = lfs/
24742494

24752495
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24762496
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2520,6 +2540,7 @@ LEVEL = Info
25202540
; [actions]
25212541
;; Enable/Disable actions capabilities
25222542
;ENABLED = false
2543+
;;
25232544
;; Default address to get action plugins, e.g. the default value means downloading from "https://gitea.com/actions/checkout" for "uses: actions/checkout@v3"
25242545
;DEFAULT_ACTIONS_URL = https://gitea.com
25252546

docs/content/doc/administration/config-cheat-sheet.en-us.md

+57-4
Original file line numberDiff line numberDiff line change
@@ -1254,8 +1254,9 @@ is `data/lfs` and the default of `MINIO_BASE_PATH` is `lfs/`.
12541254

12551255
## Storage (`storage`)
12561256

1257-
Default storage configuration for attachments, lfs, avatars and etc.
1257+
Default storage configuration for attachments, lfs, avatars, repo-avatars, repo-archive, packages, actions_log, actions_artifact.
12581258

1259+
- `STORAGE_TYPE`: **local**: Storage type, `local` for local disk or `minio` for s3 compatible object storage service.
12591260
- `SERVE_DIRECT`: **false**: Allows the storage driver to redirect to authenticated URLs to serve files directly. Currently, only Minio/S3 is supported via signed URLs, local does nothing.
12601261
- `MINIO_ENDPOINT`: **localhost:9000**: Minio endpoint to connect only available when `STORAGE_TYPE` is `minio`
12611262
- `MINIO_ACCESS_KEY_ID`: Minio accessKeyID to connect only available when `STORAGE_TYPE` is `minio`
@@ -1265,10 +1266,10 @@ Default storage configuration for attachments, lfs, avatars and etc.
12651266
- `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
12661267
- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
12671268

1268-
And you can also define a customize storage like below:
1269+
The recommanded storage configuration for minio like below:
12691270

12701271
```ini
1271-
[storage.my_minio]
1272+
[storage]
12721273
STORAGE_TYPE = minio
12731274
; Minio endpoint to connect only available when STORAGE_TYPE is `minio`
12741275
MINIO_ENDPOINT = localhost:9000
@@ -1284,9 +1285,54 @@ MINIO_LOCATION = us-east-1
12841285
MINIO_USE_SSL = false
12851286
; Minio skip SSL verification available when STORAGE_TYPE is `minio`
12861287
MINIO_INSECURE_SKIP_VERIFY = false
1288+
SERVE_DIRECT = true
1289+
```
1290+
1291+
Defaultly every storage has their default base path like below
1292+
1293+
| storage | default base path |
1294+
| ----------------- | ------------------ |
1295+
| attachments | attachments/ |
1296+
| lfs | lfs/ |
1297+
| avatars | avatars/ |
1298+
| repo-avatars | repo-avatars/ |
1299+
| repo-archive | repo-archive/ |
1300+
| packages | packages/ |
1301+
| actions_log | actions_log/ |
1302+
| actions_artifacts | actions_artifacts/ |
1303+
1304+
And bucket, basepath or `SERVE_DIRECT` could be special or overrided, if you want to use a different you can:
1305+
1306+
```ini
1307+
[storage.actions_log]
1308+
MINIO_BUCKET = gitea_actions_log
1309+
SERVE_DIRECT = true
1310+
MINIO_BASE_PATH = my_actions_log/ ; default is actions_log/ if blank
12871311
```
12881312

1289-
And used by `[attachment]`, `[lfs]` and etc. as `STORAGE_TYPE`.
1313+
If you want to customerize a different storage for `lfs` if above default storage defined
1314+
1315+
```ini
1316+
[lfs]
1317+
STORAGE_TYPE = my_minio
1318+
1319+
[storage.my_minio]
1320+
STORAGE_TYPE = minio
1321+
; Minio endpoint to connect only available when STORAGE_TYPE is `minio`
1322+
MINIO_ENDPOINT = localhost:9000
1323+
; Minio accessKeyID to connect only available when STORAGE_TYPE is `minio`
1324+
MINIO_ACCESS_KEY_ID =
1325+
; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio`
1326+
MINIO_SECRET_ACCESS_KEY =
1327+
; Minio bucket to store the attachments only available when STORAGE_TYPE is `minio`
1328+
MINIO_BUCKET = gitea
1329+
; Minio location to create bucket only available when STORAGE_TYPE is `minio`
1330+
MINIO_LOCATION = us-east-1
1331+
; Minio enabled ssl only available when STORAGE_TYPE is `minio`
1332+
MINIO_USE_SSL = false
1333+
; Minio skip SSL verification available when STORAGE_TYPE is `minio`
1334+
MINIO_INSECURE_SKIP_VERIFY = false
1335+
```
12901336

12911337
## Repository Archive Storage (`storage.repo-archive`)
12921338

@@ -1306,6 +1352,11 @@ is `data/repo-archive` and the default of `MINIO_BASE_PATH` is `repo-archive/`.
13061352
- `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
13071353
- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
13081354

1355+
## Repository Archives (`repo-archive`)
1356+
1357+
- `STORAGE_TYPE`: **local**: Storage type for actions logs, `local` for local disk or `minio` for s3 compatible object storage service, default is `local` or other name defined with `[storage.xxx]`
1358+
- `MINIO_BASE_PATH`: **repo-archive/**: Minio base path on the bucket only available when STORAGE_TYPE is `minio`
1359+
13091360
## Proxy (`proxy`)
13101361

13111362
- `PROXY_ENABLED`: **false**: Enable the proxy if true, all requests to external via HTTP will be affected, if false, no proxy will be used even environment http_proxy/https_proxy
@@ -1324,6 +1375,8 @@ PROXY_HOSTS = *.github.com
13241375

13251376
- `ENABLED`: **false**: Enable/Disable actions capabilities
13261377
- `DEFAULT_ACTIONS_URL`: **https://gitea.com**: Default address to get action plugins, e.g. the default value means downloading from "<https://gitea.com/actions/checkout>" for "uses: actions/checkout@v3"
1378+
- `STORAGE_TYPE`: **local**: Storage type for actions logs, `local` for local disk or `minio` for s3 compatible object storage service, default is `local` or other name defined with `[storage.xxx]`
1379+
- `MINIO_BASE_PATH`: **actions_log/**: Minio base path on the bucket only available when STORAGE_TYPE is `minio`
13271380

13281381
`DEFAULT_ACTIONS_URL` indicates where should we find the relative path action plugin. i.e. when use an action in a workflow file like
13291382

docs/content/doc/administration/config-cheat-sheet.zh-cn.md

+53-4
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ LFS 的存储配置。 如果 `STORAGE_TYPE` 为空,则此配置将从 `[stora
414414

415415
## Storage (`storage`)
416416

417-
Attachments, lfs, avatars and etc 的默认存储配置。
417+
Attachments, lfs, avatars, repo-avatars, repo-archive, packages, actions_log, actions_artifact 的默认存储配置。
418418

419419
- `STORAGE_TYPE`: **local**: 附件存储类型,`local` 将存储到本地文件夹, `minio` 将存储到 s3 兼容的对象存储服务中。
420420
- `SERVE_DIRECT`: **false**: 允许直接重定向到存储系统。当前,仅 Minio/S3 是支持的。
@@ -425,11 +425,13 @@ Attachments, lfs, avatars and etc 的默认存储配置。
425425
- `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket,仅当 `STORAGE_TYPE``minio` 时有效。
426426
- `MINIO_USE_SSL`: **false**: Minio enabled ssl,仅当 `STORAGE_TYPE``minio` 时有效。
427427

428-
你也可以自定义一个存储的名字如下:
428+
以下为推荐的 recommanded storage configuration for minio like below:
429429

430430
```ini
431-
[storage.my_minio]
431+
[storage]
432432
STORAGE_TYPE = minio
433+
; uncomment when STORAGE_TYPE = local
434+
; PATH = storage root path
433435
; Minio endpoint to connect only available when STORAGE_TYPE is `minio`
434436
MINIO_ENDPOINT = localhost:9000
435437
; Minio accessKeyID to connect only available when STORAGE_TYPE is `minio`
@@ -444,9 +446,56 @@ MINIO_LOCATION = us-east-1
444446
MINIO_USE_SSL = false
445447
; Minio skip SSL verification available when STORAGE_TYPE is `minio`
446448
MINIO_INSECURE_SKIP_VERIFY = false
449+
SERVE_DIRECT = true
450+
```
451+
452+
默认的,每一个存储都会有各自默认的 BasePath 在同一个minio中,默认值如下:
453+
454+
| storage | default base path |
455+
| ----------------- | ------------------ |
456+
| attachments | attachments/ |
457+
| lfs | lfs/ |
458+
| avatars | avatars/ |
459+
| repo-avatars | repo-avatars/ |
460+
| repo-archive | repo-archive/ |
461+
| packages | packages/ |
462+
| actions_log | actions_log/ |
463+
| actions_artifacts | actions_artifacts/ |
464+
465+
同时 bucket, basepath or `SERVE_DIRECT` 是可以被覆写的,像如下所示:
466+
467+
```ini
468+
[storage.actions_log]
469+
MINIO_BUCKET = gitea_actions_log
470+
SERVE_DIRECT = true
471+
MINIO_BASE_PATH = my_actions_log/ ; default is actions_log/ if blank
447472
```
448473

449-
然后你在 `[attachment]`, `[lfs]` 等中可以把这个名字用作 `STORAGE_TYPE` 的值。
474+
当然你也可以完全自定义,像如下
475+
476+
```ini
477+
[lfs]
478+
STORAGE_TYPE = my_minio
479+
MINIO_BASE_PATH = my_lfs_basepath
480+
481+
[storage.my_minio]
482+
STORAGE_TYPE = minio
483+
; Minio endpoint to connect only available when STORAGE_TYPE is `minio`
484+
MINIO_ENDPOINT = localhost:9000
485+
; Minio accessKeyID to connect only available when STORAGE_TYPE is `minio`
486+
MINIO_ACCESS_KEY_ID =
487+
; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio`
488+
MINIO_SECRET_ACCESS_KEY =
489+
; Minio bucket to store the attachments only available when STORAGE_TYPE is `minio`
490+
MINIO_BUCKET = gitea
491+
; Minio location to create bucket only available when STORAGE_TYPE is `minio`
492+
MINIO_LOCATION = us-east-1
493+
; Minio enabled ssl only available when STORAGE_TYPE is `minio`
494+
MINIO_USE_SSL = false
495+
; Minio skip SSL verification available when STORAGE_TYPE is `minio`
496+
MINIO_INSECURE_SKIP_VERIFY = false
497+
SERVE_DIRECT = true
498+
```
450499

451500
## Repository Archive Storage (`storage.repo-archive`)
452501

models/migrations/v1_10/v96.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func DeleteOrphanedAttachments(x *xorm.Engine) error {
5353

5454
for _, attachment := range attachments {
5555
uuid := attachment.UUID
56-
if err := util.RemoveAll(filepath.Join(setting.Attachment.Path, uuid[0:1], uuid[1:2], uuid)); err != nil {
56+
if err := util.RemoveAll(filepath.Join(setting.Attachment.Storage.Path, uuid[0:1], uuid[1:2], uuid)); err != nil {
5757
return err
5858
}
5959
}

models/migrations/v1_11/v112.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func RemoveAttachmentMissedRepo(x *xorm.Engine) error {
3030

3131
for i := 0; i < len(attachments); i++ {
3232
uuid := attachments[i].UUID
33-
if err = util.RemoveAll(filepath.Join(setting.Attachment.Path, uuid[0:1], uuid[1:2], uuid)); err != nil {
33+
if err = util.RemoveAll(filepath.Join(setting.Attachment.Storage.Path, uuid[0:1], uuid[1:2], uuid)); err != nil {
3434
fmt.Printf("Error: %v", err) //nolint:forbidigo
3535
}
3636
}

models/migrations/v1_11/v115.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func RenameExistingUserAvatarName(x *xorm.Engine) error {
6161
for _, user := range users {
6262
oldAvatar := user.Avatar
6363

64-
if stat, err := os.Stat(filepath.Join(setting.Avatar.Path, oldAvatar)); err != nil || !stat.Mode().IsRegular() {
64+
if stat, err := os.Stat(filepath.Join(setting.Avatar.Storage.Path, oldAvatar)); err != nil || !stat.Mode().IsRegular() {
6565
if err == nil {
6666
err = fmt.Errorf("Error: \"%s\" is not a regular file", oldAvatar)
6767
}
@@ -86,7 +86,7 @@ func RenameExistingUserAvatarName(x *xorm.Engine) error {
8686
return fmt.Errorf("[user: %s] user table update: %w", user.LowerName, err)
8787
}
8888

89-
deleteList.Add(filepath.Join(setting.Avatar.Path, oldAvatar))
89+
deleteList.Add(filepath.Join(setting.Avatar.Storage.Path, oldAvatar))
9090
migrated++
9191
select {
9292
case <-ticker.C:
@@ -135,7 +135,7 @@ func RenameExistingUserAvatarName(x *xorm.Engine) error {
135135
// copyOldAvatarToNewLocation copies oldAvatar to newAvatarLocation
136136
// and returns newAvatar location
137137
func copyOldAvatarToNewLocation(userID int64, oldAvatar string) (string, error) {
138-
fr, err := os.Open(filepath.Join(setting.Avatar.Path, oldAvatar))
138+
fr, err := os.Open(filepath.Join(setting.Avatar.Storage.Path, oldAvatar))
139139
if err != nil {
140140
return "", fmt.Errorf("os.Open: %w", err)
141141
}
@@ -151,7 +151,7 @@ func copyOldAvatarToNewLocation(userID int64, oldAvatar string) (string, error)
151151
return newAvatar, nil
152152
}
153153

154-
if err := os.WriteFile(filepath.Join(setting.Avatar.Path, newAvatar), data, 0o666); err != nil {
154+
if err := os.WriteFile(filepath.Join(setting.Avatar.Storage.Path, newAvatar), data, 0o666); err != nil {
155155
return "", fmt.Errorf("os.WriteFile: %w", err)
156156
}
157157

0 commit comments

Comments
 (0)