summaryrefslogtreecommitdiffhomepage
path: root/tstest/kernel_linux.go
blob: ed48fd071f251dd039f5a1909a1490e2fa9a5dbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause

//go:build linux

package tstest

import (
	"strconv"
	"strings"

	"golang.org/x/sys/unix"
)

// KernelVersion returns the major, minor, and patch version of the Linux kernel.
// It returns (0, 0, 0) if the version cannot be determined.
func KernelVersion() (major, minor, patch int) {
	var uname unix.Utsname
	if err := unix.Uname(&uname); err != nil {
		return 0, 0, 0
	}
	release := unix.ByteSliceToString(uname.Release[:])
	return parseKernelVersion(release)
}

// parseKernelVersion parses a Linux kernel version string like "6.12.73+deb13-amd64"
// or "5.15.0-76-generic" and returns the major, minor, and patch components.
// It returns (0, 0, 0) if the version cannot be parsed.
func parseKernelVersion(release string) (major, minor, patch int) {
	parts := strings.Split(release, ".")
	if len(parts) < 3 {
		return 0, 0, 0
	}

	major, err := strconv.Atoi(parts[0])
	if err != nil {
		return 0, 0, 0
	}

	minor, err = strconv.Atoi(parts[1])
	if err != nil {
		return 0, 0, 0
	}

	// Patch version may have additional info after a hyphen or plus (e.g., "0-76-generic" or "41+deb13-amd64")
	// Extract just the numeric part before any hyphen or plus
	patchStr := parts[2]
	if idx := strings.IndexAny(patchStr, "-+"); idx != -1 {
		patchStr = patchStr[:idx]
	}

	patch, err = strconv.Atoi(patchStr)
	if err != nil {
		return 0, 0, 0
	}

	return major, minor, patch
}