ignore non-numeric characters when parsing kernel version
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"crypto/sha256" |
| 7 | 7 |
"encoding/hex" |
| 8 | 8 |
"encoding/json" |
| 9 |
+ "errors" |
|
| 9 | 10 |
"fmt" |
| 10 | 11 |
"index/suffixarray" |
| 11 | 12 |
"io" |
| ... | ... |
@@ -556,15 +557,11 @@ type KernelVersionInfo struct {
|
| 556 | 556 |
} |
| 557 | 557 |
|
| 558 | 558 |
func (k *KernelVersionInfo) String() string {
|
| 559 |
- flavor := "" |
|
| 560 |
- if len(k.Flavor) > 0 {
|
|
| 561 |
- flavor = fmt.Sprintf("-%s", k.Flavor)
|
|
| 562 |
- } |
|
| 563 |
- return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, flavor)
|
|
| 559 |
+ return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
|
|
| 564 | 560 |
} |
| 565 | 561 |
|
| 566 | 562 |
// Compare two KernelVersionInfo struct. |
| 567 |
-// Returns -1 if a < b, = if a == b, 1 it a > b |
|
| 563 |
+// Returns -1 if a < b, 0 if a == b, 1 it a > b |
|
| 568 | 564 |
func CompareKernelVersion(a, b *KernelVersionInfo) int {
|
| 569 | 565 |
if a.Kernel < b.Kernel {
|
| 570 | 566 |
return -1 |
| ... | ... |
@@ -613,41 +610,15 @@ func GetKernelVersion() (*KernelVersionInfo, error) {
|
| 613 | 613 |
|
| 614 | 614 |
func ParseRelease(release string) (*KernelVersionInfo, error) {
|
| 615 | 615 |
var ( |
| 616 |
- flavor string |
|
| 617 |
- kernel, major, minor int |
|
| 618 |
- err error |
|
| 616 |
+ kernel, major, minor, parsed int |
|
| 617 |
+ flavor string |
|
| 619 | 618 |
) |
| 620 | 619 |
|
| 621 |
- tmp := strings.SplitN(release, "-", 2) |
|
| 622 |
- tmp2 := strings.Split(tmp[0], ".") |
|
| 623 |
- |
|
| 624 |
- if len(tmp2) > 0 {
|
|
| 625 |
- kernel, err = strconv.Atoi(tmp2[0]) |
|
| 626 |
- if err != nil {
|
|
| 627 |
- return nil, err |
|
| 628 |
- } |
|
| 629 |
- } |
|
| 630 |
- |
|
| 631 |
- if len(tmp2) > 1 {
|
|
| 632 |
- major, err = strconv.Atoi(tmp2[1]) |
|
| 633 |
- if err != nil {
|
|
| 634 |
- return nil, err |
|
| 635 |
- } |
|
| 636 |
- } |
|
| 637 |
- |
|
| 638 |
- if len(tmp2) > 2 {
|
|
| 639 |
- // Removes "+" because git kernels might set it |
|
| 640 |
- minorUnparsed := strings.Trim(tmp2[2], "+") |
|
| 641 |
- minor, err = strconv.Atoi(minorUnparsed) |
|
| 642 |
- if err != nil {
|
|
| 643 |
- return nil, err |
|
| 644 |
- } |
|
| 645 |
- } |
|
| 646 |
- |
|
| 647 |
- if len(tmp) == 2 {
|
|
| 648 |
- flavor = tmp[1] |
|
| 649 |
- } else {
|
|
| 650 |
- flavor = "" |
|
| 620 |
+ // Ignore error from Sscanf to allow an empty flavor. Instead, just |
|
| 621 |
+ // make sure we got all the version numbers. |
|
| 622 |
+ parsed, _ = fmt.Sscanf(release, "%d.%d.%d%s", &kernel, &major, &minor, &flavor) |
|
| 623 |
+ if parsed < 3 {
|
|
| 624 |
+ return nil, errors.New("Can't parse kernel version " + release)
|
|
| 651 | 625 |
} |
| 652 | 626 |
|
| 653 | 627 |
return &KernelVersionInfo{
|
| ... | ... |
@@ -237,16 +237,16 @@ func TestCompareKernelVersion(t *testing.T) {
|
| 237 | 237 |
&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
|
| 238 | 238 |
1) |
| 239 | 239 |
assertKernelVersion(t, |
| 240 |
- &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "0"},
|
|
| 241 |
- &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "16"},
|
|
| 240 |
+ &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
|
| 241 |
+ &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
|
| 242 | 242 |
0) |
| 243 | 243 |
assertKernelVersion(t, |
| 244 | 244 |
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 5},
|
| 245 | 245 |
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
| 246 | 246 |
1) |
| 247 | 247 |
assertKernelVersion(t, |
| 248 |
- &KernelVersionInfo{Kernel: 3, Major: 0, Minor: 20, Flavor: "25"},
|
|
| 249 |
- &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "0"},
|
|
| 248 |
+ &KernelVersionInfo{Kernel: 3, Major: 0, Minor: 20},
|
|
| 249 |
+ &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
|
| 250 | 250 |
-1) |
| 251 | 251 |
} |
| 252 | 252 |
|
| ... | ... |
@@ -407,13 +407,17 @@ func assertParseRelease(t *testing.T, release string, b *KernelVersionInfo, resu |
| 407 | 407 |
if r := CompareKernelVersion(a, b); r != result {
|
| 408 | 408 |
t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
|
| 409 | 409 |
} |
| 410 |
+ if a.Flavor != b.Flavor {
|
|
| 411 |
+ t.Fatalf("Unexpected parsed kernel flavor. Found %s, expected %s", a.Flavor, b.Flavor)
|
|
| 412 |
+ } |
|
| 410 | 413 |
} |
| 411 | 414 |
|
| 412 | 415 |
func TestParseRelease(t *testing.T) {
|
| 413 | 416 |
assertParseRelease(t, "3.8.0", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0)
|
| 414 |
- assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54}, 0)
|
|
| 415 |
- assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: "1"}, 0)
|
|
| 416 |
- assertParseRelease(t, "3.8.0-19-generic", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "19-generic"}, 0)
|
|
| 417 |
+ assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
|
|
| 418 |
+ assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
|
|
| 419 |
+ assertParseRelease(t, "3.8.0-19-generic", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0)
|
|
| 420 |
+ assertParseRelease(t, "3.12.8tag", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0)
|
|
| 417 | 421 |
} |
| 418 | 422 |
|
| 419 | 423 |
func TestParsePortMapping(t *testing.T) {
|