feature/sdnotify: move util/systemd to a modular feature

Updates #12614

Change-Id: I08e714c83b455df7f538cc99cafe940db936b480
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2025-09-27 19:28:35 -07:00
committed by Brad Fitzpatrick
parent 7bcab4ab28
commit 976389c0f7
18 changed files with 98 additions and 34 deletions

View File

@@ -88,6 +88,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
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/feature from tailscale.com/tsweb+ tailscale.com/feature from tailscale.com/tsweb+
tailscale.com/feature/buildfeatures from tailscale.com/feature
tailscale.com/health from tailscale.com/net/tlsdial+ tailscale.com/health from tailscale.com/net/tlsdial+
tailscale.com/hostinfo from tailscale.com/net/netmon+ tailscale.com/hostinfo from tailscale.com/net/netmon+
tailscale.com/ipn from tailscale.com/client/local tailscale.com/ipn from tailscale.com/client/local

View File

@@ -164,7 +164,6 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
L 💣 github.com/mdlayher/netlink from github.com/google/nftables+ L 💣 github.com/mdlayher/netlink from github.com/google/nftables+
L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+ L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+
L github.com/mdlayher/netlink/nltest from github.com/google/nftables L github.com/mdlayher/netlink/nltest from github.com/google/nftables
L github.com/mdlayher/sdnotify from tailscale.com/util/systemd
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
github.com/modern-go/concurrent from github.com/json-iterator/go github.com/modern-go/concurrent from github.com/json-iterator/go
@@ -957,7 +956,6 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
tailscale.com/util/syspolicy/rsop from tailscale.com/util/syspolicy+ tailscale.com/util/syspolicy/rsop from tailscale.com/util/syspolicy+
tailscale.com/util/syspolicy/setting from tailscale.com/util/syspolicy+ tailscale.com/util/syspolicy/setting from tailscale.com/util/syspolicy+
tailscale.com/util/syspolicy/source from tailscale.com/util/syspolicy+ tailscale.com/util/syspolicy/source from tailscale.com/util/syspolicy+
tailscale.com/util/systemd from tailscale.com/control/controlclient+
tailscale.com/util/testenv from tailscale.com/control/controlclient+ tailscale.com/util/testenv from tailscale.com/control/controlclient+
tailscale.com/util/truncate from tailscale.com/logtail tailscale.com/util/truncate from tailscale.com/logtail
tailscale.com/util/usermetric from tailscale.com/health+ tailscale.com/util/usermetric from tailscale.com/health+

View File

