capver, types: bump to tailscale v1.98, drop LegacyDERPString

Regenerate capver for tailscale v1.98 — `MinSupportedCapabilityVersion`
slides 109 → 113 (v1.78 → v1.80). v1.80+ clients understand
`Node.HomeDERP`, which superseded `LegacyDERPString` upstream at capver
111. Drops the emit, plumbing, the trip-wire that caught this cleanup,
the golden test fixtures, and the integration check on
`peer.LegacyDERPString()` — the sibling `HomeDERP` check covers intent.

`v1.98` was added by hand to `capver_generated.go` because tailscale
skipped publishing v1.97/v1.98 to ghcr until late in the cycle; a clean
regeneration produces the same content.
This commit is contained in:
Kristoffer Dalby
2026-05-22 08:02:13 +00:00
parent 570735f204
commit eb23c125fa
6 changed files with 25 additions and 39 deletions

View File

@@ -12,24 +12,17 @@ import (
"tailscale.com/util/set"
)
const (
// minVersionParts is the minimum number of version parts needed for major.minor.
minVersionParts = 2
// minVersionParts is the minimum number of version parts needed for major.minor.
const minVersionParts = 2
// legacyDERPCapVer is the capability version when LegacyDERP can be cleaned up.
legacyDERPCapVer = 111
)
// CanOldCodeBeCleanedUp is intended to be called on startup to see if
// there are old code that can ble cleaned up, entries should contain
// a [tailcfg.CapabilityVersion] where something can be cleaned up and a panic if it can.
// This is only intended to catch things in tests.
// CanOldCodeBeCleanedUp is called at server startup to panic when
// [MinSupportedCapabilityVersion] has crossed a threshold at which a
// backwards-compat emit path can be deleted. Each entry pairs a
// [tailcfg.CapabilityVersion] threshold with the message identifying
// the code to remove; today there are none.
//
// All uses of Capability version checks should be listed here.
// All capability-version-gated cleanups should be registered here.
func CanOldCodeBeCleanedUp() {
if MinSupportedCapabilityVersion >= legacyDERPCapVer {
panic("LegacyDERP can be cleaned up in tail.go")
}
}
func tailscaleVersSorted() []string {

View File

@@ -42,6 +42,7 @@ var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{
"v1.92": 131,
"v1.94": 131,
"v1.96": 133,
"v1.98": 138,
}
var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{
@@ -77,6 +78,7 @@ var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{
130: "v1.90",
131: "v1.92",
133: "v1.96",
138: "v1.98",
}
// SupportedMajorMinorVersions is the number of major.minor Tailscale versions supported.
@@ -84,4 +86,4 @@ const SupportedMajorMinorVersions = 10
// MinSupportedCapabilityVersion represents the minimum capability version
// supported by this Headscale instance (latest 10 minor versions)
const MinSupportedCapabilityVersion tailcfg.CapabilityVersion = 109
const MinSupportedCapabilityVersion tailcfg.CapabilityVersion = 113

View File

@@ -9,10 +9,9 @@ var tailscaleLatestMajorMinorTests = []struct {
stripV bool
expected []string
}{
{3, false, []string{"v1.92", "v1.94", "v1.96"}},
{2, true, []string{"1.94", "1.96"}},
{3, false, []string{"v1.94", "v1.96", "v1.98"}},
{2, true, []string{"1.96", "1.98"}},
{10, true, []string{
"1.78",
"1.80",
"1.82",
"1.84",
@@ -22,6 +21,7 @@ var tailscaleLatestMajorMinorTests = []struct {
"1.92",
"1.94",
"1.96",
"1.98",
}},
{0, false, nil},
}
@@ -30,7 +30,7 @@ var capVerMinimumTailscaleVersionTests = []struct {
input tailcfg.CapabilityVersion
expected string
}{
{109, "v1.78"},
{113, "v1.80"},
{32, "v1.24"},
{41, "v1.30"},
{46, "v1.32"},

View File

@@ -70,7 +70,6 @@ func TestTailNode(t *testing.T) {
Name: "empty",
StableID: "0",
HomeDERP: 0,
LegacyDERPString: "127.3.3.40:0",
Hostinfo: hiview(tailcfg.Hostinfo{}),
MachineAuthorized: true,
@@ -148,8 +147,7 @@ func TestTailNode(t *testing.T) {
PrimaryRoutes: []netip.Prefix{
netip.MustParsePrefix("192.168.0.0/24"),
},
HomeDERP: 0,
LegacyDERPString: "127.3.3.40:0",
HomeDERP: 0,
Hostinfo: hiview(tailcfg.Hostinfo{
RoutableIPs: []netip.Prefix{
tsaddr.AllIPv4(),
@@ -186,7 +184,6 @@ func TestTailNode(t *testing.T) {
Name: "minimal.example.com.",
StableID: "0",
HomeDERP: 0,
LegacyDERPString: "127.3.3.40:0",
Hostinfo: hiview(tailcfg.Hostinfo{}),
MachineAuthorized: true,

View File

@@ -1185,11 +1185,7 @@ func (nv NodeView) TailNode(
}
var derp int
// TODO(kradalby): legacyDERP was removed in tailscale/tailscale@2fc4455e6dd9ab7f879d4e2f7cffc2be81f14077
// and should be removed after 111 is the minimum capver.
legacyDERP := "127.3.3.40:0" // Zero means disconnected or unknown.
if nv.Hostinfo().Valid() && nv.Hostinfo().NetInfo().Valid() {
legacyDERP = fmt.Sprintf("127.3.3.40:%d", nv.Hostinfo().NetInfo().PreferredDERP())
derp = nv.Hostinfo().NetInfo().PreferredDERP()
}
@@ -1266,16 +1262,15 @@ func (nv NodeView) TailNode(
Key: nv.NodeKey(),
KeyExpiry: keyExpiry.UTC(),
Machine: nv.MachineKey(),
DiscoKey: nv.DiscoKey(),
Addresses: addresses,
PrimaryRoutes: primaryRoutes,
AllowedIPs: allowedIPs,
Endpoints: nv.Endpoints().AsSlice(),
HomeDERP: derp,
LegacyDERPString: legacyDERP,
Hostinfo: nv.Hostinfo(),
Created: nv.CreatedAt().UTC(),
Machine: nv.MachineKey(),
DiscoKey: nv.DiscoKey(),
Addresses: addresses,
PrimaryRoutes: primaryRoutes,
AllowedIPs: allowedIPs,
Endpoints: nv.Endpoints().AsSlice(),
HomeDERP: derp,
Hostinfo: nv.Hostinfo(),
Created: nv.CreatedAt().UTC(),
Online: nv.IsOnline().Clone(),

View File

@@ -791,7 +791,6 @@ func assertValidNetmap(t *testing.T, client TailscaleClient) {
assert.Falsef(c, netmap.SelfNode.DiscoKey().IsZero(), "%q does not have a valid DiscoKey", client.Hostname())
for _, peer := range netmap.Peers {
assert.NotEqualf(c, "127.3.3.40:0", peer.LegacyDERPString(), "peer (%s) has no home DERP in %q's netmap, got: %s", peer.ComputedName(), client.Hostname(), peer.LegacyDERPString()) //nolint:staticcheck // SA1019: testing legacy field
assert.NotEqualf(c, 0, peer.HomeDERP(), "peer (%s) has no home DERP in %q's netmap, got: %d", peer.ComputedName(), client.Hostname(), peer.HomeDERP())
assert.Truef(c, peer.Hostinfo().Valid(), "peer (%s) of %q does not have Hostinfo", peer.ComputedName(), client.Hostname())