summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-07-10 19:51:05 +0800
committerGitHub <noreply@github.com>2023-07-10 11:51:05 +0000
commitb4460cf54147e22c3f0657fbfdb680aec52a0210 (patch)
treef084a8858ab91ef29058c9fe67ce7bd710c5a065 /modules
parenta1bc2aa05ef67eecce355f237b165567ef6e07e2 (diff)
downloadgitea-b4460cf54147e22c3f0657fbfdb680aec52a0210.tar.gz
gitea-b4460cf54147e22c3f0657fbfdb680aec52a0210.zip
Make "install page" respect environment config (#25648) (#25799)
Backport #25648 Replace #25580 Fix #19453 The problem was: when users set "GITEA__XXX__YYY" , the "install page" doesn't respect it. So, to make the result consistent and avoid surprising end users, now the "install page" also writes the environment variables to the config file. And, to make things clear, there are enough messages on the UI to tell users what will happen. There are some necessary/related changes to `environment-to-ini.go`: * The "--clear" flag is removed and it was incorrectly written there. The "clear" operation should be done if INSTALL_LOCK=true * The "--prefix" flag is removed because it's never used, never documented and it only causes inconsistent behavior. The only conflict during backport is "ui divider" in templates/install.tmpl
Diffstat (limited to 'modules')
-rw-r--r--modules/assetfs/layered.go1
-rw-r--r--modules/setting/config_env.go25
-rw-r--r--modules/setting/config_env_test.go8
-rw-r--r--modules/setting/path.go3
-rw-r--r--modules/setting/security.go2
-rw-r--r--modules/setting/setting.go8
6 files changed, 38 insertions, 9 deletions
diff --git a/modules/assetfs/layered.go b/modules/assetfs/layered.go
index d032160a6f..e18a13e4aa 100644
--- a/modules/assetfs/layered.go
+++ b/modules/assetfs/layered.go
@@ -215,6 +215,7 @@ func (l *LayeredFS) WatchLocalChanges(ctx context.Context, callback func()) {
log.Error("Unable to list directories for asset local file-system %q: %v", layer.localPath, err)
continue
}
+ layerDirs = append(layerDirs, ".")
for _, dir := range layerDirs {
if err = watcher.Add(util.FilePathJoinAbs(layer.localPath, dir)); err != nil {
log.Error("Unable to watch directory %s: %v", dir, err)
diff --git a/modules/setting/config_env.go b/modules/setting/config_env.go
index 6348803705..e23b64557f 100644
--- a/modules/setting/config_env.go
+++ b/modules/setting/config_env.go
@@ -12,10 +12,31 @@ import (
"code.gitea.io/gitea/modules/log"
)
+const (
+ EnvConfigKeyPrefixGitea = "GITEA__"
+ EnvConfigKeySuffixFile = "__FILE"
+)
+
const escapeRegexpString = "_0[xX](([0-9a-fA-F][0-9a-fA-F])+)_"
var escapeRegex = regexp.MustCompile(escapeRegexpString)
+func CollectEnvConfigKeys() (keys []string) {
+ for _, env := range os.Environ() {
+ if strings.HasPrefix(env, EnvConfigKeyPrefixGitea) {
+ k, _, _ := strings.Cut(env, "=")
+ keys = append(keys, k)
+ }
+ }
+ return keys
+}
+
+func ClearEnvConfigKeys() {
+ for _, k := range CollectEnvConfigKeys() {
+ _ = os.Unsetenv(k)
+ }
+}
+
// decodeEnvSectionKey will decode a portable string encoded Section__Key pair
// Portable strings are considered to be of the form [A-Z0-9_]*
// We will encode a disallowed value as the UTF8 byte string preceded by _0X and
@@ -87,7 +108,7 @@ func decodeEnvironmentKey(prefixGitea, suffixFile, envKey string) (ok bool, sect
return ok, section, key, useFileValue
}
-func EnvironmentToConfig(cfg ConfigProvider, prefixGitea, suffixFile string, envs []string) (changed bool) {
+func EnvironmentToConfig(cfg ConfigProvider, envs []string) (changed bool) {
for _, kv := range envs {
idx := strings.IndexByte(kv, '=')
if idx < 0 {
@@ -97,7 +118,7 @@ func EnvironmentToConfig(cfg ConfigProvider, prefixGitea, suffixFile string, env
// parse the environment variable to config section name and key name
envKey := kv[:idx]
envValue := kv[idx+1:]
- ok, sectionName, keyName, useFileValue := decodeEnvironmentKey(prefixGitea, suffixFile, envKey)
+ ok, sectionName, keyName, useFileValue := decodeEnvironmentKey(EnvConfigKeyPrefixGitea, EnvConfigKeySuffixFile, envKey)
if !ok {
continue
}
diff --git a/modules/setting/config_env_test.go b/modules/setting/config_env_test.go
index d574554bcc..2c1dd2f5c7 100644
--- a/modules/setting/config_env_test.go
+++ b/modules/setting/config_env_test.go
@@ -72,7 +72,7 @@ func TestDecodeEnvironmentKey(t *testing.T) {
func TestEnvironmentToConfig(t *testing.T) {
cfg, _ := NewConfigProviderFromData("")
- changed := EnvironmentToConfig(cfg, "GITEA__", "__FILE", nil)
+ changed := EnvironmentToConfig(cfg, nil)
assert.False(t, changed)
cfg, err := NewConfigProviderFromData(`
@@ -81,16 +81,16 @@ key = old
`)
assert.NoError(t, err)
- changed = EnvironmentToConfig(cfg, "GITEA__", "__FILE", []string{"GITEA__sec__key=new"})
+ changed = EnvironmentToConfig(cfg, []string{"GITEA__sec__key=new"})
assert.True(t, changed)
assert.Equal(t, "new", cfg.Section("sec").Key("key").String())
- changed = EnvironmentToConfig(cfg, "GITEA__", "__FILE", []string{"GITEA__sec__key=new"})
+ changed = EnvironmentToConfig(cfg, []string{"GITEA__sec__key=new"})
assert.False(t, changed)
tmpFile := t.TempDir() + "/the-file"
_ = os.WriteFile(tmpFile, []byte("value-from-file"), 0o644)
- changed = EnvironmentToConfig(cfg, "GITEA__", "__FILE", []string{"GITEA__sec__key__FILE=" + tmpFile})
+ changed = EnvironmentToConfig(cfg, []string{"GITEA__sec__key__FILE=" + tmpFile})
assert.True(t, changed)
assert.Equal(t, "value-from-file", cfg.Section("sec").Key("key").String())
}
diff --git a/modules/setting/path.go b/modules/setting/path.go
index 163f1d1590..32ed8d81fa 100644
--- a/modules/setting/path.go
+++ b/modules/setting/path.go
@@ -171,6 +171,9 @@ func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkP
// only read the config but do not load/init anything more, because the AppWorkPath and CustomPath are not ready
InitCfgProvider(tmpCustomConf.Value)
+ if HasInstallLock(CfgProvider) {
+ ClearEnvConfigKeys() // if the instance has been installed, do not pass the environment variables to sub-processes
+ }
configWorkPath := ConfigSectionKeyString(CfgProvider.Section(""), "WORK_PATH")
if configWorkPath != "" {
if !filepath.IsAbs(configWorkPath) {
diff --git a/modules/setting/security.go b/modules/setting/security.go
index c39eb7f3eb..872f9b53c5 100644
--- a/modules/setting/security.go
+++ b/modules/setting/security.go
@@ -102,7 +102,7 @@ func generateSaveInternalToken(rootCfg ConfigProvider) {
func loadSecurityFrom(rootCfg ConfigProvider) {
sec := rootCfg.Section("security")
- InstallLock = sec.Key("INSTALL_LOCK").MustBool(false)
+ InstallLock = HasInstallLock(rootCfg)
LogInRememberDays = sec.Key("LOGIN_REMEMBER_DAYS").MustInt(7)
CookieUserName = sec.Key("COOKIE_USERNAME").MustString("gitea_awesome")
SecretKey = loadSecret(sec, "SECRET_KEY_URI", "SECRET_KEY")
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 0d69847dbe..d444d9a017 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -183,10 +183,14 @@ func loadRunModeFrom(rootCfg ConfigProvider) {
}
}
+// HasInstallLock checks the install-lock in ConfigProvider directly, because sometimes the config file is not loaded into setting variables yet.
+func HasInstallLock(rootCfg ConfigProvider) bool {
+ return rootCfg.Section("security").Key("INSTALL_LOCK").MustBool(false)
+}
+
func mustCurrentRunUserMatch(rootCfg ConfigProvider) {
// Does not check run user when the "InstallLock" is off.
- installLock := rootCfg.Section("security").Key("INSTALL_LOCK").MustBool(false)
- if installLock {
+ if HasInstallLock(rootCfg) {
currentUser, match := IsRunUserMatchCurrentUser(RunUser)
if !match {
log.Fatal("Expect user '%s' but current user is: %s", RunUser, currentUser)