mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 09:52:49 +00:00
kubeadm: validators pass warnings and errors
This change allows validators to pass warnings as well as errors. This was needed because of how support for docker 1.13+ and the new EE and CE versions is currently being handled.
This commit is contained in:
parent
eeefd2ca87
commit
35f07095d8
@ -323,6 +323,7 @@ func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
|
||||
reporter := &system.StreamReporter{WriteStream: bufw}
|
||||
|
||||
var errs []error
|
||||
var warns []error
|
||||
// All the validators we'd like to run:
|
||||
var validators = []system.Validator{
|
||||
&system.OSValidator{Reporter: reporter},
|
||||
@ -333,7 +334,9 @@ func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
|
||||
|
||||
// Run all validators
|
||||
for _, v := range validators {
|
||||
errs = append(errs, v.Validate(system.DefaultSysSpec))
|
||||
warn, err := v.Validate(system.DefaultSysSpec)
|
||||
errs = append(errs, err)
|
||||
warns = append(warns, warn)
|
||||
}
|
||||
|
||||
err := utilerrors.NewAggregate(errs)
|
||||
@ -341,9 +344,9 @@ func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
|
||||
// Only print the output from the system verification check if the check failed
|
||||
fmt.Println("[preflight] The system verification failed. Printing the output from the verification:")
|
||||
bufw.Flush()
|
||||
return nil, []error{err}
|
||||
return warns, []error{err}
|
||||
}
|
||||
return nil, nil
|
||||
return warns, nil
|
||||
}
|
||||
|
||||
type etcdVersionResponse struct {
|
||||
|
@ -98,7 +98,7 @@ func TestE2eNode(t *testing.T) {
|
||||
glog.Exitf("chroot %q failed: %v", rootfs, err)
|
||||
}
|
||||
}
|
||||
if err := system.ValidateDefault(framework.TestContext.ContainerRuntime); err != nil {
|
||||
if _, err := system.ValidateDefault(framework.TestContext.ContainerRuntime); err != nil {
|
||||
glog.Exitf("system validation failed: %v", err)
|
||||
}
|
||||
return
|
||||
|
@ -37,12 +37,12 @@ const (
|
||||
cgroupsConfigPrefix = "CGROUPS_"
|
||||
)
|
||||
|
||||
func (c *CgroupsValidator) Validate(spec SysSpec) error {
|
||||
func (c *CgroupsValidator) Validate(spec SysSpec) (error, error) {
|
||||
subsystems, err := c.getCgroupSubsystems()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
|
||||
return nil, fmt.Errorf("failed to get cgroup subsystems: %v", err)
|
||||
}
|
||||
return c.validateCgroupSubsystems(spec.Cgroups, subsystems)
|
||||
return nil, c.validateCgroupSubsystems(spec.Cgroups, subsystems)
|
||||
}
|
||||
|
||||
func (c *CgroupsValidator) validateCgroupSubsystems(cgroupSpec, subsystems []string) error {
|
||||
|
@ -37,29 +37,30 @@ func (d *DockerValidator) Name() string {
|
||||
}
|
||||
|
||||
const (
|
||||
dockerEndpoint = "unix:///var/run/docker.sock"
|
||||
dockerConfigPrefix = "DOCKER_"
|
||||
dockerEndpoint = "unix:///var/run/docker.sock"
|
||||
dockerConfigPrefix = "DOCKER_"
|
||||
maxDockerValidatedVersion = "1.12"
|
||||
)
|
||||
|
||||
// TODO(random-liu): Add more validating items.
|
||||
func (d *DockerValidator) Validate(spec SysSpec) error {
|
||||
func (d *DockerValidator) Validate(spec SysSpec) (error, error) {
|
||||
if spec.RuntimeSpec.DockerSpec == nil {
|
||||
// If DockerSpec is not specified, assume current runtime is not
|
||||
// docker, skip the docker configuration validation.
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
c, err := client.NewClient(dockerEndpoint, "", nil, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create docker client: %v", err)
|
||||
return nil, fmt.Errorf("failed to create docker client: %v", err)
|
||||
}
|
||||
info, err := c.Info(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get docker info: %v", err)
|
||||
return nil, fmt.Errorf("failed to get docker info: %v", err)
|
||||
}
|
||||
return d.validateDockerInfo(spec.RuntimeSpec.DockerSpec, info)
|
||||
}
|
||||
|
||||
func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info) error {
|
||||
func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info) (error, error) {
|
||||
// Validate docker version.
|
||||
matched := false
|
||||
for _, v := range spec.Version {
|
||||
@ -70,17 +71,29 @@ func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info)
|
||||
}
|
||||
}
|
||||
if !matched {
|
||||
// catch if docker is 1.13+
|
||||
ver := `1\.(1[3-9])\..*|\d{2}\.\d+\.\d+-[a-z]{2}`
|
||||
r := regexp.MustCompile(ver)
|
||||
if r.MatchString(info.ServerVersion) {
|
||||
d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, good)
|
||||
w := fmt.Errorf(
|
||||
"docker version is greater than the most recently validated version. Docker version: %s. Max validated version: %s",
|
||||
info.ServerVersion,
|
||||
maxDockerValidatedVersion,
|
||||
)
|
||||
return w, nil
|
||||
}
|
||||
d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, bad)
|
||||
return fmt.Errorf("unsupported docker version: %s", info.ServerVersion)
|
||||
return nil, fmt.Errorf("unsupported docker version: %s", info.ServerVersion)
|
||||
}
|
||||
// Validate graph driver.
|
||||
item := dockerConfigPrefix + "GRAPH_DRIVER"
|
||||
for _, gd := range spec.GraphDriver {
|
||||
if info.Driver == gd {
|
||||
d.Reporter.Report(item, info.Driver, good)
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
d.Reporter.Report(item, info.Driver, bad)
|
||||
return fmt.Errorf("unsupported graph driver: %s", info.Driver)
|
||||
return nil, fmt.Errorf("unsupported graph driver: %s", info.Driver)
|
||||
}
|
||||
|
@ -28,42 +28,53 @@ func TestValidateDockerInfo(t *testing.T) {
|
||||
Reporter: DefaultReporter,
|
||||
}
|
||||
spec := &DockerSpec{
|
||||
Version: []string{`1\.(9|\d?[0-2]{2,})\..*`}, // Requires 1.9+
|
||||
Version: []string{`1\.(9|1[0-2])\..*`}, // Requires 1.9+
|
||||
GraphDriver: []string{"driver_1", "driver_2"},
|
||||
}
|
||||
for _, test := range []struct {
|
||||
info types.Info
|
||||
err bool
|
||||
warn bool
|
||||
}{
|
||||
{
|
||||
info: types.Info{Driver: "driver_1", ServerVersion: "1.10.1"},
|
||||
err: false,
|
||||
warn: false,
|
||||
},
|
||||
{
|
||||
info: types.Info{Driver: "bad_driver", ServerVersion: "1.9.1"},
|
||||
err: true,
|
||||
warn: false,
|
||||
},
|
||||
{
|
||||
info: types.Info{Driver: "driver_2", ServerVersion: "1.8.1"},
|
||||
err: true,
|
||||
warn: false,
|
||||
},
|
||||
// TODO remove once sig-node supports 1.13
|
||||
// TODO remove/change warn value once sig-node supports 1.13
|
||||
{
|
||||
info: types.Info{Driver: "driver_2", ServerVersion: "1.13.1"},
|
||||
err: true,
|
||||
err: false,
|
||||
warn: true,
|
||||
},
|
||||
// TODO remove once sig-node supports 17.03-0-ce
|
||||
// TODO remove/change warn value once sig-node supports 17.03-0-ce
|
||||
{
|
||||
info: types.Info{Driver: "driver_2", ServerVersion: "17.03.0-ce"},
|
||||
err: true,
|
||||
err: false,
|
||||
warn: true,
|
||||
},
|
||||
} {
|
||||
err := v.validateDockerInfo(spec, test.info)
|
||||
warn, err := v.validateDockerInfo(spec, test.info)
|
||||
if !test.err {
|
||||
assert.Nil(t, err, "Expect error not to occur with docker info %+v", test.info)
|
||||
} else {
|
||||
assert.NotNil(t, err, "Expect error to occur with docker info %+v", test.info)
|
||||
}
|
||||
if !test.warn {
|
||||
assert.Nil(t, warn, "Expect error not to occur with docker info %+v", test.info)
|
||||
} else {
|
||||
assert.NotNil(t, warn, "Expect error to occur with docker info %+v", test.info)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -60,16 +60,16 @@ const (
|
||||
kConfigPrefix = "CONFIG_"
|
||||
)
|
||||
|
||||
func (k *KernelValidator) Validate(spec SysSpec) error {
|
||||
func (k *KernelValidator) Validate(spec SysSpec) (error, error) {
|
||||
release, err := exec.Command("uname", "-r").CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get kernel release: %v", err)
|
||||
return nil, fmt.Errorf("failed to get kernel release: %v", err)
|
||||
}
|
||||
k.kernelRelease = strings.TrimSpace(string(release))
|
||||
var errs []error
|
||||
errs = append(errs, k.validateKernelVersion(spec.KernelSpec))
|
||||
errs = append(errs, k.validateKernelConfig(spec.KernelSpec))
|
||||
return errors.NewAggregate(errs)
|
||||
return nil, errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
// validateKernelVersion validates the kernel version.
|
||||
|
@ -32,12 +32,12 @@ func (o *OSValidator) Name() string {
|
||||
return "os"
|
||||
}
|
||||
|
||||
func (o *OSValidator) Validate(spec SysSpec) error {
|
||||
func (o *OSValidator) Validate(spec SysSpec) (error, error) {
|
||||
os, err := exec.Command("uname").CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get os name: %v", err)
|
||||
return nil, fmt.Errorf("failed to get os name: %v", err)
|
||||
}
|
||||
return o.validateOS(strings.TrimSpace(string(os)), spec.OS)
|
||||
return nil, o.validateOS(strings.TrimSpace(string(os)), spec.OS)
|
||||
}
|
||||
|
||||
func (o *OSValidator) validateOS(os, specOS string) error {
|
||||
|
@ -26,7 +26,7 @@ type Validator interface {
|
||||
// Name is the name of the validator.
|
||||
Name() string
|
||||
// Validate is the validate function.
|
||||
Validate(SysSpec) error
|
||||
Validate(SysSpec) (error, error)
|
||||
}
|
||||
|
||||
// Reporter is the interface for the reporters for the validators.
|
||||
@ -35,19 +35,22 @@ type Reporter interface {
|
||||
Report(string, string, ValidationResultType) error
|
||||
}
|
||||
|
||||
// Validate uses validators to validate the system.
|
||||
func Validate(spec SysSpec, validators []Validator) error {
|
||||
// Validate uses validators to validate the system and returns a warning or error.
|
||||
func Validate(spec SysSpec, validators []Validator) (error, error) {
|
||||
var errs []error
|
||||
var warns []error
|
||||
|
||||
for _, v := range validators {
|
||||
glog.Infof("Validating %s...", v.Name())
|
||||
errs = append(errs, v.Validate(spec))
|
||||
warn, err := v.Validate(spec)
|
||||
errs = append(errs, err)
|
||||
warns = append(warns, warn)
|
||||
}
|
||||
return errors.NewAggregate(errs)
|
||||
return errors.NewAggregate(warns), errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
// ValidateDefault uses all default validators to validate the system and writes to stdout.
|
||||
func ValidateDefault(runtime string) error {
|
||||
func ValidateDefault(runtime string) (error, error) {
|
||||
// OS-level validators.
|
||||
var osValidators = []Validator{
|
||||
&OSValidator{Reporter: DefaultReporter},
|
||||
|
Loading…
Reference in New Issue
Block a user