Merge pull request #79449 from neolit123/kubeadm-docker-validator

kubeadm: don't use the Docker SDK in util/system/docker_validator*
This commit is contained in:
Kubernetes Prow Robot 2019-07-01 11:07:32 -07:00 committed by GitHub
commit de8fb1c9f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 31 deletions

View File

@ -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",

View File

@ -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",
],
@ -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",
],

View File

@ -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"
)
@ -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"
@ -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 {

View File

@ -17,9 +17,9 @@ limitations under the License.
package system
import (
"reflect"
"testing"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
)
@ -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,
},
@ -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)
}
})
}
}