cmd/containerboot: allow setting --accept-dns via TS_EXTRA_ARGS again (#16129)
In 1.84 we made 'tailscale set'/'tailscale up' error out if duplicate command line flags are passed. This broke some container configurations as we have two env vars that can be used to set --accept-dns flag: - TS_ACCEPT_DNS- specifically for --accept-dns - TS_EXTRA_ARGS- accepts any arbitrary 'tailscale up'/'tailscale set' flag. We default TS_ACCEPT_DNS to false (to make the container behaviour more declarative), which with the new restrictive CLI behaviour resulted in failure for users who had set --accept-dns via TS_EXTRA_ARGS as the flag would be provided twice. This PR re-instates the previous behaviour by checking if TS_EXTRA_ARGS contains --accept-dns flag and if so using its value to override TS_ACCEPT_DNS. Updates tailscale/tailscale#16108 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit is contained in:
@@ -147,12 +147,69 @@ func configFromEnv() (*settings, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// See https://github.com/tailscale/tailscale/issues/16108 for context- we
|
||||
// do this to preserve the previous behaviour where --accept-dns could be
|
||||
// set either via TS_ACCEPT_DNS or TS_EXTRA_ARGS.
|
||||
acceptDNS := cfg.AcceptDNS != nil && *cfg.AcceptDNS
|
||||
tsExtraArgs, acceptDNSNew := parseAcceptDNS(cfg.ExtraArgs, acceptDNS)
|
||||
cfg.ExtraArgs = tsExtraArgs
|
||||
if acceptDNS != acceptDNSNew {
|
||||
cfg.AcceptDNS = &acceptDNSNew
|
||||
}
|
||||
|
||||
if err := cfg.validate(); err != nil {
|
||||
return nil, fmt.Errorf("invalid configuration: %v", err)
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// parseAcceptDNS parses any values for Tailscale --accept-dns flag set via
|
||||
// TS_ACCEPT_DNS and TS_EXTRA_ARGS env vars. If TS_EXTRA_ARGS contains
|
||||
// --accept-dns flag, override the acceptDNS value with the one from
|
||||
// TS_EXTRA_ARGS.
|
||||
// The value of extraArgs can be empty string or one or more whitespace-separate
|
||||
// key value pairs for 'tailscale up' command. The value for boolean flags can
|
||||
// be omitted (default to true).
|
||||
func parseAcceptDNS(extraArgs string, acceptDNS bool) (string, bool) {
|
||||
if !strings.Contains(extraArgs, "--accept-dns") {
|
||||
return extraArgs, acceptDNS
|
||||
}
|
||||
// TODO(irbekrm): we should validate that TS_EXTRA_ARGS contains legit
|
||||
// 'tailscale up' flag values separated by whitespace.
|
||||
argsArr := strings.Fields(extraArgs)
|
||||
i := -1
|
||||
for key, val := range argsArr {
|
||||
if strings.HasPrefix(val, "--accept-dns") {
|
||||
i = key
|
||||
break
|
||||
}
|
||||
}
|
||||
if i == -1 {
|
||||
return extraArgs, acceptDNS
|
||||
}
|
||||
a := strings.TrimSpace(argsArr[i])
|
||||
var acceptDNSFromExtraArgsS string
|
||||
keyval := strings.Split(a, "=")
|
||||
if len(keyval) == 2 {
|
||||
acceptDNSFromExtraArgsS = keyval[1]
|
||||
} else if len(keyval) == 1 && keyval[0] == "--accept-dns" {
|
||||
// If the arg is just --accept-dns, we assume it means true.
|
||||
acceptDNSFromExtraArgsS = "true"
|
||||
} else {
|
||||
log.Printf("TS_EXTRA_ARGS contains --accept-dns, but it is not in the expected format --accept-dns=<true|false>, ignoring it")
|
||||
return extraArgs, acceptDNS
|
||||
}
|
||||
acceptDNSFromExtraArgs, err := strconv.ParseBool(acceptDNSFromExtraArgsS)
|
||||
if err != nil {
|
||||
log.Printf("TS_EXTRA_ARGS contains --accept-dns=%q, which is not a valid boolean value, ignoring it", acceptDNSFromExtraArgsS)
|
||||
return extraArgs, acceptDNS
|
||||
}
|
||||
if acceptDNSFromExtraArgs != acceptDNS {
|
||||
log.Printf("TS_EXTRA_ARGS contains --accept-dns=%v, which overrides TS_ACCEPT_DNS=%v", acceptDNSFromExtraArgs, acceptDNS)
|
||||
}
|
||||
return strings.Join(append(argsArr[:i], argsArr[i+1:]...), " "), acceptDNSFromExtraArgs
|
||||
}
|
||||
|
||||
func (s *settings) validate() error {
|
||||
if s.TailscaledConfigFilePath != "" {
|
||||
dir, file := path.Split(s.TailscaledConfigFilePath)
|
||||
|
||||
Reference in New Issue
Block a user