@@ -51,6 +51,7 @@ tailscale.com/cmd/stund dependencies: (generated by github.com/tailscale/depawar
tailscale.com from tailscale.com/version tailscale.com from tailscale.com/version
tailscale.com/envknob from tailscale.com/tsweb+ tailscale.com/envknob from tailscale.com/tsweb+
tailscale.com/feature from tailscale.com/tsweb tailscale.com/feature from tailscale.com/tsweb
tailscale.com/feature/buildfeatures from tailscale.com/feature
tailscale.com/kube/kubetypes from tailscale.com/envknob tailscale.com/kube/kubetypes from tailscale.com/envknob
tailscale.com/metrics from tailscale.com/net/stunserver+ tailscale.com/metrics from tailscale.com/net/stunserver+
tailscale.com/net/netaddr from tailscale.com/net/tsaddr tailscale.com/net/netaddr from tailscale.com/net/tsaddr

View File

@@ -33,7 +33,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
💣 github.com/mdlayher/netlink from github.com/google/nftables+ 💣 github.com/mdlayher/netlink from github.com/google/nftables+
💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+ 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+
github.com/mdlayher/netlink/nltest from github.com/google/nftables github.com/mdlayher/netlink/nltest from github.com/google/nftables
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/safchain/ethtool from tailscale.com/net/netkernelconf 💣 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
@@ -202,7 +201,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/util/syspolicy/pkey from tailscale.com/cmd/tailscaled+ tailscale.com/util/syspolicy/pkey from tailscale.com/cmd/tailscaled+
tailscale.com/util/syspolicy/policyclient from tailscale.com/cmd/tailscaled+ tailscale.com/util/syspolicy/policyclient from tailscale.com/cmd/tailscaled+
tailscale.com/util/syspolicy/ptype from tailscale.com/ipn/ipnlocal+ tailscale.com/util/syspolicy/ptype from tailscale.com/ipn/ipnlocal+
tailscale.com/util/systemd from tailscale.com/control/controlclient+
tailscale.com/util/testenv from tailscale.com/control/controlclient+ tailscale.com/util/testenv from tailscale.com/control/controlclient+
tailscale.com/util/usermetric from tailscale.com/health+ tailscale.com/util/usermetric from tailscale.com/health+
tailscale.com/util/vizerror from tailscale.com/tailcfg+ tailscale.com/util/vizerror from tailscale.com/tailcfg+

View File

@@ -147,7 +147,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
L 💣 github.com/mdlayher/netlink from github.com/google/nftables+ L 💣 github.com/mdlayher/netlink from github.com/google/nftables+
L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+ L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+
L github.com/mdlayher/netlink/nltest from github.com/google/nftables L github.com/mdlayher/netlink/nltest from github.com/google/nftables
L github.com/mdlayher/sdnotify from tailscale.com/util/systemd L github.com/mdlayher/sdnotify from tailscale.com/feature/sdnotify
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
L github.com/pierrec/lz4/v4 from github.com/u-root/uio/uio L github.com/pierrec/lz4/v4 from github.com/u-root/uio/uio
@@ -282,6 +282,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/feature/portlist from tailscale.com/feature/condregister tailscale.com/feature/portlist from tailscale.com/feature/condregister
tailscale.com/feature/portmapper from tailscale.com/feature/condregister/portmapper tailscale.com/feature/portmapper from tailscale.com/feature/condregister/portmapper
tailscale.com/feature/relayserver from tailscale.com/feature/condregister tailscale.com/feature/relayserver from tailscale.com/feature/condregister
L tailscale.com/feature/sdnotify from tailscale.com/feature/condregister
tailscale.com/feature/syspolicy from tailscale.com/feature/condregister+ tailscale.com/feature/syspolicy from tailscale.com/feature/condregister+
tailscale.com/feature/taildrop from tailscale.com/feature/condregister tailscale.com/feature/taildrop from tailscale.com/feature/condregister
L tailscale.com/feature/tap from tailscale.com/feature/condregister L tailscale.com/feature/tap from tailscale.com/feature/condregister
@@ -446,7 +447,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/util/syspolicy/rsop from tailscale.com/util/syspolicy+ tailscale.com/util/syspolicy/rsop from tailscale.com/util/syspolicy+
tailscale.com/util/syspolicy/setting from tailscale.com/util/syspolicy+ tailscale.com/util/syspolicy/setting from tailscale.com/util/syspolicy+
tailscale.com/util/syspolicy/source from tailscale.com/util/syspolicy+ tailscale.com/util/syspolicy/source from tailscale.com/util/syspolicy+
tailscale.com/util/systemd from tailscale.com/control/controlclient+
tailscale.com/util/testenv from tailscale.com/ipn/ipnlocal+ tailscale.com/util/testenv from tailscale.com/ipn/ipnlocal+
tailscale.com/util/truncate from tailscale.com/logtail tailscale.com/util/truncate from tailscale.com/logtail
tailscale.com/util/usermetric from tailscale.com/health+ tailscale.com/util/usermetric from tailscale.com/health+

View File

@@ -128,7 +128,6 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
L 💣 github.com/mdlayher/netlink from github.com/google/nftables+ L 💣 github.com/mdlayher/netlink from github.com/google/nftables+
L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+ L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+
L github.com/mdlayher/netlink/nltest from github.com/google/nftables L github.com/mdlayher/netlink/nltest from github.com/google/nftables
L github.com/mdlayher/sdnotify from tailscale.com/util/systemd
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
@@ -387,7 +386,6 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
tailscale.com/util/syspolicy/rsop from tailscale.com/ipn/localapi+ tailscale.com/util/syspolicy/rsop from tailscale.com/ipn/localapi+
tailscale.com/util/syspolicy/setting from tailscale.com/client/local+ tailscale.com/util/syspolicy/setting from tailscale.com/client/local+
tailscale.com/util/syspolicy/source from tailscale.com/util/syspolicy+ tailscale.com/util/syspolicy/source from tailscale.com/util/syspolicy+
tailscale.com/util/systemd from tailscale.com/control/controlclient+
tailscale.com/util/testenv from tailscale.com/control/controlclient+ tailscale.com/util/testenv from tailscale.com/control/controlclient+
tailscale.com/util/truncate from tailscale.com/logtail tailscale.com/util/truncate from tailscale.com/logtail
tailscale.com/util/usermetric from tailscale.com/health+ tailscale.com/util/usermetric from tailscale.com/health+

View File

@@ -29,6 +29,7 @@ import (
"go4.org/mem" "go4.org/mem"
"tailscale.com/control/controlknobs" "tailscale.com/control/controlknobs"
"tailscale.com/envknob" "tailscale.com/envknob"
"tailscale.com/feature"
"tailscale.com/health" "tailscale.com/health"
"tailscale.com/hostinfo" "tailscale.com/hostinfo"
"tailscale.com/ipn/ipnstate" "tailscale.com/ipn/ipnstate"
@@ -57,7 +58,6 @@ import (
"tailscale.com/util/singleflight" "tailscale.com/util/singleflight"
"tailscale.com/util/syspolicy/pkey" "tailscale.com/util/syspolicy/pkey"
"tailscale.com/util/syspolicy/policyclient" "tailscale.com/util/syspolicy/policyclient"
"tailscale.com/util/systemd"
"tailscale.com/util/testenv" "tailscale.com/util/testenv"
"tailscale.com/util/zstdframe" "tailscale.com/util/zstdframe"
) )
@@ -543,7 +543,9 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
} else { } else {
if expired { if expired {
c.logf("Old key expired -> regen=true") c.logf("Old key expired -> regen=true")
systemd.Status("key expired; run 'tailscale up' to authenticate") if f, ok := feature.HookSystemdStatus.GetOk(); ok {
f("key expired; run 'tailscale up' to authenticate")
}
regen = true regen = true
} }
if (opt.Flags & LoginInteractive) != 0 { if (opt.Flags & LoginInteractive) != 0 {

View 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_sdnotify
package buildfeatures
// HasSDNotify is whether the binary was built with support for modular feature "systemd notification support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_sdnotify" build tag.
// It's a const so it can be used for dead code elimination.
const HasSDNotify = false

View 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_sdnotify
package buildfeatures
// HasSDNotify is whether the binary was built with support for modular feature "systemd notification support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_sdnotify" build tag.
// It's a const so it can be used for dead code elimination.
const HasSDNotify = true

View File

@@ -0,0 +1,8 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build linux && !ts_omit_sdnotify
package condregister
import _ "tailscale.com/feature/sdnotify"

View File

@@ -145,6 +145,10 @@ var Features = map[FeatureTag]FeatureMeta{
Desc: "Linux systemd-resolved integration", Desc: "Linux systemd-resolved integration",
Deps: []FeatureTag{"dbus"}, Deps: []FeatureTag{"dbus"},
}, },
"sdnotify": {
Sym: "SDNotify",
Desc: "systemd notification support",
},
"serve": { "serve": {
Sym: "Serve", Sym: "Serve",
Desc: "Serve and Funnel support", Desc: "Serve and Funnel support",

32
feature/sdnotify.go Normal file
View File

@@ -0,0 +1,32 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package feature
import (
"runtime"
"tailscale.com/feature/buildfeatures"
)
// HookSystemdReady sends a readiness to systemd. This will unblock service
// dependents from starting.
var HookSystemdReady Hook[func()]
// HookSystemdStatus holds a func that will send a single line status update to
// systemd so that information shows up in systemctl output.
var HookSystemdStatus Hook[func(format string, args ...any)]
// SystemdStatus sends a single line status update to systemd so that
// information shows up in systemctl output.
//
// It does nothing on non-Linux systems or if the binary was built without
// the sdnotify feature.
func SystemdStatus(format string, args ...any) {
if runtime.GOOS != "linux" || !buildfeatures.HasSDNotify {
return
}
if f, ok := HookSystemdStatus.GetOk(); ok {
f(format, args...)
}
}

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: BSD-3-Clause // SPDX-License-Identifier: BSD-3-Clause
/* /*
Package systemd contains a minimal wrapper around systemd-notify to enable Package sdnotify contains a minimal wrapper around systemd-notify to enable
applications to signal readiness and status to systemd. applications to signal readiness and status to systemd.
This package will only have effect on Linux systems running Tailscale in a This package will only have effect on Linux systems running Tailscale in a
@@ -10,4 +10,4 @@ systemd unit with the Type=notify flag set. On other operating systems (or
when running in a Linux distro without being run from inside systemd) this when running in a Linux distro without being run from inside systemd) this
package will become a no-op. package will become a no-op.
*/ */
package systemd package sdnotify

View File

@@ -3,7 +3,7 @@
//go:build linux && !android //go:build linux && !android
package systemd package sdnotify
import ( import (
"errors" "errors"
@@ -12,8 +12,14 @@ import (
"sync" "sync"
"github.com/mdlayher/sdnotify" "github.com/mdlayher/sdnotify"
"tailscale.com/feature"
) )
func init() {
feature.HookSystemdReady.Set(ready)
feature.HookSystemdStatus.Set(status)
}
var getNotifyOnce struct { var getNotifyOnce struct {
sync.Once sync.Once
v *sdnotify.Notifier v *sdnotify.Notifier
@@ -46,15 +52,15 @@ func notifier() *sdnotify.Notifier {
return getNotifyOnce.v return getNotifyOnce.v
} }
// Ready signals readiness to systemd. This will unblock service dependents from starting. // ready signals readiness to systemd. This will unblock service dependents from starting.
func Ready() { func ready() {
err := notifier().Notify(sdnotify.Ready) err := notifier().Notify(sdnotify.Ready)
if err != nil { if err != nil {
readyOnce.logf("systemd: error notifying: %v", err) readyOnce.logf("systemd: error notifying: %v", err)
} }
} }
// Status sends a single line status update to systemd so that information shows up // status sends a single line status update to systemd so that information shows up
// in systemctl output. For example: // in systemctl output. For example:
// //
// $ systemctl status tailscale // $ systemctl status tailscale
@@ -69,7 +75,7 @@ func Ready() {
// CPU: 2min 38.469s // CPU: 2min 38.469s
// CGroup: /system.slice/tailscale.service // CGroup: /system.slice/tailscale.service
// └─26741 /nix/store/sv6cj4mw2jajm9xkbwj07k29dj30lh0n-tailscale-date.20200727/bin/tailscaled --port 41641 // └─26741 /nix/store/sv6cj4mw2jajm9xkbwj07k29dj30lh0n-tailscale-date.20200727/bin/tailscaled --port 41641
func Status(format string, args ...any) { func status(format string, args ...any) {
err := notifier().Notify(sdnotify.Statusf(format, args...)) err := notifier().Notify(sdnotify.Statusf(format, args...))
if err != nil { if err != nil {
statusOnce.logf("systemd: error notifying: %v", err) statusOnce.logf("systemd: error notifying: %v", err)

View File

@@ -102,7 +102,6 @@ import (
"tailscale.com/util/syspolicy/pkey" "tailscale.com/util/syspolicy/pkey"
"tailscale.com/util/syspolicy/policyclient" "tailscale.com/util/syspolicy/policyclient"
"tailscale.com/util/syspolicy/ptype" "tailscale.com/util/syspolicy/ptype"
"tailscale.com/util/systemd"
"tailscale.com/util/testenv" "tailscale.com/util/testenv"
"tailscale.com/util/usermetric" "tailscale.com/util/usermetric"
"tailscale.com/version" "tailscale.com/version"
@@ -5488,7 +5487,7 @@ func (b *LocalBackend) enterStateLockedOnEntry(newState ipn.State, unlock unlock
switch newState { switch newState {
case ipn.NeedsLogin: case ipn.NeedsLogin:
systemd.Status("Needs login: %s", authURL) feature.SystemdStatus("Needs login: %s", authURL)
// always block updates on NeedsLogin even if seamless renewal is enabled, // always block updates on NeedsLogin even if seamless renewal is enabled,
// to prevent calls to authReconfig from reconfiguring the engine when our // to prevent calls to authReconfig from reconfiguring the engine when our
// key has expired and we're waiting to authenticate to use the new key. // key has expired and we're waiting to authenticate to use the new key.
@@ -5503,7 +5502,7 @@ func (b *LocalBackend) enterStateLockedOnEntry(newState ipn.State, unlock unlock
} }
if newState == ipn.Stopped && authURL == "" { if newState == ipn.Stopped && authURL == "" {
systemd.Status("Stopped; run 'tailscale up' to log in") feature.SystemdStatus("Stopped; run 'tailscale up' to log in")
} }
case ipn.Starting, ipn.NeedsMachineAuth: case ipn.Starting, ipn.NeedsMachineAuth:
b.authReconfig() b.authReconfig()
@@ -5515,7 +5514,7 @@ func (b *LocalBackend) enterStateLockedOnEntry(newState ipn.State, unlock unlock
for _, p := range addrs.All() { for _, p := range addrs.All() {
addrStrs = append(addrStrs, p.Addr().String()) addrStrs = append(addrStrs, p.Addr().String())
} }
systemd.Status("Connected; %s; %s", activeLogin, strings.Join(addrStrs, " ")) feature.SystemdStatus("Connected; %s; %s", activeLogin, strings.Join(addrStrs, " "))
default: default:
b.logf("[unexpected] unknown newState %#v", newState) b.logf("[unexpected] unknown newState %#v", newState)
} }

View File

@@ -23,6 +23,7 @@ import (
"tailscale.com/client/tailscale/apitype" "tailscale.com/client/tailscale/apitype"
"tailscale.com/envknob" "tailscale.com/envknob"
"tailscale.com/feature"
"tailscale.com/ipn/ipnauth" "tailscale.com/ipn/ipnauth"
"tailscale.com/ipn/ipnlocal" "tailscale.com/ipn/ipnlocal"
"tailscale.com/ipn/localapi" "tailscale.com/ipn/localapi"
@@ -32,7 +33,6 @@ import (
"tailscale.com/util/eventbus" "tailscale.com/util/eventbus"
"tailscale.com/util/mak" "tailscale.com/util/mak"
"tailscale.com/util/set" "tailscale.com/util/set"
"tailscale.com/util/systemd"
"tailscale.com/util/testenv" "tailscale.com/util/testenv"
) )
@@ -513,7 +513,9 @@ func (s *Server) Run(ctx context.Context, ln net.Listener) error {
ln.Close() ln.Close()
}() }()
systemd.Ready() if ready, ok := feature.HookSystemdReady.GetOk(); ok {
ready()
}
hs := &http.Server{ hs := &http.Server{
Handler: http.HandlerFunc(s.serveHTTP), Handler: http.HandlerFunc(s.serveHTTP),

View File

@@ -128,7 +128,6 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
L 💣 github.com/mdlayher/netlink from github.com/google/nftables+ L 💣 github.com/mdlayher/netlink from github.com/google/nftables+
L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+ L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+
L github.com/mdlayher/netlink/nltest from github.com/google/nftables L github.com/mdlayher/netlink/nltest from github.com/google/nftables
L github.com/mdlayher/sdnotify from tailscale.com/util/systemd
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
@@ -382,7 +381,6 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
tailscale.com/util/syspolicy/rsop from tailscale.com/ipn/localapi+ tailscale.com/util/syspolicy/rsop from tailscale.com/ipn/localapi+
tailscale.com/util/syspolicy/setting from tailscale.com/client/local+ tailscale.com/util/syspolicy/setting from tailscale.com/client/local+
tailscale.com/util/syspolicy/source from tailscale.com/util/syspolicy+ tailscale.com/util/syspolicy/source from tailscale.com/util/syspolicy+
tailscale.com/util/systemd from tailscale.com/control/controlclient+
tailscale.com/util/testenv from tailscale.com/control/controlclient+ tailscale.com/util/testenv from tailscale.com/control/controlclient+
tailscale.com/util/truncate from tailscale.com/logtail tailscale.com/util/truncate from tailscale.com/logtail
tailscale.com/util/usermetric from tailscale.com/health+ tailscale.com/util/usermetric from tailscale.com/health+

View File

@@ -1,9 +0,0 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build !linux || android
package systemd
func Ready() {}
func Status(string, ...any) {}