Skip to content

Commit 8f787b0

Browse files
committed
fix
1 parent f1cb461 commit 8f787b0

File tree

11 files changed

+84
-68
lines changed

11 files changed

+84
-68
lines changed

Diff for: contrib/environment-to-ini/environment-to-ini.go

+1-30
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,13 @@ package main
55

66
import (
77
"os"
8-
"strings"
98

109
"code.gitea.io/gitea/modules/log"
1110
"code.gitea.io/gitea/modules/setting"
1211

1312
"github.com/urfave/cli"
1413
)
1514

16-
// EnvironmentPrefix environment variables prefixed with this represent ini values to write
17-
const EnvironmentPrefix = "GITEA"
18-
1915
func main() {
2016
app := cli.NewApp()
2117
app.Name = "environment-to-ini"
@@ -70,15 +66,6 @@ func main() {
7066
Value: "",
7167
Usage: "Destination file to write to",
7268
},
73-
cli.BoolFlag{
74-
Name: "clear",
75-
Usage: "Clears the matched variables from the environment",
76-
},
77-
cli.StringFlag{
78-
Name: "prefix, p",
79-
Value: EnvironmentPrefix,
80-
Usage: "Environment prefix to look for - will be suffixed by __ (2 underscores)",
81-
},
8269
}
8370
app.Action = runEnvironmentToIni
8471
err := app.Run(os.Args)
@@ -99,9 +86,7 @@ func runEnvironmentToIni(c *cli.Context) error {
9986
log.Fatal("Failed to load custom conf '%s': %v", setting.CustomConf, err)
10087
}
10188

102-
prefixGitea := c.String("prefix") + "__"
103-
suffixFile := "__FILE"
104-
changed := setting.EnvironmentToConfig(cfg, prefixGitea, suffixFile, os.Environ())
89+
changed := setting.EnvironmentToConfig(cfg, os.Environ())
10590

10691
// try to save the config file
10792
destination := c.String("out")
@@ -116,19 +101,5 @@ func runEnvironmentToIni(c *cli.Context) error {
116101
}
117102
}
118103

119-
// clear Gitea's specific environment variables if requested
120-
if c.Bool("clear") {
121-
for _, kv := range os.Environ() {
122-
idx := strings.IndexByte(kv, '=')
123-
if idx < 0 {
124-
continue
125-
}
126-
eKey := kv[:idx]
127-
if strings.HasPrefix(eKey, prefixGitea) {
128-
_ = os.Unsetenv(eKey)
129-
}
130-
}
131-
}
132-
133104
return nil
134105
}

Diff for: modules/assetfs/layered.go

+1
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ func (l *LayeredFS) WatchLocalChanges(ctx context.Context, callback func()) {
215215
log.Error("Unable to list directories for asset local file-system %q: %v", layer.localPath, err)
216216
continue
217217
}
218+
layerDirs = append(layerDirs, ".")
218219
for _, dir := range layerDirs {
219220
if err = watcher.Add(util.FilePathJoinAbs(layer.localPath, dir)); err != nil {
220221
log.Error("Unable to watch directory %s: %v", dir, err)

Diff for: modules/setting/config_env.go

+23-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,31 @@ import (
1212
"code.gitea.io/gitea/modules/log"
1313
)
1414

15+
const (
16+
EnvConfigKeyPrefixGitea = "GITEA__"
17+
EnvConfigKeySuffixFile = "__FILE"
18+
)
19+
1520
const escapeRegexpString = "_0[xX](([0-9a-fA-F][0-9a-fA-F])+)_"
1621

1722
var escapeRegex = regexp.MustCompile(escapeRegexpString)
1823

24+
func CollectEnvConfigKeys() (keys []string) {
25+
for _, env := range os.Environ() {
26+
if strings.HasPrefix(env, EnvConfigKeyPrefixGitea) {
27+
k, _, _ := strings.Cut(env, "=")
28+
keys = append(keys, k)
29+
}
30+
}
31+
return keys
32+
}
33+
34+
func ClearEnvConfigKeys() {
35+
for _, k := range CollectEnvConfigKeys() {
36+
_ = os.Unsetenv(k)
37+
}
38+
}
39+
1940
// decodeEnvSectionKey will decode a portable string encoded Section__Key pair
2041
// Portable strings are considered to be of the form [A-Z0-9_]*
2142
// 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
87108
return ok, section, key, useFileValue
88109
}
89110

90-
func EnvironmentToConfig(cfg ConfigProvider, prefixGitea, suffixFile string, envs []string) (changed bool) {
111+
func EnvironmentToConfig(cfg ConfigProvider, envs []string) (changed bool) {
91112
for _, kv := range envs {
92113
idx := strings.IndexByte(kv, '=')
93114
if idx < 0 {
@@ -97,7 +118,7 @@ func EnvironmentToConfig(cfg ConfigProvider, prefixGitea, suffixFile string, env
97118
// parse the environment variable to config section name and key name
98119
envKey := kv[:idx]
99120
envValue := kv[idx+1:]
100-
ok, sectionName, keyName, useFileValue := decodeEnvironmentKey(prefixGitea, suffixFile, envKey)
121+
ok, sectionName, keyName, useFileValue := decodeEnvironmentKey(EnvConfigKeyPrefixGitea, EnvConfigKeySuffixFile, envKey)
101122
if !ok {
102123
continue
103124
}

Diff for: modules/setting/config_env_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func TestDecodeEnvironmentKey(t *testing.T) {
7272
func TestEnvironmentToConfig(t *testing.T) {
7373
cfg, _ := NewConfigProviderFromData("")
7474

75-
changed := EnvironmentToConfig(cfg, "GITEA__", "__FILE", nil)
75+
changed := EnvironmentToConfig(cfg, nil)
7676
assert.False(t, changed)
7777

7878
cfg, err := NewConfigProviderFromData(`
@@ -81,16 +81,16 @@ key = old
8181
`)
8282
assert.NoError(t, err)
8383

84-
changed = EnvironmentToConfig(cfg, "GITEA__", "__FILE", []string{"GITEA__sec__key=new"})
84+
changed = EnvironmentToConfig(cfg, []string{"GITEA__sec__key=new"})
8585
assert.True(t, changed)
8686
assert.Equal(t, "new", cfg.Section("sec").Key("key").String())
8787

88-
changed = EnvironmentToConfig(cfg, "GITEA__", "__FILE", []string{"GITEA__sec__key=new"})
88+
changed = EnvironmentToConfig(cfg, []string{"GITEA__sec__key=new"})
8989
assert.False(t, changed)
9090

9191
tmpFile := t.TempDir() + "/the-file"
9292
_ = os.WriteFile(tmpFile, []byte("value-from-file"), 0o644)
93-
changed = EnvironmentToConfig(cfg, "GITEA__", "__FILE", []string{"GITEA__sec__key__FILE=" + tmpFile})
93+
changed = EnvironmentToConfig(cfg, []string{"GITEA__sec__key__FILE=" + tmpFile})
9494
assert.True(t, changed)
9595
assert.Equal(t, "value-from-file", cfg.Section("sec").Key("key").String())
9696
}

Diff for: modules/setting/path.go

+3
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkP
171171

172172
// only read the config but do not load/init anything more, because the AppWorkPath and CustomPath are not ready
173173
InitCfgProvider(tmpCustomConf.Value)
174+
if HasInstallLock(CfgProvider) {
175+
ClearEnvConfigKeys() // if the instance has been installed, do not pass the environment variables to sub-processes
176+
}
174177
configWorkPath := ConfigSectionKeyString(CfgProvider.Section(""), "WORK_PATH")
175178
if configWorkPath != "" {
176179
if !filepath.IsAbs(configWorkPath) {

Diff for: modules/setting/security.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func generateSaveInternalToken(rootCfg ConfigProvider) {
102102

103103
func loadSecurityFrom(rootCfg ConfigProvider) {
104104
sec := rootCfg.Section("security")
105-
InstallLock = sec.Key("INSTALL_LOCK").MustBool(false)
105+
InstallLock = HasInstallLock(rootCfg)
106106
LogInRememberDays = sec.Key("LOGIN_REMEMBER_DAYS").MustInt(7)
107107
CookieUserName = sec.Key("COOKIE_USERNAME").MustString("gitea_awesome")
108108
SecretKey = loadSecret(sec, "SECRET_KEY_URI", "SECRET_KEY")

Diff for: modules/setting/setting.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,14 @@ func loadRunModeFrom(rootCfg ConfigProvider) {
183183
}
184184
}
185185

186+
// HasInstallLock checks the install-lock in ConfigProvider directly, because sometimes the config file is not loaded into setting variables yet.
187+
func HasInstallLock(rootCfg ConfigProvider) bool {
188+
return rootCfg.Section("security").Key("INSTALL_LOCK").MustBool(false)
189+
}
190+
186191
func mustCurrentRunUserMatch(rootCfg ConfigProvider) {
187192
// Does not check run user when the "InstallLock" is off.
188-
installLock := rootCfg.Section("security").Key("INSTALL_LOCK").MustBool(false)
189-
if installLock {
193+
if HasInstallLock(rootCfg) {
190194
currentUser, match := IsRunUserMatchCurrentUser(RunUser)
191195
if !match {
192196
log.Fatal("Expect user '%s' but current user is: %s", RunUser, currentUser)

Diff for: options/locale/locale_en-US.ini

+2
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ invalid_password_algorithm = Invalid password hash algorithm
296296
password_algorithm_helper = Set the password hashing algorithm. Algorithms have differing requirements and strength. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.
297297
enable_update_checker = Enable Update Checker
298298
enable_update_checker_helper = Checks for new version releases periodically by connecting to gitea.io.
299+
env_config_keys = Environment Configuration
300+
env_config_keys_prompt = The following environment variables will also be applied to your configuration file:
299301

300302
[home]
301303
uname_holder = Username or Email Address

Diff for: routers/install/install.go

+12-6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ func getSupportedDbTypeNames() (dbTypeNames []map[string]string) {
5656
func Contexter() func(next http.Handler) http.Handler {
5757
rnd := templates.HTMLRenderer()
5858
dbTypeNames := getSupportedDbTypeNames()
59+
envConfigKeys := setting.CollectEnvConfigKeys()
5960
return func(next http.Handler) http.Handler {
6061
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
6162
base, baseCleanUp := context.NewBaseContext(resp, req)
@@ -70,11 +71,13 @@ func Contexter() func(next http.Handler) http.Handler {
7071
ctx.AppendContextValue(context.WebContextKey, ctx)
7172
ctx.Data.MergeFrom(middleware.CommonTemplateContextData())
7273
ctx.Data.MergeFrom(middleware.ContextData{
73-
"locale": ctx.Locale,
74-
"Title": ctx.Locale.Tr("install.install"),
75-
"PageIsInstall": true,
76-
"DbTypeNames": dbTypeNames,
77-
"AllLangs": translation.AllLangs(),
74+
"locale": ctx.Locale,
75+
"Title": ctx.Locale.Tr("install.install"),
76+
"PageIsInstall": true,
77+
"DbTypeNames": dbTypeNames,
78+
"EnvConfigKeys": envConfigKeys,
79+
"CustomConfFile": setting.CustomConf,
80+
"AllLangs": translation.AllLangs(),
7881

7982
"PasswordHashAlgorithms": hash.RecommendedHashAlgorithms,
8083
})
@@ -218,7 +221,7 @@ func checkDatabase(ctx *context.Context, form *forms.InstallForm) bool {
218221
return false
219222
}
220223

221-
log.Info("User confirmed reinstallation of Gitea into a pre-existing database")
224+
log.Info("User confirmed re-installation of Gitea into a pre-existing database")
222225
}
223226

224227
if hasPostInstallationUser || dbMigrationVersion > 0 {
@@ -502,6 +505,8 @@ func SubmitInstall(ctx *context.Context) {
502505
return
503506
}
504507

508+
setting.EnvironmentToConfig(cfg, os.Environ())
509+
505510
if err = cfg.SaveTo(setting.CustomConf); err != nil {
506511
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
507512
return
@@ -568,6 +573,7 @@ func SubmitInstall(ctx *context.Context) {
568573
}
569574
}
570575

576+
setting.ClearEnvConfigKeys()
571577
log.Info("First-time run install finished!")
572578
InstallDone(ctx)
573579

Diff for: templates/install.tmpl

+25-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{{template "base/head" .}}
22
<div role="main" aria-label="{{.Title}}" class="page-content install">
3-
<div class="ui middle very relaxed page grid">
3+
<div class="ui grid install-config-container">
44
<div class="sixteen wide center aligned centered column">
55
<h3 class="ui top attached header">
66
{{.locale.Tr "install.title"}}
@@ -148,8 +148,8 @@
148148
<span class="help">{{.locale.Tr "install.log_root_path_helper"}}</span>
149149
</div>
150150
<div class="inline field">
151-
<div class="ui checkbox">
152-
<label for="enable_update_checker">{{.locale.Tr "install.enable_update_checker"}}</label>
151+
<div class="ui checkbox right-content">
152+
<label>{{.locale.Tr "install.enable_update_checker"}}</label>
153153
<input name="enable_update_checker" type="checkbox">
154154
</div>
155155
<span class="help">{{.locale.Tr "install.enable_update_checker_helper"}}</span>
@@ -161,7 +161,7 @@
161161

162162
<!-- Email -->
163163
<details class="optional field">
164-
<summary class="title gt-py-3{{if .Err_SMTP}} text red{{end}}">
164+
<summary class="right-content gt-py-3{{if .Err_SMTP}} text red{{end}}">
165165
{{.locale.Tr "install.email_title"}}
166166
</summary>
167167
<div class="inline field">
@@ -201,7 +201,7 @@
201201

202202
<!-- Server and other services -->
203203
<details class="optional field">
204-
<summary class="title gt-py-3{{if .Err_Services}} text red{{end}}">
204+
<summary class="right-content gt-py-3{{if .Err_Services}} text red{{end}}">
205205
{{.locale.Tr "install.server_service_title"}}
206206
</summary>
207207
<div class="inline field">
@@ -299,7 +299,7 @@
299299

300300
<!-- Admin -->
301301
<details class="optional field">
302-
<summary class="title gt-py-3{{if .Err_Admin}} text red{{end}}">
302+
<summary class="right-content gt-py-3{{if .Err_Admin}} text red{{end}}">
303303
{{.locale.Tr "install.admin_title"}}
304304
</summary>
305305
<p class="center">{{.locale.Tr "install.admin_setting_desc"}}</p>
@@ -321,10 +321,27 @@
321321
</div>
322322
</details>
323323

324+
{{if .EnvConfigKeys}}
325+
<!-- Environment Config -->
326+
<h4 class="ui dividing header">{{.locale.Tr "install.env_config_keys"}}</h4>
327+
<div class="inline field">
328+
<div class="right-content">
329+
{{.locale.Tr "install.env_config_keys_prompt"}}
330+
</div>
331+
<div class="right-content gt-mt-3">
332+
{{range .EnvConfigKeys}}<span class="ui label">{{.}}</span>{{end}}
333+
</div>
334+
</div>
335+
{{end}}
336+
324337
<div class="divider"></div>
325338
<div class="inline field">
326-
<label></label>
327-
<button class="ui primary button">{{.locale.Tr "install.install_btn_confirm"}}</button>
339+
<div class="right-content">
340+
These configuration options will be written into: {{.CustomConfFile}}
341+
</div>
342+
<div class="right-content gt-mt-3">
343+
<button class="ui primary button">{{.locale.Tr "install.install_btn_confirm"}}</button>
344+
</div>
328345
</div>
329346
</form>
330347
</div>

Diff for: web_src/css/install.css

+6-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
.page-content.install {
2-
padding-top: 45px;
1+
.page-content.install .install-config-container {
2+
max-width: 900px;
3+
margin: auto;
34
}
45

56
.page-content.install form.ui.form .inline.field > label {
@@ -9,7 +10,8 @@
910
margin-right: 0;
1011
}
1112

12-
.page-content.install form.ui.form .inline.field > .ui.checkbox:first-child {
13+
.page-content.install .ui.form .field .help,
14+
.page-content.install .ui.form .field .right-content {
1315
margin-left: 30%;
1416
padding-left: 5px;
1517
}
@@ -18,17 +20,12 @@
1820
width: auto;
1921
}
2022

21-
.page-content.install form.ui.form .title {
22-
margin-left: 30%;
23-
padding-left: 5px;
24-
}
25-
2623
.page-content.install form.ui.form input {
2724
width: 60%;
2825
}
2926

3027
.page-content.install form.ui.form details.optional.field[open] {
31-
border-bottom: 1px solid var(--color-secondary);
28+
border-bottom: 1px dashed var(--color-secondary);
3229
padding-bottom: 10px;
3330
}
3431

@@ -44,12 +41,6 @@
4441
text-align: left;
4542
}
4643

47-
.page-content.install form.ui.form .field .help {
48-
margin-left: 30%;
49-
padding-left: 5px;
50-
width: 60%;
51-
}
52-
5344
.page-content.install .ui .reinstall-message {
5445
width: 70%;
5546
margin: 20px auto;

0 commit comments

Comments
 (0)