From e8753619de9240aee93c624f724939bcd0b4b5d9 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 18 Dec 2025 08:49:28 +0100 Subject: [PATCH] capver: generate Signed-off-by: Kristoffer Dalby --- hscontrol/capver/capver.go | 25 +++++- hscontrol/capver/capver_generated.go | 109 ++++++++++++++++----------- hscontrol/capver/capver_test_data.go | 17 +++-- 3 files changed, 99 insertions(+), 52 deletions(-) diff --git a/hscontrol/capver/capver.go b/hscontrol/capver/capver.go index b471ebcc..61d67444 100644 --- a/hscontrol/capver/capver.go +++ b/hscontrol/capver/capver.go @@ -12,6 +12,14 @@ import ( "tailscale.com/util/set" ) +const ( + // minVersionParts is the minimum number of version parts needed for major.minor. + 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 CapVer where something can be cleaned up and a panic if it can. @@ -19,7 +27,7 @@ import ( // // All uses of Capability version checks should be listed here. func CanOldCodeBeCleanedUp() { - if MinSupportedCapabilityVersion >= 111 { + if MinSupportedCapabilityVersion >= legacyDERPCapVer { panic("LegacyDERP can be cleaned up in tail.go") } } @@ -44,12 +52,25 @@ func TailscaleVersion(ver tailcfg.CapabilityVersion) string { } // CapabilityVersion returns the CapabilityVersion for the given Tailscale version. +// It accepts both full versions (v1.90.1) and minor versions (v1.90). func CapabilityVersion(ver string) tailcfg.CapabilityVersion { if !strings.HasPrefix(ver, "v") { ver = "v" + ver } - return tailscaleToCapVer[ver] + // Try direct lookup first (works for minor versions like v1.90) + if cv, ok := tailscaleToCapVer[ver]; ok { + return cv + } + + // Try extracting minor version from full version (v1.90.1 -> v1.90) + parts := strings.Split(strings.TrimPrefix(ver, "v"), ".") + if len(parts) >= minVersionParts { + minor := "v" + parts[0] + "." + parts[1] + return tailscaleToCapVer[minor] + } + + return 0 } // TailscaleLatest returns the n latest Tailscale versions. diff --git a/hscontrol/capver/capver_generated.go b/hscontrol/capver/capver_generated.go index 8fb5f575..11ad89cc 100644 --- a/hscontrol/capver/capver_generated.go +++ b/hscontrol/capver/capver_generated.go @@ -5,54 +5,79 @@ package capver import "tailscale.com/tailcfg" var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{ - "v1.70.0": 102, - "v1.72.0": 104, - "v1.72.1": 104, - "v1.74.0": 106, - "v1.74.1": 106, - "v1.76.0": 106, - "v1.76.1": 106, - "v1.76.6": 106, - "v1.78.0": 109, - "v1.78.1": 109, - "v1.80.0": 113, - "v1.80.1": 113, - "v1.80.2": 113, - "v1.80.3": 113, - "v1.82.0": 115, - "v1.82.5": 115, - "v1.84.0": 116, - "v1.84.1": 116, - "v1.84.2": 116, - "v1.86.0": 122, - "v1.86.2": 123, - "v1.88.1": 125, - "v1.88.3": 125, - "v1.90.1": 130, - "v1.90.2": 130, - "v1.90.3": 130, - "v1.90.4": 130, - "v1.90.6": 130, - "v1.90.8": 130, - "v1.90.9": 130, + "v1.24": 32, + "v1.26": 32, + "v1.28": 32, + "v1.30": 41, + "v1.32": 46, + "v1.34": 51, + "v1.36": 56, + "v1.38": 58, + "v1.40": 61, + "v1.42": 62, + "v1.44": 63, + "v1.46": 65, + "v1.48": 68, + "v1.50": 74, + "v1.52": 79, + "v1.54": 79, + "v1.56": 82, + "v1.58": 85, + "v1.60": 87, + "v1.62": 88, + "v1.64": 90, + "v1.66": 95, + "v1.68": 97, + "v1.70": 102, + "v1.72": 104, + "v1.74": 106, + "v1.76": 106, + "v1.78": 109, + "v1.80": 113, + "v1.82": 115, + "v1.84": 116, + "v1.86": 123, + "v1.88": 125, + "v1.90": 130, + "v1.92": 131, } var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{ - 102: "v1.70.0", - 104: "v1.72.0", - 106: "v1.74.0", - 109: "v1.78.0", - 113: "v1.80.0", - 115: "v1.82.0", - 116: "v1.84.0", - 122: "v1.86.0", - 123: "v1.86.2", - 125: "v1.88.1", - 130: "v1.90.1", + 32: "v1.24", + 41: "v1.30", + 46: "v1.32", + 51: "v1.34", + 56: "v1.36", + 58: "v1.38", + 61: "v1.40", + 62: "v1.42", + 63: "v1.44", + 65: "v1.46", + 68: "v1.48", + 74: "v1.50", + 79: "v1.52", + 82: "v1.56", + 85: "v1.58", + 87: "v1.60", + 88: "v1.62", + 90: "v1.64", + 95: "v1.66", + 97: "v1.68", + 102: "v1.70", + 104: "v1.72", + 106: "v1.74", + 109: "v1.78", + 113: "v1.80", + 115: "v1.82", + 116: "v1.84", + 123: "v1.86", + 125: "v1.88", + 130: "v1.90", + 131: "v1.92", } // SupportedMajorMinorVersions is the number of major.minor Tailscale versions supported. -const SupportedMajorMinorVersions = 9 +const SupportedMajorMinorVersions = 10 // MinSupportedCapabilityVersion represents the minimum capability version // supported by this Headscale instance (latest 10 minor versions) diff --git a/hscontrol/capver/capver_test_data.go b/hscontrol/capver/capver_test_data.go index 5a7608e2..91928d29 100644 --- a/hscontrol/capver/capver_test_data.go +++ b/hscontrol/capver/capver_test_data.go @@ -9,9 +9,9 @@ var tailscaleLatestMajorMinorTests = []struct { stripV bool expected []string }{ - {3, false, []string{"v1.86", "v1.88", "v1.90"}}, - {2, true, []string{"1.88", "1.90"}}, - {9, true, []string{ + {3, false, []string{"v1.88", "v1.90", "v1.92"}}, + {2, true, []string{"1.90", "1.92"}}, + {10, true, []string{ "1.74", "1.76", "1.78", @@ -21,6 +21,7 @@ var tailscaleLatestMajorMinorTests = []struct { "1.86", "1.88", "1.90", + "1.92", }}, {0, false, nil}, } @@ -29,11 +30,11 @@ var capVerMinimumTailscaleVersionTests = []struct { input tailcfg.CapabilityVersion expected string }{ - {106, "v1.74.0"}, - {102, "v1.70.0"}, - {104, "v1.72.0"}, - {109, "v1.78.0"}, - {113, "v1.80.0"}, + {106, "v1.74"}, + {32, "v1.24"}, + {41, "v1.30"}, + {46, "v1.32"}, + {51, "v1.34"}, {9001, ""}, // Test case for a version higher than any in the map {60, ""}, // Test case for a version lower than any in the map }