mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
kubeadm: don't use the Docker SDK in util/system/docker_validator*
Instead of creating a Docker client and fetching an Info object from the docker enpoint, call the "docker info" command and populate a local dockerInfo struct from JSON output. Also - add unit tests. - update import boss and bazel. This change affects "test/e2e_node/e2e_node_suite_test.go" as it consumes this Docker validator by calling "system.ValidateSpec()".
This commit is contained in:
parent
d48f123a40
commit
cb56f91cc6
@ -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",
|
||||
|
@ -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",
|
||||
],
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user