mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-25 11:21:02 +00:00
Fix config loading of cli (#3764)
This commit is contained in:
parent
2aa8531ad6
commit
2c7edbf4c8
6 changed files with 98 additions and 49 deletions
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
27
cli/internal/config/config_test.go
Normal file
27
cli/internal/config/config_test.go
Normal 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")
|
||||||
|
}
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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/
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue