Regression: Kubelet fails on older distro Dockers

Changes broke compatibility with released versions of Docker on some
distributions like Fedora and RHEL (value 1.8.1.fc21 is in the wild).
This commit is contained in:
Clayton Coleman 2016-02-08 12:40:19 -05:00
parent 57bc8719f9
commit 5aca495d73
2 changed files with 44 additions and 5 deletions

View File

@ -25,6 +25,7 @@ import (
"os"
"os/exec"
"path"
"regexp"
"strconv"
"strings"
"sync"
@ -780,24 +781,33 @@ type dockerVersion struct {
*semver.Version
}
// Older versions of Docker could return non-semantically versioned values (distros like Fedora
// included partial values such as 1.8.1.fc21 which is not semver). Force those values to be semver.
var almostSemverRegexp = regexp.MustCompile(`^(\d+\.\d+\.\d+)\.(.*)$`)
// newDockerVersion returns a semantically versioned docker version value
func newDockerVersion(version string) (dockerVersion, error) {
sem, err := semver.NewVersion(version)
if err != nil {
return dockerVersion{}, err
matches := almostSemverRegexp.FindStringSubmatch(version)
if matches == nil {
return dockerVersion{}, err
}
sem, err = semver.NewVersion(strings.Join(matches[1:], "-"))
}
return dockerVersion{sem}, nil
return dockerVersion{sem}, err
}
func (r dockerVersion) Compare(other string) (int, error) {
v, err := semver.NewVersion(other)
v, err := newDockerVersion(other)
if err != nil {
return -1, err
}
if r.LessThan(*v) {
if r.LessThan(*v.Version) {
return -1, nil
}
if v.LessThan(*r.Version) {
if v.Version.LessThan(*r.Version) {
return 1, nil
}
return 0, nil

View File

@ -115,6 +115,35 @@ func matchString(t *testing.T, pattern, str string) bool {
return match
}
func TestNewDockerVersion(t *testing.T) {
cases := []struct {
value string
out string
err bool
}{
{value: "1", err: true},
{value: "1.8", err: true},
{value: "1.8.1", out: "1.8.1"},
{value: "1.8.1.fc21", out: "1.8.1-fc21"},
{value: "1.8.1.fc21.other", out: "1.8.1-fc21.other"},
{value: "1.8.1-fc21.other", out: "1.8.1-fc21.other"},
{value: "1.8.1-beta.12", out: "1.8.1-beta.12"},
}
for _, test := range cases {
v, err := newDockerVersion(test.value)
switch {
case err != nil && test.err:
continue
case (err != nil) != test.err:
t.Errorf("error for %q: expected %t, got %v", test.value, test.err, err)
continue
}
if v.String() != test.out {
t.Errorf("unexpected parsed version %q for %q", v, test.value)
}
}
}
func TestSetEntrypointAndCommand(t *testing.T) {
cases := []struct {
name string