From 7f7a81e5aef4fbc8579d630c7079b618bd628b3f Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 19 Jul 2021 15:01:41 -0700 Subject: [PATCH] cmd/tailscaled: add func to create ipnserver.Opts To unify the Windows service and non-service/non-Windows paths a bit. And provides a way to make Linux act like Windows for testing. (notably, for testing the fix to #2137) One perhaps visible change of this is that tailscaled.exe when run in cmd.exe/powershell (not as a Windows Service) no longer uses the "_daemon" autostart key. But in addition to being naturally what falls out of this change, that's also what Windows users would likely want, as otherwise the unattended mode user is ignored when the "_daemon" autostart key is specified. Notably, this would let people debug what their normally-run-as-a-service tailscaled is doing, even when they're running in Unattended Mode. Signed-off-by: Brad Fitzpatrick --- cmd/tailscaled/tailscaled.go | 32 +++++++++++++++++++++------- cmd/tailscaled/tailscaled_windows.go | 8 +------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/cmd/tailscaled/tailscaled.go b/cmd/tailscaled/tailscaled.go index 7f6615360..ddae1a411 100644 --- a/cmd/tailscaled/tailscaled.go +++ b/cmd/tailscaled/tailscaled.go @@ -159,6 +159,28 @@ func main() { } } +func ipnServerOpts() (o ipnserver.Options) { + // Allow changing the OS-specific IPN behavior for tests + // so we can e.g. test Windows-specific behaviors on Linux. + goos := os.Getenv("TS_DEBUG_TAILSCALED_IPN_GOOS") + if goos == "" { + goos = runtime.GOOS + } + + o.Port = 41112 + o.StatePath = args.statepath + o.SocketPath = args.socketpath // even for goos=="windows", for tests + + switch goos { + default: + o.SurviveDisconnects = true + o.AutostartStateKey = ipn.GlobalDaemonStateKey + case "windows": + // Not those. + } + return o +} + func run() error { var err error @@ -263,14 +285,8 @@ func run() error { } }() - opts := ipnserver.Options{ - SocketPath: args.socketpath, - Port: 41112, - StatePath: args.statepath, - AutostartStateKey: ipn.GlobalDaemonStateKey, - SurviveDisconnects: runtime.GOOS != "windows", - DebugMux: debugMux, - } + opts := ipnServerOpts() + opts.DebugMux = debugMux err = ipnserver.Run(ctx, logf, pol.PublicID.String(), ipnserver.FixedEngine(e), opts) // Cancelation is not an error: it is the only way to stop ipnserver. if err != nil && err != context.Canceled { diff --git a/cmd/tailscaled/tailscaled_windows.go b/cmd/tailscaled/tailscaled_windows.go index 277c4987d..9d5937cdb 100644 --- a/cmd/tailscaled/tailscaled_windows.go +++ b/cmd/tailscaled/tailscaled_windows.go @@ -233,12 +233,6 @@ type engineOrError struct { } }() - opts := ipnserver.Options{ - Port: 41112, - SurviveDisconnects: false, - StatePath: args.statepath, - } - // getEngine is called by ipnserver to get the engine. It's // not called concurrently and is not called again once it // successfully returns an engine. @@ -263,7 +257,7 @@ type engineOrError struct { return nil, fmt.Errorf("%w\n\nlogid: %v", res.Err, logid) } } - err := ipnserver.Run(ctx, logf, logid, getEngine, opts) + err := ipnserver.Run(ctx, logf, logid, getEngine, ipnServerOpts()) if err != nil { logf("ipnserver.Run: %v", err) }