Skip to content

Commit

Permalink
Merge pull request #79449 from neolit123/kubeadm-docker-validator
Browse files Browse the repository at this point in the history
kubeadm: don't use the Docker SDK in util/system/docker_validator*
  • Loading branch information
k8s-ci-robot committed Jul 1, 2019
2 parents f2c4237 + cb56f91 commit de8fb1c
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 31 deletions.
8 changes: 0 additions & 8 deletions cmd/kubeadm/.import-restrictions
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,7 @@
"github.com/coreos/etcd/pkg/tlsutil",
"github.com/coreos/etcd/pkg/transport",
"github.com/davecgh/go-spew/spew",
"github.com/docker/distribution/digestset",
"github.com/docker/distribution/reference",
"github.com/docker/docker/api",
"github.com/docker/docker/client",
"github.com/docker/docker/pkg/term",
"github.com/docker/go-connections/nat",
"github.com/docker/go-connections/sockets",
"github.com/docker/go-connections/tlsconfig",
"github.com/docker/go-units",
"github.com/docker/libnetwork/ipvs",
"github.com/godbus/dbus",
"github.com/gogo/protobuf/proto",
Expand Down
3 changes: 0 additions & 3 deletions cmd/kubeadm/app/util/system/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ go_library(
deps = [
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/github.com/blang/semver:go_default_library",
"//vendor/github.com/docker/docker/api/types:go_default_library",
"//vendor/github.com/docker/docker/client:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
Expand All @@ -44,7 +42,6 @@ go_test(
embed = [":go_default_library"],
tags = ["e2e"],
deps = [
"//vendor/github.com/docker/docker/api/types:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
],
Expand Down
35 changes: 26 additions & 9 deletions cmd/kubeadm/app/util/system/docker_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ limitations under the License.
package system

import (
"context"
"encoding/json"
"os/exec"
"regexp"

"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/pkg/errors"
)

Expand All @@ -32,6 +31,14 @@ type DockerValidator struct {
Reporter Reporter
}

// dockerInfo holds a local subset of the Info struct from
// github.com/docker/docker/api/types.
// The JSON output from 'docker info' should map to this struct.
type dockerInfo struct {
Driver string `json:"Driver"`
ServerVersion string `json:"ServerVersion"`
}

// Name is part of the system.Validator interface.
func (d *DockerValidator) Name() string {
return "docker"
Expand All @@ -51,18 +58,28 @@ func (d *DockerValidator) Validate(spec SysSpec) (error, error) {
return nil, nil
}

c, err := client.NewClient(dockerEndpoint, "", nil, nil)
// Run 'docker info' with a JSON output and unmarshal it into a dockerInfo object
info := dockerInfo{}
out, err := exec.Command("docker", "info", "--format", "{{json .}}").CombinedOutput()
if err != nil {
return nil, errors.Wrap(err, "failed to create docker client")
return nil, errors.Errorf(`failed executing "docker info --format '{{json .}}'"\noutput: %s\nerror: %v`, string(out), err)
}
info, err := c.Info(context.Background())
if err != nil {
return nil, errors.Wrap(err, "failed to get docker info")
if err := d.unmarshalDockerInfo(out, &info); err != nil {
return nil, err
}

// validate the resulted docker info object against the spec
return d.validateDockerInfo(spec.RuntimeSpec.DockerSpec, info)
}

func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info) (error, error) {
func (d *DockerValidator) unmarshalDockerInfo(b []byte, info *dockerInfo) error {
if err := json.Unmarshal(b, &info); err != nil {
return errors.Wrap(err, "could not unmarshal the JSON output of 'docker info'")
}
return nil
}

func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info dockerInfo) (error, error) {
// Validate docker version.
matched := false
for _, v := range spec.Version {
Expand Down
60 changes: 49 additions & 11 deletions cmd/kubeadm/app/util/system/docker_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ limitations under the License.
package system

import (
"reflect"
"testing"

"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
)

Expand All @@ -33,61 +33,61 @@ func TestValidateDockerInfo(t *testing.T) {
}
for _, test := range []struct {
name string
info types.Info
info dockerInfo
err bool
warn bool
}{
{
name: "unsupported Docker version 1.12.1",
info: types.Info{Driver: "driver_2", ServerVersion: "1.12.1"},
info: dockerInfo{Driver: "driver_2", ServerVersion: "1.12.1"},
err: true,
warn: false,
},
{
name: "unsupported driver",
info: types.Info{Driver: "bad_driver", ServerVersion: "1.13.1"},
info: dockerInfo{Driver: "bad_driver", ServerVersion: "1.13.1"},
err: true,
warn: false,
},
{
name: "valid Docker version 1.13.1",
info: types.Info{Driver: "driver_1", ServerVersion: "1.13.1"},
info: dockerInfo{Driver: "driver_1", ServerVersion: "1.13.1"},
err: false,
warn: false,
},
{
name: "valid Docker version 17.03.0-ce",
info: types.Info{Driver: "driver_2", ServerVersion: "17.03.0-ce"},
info: dockerInfo{Driver: "driver_2", ServerVersion: "17.03.0-ce"},
err: false,
warn: false,
},
{
name: "valid Docker version 17.06.0-ce",
info: types.Info{Driver: "driver_2", ServerVersion: "17.06.0-ce"},
info: dockerInfo{Driver: "driver_2", ServerVersion: "17.06.0-ce"},
err: false,
warn: false,
},
{
name: "valid Docker version 17.09.0-ce",
info: types.Info{Driver: "driver_2", ServerVersion: "17.09.0-ce"},
info: dockerInfo{Driver: "driver_2", ServerVersion: "17.09.0-ce"},
err: false,
warn: false,
},
{
name: "valid Docker version 18.06.0-ce",
info: types.Info{Driver: "driver_2", ServerVersion: "18.06.0-ce"},
info: dockerInfo{Driver: "driver_2", ServerVersion: "18.06.0-ce"},
err: false,
warn: false,
},
{
name: "valid Docker version 18.09.1-ce",
info: types.Info{Driver: "driver_2", ServerVersion: "18.09.1-ce"},
info: dockerInfo{Driver: "driver_2", ServerVersion: "18.09.1-ce"},
err: false,
warn: false,
},
{
name: "Docker version 19.01.0 is not in the list of validated versions",
info: types.Info{Driver: "driver_2", ServerVersion: "19.01.0"},
info: dockerInfo{Driver: "driver_2", ServerVersion: "19.01.0"},
err: false,
warn: true,
},
Expand All @@ -107,3 +107,41 @@ func TestValidateDockerInfo(t *testing.T) {
})
}
}

func TestUnmarshalDockerInfo(t *testing.T) {
v := &DockerValidator{}

testCases := []struct {
name string
input string
expectedInfo dockerInfo
expectedError bool
}{
{
name: "valid: expected dockerInfo is valid",
input: `{ "Driver":"foo", "ServerVersion":"bar" }`,
expectedInfo: dockerInfo{Driver: "foo", ServerVersion: "bar"},
},
{
name: "invalid: the JSON input is not valid",
input: `{ "Driver":"foo"`,
expectedError: true,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var err error
info := dockerInfo{}
if err = v.unmarshalDockerInfo([]byte(tc.input), &info); (err != nil) != tc.expectedError {
t.Fatalf("failed unmarshaling; expected error: %v, got: %v, error: %v", tc.expectedError, (err != nil), err)
}
if err != nil {
return
}
if !reflect.DeepEqual(tc.expectedInfo, info) {
t.Fatalf("dockerInfo do not match, expected: %#v, got: %#v", tc.expectedInfo, info)
}
})
}
}

0 comments on commit de8fb1c

Please sign in to comment.