feature/featuretags: add auto-generated constants for all modular features

So code (in upcoming PRs) can test for the build tags with consts and
get dead code elimination from the compiler+linker.

Updates #12614

Change-Id: If6160453ffd01b798f09894141e7631a93385941
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2025-09-13 20:20:08 -07:00 committed by Brad Fitzpatrick
parent 082c6a25b0
commit 17ffa80138
41 changed files with 574 additions and 21 deletions

View File

@ -30,7 +30,7 @@ func main() {
if *list {
for _, f := range slices.Sorted(maps.Keys(features)) {
fmt.Printf("%20s: %s\n", f, features[f])
fmt.Printf("%20s: %s\n", f, features[f].Desc)
}
return
}

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_aws
package featuretags
// AWS is whether the binary was built with support for modular feature "AWS integration".
// Specifically, it's whether the binary was NOT built with the "ts_omit_aws" build tag.
// It's a const so it can be used for dead code elimination.
const AWS = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_aws
package featuretags
// AWS is whether the binary was built with support for modular feature "AWS integration".
// Specifically, it's whether the binary was NOT built with the "ts_omit_aws" build tag.
// It's a const so it can be used for dead code elimination.
const AWS = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_bird
package featuretags
// Bird is whether the binary was built with support for modular feature "Bird BGP integration".
// Specifically, it's whether the binary was NOT built with the "ts_omit_bird" build tag.
// It's a const so it can be used for dead code elimination.
const Bird = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_bird
package featuretags
// Bird is whether the binary was built with support for modular feature "Bird BGP integration".
// Specifically, it's whether the binary was NOT built with the "ts_omit_bird" build tag.
// It's a const so it can be used for dead code elimination.
const Bird = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_capture
package featuretags
// Capture is whether the binary was built with support for modular feature "Packet capture".
// Specifically, it's whether the binary was NOT built with the "ts_omit_capture" build tag.
// It's a const so it can be used for dead code elimination.
const Capture = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_capture
package featuretags
// Capture is whether the binary was built with support for modular feature "Packet capture".
// Specifically, it's whether the binary was NOT built with the "ts_omit_capture" build tag.
// It's a const so it can be used for dead code elimination.
const Capture = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_completion
package featuretags
// Completion is whether the binary was built with support for modular feature "CLI shell completion".
// Specifically, it's whether the binary was NOT built with the "ts_omit_completion" build tag.
// It's a const so it can be used for dead code elimination.
const Completion = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_completion
package featuretags
// Completion is whether the binary was built with support for modular feature "CLI shell completion".
// Specifically, it's whether the binary was NOT built with the "ts_omit_completion" build tag.
// It's a const so it can be used for dead code elimination.
const Completion = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_debugeventbus
package featuretags
// DebugEventBus is whether the binary was built with support for modular feature "eventbus debug support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_debugeventbus" build tag.
// It's a const so it can be used for dead code elimination.
const DebugEventBus = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_debugeventbus
package featuretags
// DebugEventBus is whether the binary was built with support for modular feature "eventbus debug support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_debugeventbus" build tag.
// It's a const so it can be used for dead code elimination.
const DebugEventBus = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_desktop_sessions
package featuretags
// DesktopSessions is whether the binary was built with support for modular feature "Desktop sessions support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_desktop_sessions" build tag.
// It's a const so it can be used for dead code elimination.
const DesktopSessions = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_desktop_sessions
package featuretags
// DesktopSessions is whether the binary was built with support for modular feature "Desktop sessions support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_desktop_sessions" build tag.
// It's a const so it can be used for dead code elimination.
const DesktopSessions = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_drive
package featuretags
// Drive is whether the binary was built with support for modular feature "Tailscale Drive (file server) support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_drive" build tag.
// It's a const so it can be used for dead code elimination.
const Drive = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_drive
package featuretags
// Drive is whether the binary was built with support for modular feature "Tailscale Drive (file server) support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_drive" build tag.
// It's a const so it can be used for dead code elimination.
const Drive = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_kube
package featuretags
// Kube is whether the binary was built with support for modular feature "Kubernetes integration".
// Specifically, it's whether the binary was NOT built with the "ts_omit_kube" build tag.
// It's a const so it can be used for dead code elimination.
const Kube = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_kube
package featuretags
// Kube is whether the binary was built with support for modular feature "Kubernetes integration".
// Specifically, it's whether the binary was NOT built with the "ts_omit_kube" build tag.
// It's a const so it can be used for dead code elimination.
const Kube = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_relayserver
package featuretags
// RelayServer is whether the binary was built with support for modular feature "Relay server".
// Specifically, it's whether the binary was NOT built with the "ts_omit_relayserver" build tag.
// It's a const so it can be used for dead code elimination.
const RelayServer = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_relayserver
package featuretags
// RelayServer is whether the binary was built with support for modular feature "Relay server".
// Specifically, it's whether the binary was NOT built with the "ts_omit_relayserver" build tag.
// It's a const so it can be used for dead code elimination.
const RelayServer = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_serve
package featuretags
// Serve is whether the binary was built with support for modular feature "Serve and Funnel support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_serve" build tag.
// It's a const so it can be used for dead code elimination.
const Serve = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_serve
package featuretags
// Serve is whether the binary was built with support for modular feature "Serve and Funnel support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_serve" build tag.
// It's a const so it can be used for dead code elimination.
const Serve = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_ssh
package featuretags
// SSH is whether the binary was built with support for modular feature "Tailscale SSH support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_ssh" build tag.
// It's a const so it can be used for dead code elimination.
const SSH = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_ssh
package featuretags
// SSH is whether the binary was built with support for modular feature "Tailscale SSH support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_ssh" build tag.
// It's a const so it can be used for dead code elimination.
const SSH = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_syspolicy
package featuretags
// SystemPolicy is whether the binary was built with support for modular feature "System policy configuration (MDM) support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_syspolicy" build tag.
// It's a const so it can be used for dead code elimination.
const SystemPolicy = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_syspolicy
package featuretags
// SystemPolicy is whether the binary was built with support for modular feature "System policy configuration (MDM) support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_syspolicy" build tag.
// It's a const so it can be used for dead code elimination.
const SystemPolicy = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_systray
package featuretags
// SysTray is whether the binary was built with support for modular feature "Linux system tray".
// Specifically, it's whether the binary was NOT built with the "ts_omit_systray" build tag.
// It's a const so it can be used for dead code elimination.
const SysTray = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_systray
package featuretags
// SysTray is whether the binary was built with support for modular feature "Linux system tray".
// Specifically, it's whether the binary was NOT built with the "ts_omit_systray" build tag.
// It's a const so it can be used for dead code elimination.
const SysTray = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_taildrop
package featuretags
// Taildrop is whether the binary was built with support for modular feature "Taildrop (file sending) support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_taildrop" build tag.
// It's a const so it can be used for dead code elimination.
const Taildrop = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_taildrop
package featuretags
// Taildrop is whether the binary was built with support for modular feature "Taildrop (file sending) support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_taildrop" build tag.
// It's a const so it can be used for dead code elimination.
const Taildrop = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_tailnetlock
package featuretags
// TailnetLock is whether the binary was built with support for modular feature "Tailnet Lock support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_tailnetlock" build tag.
// It's a const so it can be used for dead code elimination.
const TailnetLock = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_tailnetlock
package featuretags
// TailnetLock is whether the binary was built with support for modular feature "Tailnet Lock support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_tailnetlock" build tag.
// It's a const so it can be used for dead code elimination.
const TailnetLock = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_tap
package featuretags
// Tap is whether the binary was built with support for modular feature "Experimental Layer 2 (ethernet) support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_tap" build tag.
// It's a const so it can be used for dead code elimination.
const Tap = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_tap
package featuretags
// Tap is whether the binary was built with support for modular feature "Experimental Layer 2 (ethernet) support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_tap" build tag.
// It's a const so it can be used for dead code elimination.
const Tap = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_tpm
package featuretags
// TPM is whether the binary was built with support for modular feature "TPM support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_tpm" build tag.
// It's a const so it can be used for dead code elimination.
const TPM = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_tpm
package featuretags
// TPM is whether the binary was built with support for modular feature "TPM support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_tpm" build tag.
// It's a const so it can be used for dead code elimination.
const TPM = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_wakeonlan
package featuretags
// WakeOnLAN is whether the binary was built with support for modular feature "Wake-on-LAN support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_wakeonlan" build tag.
// It's a const so it can be used for dead code elimination.
const WakeOnLAN = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_wakeonlan
package featuretags
// WakeOnLAN is whether the binary was built with support for modular feature "Wake-on-LAN support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_wakeonlan" build tag.
// It's a const so it can be used for dead code elimination.
const WakeOnLAN = true

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build ts_omit_webclient
package featuretags
// WebClient is whether the binary was built with support for modular feature "Web client support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_webclient" build tag.
// It's a const so it can be used for dead code elimination.
const WebClient = false

View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code generated by gen-featuretags.go; DO NOT EDIT.
//go:build !ts_omit_webclient
package featuretags
// WebClient is whether the binary was built with support for modular feature "Web client support".
// Specifically, it's whether the binary was NOT built with the "ts_omit_webclient" build tag.
// It's a const so it can be used for dead code elimination.
const WebClient = true

View File

@ -1,6 +1,8 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:generate go run gen-featuretags.go
// The featuretags package is a registry of all the ts_omit-able build tags.
package featuretags
@ -32,26 +34,34 @@ func (ft FeatureTag) OmitTag() string {
return "ts_omit_" + string(ft)
}
// FeatureMeta describes a modular feature that can be conditionally linked into
// the binary.
type FeatureMeta struct {
Sym string // exported Go symbol for boolean const
Desc string // human-readable description
}
// Features are the known Tailscale features that can be selectively included or
// excluded via build tags, and a description of each.
var Features = map[FeatureTag]string{
"aws": "AWS integration",
"bird": "Bird BGP integration",
"capture": "Packet capture",
"cli": "embed the CLI into the tailscaled binary",
"completion": "CLI shell completion",
"debugeventbus": "eventbus debug support",
"desktop_sessions": "Desktop sessions support",
"drive": "Tailscale Drive (file server) support",
"kube": "Kubernetes integration",
"relayserver": "Relay server",
"ssh": "Tailscale SSH support",
"syspolicy": "System policy configuration (MDM) support",
"systray": "Linux system tray",
"taildrop": "Taildrop (file sending) support",
"tailnetlock": "Tailnet Lock support",
"tap": "Experimental Layer 2 (ethernet) support",
"tpm": "TPM support",
"wakeonlan": "Wake-on-LAN support",
"webclient": "Web client support",
var Features = map[FeatureTag]FeatureMeta{
"aws": {"AWS", "AWS integration"},
"bird": {"Bird", "Bird BGP integration"},
"capture": {"Capture", "Packet capture"},
"cli": {"CLI", "embed the CLI into the tailscaled binary"},
"completion": {"Completion", "CLI shell completion"},
"debugeventbus": {"DebugEventBus", "eventbus debug support"},
"desktop_sessions": {"DesktopSessions", "Desktop sessions support"},
"drive": {"Drive", "Tailscale Drive (file server) support"},
"kube": {"Kube", "Kubernetes integration"},
"relayserver": {"RelayServer", "Relay server"},
"serve": {"Serve", "Serve and Funnel support"},
"ssh": {"SSH", "Tailscale SSH support"},
"syspolicy": {"SystemPolicy", "System policy configuration (MDM) support"},
"systray": {"SysTray", "Linux system tray"},
"taildrop": {"Taildrop", "Taildrop (file sending) support"},
"tailnetlock": {"TailnetLock", "Tailnet Lock support"},
"tap": {"Tap", "Experimental Layer 2 (ethernet) support"},
"tpm": {"TPM", "TPM support"},
"wakeonlan": {"WakeOnLAN", "Wake-on-LAN support"},
"webclient": {"WebClient", "Web client support"},
}

View File

@ -0,0 +1,49 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build ignore
// The gen-featuretags.go program generates the feature_<feature>_enabled.go
// and feature_<feature>_disabled.go files for each feature tag.
package main
import (
"cmp"
"fmt"
"os"
"strings"
"tailscale.com/feature/featuretags"
"tailscale.com/util/must"
)
const header = `// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Code g|e|n|e|r|a|t|e|d by gen-featuretags.go; D|O N|OT E|D|I|T.
`
func main() {
header := strings.ReplaceAll(header, "|", "") // to avoid this file being marked as generated
for k, m := range featuretags.Features {
if !k.IsOmittable() {
continue
}
sym := cmp.Or(m.Sym, strings.ToUpper(string(k)[:1])+string(k)[1:])
for _, suf := range []string{"enabled", "disabled"} {
bang := ""
if suf == "enabled" {
bang = "!" // !ts_omit_...
}
must.Do(os.WriteFile("feature_"+string(k)+"_"+suf+".go",
fmt.Appendf(nil, "%s//go:build %s%s\n\npackage featuretags\n\n"+
"// %s is whether the binary was built with support for modular feature %q.\n"+
"// Specifically, it's whether the binary was NOT built with the %q build tag.\n"+
"// It's a const so it can be used for dead code elimination.\n"+
"const %s = %t\n",
header, bang, k.OmitTag(), sym, m.Desc, k.OmitTag(), sym, suf == "enabled"), 0644))
}
}
}