ipn/localapi, cli, clientmetric: add ipnbus feature tag; fix omit.go stub

Add a new "ipnbus" build feature tag so the watch-ipn-bus LocalAPI
endpoint can be independently controlled, rather than being gated
behind HasDebug || HasServe. Minimal/embedded builds that omit both
debug and serve were getting 404s on watch-ipn-bus, breaking
"tailscale up --authkey=..." and other CLI flows that depend on
WatchIPNBus.

In the CLI, check buildfeatures.HasIPNBus before attempting to watch
the IPN bus in "tailscale up"/"tailscale login", and exit early with
an informational message when the feature is omitted.

Also add the missing NewCounterFunc stub to clientmetric/omit.go,
which caused compilation errors when building with
ts_omit_clientmetrics and netstack enabled.

Fixes #19240

Change-Id: I2e3c69a72fc50fa02542b91b8a54859618a463d1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
main
Brad Fitzpatrick 1 week ago committed by Brad Fitzpatrick
parent 9a7f143903
commit 1b5b43787c
  1. 5
      cmd/tailscale/cli/up.go
  2. 13
      feature/buildfeatures/feature_ipnbus_disabled.go
  3. 13
      feature/buildfeatures/feature_ipnbus_enabled.go
  4. 1
      feature/featuretags/featuretags.go
  5. 2
      ipn/localapi/localapi.go
  6. 7
      util/clientmetric/omit.go

@ -599,6 +599,11 @@ func runUp(ctx context.Context, cmd string, args []string, upArgs upArgsT) (retE
} }
}() }()
if !buildfeatures.HasIPNBus {
fmt.Fprintln(Stderr, "binary built with ts_omit_ipnbus; not waiting for completion")
return nil
}
// Start watching the IPN bus before we call Start() or StartLoginInteractive(), // Start watching the IPN bus before we call Start() or StartLoginInteractive(),
// or we could miss IPN notifications. // or we could miss IPN notifications.
// //

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen.go; DO NOT EDIT.
//go:build ts_omit_ipnbus
package buildfeatures
// HasIPNBus is whether the binary was built with support for modular feature "IPN notification bus (watch-ipn-bus) support, used by GUIs, debugging, and nicer 'tailscale up' support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_ipnbus" build tag.
// It's a const so it can be used for dead code elimination.
const HasIPNBus = false

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen.go; DO NOT EDIT.
//go:build !ts_omit_ipnbus
package buildfeatures
// HasIPNBus is whether the binary was built with support for modular feature "IPN notification bus (watch-ipn-bus) support, used by GUIs, debugging, and nicer 'tailscale up' support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_ipnbus" build tag.
// It's a const so it can be used for dead code elimination.
const HasIPNBus = true

@ -168,6 +168,7 @@ var Features = map[FeatureTag]FeatureMeta{
"health": {Sym: "Health", Desc: "Health checking support"}, "health": {Sym: "Health", Desc: "Health checking support"},
"hujsonconf": {Sym: "HuJSONConf", Desc: "HuJSON config file support"}, "hujsonconf": {Sym: "HuJSONConf", Desc: "HuJSON config file support"},
"identityfederation": {Sym: "IdentityFederation", Desc: "Auth key generation via identity federation support"}, "identityfederation": {Sym: "IdentityFederation", Desc: "Auth key generation via identity federation support"},
"ipnbus": {Sym: "IPNBus", Desc: "IPN notification bus (watch-ipn-bus) support, used by GUIs, debugging, and nicer 'tailscale up' support"},
"iptables": {Sym: "IPTables", Desc: "Linux iptables support"}, "iptables": {Sym: "IPTables", Desc: "Linux iptables support"},
"kube": {Sym: "Kube", Desc: "Kubernetes integration"}, "kube": {Sym: "Kube", Desc: "Kubernetes integration"},
"lazywg": {Sym: "LazyWG", Desc: "Lazy WireGuard configuration for memory-constrained devices with large netmaps"}, "lazywg": {Sym: "LazyWG", Desc: "Lazy WireGuard configuration for memory-constrained devices with large netmaps"},

@ -115,7 +115,7 @@ func init() {
Register("bugreport", (*Handler).serveBugReport) Register("bugreport", (*Handler).serveBugReport)
Register("pprof", (*Handler).servePprof) Register("pprof", (*Handler).servePprof)
} }
if buildfeatures.HasDebug || buildfeatures.HasServe { if buildfeatures.HasIPNBus {
Register("watch-ipn-bus", (*Handler).serveWatchIPNBus) Register("watch-ipn-bus", (*Handler).serveWatchIPNBus)
} }
if buildfeatures.HasDNS { if buildfeatures.HasDNS {

@ -26,6 +26,7 @@ func WritePrometheusExpositionFormat(any) {}
var zeroMetric Metric var zeroMetric Metric
func NewCounter(string) *Metric { return &zeroMetric } func NewCounter(string) *Metric { return &zeroMetric }
func NewGauge(string) *Metric { return &zeroMetric } func NewGauge(string) *Metric { return &zeroMetric }
func NewAggregateCounter(string) *Metric { return &zeroMetric } func NewAggregateCounter(string) *Metric { return &zeroMetric }
func NewCounterFunc(string, func() int64) *Metric { return &zeroMetric }

Loading…
Cancel
Save