capver: generate

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
Kristoffer Dalby
2025-12-18 08:49:28 +01:00
committed by Kristoffer Dalby
parent 251e16d772
commit e8753619de
3 changed files with 99 additions and 52 deletions

View File

@@ -12,6 +12,14 @@ import (
"tailscale.com/util/set" "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 // CanOldCodeBeCleanedUp is intended to be called on startup to see if
// there are old code that can ble cleaned up, entries should contain // 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. // 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. // All uses of Capability version checks should be listed here.
func CanOldCodeBeCleanedUp() { func CanOldCodeBeCleanedUp() {
if MinSupportedCapabilityVersion >= 111 { if MinSupportedCapabilityVersion >= legacyDERPCapVer {
panic("LegacyDERP can be cleaned up in tail.go") 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. // 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 { func CapabilityVersion(ver string) tailcfg.CapabilityVersion {
if !strings.HasPrefix(ver, "v") { if !strings.HasPrefix(ver, "v") {
ver = "v" + ver 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. // TailscaleLatest returns the n latest Tailscale versions.

View File

@@ -5,54 +5,79 @@ package capver
import "tailscale.com/tailcfg" import "tailscale.com/tailcfg"
var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{ var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{
"v1.70.0": 102, "v1.24": 32,
"v1.72.0": 104, "v1.26": 32,
"v1.72.1": 104, "v1.28": 32,
"v1.74.0": 106, "v1.30": 41,
"v1.74.1": 106, "v1.32": 46,
"v1.76.0": 106, "v1.34": 51,
"v1.76.1": 106, "v1.36": 56,
"v1.76.6": 106, "v1.38": 58,
"v1.78.0": 109, "v1.40": 61,
"v1.78.1": 109, "v1.42": 62,
"v1.80.0": 113, "v1.44": 63,
"v1.80.1": 113, "v1.46": 65,
"v1.80.2": 113, "v1.48": 68,
"v1.80.3": 113, "v1.50": 74,
"v1.82.0": 115, "v1.52": 79,
"v1.82.5": 115, "v1.54": 79,
"v1.84.0": 116, "v1.56": 82,
"v1.84.1": 116, "v1.58": 85,
"v1.84.2": 116, "v1.60": 87,
"v1.86.0": 122, "v1.62": 88,
"v1.86.2": 123, "v1.64": 90,
"v1.88.1": 125, "v1.66": 95,
"v1.88.3": 125, "v1.68": 97,
"v1.90.1": 130, "v1.70": 102,
"v1.90.2": 130, "v1.72": 104,
"v1.90.3": 130, "v1.74": 106,
"v1.90.4": 130, "v1.76": 106,
"v1.90.6": 130, "v1.78": 109,
"v1.90.8": 130, "v1.80": 113,
"v1.90.9": 130, "v1.82": 115,
"v1.84": 116,
"v1.86": 123,
"v1.88": 125,
"v1.90": 130,
"v1.92": 131,
} }
var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{ var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{
102: "v1.70.0", 32: "v1.24",
104: "v1.72.0", 41: "v1.30",
106: "v1.74.0", 46: "v1.32",
109: "v1.78.0", 51: "v1.34",
113: "v1.80.0", 56: "v1.36",
115: "v1.82.0", 58: "v1.38",
116: "v1.84.0", 61: "v1.40",
122: "v1.86.0", 62: "v1.42",
123: "v1.86.2", 63: "v1.44",
125: "v1.88.1", 65: "v1.46",
130: "v1.90.1", 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. // SupportedMajorMinorVersions is the number of major.minor Tailscale versions supported.
const SupportedMajorMinorVersions = 9 const SupportedMajorMinorVersions = 10
// MinSupportedCapabilityVersion represents the minimum capability version // MinSupportedCapabilityVersion represents the minimum capability version
// supported by this Headscale instance (latest 10 minor versions) // supported by this Headscale instance (latest 10 minor versions)

View File

@@ -9,9 +9,9 @@ var tailscaleLatestMajorMinorTests = []struct {
stripV bool stripV bool
expected []string expected []string
}{ }{
{3, false, []string{"v1.86", "v1.88", "v1.90"}}, {3, false, []string{"v1.88", "v1.90", "v1.92"}},
{2, true, []string{"1.88", "1.90"}}, {2, true, []string{"1.90", "1.92"}},
{9, true, []string{ {10, true, []string{
"1.74", "1.74",
"1.76", "1.76",
"1.78", "1.78",
@@ -21,6 +21,7 @@ var tailscaleLatestMajorMinorTests = []struct {
"1.86", "1.86",
"1.88", "1.88",
"1.90", "1.90",
"1.92",
}}, }},
{0, false, nil}, {0, false, nil},
} }
@@ -29,11 +30,11 @@ var capVerMinimumTailscaleVersionTests = []struct {
input tailcfg.CapabilityVersion input tailcfg.CapabilityVersion
expected string expected string
}{ }{
{106, "v1.74.0"}, {106, "v1.74"},
{102, "v1.70.0"}, {32, "v1.24"},
{104, "v1.72.0"}, {41, "v1.30"},
{109, "v1.78.0"}, {46, "v1.32"},
{113, "v1.80.0"}, {51, "v1.34"},
{9001, ""}, // Test case for a version higher than any in the map {9001, ""}, // Test case for a version higher than any in the map
{60, ""}, // Test case for a version lower than any in the map {60, ""}, // Test case for a version lower than any in the map
} }