From eb23c125fab016b706c1bc5b7d4be6a47d3bac6d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 22 May 2026 08:02:13 +0000 Subject: [PATCH] capver, types: bump to tailscale v1.98, drop LegacyDERPString MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- hscontrol/capver/capver.go | 23 ++++++++--------------- hscontrol/capver/capver_generated.go | 4 +++- hscontrol/capver/capver_test_data.go | 8 ++++---- hscontrol/mapper/tail_test.go | 5 +---- hscontrol/types/node.go | 23 +++++++++-------------- integration/helpers.go | 1 - 6 files changed, 25 insertions(+), 39 deletions(-) diff --git a/hscontrol/capver/capver.go b/hscontrol/capver/capver.go index e145b935..86a653dd 100644 --- a/hscontrol/capver/capver.go +++ b/hscontrol/capver/capver.go @@ -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 { diff --git a/hscontrol/capver/capver_generated.go b/hscontrol/capver/capver_generated.go index 72318ae5..1091f42b 100644 --- a/hscontrol/capver/capver_generated.go +++ b/hscontrol/capver/capver_generated.go @@ -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 diff --git a/hscontrol/capver/capver_test_data.go b/hscontrol/capver/capver_test_data.go index 83bccc08..7309459a 100644 --- a/hscontrol/capver/capver_test_data.go +++ b/hscontrol/capver/capver_test_data.go @@ -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"}, diff --git a/hscontrol/mapper/tail_test.go b/hscontrol/mapper/tail_test.go index f973caaf..ee5da85c 100644 --- a/hscontrol/mapper/tail_test.go +++ b/hscontrol/mapper/tail_test.go @@ -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, diff --git a/hscontrol/types/node.go b/hscontrol/types/node.go index 328a3b28..580df92b 100644 --- a/hscontrol/types/node.go +++ b/hscontrol/types/node.go @@ -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(), diff --git a/integration/helpers.go b/integration/helpers.go index 197efab7..d47766bd 100644 --- a/integration/helpers.go +++ b/integration/helpers.go @@ -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())