Fix config loading of cli (#3764)

This commit is contained in:
Anbraten 2024-06-06 13:30:08 +02:00 committed by GitHub
parent 2aa8531ad6
commit 2c7edbf4c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 98 additions and 49 deletions

View file

@ -27,18 +27,18 @@ var GlobalFlags = append([]cli.Flag{
Aliases: []string{"c"}, Aliases: []string{"c"},
Usage: "path to config file", Usage: "path to config file",
}, },
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_TOKEN"},
Name: "token",
Aliases: []string{"t"},
Usage: "server auth token",
},
&cli.StringFlag{ &cli.StringFlag{
EnvVars: []string{"WOODPECKER_SERVER"}, EnvVars: []string{"WOODPECKER_SERVER"},
Name: "server", Name: "server",
Aliases: []string{"s"}, Aliases: []string{"s"},
Usage: "server address", Usage: "server address",
}, },
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_TOKEN"},
Name: "token",
Aliases: []string{"t"},
Usage: "server auth token",
},
&cli.BoolFlag{ &cli.BoolFlag{
EnvVars: []string{"WOODPECKER_DISABLE_UPDATE_CHECK"}, EnvVars: []string{"WOODPECKER_DISABLE_UPDATE_CHECK"},
Name: "disable-update-check", Name: "disable-update-check",

View file

@ -18,6 +18,18 @@ type Config struct {
LogLevel string `json:"log_level"` LogLevel string `json:"log_level"`
} }
func (c *Config) MergeIfNotSet(c2 *Config) {
if c.ServerURL == "" {
c.ServerURL = c2.ServerURL
}
if c.Token == "" {
c.Token = c2.Token
}
if c.LogLevel == "" {
c.LogLevel = c2.LogLevel
}
}
var skipSetupForCommands = []string{"setup", "help", "h", "version", "update", "lint", "exec", ""} var skipSetupForCommands = []string{"setup", "help", "h", "version", "update", "lint", "exec", ""}
func Load(c *cli.Context) error { func Load(c *cli.Context) error {
@ -30,40 +42,28 @@ func Load(c *cli.Context) error {
return err return err
} }
if config == nil {
config = &Config{
LogLevel: "info",
ServerURL: c.String("server-url"),
Token: c.String("token"),
}
}
if !c.IsSet("server") {
err = c.Set("server", config.ServerURL)
if err != nil {
return err
}
}
if !c.IsSet("token") {
err = c.Set("token", config.Token)
if err != nil {
return err
}
}
if !c.IsSet("log-level") {
err = c.Set("log-level", config.LogLevel)
if err != nil {
return err
}
}
if config.ServerURL == "" || config.Token == "" { if config.ServerURL == "" || config.Token == "" {
log.Info().Msg("The woodpecker-cli is not yet set up. Please run `woodpecker-cli setup` or provide the required environment variables / flags.") log.Info().Msg("The woodpecker-cli is not yet set up. Please run `woodpecker-cli setup` or provide the required environment variables / flags.")
return errors.New("woodpecker-cli is not configured") return errors.New("woodpecker-cli is not configured")
} }
err = c.Set("server", config.ServerURL)
if err != nil {
return err
}
err = c.Set("token", config.Token)
if err != nil {
return err
}
err = c.Set("log-level", config.LogLevel)
if err != nil {
return err
}
log.Debug().Any("config", config).Msg("Loaded config")
return nil return nil
} }
@ -81,35 +81,55 @@ func getConfigPath(configPath string) (string, error) {
} }
func Get(ctx *cli.Context, _configPath string) (*Config, error) { func Get(ctx *cli.Context, _configPath string) (*Config, error) {
c := &Config{
LogLevel: ctx.String("log-level"),
Token: ctx.String("token"),
ServerURL: ctx.String("server"),
}
configPath, err := getConfigPath(_configPath) configPath, err := getConfigPath(_configPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.Debug().Str("configPath", configPath).Msg("Checking for config file")
content, err := os.ReadFile(configPath) content, err := os.ReadFile(configPath)
if err != nil && !os.IsNotExist(err) { switch {
case err != nil && !os.IsNotExist(err):
log.Debug().Err(err).Msg("Failed to read the config file") log.Debug().Err(err).Msg("Failed to read the config file")
return nil, err return nil, err
} else if err != nil && os.IsNotExist(err) {
case err != nil && os.IsNotExist(err):
log.Debug().Msg("The config file does not exist") log.Debug().Msg("The config file does not exist")
return nil, nil
default:
configFromFile := &Config{}
err = json.Unmarshal(content, configFromFile)
if err != nil {
return nil, err
}
c.MergeIfNotSet(configFromFile)
log.Debug().Msg("Loaded config from file")
} }
c := &Config{} // if server or token are explicitly set, use them
err = json.Unmarshal(content, c) if ctx.IsSet("server") || ctx.IsSet("token") {
if err != nil { return c, nil
return nil, err
} }
// load token from keyring // load token from keyring
service := ctx.App.Name service := ctx.App.Name
secret, err := keyring.Get(service, c.ServerURL) secret, err := keyring.Get(service, c.ServerURL)
if err != nil && !errors.Is(err, keyring.ErrNotFound) { if errors.Is(err, keyring.ErrUnsupportedPlatform) {
return nil, err log.Warn().Msg("Keyring is not supported on this platform")
return c, nil
} }
if err == nil { if errors.Is(err, keyring.ErrNotFound) {
c.Token = secret log.Warn().Msg("Token not found in keyring")
return c, nil
} }
c.Token = secret
return c, nil return c, nil
} }

View file

@ -0,0 +1,27 @@
package config
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestConfigMerge(t *testing.T) {
config := &Config{
ServerURL: "http://localhost:8080",
Token: "1234567890",
LogLevel: "debug",
}
configFromFile := &Config{
ServerURL: "https://ci.woodpecker-ci.org",
Token: "",
LogLevel: "info",
}
config.MergeIfNotSet(configFromFile)
assert.Equal(t, config.ServerURL, "http://localhost:8080")
assert.Equal(t, config.Token, "1234567890")
assert.Equal(t, config.LogLevel, "debug")
}

View file

@ -16,10 +16,10 @@ var Command = &cli.Command{
Name: "setup", Name: "setup",
Usage: "setup the woodpecker-cli for the first time", Usage: "setup the woodpecker-cli for the first time",
Args: true, Args: true,
ArgsUsage: "[server-url]", ArgsUsage: "[server]",
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
Name: "server-url", Name: "server",
Usage: "The URL of the woodpecker server", Usage: "The URL of the woodpecker server",
}, },
&cli.StringFlag{ &cli.StringFlag{
@ -46,7 +46,7 @@ func setup(c *cli.Context) error {
} }
} }
serverURL := c.String("server-url") serverURL := c.String("server")
if serverURL == "" { if serverURL == "" {
serverURL = c.Args().First() serverURL = c.Args().First()
} }

View file

@ -12,6 +12,7 @@ FROM docker.io/alpine:3.20
ENV CA_CERTIFICATES_VERSION="20240226-r0" ENV CA_CERTIFICATES_VERSION="20240226-r0"
RUN apk add -U --no-cache ca-certificates=${CA_CERTIFICATES_VERSION} RUN apk add -U --no-cache ca-certificates=${CA_CERTIFICATES_VERSION}
ENV GODEBUG=netdns=go ENV GODEBUG=netdns=go
ENV WOODPECKER_DISABLE_UPDATE_CHECK=true
COPY --from=build /src/dist/woodpecker-cli /bin/ COPY --from=build /src/dist/woodpecker-cli /bin/

View file

@ -9,6 +9,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
FROM scratch FROM scratch
ENV GODEBUG=netdns=go ENV GODEBUG=netdns=go
ENV WOODPECKER_DISABLE_UPDATE_CHECK=true
# copy certs from build image # copy certs from build image
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt