mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-05 04:21:01 +02:00
doctor: add ts_omit_doctor support
Updates #12614 Change-Id: I84c166c4b99ca75d70abe4087e5ff3f7d90d4bcc Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
87ee0f4e98
commit
832e94607e
@ -185,7 +185,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
LD github.com/prometheus/procfs from github.com/prometheus/client_golang/prometheus
|
LD github.com/prometheus/procfs from github.com/prometheus/client_golang/prometheus
|
||||||
LD github.com/prometheus/procfs/internal/fs from github.com/prometheus/procfs
|
LD github.com/prometheus/procfs/internal/fs from github.com/prometheus/procfs
|
||||||
LD github.com/prometheus/procfs/internal/util from github.com/prometheus/procfs
|
LD github.com/prometheus/procfs/internal/util from github.com/prometheus/procfs
|
||||||
L 💣 github.com/safchain/ethtool from tailscale.com/doctor/ethtool+
|
L 💣 github.com/safchain/ethtool from tailscale.com/net/netkernelconf
|
||||||
github.com/spf13/pflag from k8s.io/client-go/tools/clientcmd
|
github.com/spf13/pflag from k8s.io/client-go/tools/clientcmd
|
||||||
W 💣 github.com/tailscale/certstore from tailscale.com/control/controlclient
|
W 💣 github.com/tailscale/certstore from tailscale.com/control/controlclient
|
||||||
W 💣 github.com/tailscale/go-winio from tailscale.com/safesocket
|
W 💣 github.com/tailscale/go-winio from tailscale.com/safesocket
|
||||||
@ -200,7 +200,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
github.com/tailscale/goupnp/soap from github.com/tailscale/goupnp+
|
github.com/tailscale/goupnp/soap from github.com/tailscale/goupnp+
|
||||||
github.com/tailscale/goupnp/ssdp from github.com/tailscale/goupnp
|
github.com/tailscale/goupnp/ssdp from github.com/tailscale/goupnp
|
||||||
github.com/tailscale/hujson from tailscale.com/ipn/conffile+
|
github.com/tailscale/hujson from tailscale.com/ipn/conffile+
|
||||||
L 💣 github.com/tailscale/netlink from tailscale.com/net/routetable+
|
L 💣 github.com/tailscale/netlink from tailscale.com/util/linuxfw+
|
||||||
L 💣 github.com/tailscale/netlink/nl from github.com/tailscale/netlink
|
L 💣 github.com/tailscale/netlink/nl from github.com/tailscale/netlink
|
||||||
github.com/tailscale/peercred from tailscale.com/ipn/ipnauth
|
github.com/tailscale/peercred from tailscale.com/ipn/ipnauth
|
||||||
github.com/tailscale/web-client-prebuilt from tailscale.com/client/web
|
github.com/tailscale/web-client-prebuilt from tailscale.com/client/web
|
||||||
@ -787,10 +787,6 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
||||||
tailscale.com/derp/derphttp from tailscale.com/ipn/localapi+
|
tailscale.com/derp/derphttp from tailscale.com/ipn/localapi+
|
||||||
tailscale.com/disco from tailscale.com/net/tstun+
|
tailscale.com/disco from tailscale.com/net/tstun+
|
||||||
tailscale.com/doctor from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/doctor/ethtool from tailscale.com/ipn/ipnlocal
|
|
||||||
💣 tailscale.com/doctor/permissions from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/doctor/routetable from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/drive from tailscale.com/client/local+
|
tailscale.com/drive from tailscale.com/client/local+
|
||||||
tailscale.com/envknob from tailscale.com/client/local+
|
tailscale.com/envknob from tailscale.com/client/local+
|
||||||
tailscale.com/envknob/featureknob from tailscale.com/client/web+
|
tailscale.com/envknob/featureknob from tailscale.com/client/web+
|
||||||
@ -868,7 +864,6 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
tailscale.com/net/portmapper from tailscale.com/feature/portmapper
|
tailscale.com/net/portmapper from tailscale.com/feature/portmapper
|
||||||
tailscale.com/net/portmapper/portmappertype from tailscale.com/net/netcheck+
|
tailscale.com/net/portmapper/portmappertype from tailscale.com/net/netcheck+
|
||||||
tailscale.com/net/proxymux from tailscale.com/tsnet
|
tailscale.com/net/proxymux from tailscale.com/tsnet
|
||||||
tailscale.com/net/routetable from tailscale.com/doctor/routetable
|
|
||||||
💣 tailscale.com/net/sockopts from tailscale.com/wgengine/magicsock
|
💣 tailscale.com/net/sockopts from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/net/socks5 from tailscale.com/tsnet
|
tailscale.com/net/socks5 from tailscale.com/tsnet
|
||||||
tailscale.com/net/sockstats from tailscale.com/control/controlclient+
|
tailscale.com/net/sockstats from tailscale.com/control/controlclient+
|
||||||
|
@ -37,9 +37,9 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
github.com/mdlayher/sdnotify from tailscale.com/util/systemd
|
github.com/mdlayher/sdnotify from tailscale.com/util/systemd
|
||||||
💣 github.com/mdlayher/socket from github.com/mdlayher/netlink+
|
💣 github.com/mdlayher/socket from github.com/mdlayher/netlink+
|
||||||
github.com/mitchellh/go-ps from tailscale.com/safesocket
|
github.com/mitchellh/go-ps from tailscale.com/safesocket
|
||||||
💣 github.com/safchain/ethtool from tailscale.com/doctor/ethtool+
|
💣 github.com/safchain/ethtool from tailscale.com/net/netkernelconf
|
||||||
github.com/tailscale/hujson from tailscale.com/ipn/conffile
|
github.com/tailscale/hujson from tailscale.com/ipn/conffile
|
||||||
💣 github.com/tailscale/netlink from tailscale.com/net/routetable+
|
💣 github.com/tailscale/netlink from tailscale.com/util/linuxfw+
|
||||||
💣 github.com/tailscale/netlink/nl from github.com/tailscale/netlink
|
💣 github.com/tailscale/netlink/nl from github.com/tailscale/netlink
|
||||||
github.com/tailscale/peercred from tailscale.com/ipn/ipnauth
|
github.com/tailscale/peercred from tailscale.com/ipn/ipnauth
|
||||||
💣 github.com/tailscale/wireguard-go/conn from github.com/tailscale/wireguard-go/device+
|
💣 github.com/tailscale/wireguard-go/conn from github.com/tailscale/wireguard-go/device+
|
||||||
@ -69,10 +69,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
||||||
tailscale.com/derp/derphttp from tailscale.com/cmd/tailscaled+
|
tailscale.com/derp/derphttp from tailscale.com/cmd/tailscaled+
|
||||||
tailscale.com/disco from tailscale.com/net/tstun+
|
tailscale.com/disco from tailscale.com/net/tstun+
|
||||||
tailscale.com/doctor from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/doctor/ethtool from tailscale.com/ipn/ipnlocal
|
|
||||||
💣 tailscale.com/doctor/permissions from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/doctor/routetable from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/drive from tailscale.com/ipn+
|
tailscale.com/drive from tailscale.com/ipn+
|
||||||
tailscale.com/envknob from tailscale.com/cmd/tailscaled+
|
tailscale.com/envknob from tailscale.com/cmd/tailscaled+
|
||||||
tailscale.com/envknob/featureknob from tailscale.com/ipn/ipnlocal
|
tailscale.com/envknob/featureknob from tailscale.com/ipn/ipnlocal
|
||||||
@ -127,7 +123,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/net/packet/checksum from tailscale.com/net/tstun
|
tailscale.com/net/packet/checksum from tailscale.com/net/tstun
|
||||||
tailscale.com/net/ping from tailscale.com/net/netcheck+
|
tailscale.com/net/ping from tailscale.com/net/netcheck+
|
||||||
tailscale.com/net/portmapper/portmappertype from tailscale.com/net/netcheck+
|
tailscale.com/net/portmapper/portmappertype from tailscale.com/net/netcheck+
|
||||||
tailscale.com/net/routetable from tailscale.com/doctor/routetable
|
|
||||||
tailscale.com/net/sockopts from tailscale.com/wgengine/magicsock
|
tailscale.com/net/sockopts from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/net/sockstats from tailscale.com/control/controlclient+
|
tailscale.com/net/sockstats from tailscale.com/control/controlclient+
|
||||||
tailscale.com/net/stun from tailscale.com/ipn/localapi+
|
tailscale.com/net/stun from tailscale.com/ipn/localapi+
|
||||||
@ -242,7 +237,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box
|
golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box
|
||||||
golang.org/x/crypto/poly1305 from github.com/tailscale/wireguard-go/device
|
golang.org/x/crypto/poly1305 from github.com/tailscale/wireguard-go/device
|
||||||
golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+
|
golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+
|
||||||
golang.org/x/exp/constraints from tailscale.com/doctor/permissions+
|
golang.org/x/exp/constraints from tailscale.com/tsweb/varz+
|
||||||
golang.org/x/exp/maps from tailscale.com/ipn/store/mem
|
golang.org/x/exp/maps from tailscale.com/ipn/store/mem
|
||||||
golang.org/x/net/bpf from github.com/mdlayher/genetlink+
|
golang.org/x/net/bpf from github.com/mdlayher/genetlink+
|
||||||
golang.org/x/net/dns/dnsmessage from net+
|
golang.org/x/net/dns/dnsmessage from net+
|
||||||
|
@ -259,10 +259,10 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
||||||
tailscale.com/derp/derphttp from tailscale.com/cmd/tailscaled+
|
tailscale.com/derp/derphttp from tailscale.com/cmd/tailscaled+
|
||||||
tailscale.com/disco from tailscale.com/feature/relayserver+
|
tailscale.com/disco from tailscale.com/feature/relayserver+
|
||||||
tailscale.com/doctor from tailscale.com/ipn/ipnlocal
|
tailscale.com/doctor from tailscale.com/feature/doctor
|
||||||
tailscale.com/doctor/ethtool from tailscale.com/ipn/ipnlocal
|
tailscale.com/doctor/ethtool from tailscale.com/feature/doctor
|
||||||
💣 tailscale.com/doctor/permissions from tailscale.com/ipn/ipnlocal
|
💣 tailscale.com/doctor/permissions from tailscale.com/feature/doctor
|
||||||
tailscale.com/doctor/routetable from tailscale.com/ipn/ipnlocal
|
tailscale.com/doctor/routetable from tailscale.com/feature/doctor
|
||||||
tailscale.com/drive from tailscale.com/client/local+
|
tailscale.com/drive from tailscale.com/client/local+
|
||||||
tailscale.com/drive/driveimpl from tailscale.com/cmd/tailscaled
|
tailscale.com/drive/driveimpl from tailscale.com/cmd/tailscaled
|
||||||
tailscale.com/drive/driveimpl/compositedav from tailscale.com/drive/driveimpl
|
tailscale.com/drive/driveimpl/compositedav from tailscale.com/drive/driveimpl
|
||||||
@ -276,6 +276,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/feature/condregister from tailscale.com/cmd/tailscaled
|
tailscale.com/feature/condregister from tailscale.com/cmd/tailscaled
|
||||||
tailscale.com/feature/condregister/portmapper from tailscale.com/feature/condregister
|
tailscale.com/feature/condregister/portmapper from tailscale.com/feature/condregister
|
||||||
tailscale.com/feature/debugportmapper from tailscale.com/feature/condregister
|
tailscale.com/feature/debugportmapper from tailscale.com/feature/condregister
|
||||||
|
tailscale.com/feature/doctor from tailscale.com/feature/condregister
|
||||||
tailscale.com/feature/drive from tailscale.com/feature/condregister
|
tailscale.com/feature/drive from tailscale.com/feature/condregister
|
||||||
L tailscale.com/feature/linuxdnsfight from tailscale.com/feature/condregister
|
L tailscale.com/feature/linuxdnsfight from tailscale.com/feature/condregister
|
||||||
tailscale.com/feature/portlist from tailscale.com/feature/condregister
|
tailscale.com/feature/portlist from tailscale.com/feature/condregister
|
||||||
|
@ -132,7 +132,7 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
|
|||||||
L 💣 github.com/mdlayher/socket from github.com/mdlayher/netlink+
|
L 💣 github.com/mdlayher/socket from github.com/mdlayher/netlink+
|
||||||
💣 github.com/mitchellh/go-ps from tailscale.com/safesocket
|
💣 github.com/mitchellh/go-ps from tailscale.com/safesocket
|
||||||
D github.com/prometheus-community/pro-bing from tailscale.com/wgengine/netstack
|
D github.com/prometheus-community/pro-bing from tailscale.com/wgengine/netstack
|
||||||
L 💣 github.com/safchain/ethtool from tailscale.com/doctor/ethtool+
|
L 💣 github.com/safchain/ethtool from tailscale.com/net/netkernelconf
|
||||||
W 💣 github.com/tailscale/certstore from tailscale.com/control/controlclient
|
W 💣 github.com/tailscale/certstore from tailscale.com/control/controlclient
|
||||||
W 💣 github.com/tailscale/go-winio from tailscale.com/safesocket
|
W 💣 github.com/tailscale/go-winio from tailscale.com/safesocket
|
||||||
W 💣 github.com/tailscale/go-winio/internal/fs from github.com/tailscale/go-winio
|
W 💣 github.com/tailscale/go-winio/internal/fs from github.com/tailscale/go-winio
|
||||||
@ -146,7 +146,7 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
|
|||||||
github.com/tailscale/goupnp/soap from github.com/tailscale/goupnp+
|
github.com/tailscale/goupnp/soap from github.com/tailscale/goupnp+
|
||||||
github.com/tailscale/goupnp/ssdp from github.com/tailscale/goupnp
|
github.com/tailscale/goupnp/ssdp from github.com/tailscale/goupnp
|
||||||
github.com/tailscale/hujson from tailscale.com/ipn/conffile
|
github.com/tailscale/hujson from tailscale.com/ipn/conffile
|
||||||
L 💣 github.com/tailscale/netlink from tailscale.com/net/routetable+
|
L 💣 github.com/tailscale/netlink from tailscale.com/util/linuxfw+
|
||||||
L 💣 github.com/tailscale/netlink/nl from github.com/tailscale/netlink
|
L 💣 github.com/tailscale/netlink/nl from github.com/tailscale/netlink
|
||||||
github.com/tailscale/peercred from tailscale.com/ipn/ipnauth
|
github.com/tailscale/peercred from tailscale.com/ipn/ipnauth
|
||||||
github.com/tailscale/web-client-prebuilt from tailscale.com/client/web
|
github.com/tailscale/web-client-prebuilt from tailscale.com/client/web
|
||||||
@ -229,10 +229,6 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
|
|||||||
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
||||||
tailscale.com/derp/derphttp from tailscale.com/ipn/localapi+
|
tailscale.com/derp/derphttp from tailscale.com/ipn/localapi+
|
||||||
tailscale.com/disco from tailscale.com/net/tstun+
|
tailscale.com/disco from tailscale.com/net/tstun+
|
||||||
tailscale.com/doctor from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/doctor/ethtool from tailscale.com/ipn/ipnlocal
|
|
||||||
💣 tailscale.com/doctor/permissions from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/doctor/routetable from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/drive from tailscale.com/client/local+
|
tailscale.com/drive from tailscale.com/client/local+
|
||||||
tailscale.com/envknob from tailscale.com/client/local+
|
tailscale.com/envknob from tailscale.com/client/local+
|
||||||
tailscale.com/envknob/featureknob from tailscale.com/client/web+
|
tailscale.com/envknob/featureknob from tailscale.com/client/web+
|
||||||
@ -299,7 +295,6 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
|
|||||||
tailscale.com/net/portmapper from tailscale.com/feature/portmapper
|
tailscale.com/net/portmapper from tailscale.com/feature/portmapper
|
||||||
tailscale.com/net/portmapper/portmappertype from tailscale.com/net/netcheck+
|
tailscale.com/net/portmapper/portmappertype from tailscale.com/net/netcheck+
|
||||||
tailscale.com/net/proxymux from tailscale.com/tsnet
|
tailscale.com/net/proxymux from tailscale.com/tsnet
|
||||||
tailscale.com/net/routetable from tailscale.com/doctor/routetable
|
|
||||||
💣 tailscale.com/net/sockopts from tailscale.com/wgengine/magicsock
|
💣 tailscale.com/net/sockopts from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/net/socks5 from tailscale.com/tsnet
|
tailscale.com/net/socks5 from tailscale.com/tsnet
|
||||||
tailscale.com/net/sockstats from tailscale.com/control/controlclient+
|
tailscale.com/net/sockstats from tailscale.com/control/controlclient+
|
||||||
|
13
feature/buildfeatures/feature_doctor_disabled.go
Normal file
13
feature/buildfeatures/feature_doctor_disabled.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// Code generated by gen.go; DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build ts_omit_doctor
|
||||||
|
|
||||||
|
package buildfeatures
|
||||||
|
|
||||||
|
// HasDoctor is whether the binary was built with support for modular feature "Diagnose possible issues with Tailscale and its host environment".
|
||||||
|
// Specifically, it's whether the binary was NOT built with the "ts_omit_doctor" build tag.
|
||||||
|
// It's a const so it can be used for dead code elimination.
|
||||||
|
const HasDoctor = false
|
13
feature/buildfeatures/feature_doctor_enabled.go
Normal file
13
feature/buildfeatures/feature_doctor_enabled.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// Code generated by gen.go; DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build !ts_omit_doctor
|
||||||
|
|
||||||
|
package buildfeatures
|
||||||
|
|
||||||
|
// HasDoctor is whether the binary was built with support for modular feature "Diagnose possible issues with Tailscale and its host environment".
|
||||||
|
// Specifically, it's whether the binary was NOT built with the "ts_omit_doctor" build tag.
|
||||||
|
// It's a const so it can be used for dead code elimination.
|
||||||
|
const HasDoctor = true
|
8
feature/condregister/maybe_doctor.go
Normal file
8
feature/condregister/maybe_doctor.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build !ts_omit_doctor
|
||||||
|
|
||||||
|
package condregister
|
||||||
|
|
||||||
|
import _ "tailscale.com/feature/doctor"
|
95
feature/doctor/doctor.go
Normal file
95
feature/doctor/doctor.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// The doctor package registers the "doctor" problem diagnosis support into the
|
||||||
|
// rest of Tailscale.
|
||||||
|
package doctor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"html"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tailscale.com/doctor"
|
||||||
|
"tailscale.com/doctor/ethtool"
|
||||||
|
"tailscale.com/doctor/permissions"
|
||||||
|
"tailscale.com/doctor/routetable"
|
||||||
|
"tailscale.com/ipn/ipnlocal"
|
||||||
|
"tailscale.com/net/tsaddr"
|
||||||
|
"tailscale.com/types/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ipnlocal.HookDoctor.Set(visitDoctor)
|
||||||
|
ipnlocal.RegisterPeerAPIHandler("/v0/doctor", handleServeDoctor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleServeDoctor(h ipnlocal.PeerAPIHandler, w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !h.CanDebug() {
|
||||||
|
http.Error(w, "denied; no debug access", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
fmt.Fprintln(w, "<h1>Doctor Output</h1>")
|
||||||
|
|
||||||
|
fmt.Fprintln(w, "<pre>")
|
||||||
|
|
||||||
|
b := h.LocalBackend()
|
||||||
|
visitDoctor(r.Context(), b, func(format string, args ...any) {
|
||||||
|
line := fmt.Sprintf(format, args...)
|
||||||
|
fmt.Fprintln(w, html.EscapeString(line))
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Fprintln(w, "</pre>")
|
||||||
|
}
|
||||||
|
|
||||||
|
func visitDoctor(ctx context.Context, b *ipnlocal.LocalBackend, logf logger.Logf) {
|
||||||
|
// We can write logs too fast for logtail to handle, even when
|
||||||
|
// opting-out of rate limits. Limit ourselves to at most one message
|
||||||
|
// per 20ms and a burst of 60 log lines, which should be fast enough to
|
||||||
|
// not block for too long but slow enough that we can upload all lines.
|
||||||
|
logf = logger.SlowLoggerWithClock(ctx, logf, 20*time.Millisecond, 60, b.Clock().Now)
|
||||||
|
|
||||||
|
var checks []doctor.Check
|
||||||
|
checks = append(checks,
|
||||||
|
permissions.Check{},
|
||||||
|
routetable.Check{},
|
||||||
|
ethtool.Check{},
|
||||||
|
)
|
||||||
|
|
||||||
|
// Print a log message if any of the global DNS resolvers are Tailscale
|
||||||
|
// IPs; this can interfere with our ability to connect to the Tailscale
|
||||||
|
// controlplane.
|
||||||
|
checks = append(checks, doctor.CheckFunc("dns-resolvers", func(_ context.Context, logf logger.Logf) error {
|
||||||
|
nm := b.NetMap()
|
||||||
|
if nm == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, resolver := range nm.DNS.Resolvers {
|
||||||
|
ipp, ok := resolver.IPPort()
|
||||||
|
if ok && tsaddr.IsTailscaleIP(ipp.Addr()) {
|
||||||
|
logf("resolver %d is a Tailscale address: %v", i, resolver)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, resolver := range nm.DNS.FallbackResolvers {
|
||||||
|
ipp, ok := resolver.IPPort()
|
||||||
|
if ok && tsaddr.IsTailscaleIP(ipp.Addr()) {
|
||||||
|
logf("fallback resolver %d is a Tailscale address: %v", i, resolver)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
|
||||||
|
// TODO(andrew): more
|
||||||
|
|
||||||
|
numChecks := len(checks)
|
||||||
|
checks = append(checks, doctor.CheckFunc("numchecks", func(_ context.Context, log logger.Logf) error {
|
||||||
|
log("%d checks", numChecks)
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
|
||||||
|
doctor.RunChecks(ctx, logf, checks...)
|
||||||
|
}
|
@ -105,6 +105,7 @@ var Features = map[FeatureTag]FeatureMeta{
|
|||||||
Deps: []FeatureTag{"portmapper"},
|
Deps: []FeatureTag{"portmapper"},
|
||||||
},
|
},
|
||||||
"desktop_sessions": {"DesktopSessions", "Desktop sessions support", nil},
|
"desktop_sessions": {"DesktopSessions", "Desktop sessions support", nil},
|
||||||
|
"doctor": {"Doctor", "Diagnose possible issues with Tailscale and its host environment", nil},
|
||||||
"drive": {"Drive", "Tailscale Drive (file server) support", nil},
|
"drive": {"Drive", "Tailscale Drive (file server) support", nil},
|
||||||
"gro": {
|
"gro": {
|
||||||
Sym: "GRO",
|
Sym: "GRO",
|
||||||
|
@ -33,11 +33,13 @@ type peerAPIHandler struct {
|
|||||||
isSelf bool // whether peerNode is owned by same user as this node
|
isSelf bool // whether peerNode is owned by same user as this node
|
||||||
selfNode tailcfg.NodeView // this node; always non-nil
|
selfNode tailcfg.NodeView // this node; always non-nil
|
||||||
peerNode tailcfg.NodeView // peerNode is who's making the request
|
peerNode tailcfg.NodeView // peerNode is who's making the request
|
||||||
|
canDebug bool // whether peerNode can debug this node (goroutines, metrics, magicsock internal state, etc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *peerAPIHandler) IsSelfUntagged() bool {
|
func (h *peerAPIHandler) IsSelfUntagged() bool {
|
||||||
return !h.selfNode.IsTagged() && !h.peerNode.IsTagged() && h.isSelf
|
return !h.selfNode.IsTagged() && !h.peerNode.IsTagged() && h.isSelf
|
||||||
}
|
}
|
||||||
|
func (h *peerAPIHandler) CanDebug() bool { return h.canDebug }
|
||||||
func (h *peerAPIHandler) Peer() tailcfg.NodeView { return h.peerNode }
|
func (h *peerAPIHandler) Peer() tailcfg.NodeView { return h.peerNode }
|
||||||
func (h *peerAPIHandler) Self() tailcfg.NodeView { return h.selfNode }
|
func (h *peerAPIHandler) Self() tailcfg.NodeView { return h.selfNode }
|
||||||
func (h *peerAPIHandler) RemoteAddr() netip.AddrPort { return h.remoteAddr }
|
func (h *peerAPIHandler) RemoteAddr() netip.AddrPort { return h.remoteAddr }
|
||||||
|
@ -43,10 +43,6 @@ import (
|
|||||||
"tailscale.com/clientupdate"
|
"tailscale.com/clientupdate"
|
||||||
"tailscale.com/control/controlclient"
|
"tailscale.com/control/controlclient"
|
||||||
"tailscale.com/control/controlknobs"
|
"tailscale.com/control/controlknobs"
|
||||||
"tailscale.com/doctor"
|
|
||||||
"tailscale.com/doctor/ethtool"
|
|
||||||
"tailscale.com/doctor/permissions"
|
|
||||||
"tailscale.com/doctor/routetable"
|
|
||||||
"tailscale.com/drive"
|
"tailscale.com/drive"
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/envknob/featureknob"
|
"tailscale.com/envknob/featureknob"
|
||||||
@ -6706,56 +6702,8 @@ func (b *LocalBackend) handleQuad100Port80Conn(w http.ResponseWriter, r *http.Re
|
|||||||
io.WriteString(w, "</ul>\n")
|
io.WriteString(w, "</ul>\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LocalBackend) Doctor(ctx context.Context, logf logger.Logf) {
|
// HookDoctor is an optional hook for the "doctor" problem diagnosis feature.
|
||||||
// We can write logs too fast for logtail to handle, even when
|
var HookDoctor feature.Hook[func(context.Context, *LocalBackend, logger.Logf)]
|
||||||
// opting-out of rate limits. Limit ourselves to at most one message
|
|
||||||
// per 20ms and a burst of 60 log lines, which should be fast enough to
|
|
||||||
// not block for too long but slow enough that we can upload all lines.
|
|
||||||
logf = logger.SlowLoggerWithClock(ctx, logf, 20*time.Millisecond, 60, b.clock.Now)
|
|
||||||
|
|
||||||
var checks []doctor.Check
|
|
||||||
checks = append(checks,
|
|
||||||
permissions.Check{},
|
|
||||||
routetable.Check{},
|
|
||||||
ethtool.Check{},
|
|
||||||
)
|
|
||||||
|
|
||||||
// Print a log message if any of the global DNS resolvers are Tailscale
|
|
||||||
// IPs; this can interfere with our ability to connect to the Tailscale
|
|
||||||
// controlplane.
|
|
||||||
checks = append(checks, doctor.CheckFunc("dns-resolvers", func(_ context.Context, logf logger.Logf) error {
|
|
||||||
b.mu.Lock()
|
|
||||||
nm := b.NetMap()
|
|
||||||
b.mu.Unlock()
|
|
||||||
if nm == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, resolver := range nm.DNS.Resolvers {
|
|
||||||
ipp, ok := resolver.IPPort()
|
|
||||||
if ok && tsaddr.IsTailscaleIP(ipp.Addr()) {
|
|
||||||
logf("resolver %d is a Tailscale address: %v", i, resolver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, resolver := range nm.DNS.FallbackResolvers {
|
|
||||||
ipp, ok := resolver.IPPort()
|
|
||||||
if ok && tsaddr.IsTailscaleIP(ipp.Addr()) {
|
|
||||||
logf("fallback resolver %d is a Tailscale address: %v", i, resolver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}))
|
|
||||||
|
|
||||||
// TODO(andrew): more
|
|
||||||
|
|
||||||
numChecks := len(checks)
|
|
||||||
checks = append(checks, doctor.CheckFunc("numchecks", func(_ context.Context, log logger.Logf) error {
|
|
||||||
log("%d checks", numChecks)
|
|
||||||
return nil
|
|
||||||
}))
|
|
||||||
|
|
||||||
doctor.RunChecks(ctx, logf, checks...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDevStateStore updates the LocalBackend's state storage to the provided values.
|
// SetDevStateStore updates the LocalBackend's state storage to the provided values.
|
||||||
//
|
//
|
||||||
|
@ -217,6 +217,7 @@ type peerAPIHandler struct {
|
|||||||
type PeerAPIHandler interface {
|
type PeerAPIHandler interface {
|
||||||
Peer() tailcfg.NodeView
|
Peer() tailcfg.NodeView
|
||||||
PeerCaps() tailcfg.PeerCapMap
|
PeerCaps() tailcfg.PeerCapMap
|
||||||
|
CanDebug() bool // can remote node can debug this node (internal state, etc)
|
||||||
Self() tailcfg.NodeView
|
Self() tailcfg.NodeView
|
||||||
LocalBackend() *LocalBackend
|
LocalBackend() *LocalBackend
|
||||||
IsSelfUntagged() bool // whether the peer is untagged and the same as this user
|
IsSelfUntagged() bool // whether the peer is untagged and the same as this user
|
||||||
@ -380,9 +381,6 @@ func (h *peerAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
case "/v0/interfaces":
|
case "/v0/interfaces":
|
||||||
h.handleServeInterfaces(w, r)
|
h.handleServeInterfaces(w, r)
|
||||||
return
|
return
|
||||||
case "/v0/doctor":
|
|
||||||
h.handleServeDoctor(w, r)
|
|
||||||
return
|
|
||||||
case "/v0/sockstats":
|
case "/v0/sockstats":
|
||||||
h.handleServeSockStats(w, r)
|
h.handleServeSockStats(w, r)
|
||||||
return
|
return
|
||||||
@ -455,24 +453,6 @@ func (h *peerAPIHandler) handleServeInterfaces(w http.ResponseWriter, r *http.Re
|
|||||||
fmt.Fprintln(w, "</table>")
|
fmt.Fprintln(w, "</table>")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *peerAPIHandler) handleServeDoctor(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if !h.canDebug() {
|
|
||||||
http.Error(w, "denied; no debug access", http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
||||||
fmt.Fprintln(w, "<h1>Doctor Output</h1>")
|
|
||||||
|
|
||||||
fmt.Fprintln(w, "<pre>")
|
|
||||||
|
|
||||||
h.ps.b.Doctor(r.Context(), func(format string, args ...any) {
|
|
||||||
line := fmt.Sprintf(format, args...)
|
|
||||||
fmt.Fprintln(w, html.EscapeString(line))
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Fprintln(w, "</pre>")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *peerAPIHandler) handleServeSockStats(w http.ResponseWriter, r *http.Request) {
|
func (h *peerAPIHandler) handleServeSockStats(w http.ResponseWriter, r *http.Request) {
|
||||||
if !h.canDebug() {
|
if !h.canDebug() {
|
||||||
http.Error(w, "denied; no debug access", http.StatusForbidden)
|
http.Error(w, "denied; no debug access", http.StatusForbidden)
|
||||||
@ -571,6 +551,8 @@ func (h *peerAPIHandler) handleServeSockStats(w http.ResponseWriter, r *http.Req
|
|||||||
fmt.Fprintln(w, "</pre>")
|
fmt.Fprintln(w, "</pre>")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *peerAPIHandler) CanDebug() bool { return h.canDebug() }
|
||||||
|
|
||||||
// canDebug reports whether h can debug this node (goroutines, metrics,
|
// canDebug reports whether h can debug this node (goroutines, metrics,
|
||||||
// magicsock internal state, etc).
|
// magicsock internal state, etc).
|
||||||
func (h *peerAPIHandler) canDebug() bool {
|
func (h *peerAPIHandler) canDebug() bool {
|
||||||
|
@ -402,7 +402,9 @@ func (h *Handler) serveBugReport(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if defBool(r.URL.Query().Get("diagnose"), false) {
|
if defBool(r.URL.Query().Get("diagnose"), false) {
|
||||||
h.b.Doctor(r.Context(), logger.WithPrefix(h.logf, "diag: "))
|
if f, ok := ipnlocal.HookDoctor.GetOk(); ok {
|
||||||
|
f(r.Context(), h.b, logger.WithPrefix(h.logf, "diag: "))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "text/plain")
|
w.Header().Set("Content-Type", "text/plain")
|
||||||
fmt.Fprintln(w, startMarker)
|
fmt.Fprintln(w, startMarker)
|
||||||
|
@ -132,7 +132,7 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
|
|||||||
LA 💣 github.com/mdlayher/socket from github.com/mdlayher/netlink+
|
LA 💣 github.com/mdlayher/socket from github.com/mdlayher/netlink+
|
||||||
LDW 💣 github.com/mitchellh/go-ps from tailscale.com/safesocket
|
LDW 💣 github.com/mitchellh/go-ps from tailscale.com/safesocket
|
||||||
DI github.com/prometheus-community/pro-bing from tailscale.com/wgengine/netstack
|
DI github.com/prometheus-community/pro-bing from tailscale.com/wgengine/netstack
|
||||||
L 💣 github.com/safchain/ethtool from tailscale.com/doctor/ethtool+
|
L 💣 github.com/safchain/ethtool from tailscale.com/net/netkernelconf
|
||||||
W 💣 github.com/tailscale/certstore from tailscale.com/control/controlclient
|
W 💣 github.com/tailscale/certstore from tailscale.com/control/controlclient
|
||||||
W 💣 github.com/tailscale/go-winio from tailscale.com/safesocket
|
W 💣 github.com/tailscale/go-winio from tailscale.com/safesocket
|
||||||
W 💣 github.com/tailscale/go-winio/internal/fs from github.com/tailscale/go-winio
|
W 💣 github.com/tailscale/go-winio/internal/fs from github.com/tailscale/go-winio
|
||||||
@ -146,7 +146,7 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
|
|||||||
github.com/tailscale/goupnp/soap from github.com/tailscale/goupnp+
|
github.com/tailscale/goupnp/soap from github.com/tailscale/goupnp+
|
||||||
github.com/tailscale/goupnp/ssdp from github.com/tailscale/goupnp
|
github.com/tailscale/goupnp/ssdp from github.com/tailscale/goupnp
|
||||||
LDW github.com/tailscale/hujson from tailscale.com/ipn/conffile
|
LDW github.com/tailscale/hujson from tailscale.com/ipn/conffile
|
||||||
L 💣 github.com/tailscale/netlink from tailscale.com/net/routetable+
|
L 💣 github.com/tailscale/netlink from tailscale.com/util/linuxfw+
|
||||||
L 💣 github.com/tailscale/netlink/nl from github.com/tailscale/netlink
|
L 💣 github.com/tailscale/netlink/nl from github.com/tailscale/netlink
|
||||||
github.com/tailscale/peercred from tailscale.com/ipn/ipnauth
|
github.com/tailscale/peercred from tailscale.com/ipn/ipnauth
|
||||||
LDW github.com/tailscale/web-client-prebuilt from tailscale.com/client/web
|
LDW github.com/tailscale/web-client-prebuilt from tailscale.com/client/web
|
||||||
@ -225,10 +225,6 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
|
|||||||
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+
|
||||||
tailscale.com/derp/derphttp from tailscale.com/ipn/localapi+
|
tailscale.com/derp/derphttp from tailscale.com/ipn/localapi+
|
||||||
tailscale.com/disco from tailscale.com/net/tstun+
|
tailscale.com/disco from tailscale.com/net/tstun+
|
||||||
tailscale.com/doctor from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/doctor/ethtool from tailscale.com/ipn/ipnlocal
|
|
||||||
💣 tailscale.com/doctor/permissions from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/doctor/routetable from tailscale.com/ipn/ipnlocal
|
|
||||||
tailscale.com/drive from tailscale.com/client/local+
|
tailscale.com/drive from tailscale.com/client/local+
|
||||||
tailscale.com/envknob from tailscale.com/client/local+
|
tailscale.com/envknob from tailscale.com/client/local+
|
||||||
tailscale.com/envknob/featureknob from tailscale.com/client/web+
|
tailscale.com/envknob/featureknob from tailscale.com/client/web+
|
||||||
@ -295,7 +291,6 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
|
|||||||
tailscale.com/net/portmapper from tailscale.com/feature/portmapper
|
tailscale.com/net/portmapper from tailscale.com/feature/portmapper
|
||||||
tailscale.com/net/portmapper/portmappertype from tailscale.com/net/netcheck+
|
tailscale.com/net/portmapper/portmappertype from tailscale.com/net/netcheck+
|
||||||
tailscale.com/net/proxymux from tailscale.com/tsnet
|
tailscale.com/net/proxymux from tailscale.com/tsnet
|
||||||
tailscale.com/net/routetable from tailscale.com/doctor/routetable
|
|
||||||
💣 tailscale.com/net/sockopts from tailscale.com/wgengine/magicsock
|
💣 tailscale.com/net/sockopts from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/net/socks5 from tailscale.com/tsnet
|
tailscale.com/net/socks5 from tailscale.com/tsnet
|
||||||
tailscale.com/net/sockstats from tailscale.com/control/controlclient+
|
tailscale.com/net/sockstats from tailscale.com/control/controlclient+
|
||||||
|
Loading…
x
Reference in New Issue
Block a user