mirror of
				https://github.com/go-gitea/gitea
				synced 2025-09-28 03:28:13 +00:00 
			
		
		
		
	Backport #30169 by wxiaoguang Replace #29171 Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
		| @@ -58,7 +58,7 @@ func loadIndexerFrom(rootCfg ConfigProvider) { | |||||||
| 		if !filepath.IsAbs(Indexer.IssuePath) { | 		if !filepath.IsAbs(Indexer.IssuePath) { | ||||||
| 			Indexer.IssuePath = filepath.ToSlash(filepath.Join(AppWorkPath, Indexer.IssuePath)) | 			Indexer.IssuePath = filepath.ToSlash(filepath.Join(AppWorkPath, Indexer.IssuePath)) | ||||||
| 		} | 		} | ||||||
| 		fatalDuplicatedPath("issue_indexer", Indexer.IssuePath) | 		checkOverlappedPath("indexer.ISSUE_INDEXER_PATH", Indexer.IssuePath) | ||||||
| 	} else { | 	} else { | ||||||
| 		Indexer.IssueConnStr = sec.Key("ISSUE_INDEXER_CONN_STR").MustString(Indexer.IssueConnStr) | 		Indexer.IssueConnStr = sec.Key("ISSUE_INDEXER_CONN_STR").MustString(Indexer.IssueConnStr) | ||||||
| 		if Indexer.IssueType == "meilisearch" { | 		if Indexer.IssueType == "meilisearch" { | ||||||
|   | |||||||
| @@ -66,12 +66,8 @@ func init() { | |||||||
| 		AppWorkPath = filepath.Dir(AppPath) | 		AppWorkPath = filepath.Dir(AppPath) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fatalDuplicatedPath("app_work_path", AppWorkPath) |  | ||||||
|  |  | ||||||
| 	appWorkPathBuiltin = AppWorkPath | 	appWorkPathBuiltin = AppWorkPath | ||||||
| 	customPathBuiltin = CustomPath | 	customPathBuiltin = CustomPath | ||||||
|  |  | ||||||
| 	fatalDuplicatedPath("custom_path", CustomPath) |  | ||||||
| 	customConfBuiltin = CustomConf | 	customConfBuiltin = CustomConf | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -286,7 +286,7 @@ func loadRepositoryFrom(rootCfg ConfigProvider) { | |||||||
| 		RepoRootPath = filepath.Clean(RepoRootPath) | 		RepoRootPath = filepath.Clean(RepoRootPath) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fatalDuplicatedPath("repository.ROOT", RepoRootPath) | 	checkOverlappedPath("repository.ROOT", RepoRootPath) | ||||||
|  |  | ||||||
| 	defaultDetectedCharsetsOrder := make([]string, 0, len(Repository.DetectedCharsetsOrder)) | 	defaultDetectedCharsetsOrder := make([]string, 0, len(Repository.DetectedCharsetsOrder)) | ||||||
| 	for _, charset := range Repository.DetectedCharsetsOrder { | 	for _, charset := range Repository.DetectedCharsetsOrder { | ||||||
|   | |||||||
| @@ -324,7 +324,6 @@ func loadServerFrom(rootCfg ConfigProvider) { | |||||||
| 	if !filepath.IsAbs(AppDataPath) { | 	if !filepath.IsAbs(AppDataPath) { | ||||||
| 		AppDataPath = filepath.ToSlash(filepath.Join(AppWorkPath, AppDataPath)) | 		AppDataPath = filepath.ToSlash(filepath.Join(AppWorkPath, AppDataPath)) | ||||||
| 	} | 	} | ||||||
| 	fatalDuplicatedPath("app_data_path", AppDataPath) |  | ||||||
|  |  | ||||||
| 	EnableGzip = sec.Key("ENABLE_GZIP").MustBool() | 	EnableGzip = sec.Key("ENABLE_GZIP").MustBool() | ||||||
| 	EnablePprof = sec.Key("ENABLE_PPROF").MustBool(false) | 	EnablePprof = sec.Key("ENABLE_PPROF").MustBool(false) | ||||||
| @@ -332,7 +331,7 @@ func loadServerFrom(rootCfg ConfigProvider) { | |||||||
| 	if !filepath.IsAbs(PprofDataPath) { | 	if !filepath.IsAbs(PprofDataPath) { | ||||||
| 		PprofDataPath = filepath.Join(AppWorkPath, PprofDataPath) | 		PprofDataPath = filepath.Join(AppWorkPath, PprofDataPath) | ||||||
| 	} | 	} | ||||||
| 	fatalDuplicatedPath("pprof_data_path", PprofDataPath) | 	checkOverlappedPath("server.PPROF_DATA_PATH", PprofDataPath) | ||||||
|  |  | ||||||
| 	landingPage := sec.Key("LANDING_PAGE").MustString("home") | 	landingPage := sec.Key("LANDING_PAGE").MustString("home") | ||||||
| 	switch landingPage { | 	switch landingPage { | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ func loadSessionFrom(rootCfg ConfigProvider) { | |||||||
| 	SessionConfig.ProviderConfig = strings.Trim(sec.Key("PROVIDER_CONFIG").MustString(filepath.Join(AppDataPath, "sessions")), "\" ") | 	SessionConfig.ProviderConfig = strings.Trim(sec.Key("PROVIDER_CONFIG").MustString(filepath.Join(AppDataPath, "sessions")), "\" ") | ||||||
| 	if SessionConfig.Provider == "file" && !filepath.IsAbs(SessionConfig.ProviderConfig) { | 	if SessionConfig.Provider == "file" && !filepath.IsAbs(SessionConfig.ProviderConfig) { | ||||||
| 		SessionConfig.ProviderConfig = filepath.Join(AppWorkPath, SessionConfig.ProviderConfig) | 		SessionConfig.ProviderConfig = filepath.Join(AppWorkPath, SessionConfig.ProviderConfig) | ||||||
| 		fatalDuplicatedPath("session", SessionConfig.ProviderConfig) | 		checkOverlappedPath("session.PROVIDER_CONFIG", SessionConfig.ProviderConfig) | ||||||
| 	} | 	} | ||||||
| 	SessionConfig.CookieName = sec.Key("COOKIE_NAME").MustString("i_like_gitea") | 	SessionConfig.CookieName = sec.Key("COOKIE_NAME").MustString("i_like_gitea") | ||||||
| 	SessionConfig.CookiePath = AppSubURL | 	SessionConfig.CookiePath = AppSubURL | ||||||
|   | |||||||
| @@ -230,11 +230,14 @@ func LoadSettingsForInstall() { | |||||||
| 	loadMailerFrom(CfgProvider) | 	loadMailerFrom(CfgProvider) | ||||||
| } | } | ||||||
|  |  | ||||||
| var uniquePaths = make(map[string]string) | var configuredPaths = make(map[string]string) | ||||||
|  |  | ||||||
| func fatalDuplicatedPath(name, p string) { | func checkOverlappedPath(name, path string) { | ||||||
| 	if targetName, ok := uniquePaths[p]; ok && targetName != name { | 	// TODO: some paths shouldn't overlap (storage.xxx.path), while some could (data path is the base path for storage path) | ||||||
| 		log.Fatal("storage path %q is being used by %q and %q and all storage paths must be unique to prevent data loss.", p, targetName, name) | 	if targetName, ok := configuredPaths[path]; ok && targetName != name { | ||||||
|  | 		msg := fmt.Sprintf("Configured path %q is used by %q and %q at the same time. The paths must be unique to prevent data loss.", path, targetName, name) | ||||||
|  | 		log.Error("%s", msg) | ||||||
|  | 		DeprecatedWarnings = append(DeprecatedWarnings, msg) | ||||||
| 	} | 	} | ||||||
| 	uniquePaths[p] = name | 	configuredPaths[path] = name | ||||||
| } | } | ||||||
|   | |||||||
| @@ -240,7 +240,7 @@ func getStorageForLocal(targetSec, overrideSec ConfigSection, tp targetSecType, | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fatalDuplicatedPath("storage."+name, storage.Path) | 	checkOverlappedPath("storage."+name+".PATH", storage.Path) | ||||||
|  |  | ||||||
| 	return &storage, nil | 	return &storage, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2775,6 +2775,7 @@ teams.invite.by = Invited by %s | |||||||
| teams.invite.description = Please click the button below to join the team. | teams.invite.description = Please click the button below to join the team. | ||||||
|  |  | ||||||
| [admin] | [admin] | ||||||
|  | maintenance = Maintenance | ||||||
| dashboard = Dashboard | dashboard = Dashboard | ||||||
| self_check = Self Check | self_check = Self Check | ||||||
| identity_access = Identity & Access | identity_access = Identity & Access | ||||||
| @@ -2798,7 +2799,7 @@ settings = Admin Settings | |||||||
|  |  | ||||||
| dashboard.new_version_hint = Gitea %s is now available, you are running %s. Check <a target="_blank" rel="noreferrer" href="https://blog.gitea.io">the blog</a> for more details. | dashboard.new_version_hint = Gitea %s is now available, you are running %s. Check <a target="_blank" rel="noreferrer" href="https://blog.gitea.io">the blog</a> for more details. | ||||||
| dashboard.statistic = Summary | dashboard.statistic = Summary | ||||||
| dashboard.operations = Maintenance Operations | dashboard.maintenance_operations = Maintenance Operations | ||||||
| dashboard.system_status = System Status | dashboard.system_status = System Status | ||||||
| dashboard.operation_name = Operation Name | dashboard.operation_name = Operation Name | ||||||
| dashboard.operation_switch = Switch | dashboard.operation_switch = Switch | ||||||
| @@ -3305,6 +3306,7 @@ notices.op = Op. | |||||||
| notices.delete_success = The system notices have been deleted. | notices.delete_success = The system notices have been deleted. | ||||||
|  |  | ||||||
| self_check.no_problem_found = No problem found yet. | self_check.no_problem_found = No problem found yet. | ||||||
|  | self_check.startup_warnings = Startup warnings: | ||||||
| self_check.database_collation_mismatch = Expect database to use collation: %s | self_check.database_collation_mismatch = Expect database to use collation: %s | ||||||
| self_check.database_collation_case_insensitive = Database is using a collation %s, which is an insensitive collation. Although Gitea could work with it, there might be some rare cases which don't work as expected. | self_check.database_collation_case_insensitive = Database is using a collation %s, which is an insensitive collation. Although Gitea could work with it, there might be some rare cases which don't work as expected. | ||||||
| self_check.database_inconsistent_collation_columns = Database is using collation %s, but these columns are using mismatched collations. It might cause some unexpected problems. | self_check.database_inconsistent_collation_columns = Database is using collation %s, but these columns are using mismatched collations. It might cause some unexpected problems. | ||||||
|   | |||||||
| @@ -190,6 +190,14 @@ func DashboardPost(ctx *context.Context) { | |||||||
|  |  | ||||||
| func SelfCheck(ctx *context.Context) { | func SelfCheck(ctx *context.Context) { | ||||||
| 	ctx.Data["PageIsAdminSelfCheck"] = true | 	ctx.Data["PageIsAdminSelfCheck"] = true | ||||||
|  |  | ||||||
|  | 	ctx.Data["DeprecatedWarnings"] = setting.DeprecatedWarnings | ||||||
|  | 	if len(setting.DeprecatedWarnings) == 0 && !setting.IsProd { | ||||||
|  | 		if time.Now().Unix()%2 == 0 { | ||||||
|  | 			ctx.Data["DeprecatedWarnings"] = []string{"This is a test warning message in dev mode"} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	r, err := db.CheckCollationsDefaultEngine() | 	r, err := db.CheckCollationsDefaultEngine() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Flash.Error(fmt.Sprintf("CheckCollationsDefaultEngine: %v", err), true) | 		ctx.Flash.Error(fmt.Sprintf("CheckCollationsDefaultEngine: %v", err), true) | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
| 			</div> | 			</div> | ||||||
| 		{{end}} | 		{{end}} | ||||||
| 		<h4 class="ui top attached header"> | 		<h4 class="ui top attached header"> | ||||||
| 			{{ctx.Locale.Tr "admin.dashboard.operations"}} | 			{{ctx.Locale.Tr "admin.dashboard.maintenance_operations"}} | ||||||
| 		</h4> | 		</h4> | ||||||
| 		<div class="ui attached table segment"> | 		<div class="ui attached table segment"> | ||||||
| 			<form method="post" action="{{AppSubUrl}}/admin"> | 			<form method="post" action="{{AppSubUrl}}/admin"> | ||||||
|   | |||||||
| @@ -1,12 +1,18 @@ | |||||||
| <div class="flex-container-nav"> | <div class="flex-container-nav"> | ||||||
| 	<div class="ui fluid vertical menu"> | 	<div class="ui fluid vertical menu"> | ||||||
| 		<div class="header item">{{ctx.Locale.Tr "admin.settings"}}</div> | 		<div class="header item">{{ctx.Locale.Tr "admin.settings"}}</div> | ||||||
|  |  | ||||||
|  | 		<details class="item toggleable-item" {{if or .PageIsAdminDashboard .PageIsAdminSelfCheck}}open{{end}}> | ||||||
|  | 			<summary>{{ctx.Locale.Tr "admin.maintenance"}}</summary> | ||||||
|  | 			<div class="menu"> | ||||||
| 				<a class="{{if .PageIsAdminDashboard}}active {{end}}item" href="{{AppSubUrl}}/admin"> | 				<a class="{{if .PageIsAdminDashboard}}active {{end}}item" href="{{AppSubUrl}}/admin"> | ||||||
| 					{{ctx.Locale.Tr "admin.dashboard"}} | 					{{ctx.Locale.Tr "admin.dashboard"}} | ||||||
| 				</a> | 				</a> | ||||||
| 				<a class="{{if .PageIsAdminSelfCheck}}active {{end}}item" href="{{AppSubUrl}}/admin/self_check"> | 				<a class="{{if .PageIsAdminSelfCheck}}active {{end}}item" href="{{AppSubUrl}}/admin/self_check"> | ||||||
| 					{{ctx.Locale.Tr "admin.self_check"}} | 					{{ctx.Locale.Tr "admin.self_check"}} | ||||||
| 				</a> | 				</a> | ||||||
|  | 			</div> | ||||||
|  | 		</details> | ||||||
| 		<details class="item toggleable-item" {{if or .PageIsAdminUsers .PageIsAdminEmails .PageIsAdminOrganizations .PageIsAdminAuthentications}}open{{end}}> | 		<details class="item toggleable-item" {{if or .PageIsAdminUsers .PageIsAdminEmails .PageIsAdminOrganizations .PageIsAdminAuthentications}}open{{end}}> | ||||||
| 			<summary>{{ctx.Locale.Tr "admin.identity_access"}}</summary> | 			<summary>{{ctx.Locale.Tr "admin.identity_access"}}</summary> | ||||||
| 			<div class="menu"> | 			<div class="menu"> | ||||||
|   | |||||||
| @@ -4,8 +4,18 @@ | |||||||
| 	<h4 class="ui top attached header"> | 	<h4 class="ui top attached header"> | ||||||
| 		{{ctx.Locale.Tr "admin.self_check"}} | 		{{ctx.Locale.Tr "admin.self_check"}} | ||||||
| 	</h4> | 	</h4> | ||||||
|  |  | ||||||
|  | 	{{if .DeprecatedWarnings}} | ||||||
| 	<div class="ui attached segment"> | 	<div class="ui attached segment"> | ||||||
|  | 		<div class="ui warning message"> | ||||||
|  | 			<div>{{ctx.Locale.Tr "admin.self_check.startup_warnings"}}</div> | ||||||
|  | 			<ul class="tw-w-full">{{range .DeprecatedWarnings}}<li>{{.}}</li>{{end}}</ul> | ||||||
|  | 		</div> | ||||||
|  | 	</div> | ||||||
|  | 	{{end}} | ||||||
|  |  | ||||||
| 	{{if .DatabaseCheckHasProblems}} | 	{{if .DatabaseCheckHasProblems}} | ||||||
|  | 	<div class="ui attached segment"> | ||||||
| 		{{if .DatabaseType.IsMySQL}} | 		{{if .DatabaseType.IsMySQL}} | ||||||
| 			<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.database_fix_mysql"}}</div> | 			<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.database_fix_mysql"}}</div> | ||||||
| 		{{else if .DatabaseType.IsMSSQL}} | 		{{else if .DatabaseType.IsMSSQL}} | ||||||
| @@ -27,10 +37,14 @@ | |||||||
| 				</ul> | 				</ul> | ||||||
| 			</div> | 			</div> | ||||||
| 		{{end}} | 		{{end}} | ||||||
| 		{{else}} |  | ||||||
| 			<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.no_problem_found"}}</div> |  | ||||||
| 		{{end}} |  | ||||||
| 	</div> | 	</div> | ||||||
|  | 	{{end}} | ||||||
|  |  | ||||||
|  | 	{{if and (not .DeprecatedWarnings) (not .DatabaseCheckHasProblems)}} | ||||||
|  | 	<div class="ui attached segment"> | ||||||
|  | 		{{ctx.Locale.Tr "admin.self_check.no_problem_found"}} | ||||||
|  | 	</div> | ||||||
|  | 	{{end}} | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
| {{template "admin/layout_footer" .}} | {{template "admin/layout_footer" .}} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user