mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-28 14:43:52 +03:00
Fix the wrong derive path (#26271)
This PR will fix #26264, caused by #23911. The package configuration derive is totally wrong when storage type is local in that PR. This PR fixed the inherit logic when storage type is local with some unit tests. --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
parent
8a2f019d69
commit
96f151392f
2 changed files with 215 additions and 17 deletions
|
@ -84,12 +84,15 @@ func getDefaultStorageSection(rootCfg ConfigProvider) ConfigSection {
|
||||||
return storageSec
|
return storageSec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getStorage will find target section and extra special section first and then read override
|
||||||
|
// items from extra section
|
||||||
func getStorage(rootCfg ConfigProvider, name, typ string, sec ConfigSection) (*Storage, error) {
|
func getStorage(rootCfg ConfigProvider, name, typ string, sec ConfigSection) (*Storage, error) {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return nil, errors.New("no name for storage")
|
return nil, errors.New("no name for storage")
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetSec ConfigSection
|
var targetSec ConfigSection
|
||||||
|
// check typ first
|
||||||
if typ != "" {
|
if typ != "" {
|
||||||
var err error
|
var err error
|
||||||
targetSec, err = rootCfg.GetSection(storageSectionName + "." + typ)
|
targetSec, err = rootCfg.GetSection(storageSectionName + "." + typ)
|
||||||
|
@ -111,24 +114,40 @@ func getStorage(rootCfg ConfigProvider, name, typ string, sec ConfigSection) (*S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
storageNameSec, _ := rootCfg.GetSection(storageSectionName + "." + name)
|
if targetSec == nil && sec != nil {
|
||||||
|
secTyp := sec.Key("STORAGE_TYPE").String()
|
||||||
if targetSec == nil {
|
if IsValidStorageType(StorageType(secTyp)) {
|
||||||
targetSec = sec
|
targetSec = sec
|
||||||
|
} else if secTyp != "" {
|
||||||
|
targetSec, _ = rootCfg.GetSection(storageSectionName + "." + secTyp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetSecIsStoragename := false
|
||||||
|
storageNameSec, _ := rootCfg.GetSection(storageSectionName + "." + name)
|
||||||
if targetSec == nil {
|
if targetSec == nil {
|
||||||
targetSec = storageNameSec
|
targetSec = storageNameSec
|
||||||
|
targetSecIsStoragename = storageNameSec != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if targetSec == nil {
|
if targetSec == nil {
|
||||||
targetSec = getDefaultStorageSection(rootCfg)
|
targetSec = getDefaultStorageSection(rootCfg)
|
||||||
} else {
|
} else {
|
||||||
targetType := targetSec.Key("STORAGE_TYPE").String()
|
targetType := targetSec.Key("STORAGE_TYPE").String()
|
||||||
switch {
|
switch {
|
||||||
case targetType == "":
|
case targetType == "":
|
||||||
if targetSec.Key("PATH").String() == "" {
|
if targetSec != storageNameSec && storageNameSec != nil {
|
||||||
targetSec = getDefaultStorageSection(rootCfg)
|
targetSec = storageNameSec
|
||||||
|
targetSecIsStoragename = true
|
||||||
|
if targetSec.Key("STORAGE_TYPE").String() == "" {
|
||||||
|
return nil, fmt.Errorf("storage section %s.%s has no STORAGE_TYPE", storageSectionName, name)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
targetSec.Key("STORAGE_TYPE").SetValue("local")
|
if targetSec.Key("PATH").String() == "" {
|
||||||
|
targetSec = getDefaultStorageSection(rootCfg)
|
||||||
|
} else {
|
||||||
|
targetSec.Key("STORAGE_TYPE").SetValue("local")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
newTargetSec, _ := rootCfg.GetSection(storageSectionName + "." + targetType)
|
newTargetSec, _ := rootCfg.GetSection(storageSectionName + "." + targetType)
|
||||||
|
@ -153,26 +172,46 @@ func getStorage(rootCfg ConfigProvider, name, typ string, sec ConfigSection) (*S
|
||||||
return nil, fmt.Errorf("invalid storage type %q", targetType)
|
return nil, fmt.Errorf("invalid storage type %q", targetType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extra config section will be read SERVE_DIRECT, PATH, MINIO_BASE_PATH, MINIO_BUCKET to override the targetsec when possible
|
||||||
|
extraConfigSec := sec
|
||||||
|
if extraConfigSec == nil {
|
||||||
|
extraConfigSec = storageNameSec
|
||||||
|
}
|
||||||
|
|
||||||
var storage Storage
|
var storage Storage
|
||||||
storage.Type = StorageType(targetType)
|
storage.Type = StorageType(targetType)
|
||||||
|
|
||||||
switch targetType {
|
switch targetType {
|
||||||
case string(LocalStorageType):
|
case string(LocalStorageType):
|
||||||
storage.Path = ConfigSectionKeyString(targetSec, "PATH", filepath.Join(AppDataPath, name))
|
targetPath := ConfigSectionKeyString(targetSec, "PATH", "")
|
||||||
if !filepath.IsAbs(storage.Path) {
|
if targetPath == "" {
|
||||||
storage.Path = filepath.Join(AppWorkPath, storage.Path)
|
targetPath = AppDataPath
|
||||||
|
} else if !filepath.IsAbs(targetPath) {
|
||||||
|
targetPath = filepath.Join(AppDataPath, targetPath)
|
||||||
}
|
}
|
||||||
case string(MinioStorageType):
|
|
||||||
storage.MinioConfig.BasePath = name + "/"
|
|
||||||
|
|
||||||
|
var fallbackPath string
|
||||||
|
if targetSecIsStoragename {
|
||||||
|
fallbackPath = targetPath
|
||||||
|
} else {
|
||||||
|
fallbackPath = filepath.Join(targetPath, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if extraConfigSec == nil {
|
||||||
|
storage.Path = fallbackPath
|
||||||
|
} else {
|
||||||
|
storage.Path = ConfigSectionKeyString(extraConfigSec, "PATH", fallbackPath)
|
||||||
|
if !filepath.IsAbs(storage.Path) {
|
||||||
|
storage.Path = filepath.Join(targetPath, storage.Path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case string(MinioStorageType):
|
||||||
if err := targetSec.MapTo(&storage.MinioConfig); err != nil {
|
if err := targetSec.MapTo(&storage.MinioConfig); err != nil {
|
||||||
return nil, fmt.Errorf("map minio config failed: %v", err)
|
return nil, fmt.Errorf("map minio config failed: %v", err)
|
||||||
}
|
}
|
||||||
// extra config section will be read SERVE_DIRECT, PATH, MINIO_BASE_PATH to override the targetsec
|
|
||||||
extraConfigSec := sec
|
storage.MinioConfig.BasePath = name + "/"
|
||||||
if extraConfigSec == nil {
|
|
||||||
extraConfigSec = storageNameSec
|
|
||||||
}
|
|
||||||
|
|
||||||
if extraConfigSec != nil {
|
if extraConfigSec != nil {
|
||||||
storage.MinioConfig.ServeDirect = ConfigSectionKeyBool(extraConfigSec, "SERVE_DIRECT", storage.MinioConfig.ServeDirect)
|
storage.MinioConfig.ServeDirect = ConfigSectionKeyBool(extraConfigSec, "SERVE_DIRECT", storage.MinioConfig.ServeDirect)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
package setting
|
package setting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -90,3 +91,161 @@ STORAGE_TYPE = minio
|
||||||
assert.EqualValues(t, "gitea", RepoAvatar.Storage.MinioConfig.Bucket)
|
assert.EqualValues(t, "gitea", RepoAvatar.Storage.MinioConfig.Bucket)
|
||||||
assert.EqualValues(t, "repo-avatars/", RepoAvatar.Storage.MinioConfig.BasePath)
|
assert.EqualValues(t, "repo-avatars/", RepoAvatar.Storage.MinioConfig.BasePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testLocalStoragePathCase struct {
|
||||||
|
loader func(rootCfg ConfigProvider) error
|
||||||
|
storagePtr **Storage
|
||||||
|
expectedPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLocalStoragePath(t *testing.T, appDataPath, iniStr string, cases []testLocalStoragePathCase) {
|
||||||
|
cfg, err := NewConfigProviderFromData(iniStr)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
AppDataPath = appDataPath
|
||||||
|
for _, c := range cases {
|
||||||
|
assert.NoError(t, c.loader(cfg))
|
||||||
|
storage := *c.storagePtr
|
||||||
|
|
||||||
|
assert.EqualValues(t, "local", storage.Type)
|
||||||
|
assert.True(t, filepath.IsAbs(storage.Path))
|
||||||
|
assert.EqualValues(t, filepath.Clean(c.expectedPath), filepath.Clean(storage.Path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getStorageInheritStorageTypeLocal(t *testing.T) {
|
||||||
|
testLocalStoragePath(t, "/appdata", `
|
||||||
|
[storage]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
`, []testLocalStoragePathCase{
|
||||||
|
{loadPackagesFrom, &Packages.Storage, "/appdata/packages"},
|
||||||
|
{loadRepoArchiveFrom, &RepoArchive.Storage, "/appdata/repo-archive"},
|
||||||
|
{loadActionsFrom, &Actions.LogStorage, "/appdata/actions_log"},
|
||||||
|
{loadAvatarsFrom, &Avatar.Storage, "/appdata/avatars"},
|
||||||
|
{loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/repo-avatars"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getStorageInheritStorageTypeLocalPath(t *testing.T) {
|
||||||
|
testLocalStoragePath(t, "/appdata", `
|
||||||
|
[storage]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
PATH = /data/gitea
|
||||||
|
`, []testLocalStoragePathCase{
|
||||||
|
{loadPackagesFrom, &Packages.Storage, "/data/gitea/packages"},
|
||||||
|
{loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/repo-archive"},
|
||||||
|
{loadActionsFrom, &Actions.LogStorage, "/data/gitea/actions_log"},
|
||||||
|
{loadAvatarsFrom, &Avatar.Storage, "/data/gitea/avatars"},
|
||||||
|
{loadRepoAvatarFrom, &RepoAvatar.Storage, "/data/gitea/repo-avatars"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getStorageInheritStorageTypeLocalRelativePath(t *testing.T) {
|
||||||
|
testLocalStoragePath(t, "/appdata", `
|
||||||
|
[storage]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
PATH = storages
|
||||||
|
`, []testLocalStoragePathCase{
|
||||||
|
{loadPackagesFrom, &Packages.Storage, "/appdata/storages/packages"},
|
||||||
|
{loadRepoArchiveFrom, &RepoArchive.Storage, "/appdata/storages/repo-archive"},
|
||||||
|
{loadActionsFrom, &Actions.LogStorage, "/appdata/storages/actions_log"},
|
||||||
|
{loadAvatarsFrom, &Avatar.Storage, "/appdata/storages/avatars"},
|
||||||
|
{loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/storages/repo-avatars"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getStorageInheritStorageTypeLocalPathOverride(t *testing.T) {
|
||||||
|
testLocalStoragePath(t, "/appdata", `
|
||||||
|
[storage]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
PATH = /data/gitea
|
||||||
|
|
||||||
|
[repo-archive]
|
||||||
|
PATH = /data/gitea/the-archives-dir
|
||||||
|
`, []testLocalStoragePathCase{
|
||||||
|
{loadPackagesFrom, &Packages.Storage, "/data/gitea/packages"},
|
||||||
|
{loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/the-archives-dir"},
|
||||||
|
{loadActionsFrom, &Actions.LogStorage, "/data/gitea/actions_log"},
|
||||||
|
{loadAvatarsFrom, &Avatar.Storage, "/data/gitea/avatars"},
|
||||||
|
{loadRepoAvatarFrom, &RepoAvatar.Storage, "/data/gitea/repo-avatars"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getStorageInheritStorageTypeLocalPathOverrideEmpty(t *testing.T) {
|
||||||
|
testLocalStoragePath(t, "/appdata", `
|
||||||
|
[storage]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
PATH = /data/gitea
|
||||||
|
|
||||||
|
[repo-archive]
|
||||||
|
`, []testLocalStoragePathCase{
|
||||||
|
{loadPackagesFrom, &Packages.Storage, "/data/gitea/packages"},
|
||||||
|
{loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/repo-archive"},
|
||||||
|
{loadActionsFrom, &Actions.LogStorage, "/data/gitea/actions_log"},
|
||||||
|
{loadAvatarsFrom, &Avatar.Storage, "/data/gitea/avatars"},
|
||||||
|
{loadRepoAvatarFrom, &RepoAvatar.Storage, "/data/gitea/repo-avatars"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getStorageInheritStorageTypeLocalRelativePathOverride(t *testing.T) {
|
||||||
|
testLocalStoragePath(t, "/appdata", `
|
||||||
|
[storage]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
PATH = /data/gitea
|
||||||
|
|
||||||
|
[repo-archive]
|
||||||
|
PATH = the-archives-dir
|
||||||
|
`, []testLocalStoragePathCase{
|
||||||
|
{loadPackagesFrom, &Packages.Storage, "/data/gitea/packages"},
|
||||||
|
{loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/the-archives-dir"},
|
||||||
|
{loadActionsFrom, &Actions.LogStorage, "/data/gitea/actions_log"},
|
||||||
|
{loadAvatarsFrom, &Avatar.Storage, "/data/gitea/avatars"},
|
||||||
|
{loadRepoAvatarFrom, &RepoAvatar.Storage, "/data/gitea/repo-avatars"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getStorageInheritStorageTypeLocalPathOverride3(t *testing.T) {
|
||||||
|
testLocalStoragePath(t, "/appdata", `
|
||||||
|
[storage.repo-archive]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
PATH = /data/gitea/archives
|
||||||
|
`, []testLocalStoragePathCase{
|
||||||
|
{loadPackagesFrom, &Packages.Storage, "/appdata/packages"},
|
||||||
|
{loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/archives"},
|
||||||
|
{loadActionsFrom, &Actions.LogStorage, "/appdata/actions_log"},
|
||||||
|
{loadAvatarsFrom, &Avatar.Storage, "/appdata/avatars"},
|
||||||
|
{loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/repo-avatars"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getStorageInheritStorageTypeLocalPathOverride4(t *testing.T) {
|
||||||
|
testLocalStoragePath(t, "/appdata", `
|
||||||
|
[storage.repo-archive]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
PATH = /data/gitea/archives
|
||||||
|
|
||||||
|
[repo-archive]
|
||||||
|
PATH = /tmp/gitea/archives
|
||||||
|
`, []testLocalStoragePathCase{
|
||||||
|
{loadPackagesFrom, &Packages.Storage, "/appdata/packages"},
|
||||||
|
{loadRepoArchiveFrom, &RepoArchive.Storage, "/tmp/gitea/archives"},
|
||||||
|
{loadActionsFrom, &Actions.LogStorage, "/appdata/actions_log"},
|
||||||
|
{loadAvatarsFrom, &Avatar.Storage, "/appdata/avatars"},
|
||||||
|
{loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/repo-avatars"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getStorageInheritStorageTypeLocalPathOverride5(t *testing.T) {
|
||||||
|
testLocalStoragePath(t, "/appdata", `
|
||||||
|
[storage.repo-archive]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
PATH = /data/gitea/archives
|
||||||
|
|
||||||
|
[repo-archive]
|
||||||
|
`, []testLocalStoragePathCase{
|
||||||
|
{loadPackagesFrom, &Packages.Storage, "/appdata/packages"},
|
||||||
|
{loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/archives"},
|
||||||
|
{loadActionsFrom, &Actions.LogStorage, "/appdata/actions_log"},
|
||||||
|
{loadAvatarsFrom, &Avatar.Storage, "/appdata/avatars"},
|
||||||
|
{loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/repo-avatars"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue