Skip to content

Commit 13185e6

Browse files
committed
fix
1 parent e03a68c commit 13185e6

File tree

10 files changed

+235
-175
lines changed

10 files changed

+235
-175
lines changed

Dockerfile

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,16 @@ WORKDIR ${GOPATH}/src/code.gitea.io/gitea
2626
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
2727
&& make clean-all build
2828

29-
# Begin env-to-ini build
30-
RUN go build contrib/environment-to-ini/environment-to-ini.go
31-
3229
# Copy local files
3330
COPY docker/root /tmp/local
3431

3532
# Set permissions
3633
RUN chmod 755 /tmp/local/usr/bin/entrypoint \
37-
/tmp/local/usr/local/bin/gitea \
34+
/tmp/local/usr/local/bin/* \
3835
/tmp/local/etc/s6/gitea/* \
3936
/tmp/local/etc/s6/openssh/* \
4037
/tmp/local/etc/s6/.s6-svscan/* \
41-
/go/src/code.gitea.io/gitea/gitea \
42-
/go/src/code.gitea.io/gitea/environment-to-ini
38+
/go/src/code.gitea.io/gitea/gitea
4339

4440
FROM docker.io/library/alpine:3.22
4541
LABEL maintainer="maintainers@gitea.io"
@@ -82,4 +78,3 @@ CMD ["/usr/bin/s6-svscan", "/etc/s6"]
8278

8379
COPY --from=build-env /tmp/local /
8480
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
85-
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini

Dockerfile.rootless

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,12 @@ WORKDIR ${GOPATH}/src/code.gitea.io/gitea
2626
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
2727
&& make clean-all build
2828

29-
# Begin env-to-ini build
30-
RUN go build contrib/environment-to-ini/environment-to-ini.go
31-
3229
# Copy local files
3330
COPY docker/rootless /tmp/local
3431

3532
# Set permissions
36-
RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \
37-
/tmp/local/usr/local/bin/docker-setup.sh \
38-
/tmp/local/usr/local/bin/gitea \
39-
/go/src/code.gitea.io/gitea/gitea \
40-
/go/src/code.gitea.io/gitea/environment-to-ini
33+
RUN chmod 755 /tmp/local/usr/local/bin/* \
34+
/go/src/code.gitea.io/gitea/gitea
4135

4236
FROM docker.io/library/alpine:3.22
4337
LABEL maintainer="maintainers@gitea.io"
@@ -71,7 +65,6 @@ RUN chown git:git /var/lib/gitea /etc/gitea
7165

7266
COPY --from=build-env /tmp/local /
7367
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
74-
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
7568

7669
# git:git
7770
USER 1000:1000

cmd/config_update.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package cmd
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"os"
10+
11+
"code.gitea.io/gitea/modules/setting"
12+
"code.gitea.io/gitea/modules/util"
13+
14+
"github.com/urfave/cli/v3"
15+
)
16+
17+
func cmdConfig() *cli.Command {
18+
subcmdConfigUpdateIni := &cli.Command{
19+
Name: "update-ini",
20+
Usage: "Load an existing INI file, apply environment variables, keep specified keys, and output to a new INI file.",
21+
Description: `
22+
Help users to update the gitea configuration INI file:
23+
* Keep specified keys to for the new INI file.
24+
* Map environment variables to values in the INI.
25+
26+
# Keep Specified Keys
27+
28+
If you need to re-create the configuration file with only a subset of keys,
29+
you can provide an INI template file and use the "--config-keep-template" flag.
30+
For example, if a helm chart needs to reset the settings and only keep SECRET_KEY,
31+
it can use a template file like:
32+
33+
[security]
34+
SECRET_KEY=
35+
36+
$ ./gitea config update-ini --config app-old.ini --config-keep-template app-template.ini --out app-new.ini
37+
38+
# Map Environment Variables to INI Configuration
39+
40+
Environment variables of the form "GITEA__section_name__KEY_NAME"
41+
will be mapped to the ini section "[section_name]" and the key
42+
"KEY_NAME" with the value as provided.
43+
44+
Environment variables of the form "GITEA__section_name__KEY_NAME__FILE"
45+
will be mapped to the ini section "[section_name]" and the key
46+
"KEY_NAME" with the value loaded from the specified file.
47+
48+
Environment variable keys can only contain characters "0-9A-Z_",
49+
if a section or key name contains dot ".", it needs to be escaped as _0x2E_.
50+
For example, to apply this config:
51+
52+
[git.config]
53+
foo.bar=val
54+
55+
$ export GITEA__git_0x2E_config__foo_0x2E_bar=val
56+
57+
# Put All Together
58+
59+
$ ./gitea config update-ini --config app.ini --config-keep-template app-template.ini --apply-env
60+
`,
61+
Flags: []cli.Flag{
62+
// "--config" flag is provided by global flags, and this flag is also used by "environment-to-ini" script wrapper
63+
&cli.StringFlag{
64+
Name: "config-keep-template",
65+
Usage: "An INI template file containing keys for updating. Only the keys defined in the INI template will be kept from old config. If not set, all keys will be kept.",
66+
},
67+
&cli.BoolFlag{
68+
Name: "apply-env",
69+
Usage: "Apply all GITEA__* variables from the environment to the config.",
70+
},
71+
&cli.StringFlag{
72+
Name: "out",
73+
Usage: "Destination config file to write to. If not set, will overwrite the source config file.",
74+
},
75+
},
76+
Action: runConfigUpdateIni,
77+
}
78+
79+
return &cli.Command{
80+
Name: "config",
81+
Usage: "Manage Gitea configuration",
82+
Commands: []*cli.Command{
83+
subcmdConfigUpdateIni,
84+
},
85+
}
86+
}
87+
88+
func runConfigUpdateIni(_ context.Context, c *cli.Command) error {
89+
// the config system may change the environment variables, so get a copy first, to be used later
90+
env := append([]string{}, os.Environ()...)
91+
if !c.IsSet("config") {
92+
return fmt.Errorf("flag is required but not set: --config")
93+
}
94+
95+
configFileIn := c.String("config")
96+
cfgIn, err := setting.NewConfigProviderFromFile(configFileIn)
97+
if err != nil {
98+
return fmt.Errorf("failed to load config file %q: %v", configFileIn, err)
99+
}
100+
101+
configFileOut := c.String("out")
102+
configFileOut = util.IfZero(configFileOut, configFileIn)
103+
needWriteOut := configFileOut != configFileIn
104+
105+
cfgOut := cfgIn
106+
if c.IsSet("config-keep-template") {
107+
needWriteOut = true
108+
configKeepTemplate := c.String("config-keep-template")
109+
cfgOut, err = setting.NewConfigProviderFromFile(configKeepTemplate)
110+
if err != nil {
111+
return fmt.Errorf("failed to load config keep template file %q: %v", configKeepTemplate, err)
112+
}
113+
114+
for _, secOut := range cfgOut.Sections() {
115+
for _, keyOut := range secOut.Keys() {
116+
secIn := cfgIn.Section(secOut.Name())
117+
keyIn := setting.ConfigSectionKey(secIn, keyOut.Name())
118+
if keyIn != nil {
119+
keyOut.SetValue(keyIn.String())
120+
} else {
121+
secOut.DeleteKey(keyOut.Name())
122+
}
123+
}
124+
if len(secOut.Keys()) == 0 {
125+
cfgOut.DeleteSection(secOut.Name())
126+
}
127+
}
128+
}
129+
130+
if c.Bool("apply-env") {
131+
if setting.EnvironmentToConfig(cfgOut, env) {
132+
needWriteOut = true
133+
}
134+
}
135+
136+
if needWriteOut {
137+
_, _ = fmt.Fprintf(c.Writer, "Saving config to: %q\n", configFileOut)
138+
err = cfgOut.SaveTo(configFileOut)
139+
if err != nil {
140+
return err
141+
}
142+
}
143+
return nil
144+
}

cmd/config_update_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package cmd
5+
6+
import (
7+
"os"
8+
"testing"
9+
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestConfigUpdate(t *testing.T) {
14+
configOld := t.TempDir() + "/app-old.ini"
15+
configTemplate := t.TempDir() + "/app-template.ini"
16+
_ = os.WriteFile(configOld, []byte(`
17+
[sec]
18+
k1=v1
19+
k2=v2
20+
`), os.ModePerm)
21+
22+
_ = os.WriteFile(configTemplate, []byte(`
23+
[sec]
24+
k1=in-template
25+
26+
[sec2]
27+
k3=v3
28+
`), os.ModePerm)
29+
30+
t.Setenv("GITEA__EnV__KeY", "val")
31+
32+
t.Run("OutputToNewWithEnv", func(t *testing.T) {
33+
configNew := t.TempDir() + "/app-new.ini"
34+
err := NewMainApp(AppVersion{}).Run(t.Context(), []string{
35+
"./gitea", "--config", configOld, "config", "update-ini",
36+
"--apply-env",
37+
"--config-keep-template", configTemplate,
38+
"--out", configNew,
39+
})
40+
require.NoError(t, err)
41+
42+
// "k1" old value is kept because its key is in the template
43+
// "k2" is removed because it isn't in the template
44+
// "k3" isn't in new config because it isn't in the old config
45+
// [env] is applied from environment variable
46+
data, _ := os.ReadFile(configNew)
47+
require.Equal(t, `[sec]
48+
k1 = v1
49+
50+
[env]
51+
KeY = val
52+
`, string(data))
53+
})
54+
55+
t.Run("OutputToExisting(environment-to-ini)", func(t *testing.T) {
56+
err := NewMainApp(AppVersion{}).Run(t.Context(), []string{
57+
"./gitea", "config", "update-ini",
58+
"--apply-env",
59+
"--config", configOld,
60+
})
61+
require.NoError(t, err)
62+
63+
data, _ := os.ReadFile(configOld)
64+
require.Equal(t, `[sec]
65+
k1 = v1
66+
k2 = v2
67+
68+
[env]
69+
KeY = val
70+
`, string(data))
71+
})
72+
}

cmd/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ func NewMainApp(appVer AppVersion) *cli.Command {
128128

129129
// these sub-commands do not need the config file, and they do not depend on any path or environment variable.
130130
subCmdStandalone := []*cli.Command{
131+
cmdConfig(),
131132
cmdCert(),
132133
CmdGenerate,
133134
CmdDocs,

contrib/environment-to-ini/README

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)