Skip to content

Commit a63f9d5

Browse files
committed
uname: add
This is a tiny package to check the Linux kernel version. It is taken from the golang sources (src/internal/syscall/unix), with the following changes: - removed irrelevant parts, including FreeBSD and Solaris kernelVersion implementations; - added a tiny test case for KernelVersion; - added some documentation; - added proper copyright headers. The code is covered by the "BSD 3-clause" license, which is compatible with Apache license. The history of the code before the fork can be seen here (oldest first): - https://go-review.googlesource.com/c/go/+/424896 - https://go-review.googlesource.com/c/go/+/427675 - https://go-review.googlesource.com/c/go/+/427676 - https://go-review.googlesource.com/c/go/+/700796 This is aimed to replace the relevant containerd package (github.com/containerd/containerd/pkg/kernelversion) and its forks. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1 parent 9dc3a90 commit a63f9d5

File tree

8 files changed

+219
-0
lines changed

8 files changed

+219
-0
lines changed

uname/LICENSE.BSD

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright 2009 The Go Authors.
2+
3+
Redistribution and use in source and binary forms, with or without
4+
modification, are permitted provided that the following conditions are
5+
met:
6+
7+
* Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
* Redistributions in binary form must reproduce the above
10+
copyright notice, this list of conditions and the following disclaimer
11+
in the documentation and/or other materials provided with the
12+
distribution.
13+
* Neither the name of Google LLC nor the names of its
14+
contributors may be used to endorse or promote products derived from
15+
this software without specific prior written permission.
16+
17+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

uname/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/moby/sys/uname
2+
3+
go 1.18

uname/kernel_version.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// SPDX-FileCopyrightText: 2025 The moby/sys Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
// Package uname provides a simple way to check the kernel version.
5+
// Currently it only supports Linux.
6+
package uname
7+
8+
// KernelVersion returns major and minor kernel version numbers
9+
// parsed from the [syscall.Uname] Release field, or (0, 0) if
10+
// the version can't be obtained or parsed.
11+
func KernelVersion() (major, minor int) {
12+
return kernelVersion()
13+
}

uname/kernel_version_ge.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-FileCopyrightText: 2025 The Go Authors
2+
// SPDX-FileCopyrightText: 2025 The uname Authors.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
// Copyright 2025 The Go Authors. All rights reserved.
6+
// Use of this source code is governed by a BSD-style
7+
// license that can be found in the LICENSE.BSD file.
8+
9+
package uname
10+
11+
// KernelVersionGE checks if the running kernel version
12+
// is greater than or equal to the provided version.
13+
func KernelVersionGE(x, y int) bool {
14+
xx, yy := KernelVersion()
15+
16+
return xx > x || (xx == x && yy >= y)
17+
}

uname/kernel_version_ge_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// SPDX-FileCopyrightText: 2025 The Go Authors
2+
// SPDX-FileCopyrightText: 2025 The uname Authors.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
// Copyright 2025 The Go Authors. All rights reserved.
6+
// Use of this source code is governed by a BSD-style
7+
// license that can be found in the LICENSE.BSD file.
8+
9+
package uname_test
10+
11+
import (
12+
"testing"
13+
14+
"github.com/moby/sys/uname"
15+
)
16+
17+
func TestKernelVersionGE(t *testing.T) {
18+
major, minor := uname.KernelVersion()
19+
t.Logf("Running on kernel %d.%d", major, minor)
20+
21+
tests := []struct {
22+
name string
23+
x, y int
24+
want bool
25+
}{
26+
{
27+
name: "current version equals itself",
28+
x: major,
29+
y: minor,
30+
want: true,
31+
},
32+
{
33+
name: "older major version",
34+
x: major - 1,
35+
y: 0,
36+
want: true,
37+
},
38+
{
39+
name: "same major, older minor version",
40+
x: major,
41+
y: minor - 1,
42+
want: true,
43+
},
44+
{
45+
name: "newer major version",
46+
x: major + 1,
47+
y: 0,
48+
want: false,
49+
},
50+
{
51+
name: "same major, newer minor version",
52+
x: major,
53+
y: minor + 1,
54+
want: false,
55+
},
56+
{
57+
name: "min version (0.0)",
58+
x: 0,
59+
y: 0,
60+
want: true,
61+
},
62+
}
63+
64+
for _, tt := range tests {
65+
t.Run(tt.name, func(t *testing.T) {
66+
got := uname.KernelVersionGE(tt.x, tt.y)
67+
if got != tt.want {
68+
t.Errorf("KernelVersionGE(%d, %d): got %v, want %v", tt.x, tt.y, got, tt.want)
69+
}
70+
})
71+
}
72+
}

uname/kernel_version_linux.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// SPDX-FileCopyrightText: 2022 The Go Authors
2+
// SPDX-FileCopyrightText: 2025 The moby/sys Authors.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
// Copyright 2022 The Go Authors. All rights reserved.
6+
// Use of this source code is governed by a BSD-style
7+
// license that can be found in the LICENSE.BSD file.
8+
9+
package uname
10+
11+
import (
12+
"syscall"
13+
)
14+
15+
func kernelVersion() (major, minor int) {
16+
var uname syscall.Utsname
17+
if err := syscall.Uname(&uname); err != nil {
18+
return
19+
}
20+
21+
var (
22+
values [2]int
23+
value, vi int
24+
)
25+
for _, c := range uname.Release {
26+
if '0' <= c && c <= '9' {
27+
value = (value * 10) + int(c-'0')
28+
} else {
29+
// Note that we're assuming N.N.N here.
30+
// If we see anything else, we are likely to mis-parse it.
31+
values[vi] = value
32+
vi++
33+
if vi >= len(values) {
34+
break
35+
}
36+
value = 0
37+
}
38+
}
39+
40+
return values[0], values[1]
41+
}

uname/kernel_version_other.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-FileCopyrightText: 2022 The Go Authors
2+
// SPDX-FileCopyrightText: 2025 The moby/sys Authors.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
// Copyright 2022 The Go Authors. All rights reserved.
6+
// Use of this source code is governed by a BSD-style
7+
// license that can be found in the LICENSE.BSD file.
8+
9+
//go:build !linux
10+
11+
package uname
12+
13+
func kernelVersion() (major int, minor int) {
14+
return 0, 0
15+
}

uname/kernel_version_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-FileCopyrightText: 2025 The moby/sys Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package uname_test
5+
6+
import (
7+
"runtime"
8+
"testing"
9+
10+
"github.com/moby/sys/uname"
11+
)
12+
13+
func TestKernelVersion(t *testing.T) {
14+
x, y := uname.KernelVersion()
15+
t.Logf("KernelVersion: %d.%d (GOOS: %s)", x, y, runtime.GOOS)
16+
switch runtime.GOOS {
17+
case "linux":
18+
// Go requires Linux >= 2.x.
19+
if x < 2 {
20+
t.Errorf("want major >= 2, got %d", x)
21+
}
22+
// Sanity check.
23+
if y < 0 {
24+
t.Errorf("want minor >= 0, got %d", y)
25+
}
26+
default:
27+
if x != 0 || y != 0 {
28+
t.Fatalf("want 0.0, got %d.%d", x, y)
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)