backport #26094 Temporily resolve #25915 Related #25994 This PR includes #26007 's changes but have a UI to prompt administrator about the deprecated settings as well as the log or console warning. Then users will have enough time to notice the problem and don't have surprise like before. <img width="1293" alt="图片" src="https://github.com/go-gitea/gitea/assets/81045/c33355f0-1ea7-4fb3-ad43-cd23cd15391d">tags/v1.20.2
@@ -316,15 +316,14 @@ func mustMapSetting(rootCfg ConfigProvider, sectionName string, setting any) { | |||
} | |||
} | |||
func deprecatedSetting(rootCfg ConfigProvider, oldSection, oldKey, newSection, newKey, version string) { | |||
if rootCfg.Section(oldSection).HasKey(oldKey) { | |||
log.Error("Deprecated fallback `[%s]` `%s` present. Use `[%s]` `%s` instead. This fallback will be/has been removed in %s", oldSection, oldKey, newSection, newKey, version) | |||
} | |||
} | |||
// DeprecatedWarnings contains the warning message for various deprecations, including: setting option, file/folder, etc | |||
var DeprecatedWarnings []string | |||
func deprecatedSettingFatal(rootCfg ConfigProvider, oldSection, oldKey, newSection, newKey, version string) { | |||
func deprecatedSetting(rootCfg ConfigProvider, oldSection, oldKey, newSection, newKey, version string) { | |||
if rootCfg.Section(oldSection).HasKey(oldKey) { | |||
log.Fatal("Deprecated fallback `[%s]` `%s` present. Use `[%s]` `%s` instead. This fallback will be/has been removed in %s. Shutting down", oldSection, oldKey, newSection, newKey, version) | |||
msg := fmt.Sprintf("Deprecated config option `[%s]` `%s` present. Use `[%s]` `%s` instead. This fallback will be/has been removed in %s", oldSection, oldKey, newSection, newKey, version) | |||
log.Error("%v", msg) | |||
DeprecatedWarnings = append(DeprecatedWarnings, msg) | |||
} | |||
} | |||
@@ -34,7 +34,14 @@ func loadLFSFrom(rootCfg ConfigProvider) error { | |||
// Specifically default PATH to LFS_CONTENT_PATH | |||
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version | |||
// if these are removed, the warning will not be shown | |||
deprecatedSettingFatal(rootCfg, "server", "LFS_CONTENT_PATH", "lfs", "PATH", "v1.19.0") | |||
deprecatedSetting(rootCfg, "server", "LFS_CONTENT_PATH", "lfs", "PATH", "v1.19.0") | |||
if val := sec.Key("LFS_CONTENT_PATH").String(); val != "" { | |||
if lfsSec == nil { | |||
lfsSec = rootCfg.Section("lfs") | |||
} | |||
lfsSec.Key("PATH").MustString(val) | |||
} | |||
var err error | |||
LFS.Storage, err = getStorage(rootCfg, "lfs", "", lfsSec) |
@@ -21,6 +21,30 @@ func Test_getStorageInheritNameSectionTypeForLFS(t *testing.T) { | |||
assert.EqualValues(t, "minio", LFS.Storage.Type) | |||
assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath) | |||
iniStr = ` | |||
[server] | |||
LFS_CONTENT_PATH = path_ignored | |||
[lfs] | |||
PATH = path_used | |||
` | |||
cfg, err = NewConfigProviderFromData(iniStr) | |||
assert.NoError(t, err) | |||
assert.NoError(t, loadLFSFrom(cfg)) | |||
assert.EqualValues(t, "local", LFS.Storage.Type) | |||
assert.Contains(t, LFS.Storage.Path, "path_used") | |||
iniStr = ` | |||
[server] | |||
LFS_CONTENT_PATH = deprecatedpath | |||
` | |||
cfg, err = NewConfigProviderFromData(iniStr) | |||
assert.NoError(t, err) | |||
assert.NoError(t, loadLFSFrom(cfg)) | |||
assert.EqualValues(t, "local", LFS.Storage.Type) | |||
assert.Contains(t, LFS.Storage.Path, "deprecatedpath") | |||
iniStr = ` | |||
[storage.lfs] | |||
STORAGE_TYPE = minio |
@@ -110,6 +110,16 @@ func updateSystemStatus() { | |||
sysStatus.NumGC = m.NumGC | |||
} | |||
func prepareDeprecatedWarningsAlert(ctx *context.Context) { | |||
if len(setting.DeprecatedWarnings) > 0 { | |||
content := setting.DeprecatedWarnings[0] | |||
if len(setting.DeprecatedWarnings) > 1 { | |||
content += fmt.Sprintf(" (and %d more)", len(setting.DeprecatedWarnings)-1) | |||
} | |||
ctx.Flash.Error(content, true) | |||
} | |||
} | |||
// Dashboard show admin panel dashboard | |||
func Dashboard(ctx *context.Context) { | |||
ctx.Data["Title"] = ctx.Tr("admin.dashboard") | |||
@@ -120,6 +130,7 @@ func Dashboard(ctx *context.Context) { | |||
updateSystemStatus() | |||
ctx.Data["SysStatus"] = sysStatus | |||
ctx.Data["SSH"] = setting.SSH | |||
prepareDeprecatedWarningsAlert(ctx) | |||
ctx.HTML(http.StatusOK, tplDashboard) | |||
} | |||
@@ -171,6 +171,8 @@ func Config(ctx *context.Context) { | |||
ctx.Data["Loggers"] = log.GetManager().DumpLoggers() | |||
prepareDeprecatedWarningsAlert(ctx) | |||
ctx.HTML(http.StatusOK, tplConfig) | |||
} | |||
@@ -1,9 +1,11 @@ | |||
{{template "base/head" .ctxData}} | |||
<div role="main" aria-label="{{.ctxData.Title}}" class="page-content {{.pageClass}}"> | |||
<div class="ui container stackable grid"> | |||
<div class="ui container"> | |||
{{template "base/alert" .ctxData}} | |||
</div> | |||
<div class="ui container admin-container"> | |||
{{template "admin/navbar" .ctxData}} | |||
<div class="twelve wide column"> | |||
{{template "base/alert" .ctxData}} | |||
<div class="admin-main"> | |||
{{/* block: admin-setting-content */}} | |||
{{if false}}{{/* to make html structure "likely" complete to prevent IDE warnings */}} |
@@ -1,4 +1,4 @@ | |||
<div class="four wide column"> | |||
<div class="admin-nav"> | |||
<div class="ui fluid vertical menu"> | |||
<div class="header item">{{.locale.Tr "settings"}}</div> | |||
<a class="{{if .PageIsAdminDashboard}}active {{end}}item" href="{{AppSubUrl}}/admin"> |
@@ -1,3 +1,26 @@ | |||
.admin-container { | |||
margin-top: 15px; | |||
display: flex !important; | |||
gap: 16px; | |||
} | |||
.admin-nav { | |||
width: 240px; | |||
} | |||
.admin-main { | |||
flex: 1; | |||
} | |||
@media (max-width: 767.98px) { | |||
.admin-container { | |||
flex-direction: column; | |||
} | |||
.admin-nav { | |||
width: auto; | |||
} | |||
} | |||
.admin.hooks .list > .item:not(:first-child) { | |||
border-top: 1px solid var(--color-secondary); | |||
padding: 0.25rem 1rem; |