Skip to content

Commit b89f0aa

Browse files
authored
Merge pull request #1229 from AkihiroSuda/dev
Fix `nerdctl version` output
2 parents 947bf75 + ad0e42f commit b89f0aa

File tree

2 files changed

+131
-19
lines changed

2 files changed

+131
-19
lines changed

pkg/infoutil/infoutil.go

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -158,30 +158,48 @@ func ServerSemVer(ctx context.Context, client *containerd.Client) (*semver.Versi
158158
}
159159

160160
func buildctlVersion() dockercompat.ComponentVersion {
161-
const buildctl = "buildctl"
162161
buildctlBinary, err := buildkitutil.BuildctlBinary()
163162
if err != nil {
164163
logrus.Warnf("unable to determine buildctl version: %s", err.Error())
165-
return dockercompat.ComponentVersion{Name: buildctl}
164+
return dockercompat.ComponentVersion{Name: "builctl"}
166165
}
167166

168167
stdout, err := exec.Command(buildctlBinary, "--version").Output()
169168
if err != nil {
170169
logrus.Warnf("unable to determine buildctl version: %s", err.Error())
171-
return dockercompat.ComponentVersion{Name: buildctl}
170+
return dockercompat.ComponentVersion{Name: "buildctl"}
172171
}
173172

174-
versionStr := strings.Fields(strings.TrimSpace(string(stdout)))
175-
if len(versionStr) != 4 {
176-
logrus.Errorf("unable to determine buildctl version got: %s", versionStr)
177-
return dockercompat.ComponentVersion{Name: buildctl}
173+
v, err := parseBuildctlVersion(stdout)
174+
if err != nil {
175+
logrus.Warn(err)
176+
return dockercompat.ComponentVersion{Name: "buildctl"}
178177
}
178+
return *v
179+
}
179180

180-
return dockercompat.ComponentVersion{
181-
Name: buildctl,
182-
Version: versionStr[2],
183-
Details: map[string]string{"GitCommit": versionStr[3]},
181+
func parseBuildctlVersion(buildctlVersionStdout []byte) (*dockercompat.ComponentVersion, error) {
182+
fields := strings.Fields(strings.TrimSpace(string(buildctlVersionStdout)))
183+
var v *dockercompat.ComponentVersion
184+
switch len(fields) {
185+
case 4:
186+
v = &dockercompat.ComponentVersion{
187+
Name: fields[0],
188+
Version: fields[2],
189+
Details: map[string]string{"GitCommit": fields[3]},
190+
}
191+
case 3:
192+
v = &dockercompat.ComponentVersion{
193+
Name: fields[0],
194+
Version: fields[2],
195+
}
196+
default:
197+
return nil, fmt.Errorf("unable to determine buildctl version, got %q", string(buildctlVersionStdout))
184198
}
199+
if v.Name != "buildctl" {
200+
return nil, fmt.Errorf("unable to determine buildctl version, got %q", string(buildctlVersionStdout))
201+
}
202+
return v, nil
185203
}
186204

187205
func runcVersion() dockercompat.ComponentVersion {
@@ -190,30 +208,40 @@ func runcVersion() dockercompat.ComponentVersion {
190208
logrus.Warnf("unable to determine runc version: %s", err.Error())
191209
return dockercompat.ComponentVersion{Name: "runc"}
192210
}
211+
v, err := parseRuncVersion(stdout)
212+
if err != nil {
213+
logrus.Warn(err)
214+
return dockercompat.ComponentVersion{Name: "runc"}
215+
}
216+
return *v
217+
}
193218

194-
var versionList = strings.Split(strings.TrimSpace(string(stdout)), "\n")
219+
func parseRuncVersion(runcVersionStdout []byte) (*dockercompat.ComponentVersion, error) {
220+
var versionList = strings.Split(strings.TrimSpace(string(runcVersionStdout)), "\n")
195221
firstLine := strings.Fields(versionList[0])
196-
if len(firstLine) != 3 {
197-
logrus.Errorf("unable to determine runc version, got: %s", firstLine)
198-
return dockercompat.ComponentVersion{Name: "runc"}
222+
if len(firstLine) != 3 || firstLine[0] != "runc" {
223+
return nil, fmt.Errorf("unable to determine runc version, got: %s", string(runcVersionStdout))
199224
}
200225
version := firstLine[2]
201226

202227
details := map[string]string{}
203228
for _, detailsLine := range versionList[1:] {
204-
detail := strings.Split(detailsLine, ": ")
229+
detail := strings.SplitN(detailsLine, ":", 2)
205230
if len(detail) != 2 {
206231
logrus.Warnf("unable to determine one of runc details, got: %s, %d", detail, len(detail))
207232
continue
208233
}
209-
details[detail[0]] = detail[1]
234+
switch strings.TrimSpace(detail[0]) {
235+
case "commit":
236+
details["GitCommit"] = strings.TrimSpace(detail[1])
237+
}
210238
}
211239

212-
return dockercompat.ComponentVersion{
240+
return &dockercompat.ComponentVersion{
213241
Name: "runc",
214242
Version: version,
215243
Details: details,
216-
}
244+
}, nil
217245
}
218246

219247
//BlockIOWeight return whether Block IO weight is supported or not

pkg/infoutil/infoutil_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package infoutil
18+
19+
import (
20+
"testing"
21+
22+
"github.com/containerd/nerdctl/pkg/inspecttypes/dockercompat"
23+
"gotest.tools/v3/assert"
24+
)
25+
26+
func TestParseBuildctlVersion(t *testing.T) {
27+
testCases := map[string]*dockercompat.ComponentVersion{
28+
"buildctl github.com/moby/buildkit v0.10.3 c8d25d9a103b70dc300a4fd55e7e576472284e31": {
29+
Name: "buildctl",
30+
Version: "v0.10.3",
31+
Details: map[string]string{
32+
"GitCommit": "c8d25d9a103b70dc300a4fd55e7e576472284e31",
33+
},
34+
},
35+
"buildctl github.com/moby/buildkit v0.10.0-380-g874eef9b 874eef9b70dbaf4f074d2bc8f4dc64237f8e83a0": {
36+
Name: "buildctl",
37+
Version: "v0.10.0-380-g874eef9b",
38+
Details: map[string]string{
39+
"GitCommit": "874eef9b70dbaf4f074d2bc8f4dc64237f8e83a0",
40+
},
41+
},
42+
"buildctl github.com/moby/buildkit 0.0.0+unknown": {
43+
Name: "buildctl",
44+
Version: "0.0.0+unknown",
45+
},
46+
"foo bar baz": nil,
47+
}
48+
49+
for s, expected := range testCases {
50+
got, err := parseBuildctlVersion([]byte(s))
51+
if expected != nil {
52+
assert.NilError(t, err)
53+
assert.DeepEqual(t, expected, got)
54+
} else {
55+
assert.Assert(t, err != nil)
56+
}
57+
}
58+
}
59+
60+
func TestParseRuncVersion(t *testing.T) {
61+
testCases := map[string]*dockercompat.ComponentVersion{
62+
`runc version 1.1.2
63+
commit: v1.1.2-0-ga916309f
64+
spec: 1.0.2-dev
65+
go: go1.18.3
66+
libseccomp: 2.5.1`: {
67+
Name: "runc",
68+
Version: "1.1.2",
69+
Details: map[string]string{
70+
"GitCommit": "v1.1.2-0-ga916309f",
71+
},
72+
},
73+
}
74+
75+
for s, expected := range testCases {
76+
got, err := parseRuncVersion([]byte(s))
77+
if expected != nil {
78+
assert.NilError(t, err)
79+
assert.DeepEqual(t, expected, got)
80+
} else {
81+
assert.Assert(t, err != nil)
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)