cmd/tailscale/cli: improve error when bg serve config is present (#9961)

We prevent shodow configs when starting a foreground when a background serve config already exists for the serve type and port. This PR improves the messaging to let the user know how to remove the previous config.

Updates #8489
ENG-2314

Signed-off-by: Tyler Smalley <tyler@tailscale.com>
This commit is contained in:
Tyler Smalley 2023-10-25 14:27:46 -07:00 committed by GitHub
parent 1873bc471b
commit 131518eed1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 3 deletions

View File

@ -271,7 +271,13 @@ func (e *serveEnv) runServeCombined(subcmd serveMode) execFunc {
}
var watcher *tailscale.IPNBusWatcher
if !e.bg && !turnOff {
wantFg := !e.bg && !turnOff
if wantFg {
// validate the config before creating a WatchIPNBus session
if err := e.validateConfig(parentSC, srvPort, srvType); err != nil {
return err
}
// if foreground mode, create a WatchIPNBus session
// and use the nested config for all following operations
// TODO(marwan-at-work): nested-config validations should happen here or previous to this point.
@ -334,6 +340,8 @@ func (e *serveEnv) runServeCombined(subcmd serveMode) execFunc {
}
}
const backgroundExistsMsg = "background configuration already exists, use `tailscale %s --%s=%d off` to remove the existing configuration"
func (e *serveEnv) validateConfig(sc *ipn.ServeConfig, port uint16, wantServe serveType) error {
sc, isFg := findConfig(sc, port)
if sc == nil {
@ -343,7 +351,7 @@ func (e *serveEnv) validateConfig(sc *ipn.ServeConfig, port uint16, wantServe se
return errors.New("foreground already exists under this port")
}
if !e.bg {
return errors.New("background serve already exists under this port")
return fmt.Errorf(backgroundExistsMsg, infoMap[e.subcmd].Name, wantServe.String(), port)
}
existingServe := serveFromPortHandler(sc.TCP[port])
if wantServe != existingServe {

View File

@ -792,6 +792,26 @@ type group struct {
},
},
},
{
name: "forground_with_bg_conflict",
steps: []step{
{
command: cmd("serve --bg --http=3000 localhost:3000"),
want: &ipn.ServeConfig{
TCP: map[uint16]*ipn.TCPPortHandler{3000: {HTTP: true}},
Web: map[ipn.HostPort]*ipn.WebServerConfig{
"foo.test.ts.net:3000": {Handlers: map[string]*ipn.HTTPHandler{
"/": {Proxy: "http://127.0.0.1:3000"},
}},
},
},
},
{
command: cmd("serve --http=3000 localhost:3000"),
wantErr: exactErrMsg(fmt.Errorf(backgroundExistsMsg, "serve", "http", 3000)),
},
},
},
}
for _, group := range groups {
@ -1330,6 +1350,6 @@ func exactErrMsg(want error) func(error) string {
if got.Error() == want.Error() {
return ""
}
return fmt.Sprintf("got error %v, want %v", got, want)
return fmt.Sprintf("\ngot: %v\nwant: %v\n", got, want)
}
}