mirror of https://github.com/k3s-io/k3s
Implement individual control for kubeadm preflight checks
With new flag `--ignore-checks-errors` user is able to decrease severity of each individual check to warning. Old flag `--skip-preflight-checks` now acts as `--ignore-checks-errors=all` and will produce warnings. Fixes: kubernetes/kubeadm#480pull/6/head
parent
bf32170dca
commit
e42eb28500
|
@ -33,6 +33,7 @@ go_library(
|
||||||
"//pkg/registry/core/service/ipallocator:go_default_library",
|
"//pkg/registry/core/service/ipallocator:go_default_library",
|
||||||
"//pkg/util/node:go_default_library",
|
"//pkg/util/node:go_default_library",
|
||||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
],
|
],
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
@ -289,7 +290,7 @@ func ValidateMixedArguments(flag *pflag.FlagSet) error {
|
||||||
|
|
||||||
mixedInvalidFlags := []string{}
|
mixedInvalidFlags := []string{}
|
||||||
flag.Visit(func(f *pflag.Flag) {
|
flag.Visit(func(f *pflag.Flag) {
|
||||||
if f.Name == "config" || strings.HasPrefix(f.Name, "skip-") || f.Name == "dry-run" || f.Name == "kubeconfig" {
|
if f.Name == "config" || strings.HasPrefix(f.Name, "ignore-checks-") || strings.HasPrefix(f.Name, "skip-") || f.Name == "dry-run" || f.Name == "kubeconfig" {
|
||||||
// "--skip-*" flags or other whitelisted flags can be set with --config
|
// "--skip-*" flags or other whitelisted flags can be set with --config
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -328,3 +329,27 @@ func ValidateAPIEndpoint(c *kubeadm.MasterConfiguration, fldPath *field.Path) fi
|
||||||
}
|
}
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidateIgnoreChecksErrors validates duplicates in ignore-checks-errors flag.
|
||||||
|
func ValidateIgnoreChecksErrors(ignoreChecksErrors []string, skipPreflightChecks bool) (sets.String, error) {
|
||||||
|
ignoreErrors := sets.NewString()
|
||||||
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
|
for _, item := range ignoreChecksErrors {
|
||||||
|
ignoreErrors.Insert(strings.ToLower(item)) // parameters are case insensitive
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove once deprecated flag --skip-preflight-checks is removed.
|
||||||
|
if skipPreflightChecks {
|
||||||
|
if ignoreErrors.Has("all") {
|
||||||
|
allErrs = append(allErrs, field.Invalid(field.NewPath("ignore-checks-errors"), strings.Join(ignoreErrors.List(), ","), "'all' is used together with deprecated flag --skip-preflight-checks. Remove deprecated flag"))
|
||||||
|
}
|
||||||
|
ignoreErrors.Insert("all")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ignoreErrors.Has("all") && ignoreErrors.Len() > 1 {
|
||||||
|
allErrs = append(allErrs, field.Invalid(field.NewPath("ignore-checks-errors"), strings.Join(ignoreErrors.List(), ","), "don't specify individual checks if 'all' is used"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return ignoreErrors, allErrs.ToAggregate()
|
||||||
|
}
|
||||||
|
|
|
@ -458,3 +458,32 @@ func TestValidateFeatureGates(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateIgnoreChecksErrors(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
ignoreChecksErrors []string
|
||||||
|
skipPreflightChecks bool
|
||||||
|
expectedLen int
|
||||||
|
expectedError bool
|
||||||
|
}{
|
||||||
|
{[]string{}, false, 0, false}, // empty list, no old skip-preflight-checks
|
||||||
|
{[]string{}, true, 1, false}, // empty list, old skip-preflight-checks
|
||||||
|
{[]string{"check1", "check2"}, false, 2, false}, // non-duplicate
|
||||||
|
{[]string{"check1", "check2"}, true, 3, true}, // non-duplicate, but skip-preflight-checks
|
||||||
|
{[]string{"check1", "check2", "check1"}, false, 2, false}, // duplicates
|
||||||
|
{[]string{"check1", "check2", "all"}, false, 3, true}, // non-duplicate, but 'all' present together wth individual checks
|
||||||
|
{[]string{"all"}, false, 1, false}, // skip all checks by using new flag
|
||||||
|
{[]string{"all"}, true, 1, true}, // skip all checks by using both old and new flags at the same time
|
||||||
|
}
|
||||||
|
for _, rt := range tests {
|
||||||
|
result, err := ValidateIgnoreChecksErrors(rt.ignoreChecksErrors, rt.skipPreflightChecks)
|
||||||
|
switch {
|
||||||
|
case err != nil && !rt.expectedError:
|
||||||
|
t.Errorf("ValidateIgnoreChecksErrors: unexpected error for input (%s, %v), error: %v", rt.ignoreChecksErrors, rt.skipPreflightChecks, err)
|
||||||
|
case err == nil && rt.expectedError:
|
||||||
|
t.Errorf("ValidateIgnoreChecksErrors: expected error for input (%s, %v) but got: %v", rt.ignoreChecksErrors, rt.skipPreflightChecks, result)
|
||||||
|
case result.Len() != rt.expectedLen:
|
||||||
|
t.Errorf("ValidateIgnoreChecksErrors: expected Len = %d for input (%s, %v) but got: %v, %v", rt.expectedLen, rt.ignoreChecksErrors, rt.skipPreflightChecks, result.Len(), result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import (
|
||||||
flag "github.com/spf13/pflag"
|
flag "github.com/spf13/pflag"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||||
|
@ -112,6 +113,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
|
||||||
var dryRun bool
|
var dryRun bool
|
||||||
var featureGatesString string
|
var featureGatesString string
|
||||||
var criSocket string
|
var criSocket string
|
||||||
|
var ignoreChecksErrors []string
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "init",
|
Use: "init",
|
||||||
|
@ -126,7 +128,10 @@ func NewCmdInit(out io.Writer) *cobra.Command {
|
||||||
internalcfg := &kubeadmapi.MasterConfiguration{}
|
internalcfg := &kubeadmapi.MasterConfiguration{}
|
||||||
legacyscheme.Scheme.Convert(cfg, internalcfg, nil)
|
legacyscheme.Scheme.Convert(cfg, internalcfg, nil)
|
||||||
|
|
||||||
i, err := NewInit(cfgPath, internalcfg, skipPreFlight, skipTokenPrint, dryRun, criSocket)
|
ignoreChecksErrorsSet, err := validation.ValidateIgnoreChecksErrors(ignoreChecksErrors, skipPreFlight)
|
||||||
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
|
i, err := NewInit(cfgPath, internalcfg, ignoreChecksErrorsSet, skipTokenPrint, dryRun, criSocket)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
kubeadmutil.CheckErr(i.Validate(cmd))
|
kubeadmutil.CheckErr(i.Validate(cmd))
|
||||||
kubeadmutil.CheckErr(i.Run(out))
|
kubeadmutil.CheckErr(i.Run(out))
|
||||||
|
@ -134,7 +139,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString)
|
AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString)
|
||||||
AddInitOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight, &skipTokenPrint, &dryRun, &criSocket)
|
AddInitOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight, &skipTokenPrint, &dryRun, &criSocket, &ignoreChecksErrors)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -190,16 +195,21 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfigur
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddInitOtherFlags adds init flags that are not bound to a configuration file to the given flagset
|
// AddInitOtherFlags adds init flags that are not bound to a configuration file to the given flagset
|
||||||
func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, skipTokenPrint, dryRun *bool, criSocket *string) {
|
func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, skipTokenPrint, dryRun *bool, criSocket *string, ignoreChecksErrors *[]string) {
|
||||||
flagSet.StringVar(
|
flagSet.StringVar(
|
||||||
cfgPath, "config", *cfgPath,
|
cfgPath, "config", *cfgPath,
|
||||||
"Path to kubeadm config file. WARNING: Usage of a configuration file is experimental.",
|
"Path to kubeadm config file. WARNING: Usage of a configuration file is experimental.",
|
||||||
)
|
)
|
||||||
|
flagSet.StringSliceVar(
|
||||||
|
ignoreChecksErrors, "ignore-checks-errors", *ignoreChecksErrors,
|
||||||
|
"A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.",
|
||||||
|
)
|
||||||
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
|
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
|
||||||
flagSet.BoolVar(
|
flagSet.BoolVar(
|
||||||
skipPreFlight, "skip-preflight-checks", *skipPreFlight,
|
skipPreFlight, "skip-preflight-checks", *skipPreFlight,
|
||||||
"Skip preflight checks which normally run before modifying the system.",
|
"Skip preflight checks which normally run before modifying the system.",
|
||||||
)
|
)
|
||||||
|
flagSet.MarkDeprecated("skip-preflight-checks", "it is now equivalent to --ignore-checks-errors=all")
|
||||||
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
|
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
|
||||||
flagSet.BoolVar(
|
flagSet.BoolVar(
|
||||||
skipTokenPrint, "skip-token-print", *skipTokenPrint,
|
skipTokenPrint, "skip-token-print", *skipTokenPrint,
|
||||||
|
@ -217,7 +227,7 @@ func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, sk
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInit validates given arguments and instantiates Init struct with provided information.
|
// NewInit validates given arguments and instantiates Init struct with provided information.
|
||||||
func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight, skipTokenPrint, dryRun bool, criSocket string) (*Init, error) {
|
func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, ignoreChecksErrors sets.String, skipTokenPrint, dryRun bool, criSocket string) (*Init, error) {
|
||||||
fmt.Println("[kubeadm] WARNING: kubeadm is currently in beta")
|
fmt.Println("[kubeadm] WARNING: kubeadm is currently in beta")
|
||||||
|
|
||||||
if cfgPath != "" {
|
if cfgPath != "" {
|
||||||
|
@ -249,19 +259,15 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight,
|
||||||
fmt.Println("\t(/etc/systemd/system/kubelet.service.d/10-kubeadm.conf should be edited for this purpose)")
|
fmt.Println("\t(/etc/systemd/system/kubelet.service.d/10-kubeadm.conf should be edited for this purpose)")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !skipPreFlight {
|
fmt.Println("[preflight] Running pre-flight checks.")
|
||||||
fmt.Println("[preflight] Running pre-flight checks.")
|
|
||||||
|
|
||||||
if err := preflight.RunInitMasterChecks(utilsexec.New(), cfg, criSocket); err != nil {
|
if err := preflight.RunInitMasterChecks(utilsexec.New(), cfg, criSocket, ignoreChecksErrors); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
|
||||||
|
|
||||||
// Try to start the kubelet service in case it's inactive
|
|
||||||
preflight.TryStartKubelet()
|
|
||||||
} else {
|
|
||||||
fmt.Println("[preflight] Skipping pre-flight checks.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to start the kubelet service in case it's inactive
|
||||||
|
preflight.TryStartKubelet(ignoreChecksErrors)
|
||||||
|
|
||||||
return &Init{cfg: cfg, skipTokenPrint: skipTokenPrint, dryRun: dryRun}, nil
|
return &Init{cfg: cfg, skipTokenPrint: skipTokenPrint, dryRun: dryRun}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
flag "github.com/spf13/pflag"
|
flag "github.com/spf13/pflag"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
|
@ -110,6 +111,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
|
||||||
var cfgPath string
|
var cfgPath string
|
||||||
var criSocket string
|
var criSocket string
|
||||||
var featureGatesString string
|
var featureGatesString string
|
||||||
|
var ignoreChecksErrors []string
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "join [flags]",
|
Use: "join [flags]",
|
||||||
|
@ -127,7 +129,10 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
|
||||||
internalcfg := &kubeadmapi.NodeConfiguration{}
|
internalcfg := &kubeadmapi.NodeConfiguration{}
|
||||||
legacyscheme.Scheme.Convert(cfg, internalcfg, nil)
|
legacyscheme.Scheme.Convert(cfg, internalcfg, nil)
|
||||||
|
|
||||||
j, err := NewJoin(cfgPath, args, internalcfg, skipPreFlight, criSocket)
|
ignoreChecksErrorsSet, err := validation.ValidateIgnoreChecksErrors(ignoreChecksErrors, skipPreFlight)
|
||||||
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
|
j, err := NewJoin(cfgPath, args, internalcfg, ignoreChecksErrorsSet, criSocket)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
kubeadmutil.CheckErr(j.Validate(cmd))
|
kubeadmutil.CheckErr(j.Validate(cmd))
|
||||||
kubeadmutil.CheckErr(j.Run(out))
|
kubeadmutil.CheckErr(j.Run(out))
|
||||||
|
@ -135,7 +140,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
AddJoinConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString)
|
AddJoinConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString)
|
||||||
AddJoinOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight, &criSocket)
|
AddJoinOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight, &criSocket, &ignoreChecksErrors)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -170,15 +175,20 @@ func AddJoinConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.NodeConfigurat
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddJoinOtherFlags adds join flags that are not bound to a configuration file to the given flagset
|
// AddJoinOtherFlags adds join flags that are not bound to a configuration file to the given flagset
|
||||||
func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight *bool, criSocket *string) {
|
func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight *bool, criSocket *string, ignoreChecksErrors *[]string) {
|
||||||
flagSet.StringVar(
|
flagSet.StringVar(
|
||||||
cfgPath, "config", *cfgPath,
|
cfgPath, "config", *cfgPath,
|
||||||
"Path to kubeadm config file.")
|
"Path to kubeadm config file.")
|
||||||
|
|
||||||
|
flagSet.StringSliceVar(
|
||||||
|
ignoreChecksErrors, "ignore-checks-errors", *ignoreChecksErrors,
|
||||||
|
"A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.",
|
||||||
|
)
|
||||||
flagSet.BoolVar(
|
flagSet.BoolVar(
|
||||||
skipPreFlight, "skip-preflight-checks", false,
|
skipPreFlight, "skip-preflight-checks", false,
|
||||||
"Skip preflight checks which normally run before modifying the system.",
|
"Skip preflight checks which normally run before modifying the system.",
|
||||||
)
|
)
|
||||||
|
flagSet.MarkDeprecated("skip-preflight-checks", "it is now equivalent to --ignore-checks-errors=all")
|
||||||
flagSet.StringVar(
|
flagSet.StringVar(
|
||||||
criSocket, "cri-socket", "/var/run/dockershim.sock",
|
criSocket, "cri-socket", "/var/run/dockershim.sock",
|
||||||
`Specify the CRI socket to connect to.`,
|
`Specify the CRI socket to connect to.`,
|
||||||
|
@ -191,7 +201,7 @@ type Join struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewJoin instantiates Join struct with given arguments
|
// NewJoin instantiates Join struct with given arguments
|
||||||
func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, skipPreFlight bool, criSocket string) (*Join, error) {
|
func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, ignoreChecksErrors sets.String, criSocket string) (*Join, error) {
|
||||||
fmt.Println("[kubeadm] WARNING: kubeadm is currently in beta")
|
fmt.Println("[kubeadm] WARNING: kubeadm is currently in beta")
|
||||||
|
|
||||||
if cfg.NodeName == "" {
|
if cfg.NodeName == "" {
|
||||||
|
@ -208,20 +218,16 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !skipPreFlight {
|
fmt.Println("[preflight] Running pre-flight checks.")
|
||||||
fmt.Println("[preflight] Running pre-flight checks.")
|
|
||||||
|
|
||||||
// Then continue with the others...
|
// Then continue with the others...
|
||||||
if err := preflight.RunJoinNodeChecks(utilsexec.New(), cfg, criSocket); err != nil {
|
if err := preflight.RunJoinNodeChecks(utilsexec.New(), cfg, criSocket, ignoreChecksErrors); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
|
||||||
|
|
||||||
// Try to start the kubelet service in case it's inactive
|
|
||||||
preflight.TryStartKubelet()
|
|
||||||
} else {
|
|
||||||
fmt.Println("[preflight] Skipping pre-flight checks.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to start the kubelet service in case it's inactive
|
||||||
|
preflight.TryStartKubelet(ignoreChecksErrors)
|
||||||
|
|
||||||
return &Join{cfg: cfg}, nil
|
return &Join{cfg: cfg}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ go_library(
|
||||||
"//pkg/util/normalizer:go_default_library",
|
"//pkg/util/normalizer:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||||
],
|
],
|
||||||
|
|
|
@ -19,6 +19,7 @@ package phases
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||||
|
@ -70,7 +71,7 @@ func NewCmdPreFlightMaster() *cobra.Command {
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cfg := &kubeadmapi.MasterConfiguration{}
|
cfg := &kubeadmapi.MasterConfiguration{}
|
||||||
criSocket := ""
|
criSocket := ""
|
||||||
err := preflight.RunInitMasterChecks(utilsexec.New(), cfg, criSocket)
|
err := preflight.RunInitMasterChecks(utilsexec.New(), cfg, criSocket, sets.NewString())
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -88,7 +89,7 @@ func NewCmdPreFlightNode() *cobra.Command {
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cfg := &kubeadmapi.NodeConfiguration{}
|
cfg := &kubeadmapi.NodeConfiguration{}
|
||||||
criSocket := ""
|
criSocket := ""
|
||||||
err := preflight.RunJoinNodeChecks(utilsexec.New(), cfg, criSocket)
|
err := preflight.RunJoinNodeChecks(utilsexec.New(), cfg, criSocket, sets.NewString())
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,9 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
|
@ -45,20 +47,30 @@ func NewCmdReset(out io.Writer) *cobra.Command {
|
||||||
var skipPreFlight bool
|
var skipPreFlight bool
|
||||||
var certsDir string
|
var certsDir string
|
||||||
var criSocketPath string
|
var criSocketPath string
|
||||||
|
var ignoreChecksErrors []string
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "reset",
|
Use: "reset",
|
||||||
Short: "Run this to revert any changes made to this host by 'kubeadm init' or 'kubeadm join'.",
|
Short: "Run this to revert any changes made to this host by 'kubeadm init' or 'kubeadm join'.",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
r, err := NewReset(skipPreFlight, certsDir, criSocketPath)
|
ignoreChecksErrorsSet, err := validation.ValidateIgnoreChecksErrors(ignoreChecksErrors, skipPreFlight)
|
||||||
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
|
r, err := NewReset(ignoreChecksErrorsSet, certsDir, criSocketPath)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
kubeadmutil.CheckErr(r.Run(out))
|
kubeadmutil.CheckErr(r.Run(out))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd.PersistentFlags().StringSliceVar(
|
||||||
|
&ignoreChecksErrors, "ignore-checks-errors", ignoreChecksErrors,
|
||||||
|
"A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.",
|
||||||
|
)
|
||||||
cmd.PersistentFlags().BoolVar(
|
cmd.PersistentFlags().BoolVar(
|
||||||
&skipPreFlight, "skip-preflight-checks", false,
|
&skipPreFlight, "skip-preflight-checks", false,
|
||||||
"Skip preflight checks which normally run before modifying the system.",
|
"Skip preflight checks which normally run before modifying the system.",
|
||||||
)
|
)
|
||||||
|
cmd.PersistentFlags().MarkDeprecated("skip-preflight-checks", "it is now equivalent to --ignore-checks-errors=all")
|
||||||
|
|
||||||
cmd.PersistentFlags().StringVar(
|
cmd.PersistentFlags().StringVar(
|
||||||
&certsDir, "cert-dir", kubeadmapiext.DefaultCertificatesDir,
|
&certsDir, "cert-dir", kubeadmapiext.DefaultCertificatesDir,
|
||||||
|
@ -80,15 +92,11 @@ type Reset struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReset instantiate Reset struct
|
// NewReset instantiate Reset struct
|
||||||
func NewReset(skipPreFlight bool, certsDir, criSocketPath string) (*Reset, error) {
|
func NewReset(ignoreChecksErrors sets.String, certsDir, criSocketPath string) (*Reset, error) {
|
||||||
if !skipPreFlight {
|
fmt.Println("[preflight] Running pre-flight checks.")
|
||||||
fmt.Println("[preflight] Running pre-flight checks.")
|
|
||||||
|
|
||||||
if err := preflight.RunRootCheckOnly(); err != nil {
|
if err := preflight.RunRootCheckOnly(ignoreChecksErrors); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println("[preflight] Skipping pre-flight checks.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Reset{
|
return &Reset{
|
||||||
|
|
|
@ -195,6 +195,10 @@ func (c *fakeDockerChecker) Check() (warnings, errors []error) {
|
||||||
return c.warnings, c.errors
|
return c.warnings, c.errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *fakeDockerChecker) Name() string {
|
||||||
|
return "FakeDocker"
|
||||||
|
}
|
||||||
|
|
||||||
func newFakeDockerChecker(warnings, errors []error) preflight.Checker {
|
func newFakeDockerChecker(warnings, errors []error) preflight.Checker {
|
||||||
return &fakeDockerChecker{warnings: warnings, errors: errors}
|
return &fakeDockerChecker{warnings: warnings, errors: errors}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ go_library(
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
||||||
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||||
|
@ -27,6 +28,7 @@ go_library(
|
||||||
"//pkg/util/version:go_default_library",
|
"//pkg/util/version:go_default_library",
|
||||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/discovery/fake:go_default_library",
|
"//vendor/k8s.io/client-go/discovery/fake:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
],
|
],
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
|
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
||||||
|
@ -70,8 +71,12 @@ func NewCmdApply(parentFlags *cmdUpgradeFlags) *cobra.Command {
|
||||||
Use: "apply [version]",
|
Use: "apply [version]",
|
||||||
Short: "Upgrade your Kubernetes cluster to the specified version.",
|
Short: "Upgrade your Kubernetes cluster to the specified version.",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
var err error
|
||||||
|
flags.parent.ignoreChecksErrorsSet, err = validation.ValidateIgnoreChecksErrors(flags.parent.ignoreChecksErrors, flags.parent.skipPreFlight)
|
||||||
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
// Ensure the user is root
|
// Ensure the user is root
|
||||||
err := runPreflightChecks(flags.parent.skipPreFlight)
|
err = runPreflightChecks(flags.parent.ignoreChecksErrorsSet)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
err = cmdutil.ValidateExactArgNumber(args, []string{"version"})
|
err = cmdutil.ValidateExactArgNumber(args, []string{"version"})
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
fakediscovery "k8s.io/client-go/discovery/fake"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||||
|
@ -97,14 +98,9 @@ func printConfiguration(cfg *kubeadmapiext.MasterConfiguration, w io.Writer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// runPreflightChecks runs the root preflight check
|
// runPreflightChecks runs the root preflight check
|
||||||
func runPreflightChecks(skipPreFlight bool) error {
|
func runPreflightChecks(ignoreChecksErrors sets.String) error {
|
||||||
if skipPreFlight {
|
|
||||||
fmt.Println("[preflight] Skipping pre-flight checks.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("[preflight] Running pre-flight checks.")
|
fmt.Println("[preflight] Running pre-flight checks.")
|
||||||
return preflight.RunRootCheckOnly()
|
return preflight.RunRootCheckOnly(ignoreChecksErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getClient gets a real or fake client depending on whether the user is dry-running or not
|
// getClient gets a real or fake client depending on whether the user is dry-running or not
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
)
|
)
|
||||||
|
@ -35,8 +36,11 @@ func NewCmdPlan(parentFlags *cmdUpgradeFlags) *cobra.Command {
|
||||||
Use: "plan",
|
Use: "plan",
|
||||||
Short: "Check which versions are available to upgrade to and validate whether your current cluster is upgradeable.",
|
Short: "Check which versions are available to upgrade to and validate whether your current cluster is upgradeable.",
|
||||||
Run: func(_ *cobra.Command, _ []string) {
|
Run: func(_ *cobra.Command, _ []string) {
|
||||||
|
var err error
|
||||||
|
parentFlags.ignoreChecksErrorsSet, err = validation.ValidateIgnoreChecksErrors(parentFlags.ignoreChecksErrors, parentFlags.skipPreFlight)
|
||||||
|
kubeadmutil.CheckErr(err)
|
||||||
// Ensure the user is root
|
// Ensure the user is root
|
||||||
err := runPreflightChecks(parentFlags.skipPreFlight)
|
err = runPreflightChecks(parentFlags.ignoreChecksErrorsSet)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
err = RunPlan(parentFlags)
|
err = RunPlan(parentFlags)
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -31,6 +32,8 @@ type cmdUpgradeFlags struct {
|
||||||
allowRCUpgrades bool
|
allowRCUpgrades bool
|
||||||
printConfig bool
|
printConfig bool
|
||||||
skipPreFlight bool
|
skipPreFlight bool
|
||||||
|
ignoreChecksErrors []string
|
||||||
|
ignoreChecksErrorsSet sets.String
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmdUpgrade returns the cobra command for `kubeadm upgrade`
|
// NewCmdUpgrade returns the cobra command for `kubeadm upgrade`
|
||||||
|
@ -42,6 +45,7 @@ func NewCmdUpgrade(out io.Writer) *cobra.Command {
|
||||||
allowRCUpgrades: false,
|
allowRCUpgrades: false,
|
||||||
printConfig: false,
|
printConfig: false,
|
||||||
skipPreFlight: false,
|
skipPreFlight: false,
|
||||||
|
ignoreChecksErrorsSet: sets.NewString(),
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
@ -55,7 +59,9 @@ func NewCmdUpgrade(out io.Writer) *cobra.Command {
|
||||||
cmd.PersistentFlags().BoolVar(&flags.allowExperimentalUpgrades, "allow-experimental-upgrades", flags.allowExperimentalUpgrades, "Show unstable versions of Kubernetes as an upgrade alternative and allow upgrading to an alpha/beta/release candidate versions of Kubernetes.")
|
cmd.PersistentFlags().BoolVar(&flags.allowExperimentalUpgrades, "allow-experimental-upgrades", flags.allowExperimentalUpgrades, "Show unstable versions of Kubernetes as an upgrade alternative and allow upgrading to an alpha/beta/release candidate versions of Kubernetes.")
|
||||||
cmd.PersistentFlags().BoolVar(&flags.allowRCUpgrades, "allow-release-candidate-upgrades", flags.allowRCUpgrades, "Show release candidate versions of Kubernetes as an upgrade alternative and allow upgrading to a release candidate versions of Kubernetes.")
|
cmd.PersistentFlags().BoolVar(&flags.allowRCUpgrades, "allow-release-candidate-upgrades", flags.allowRCUpgrades, "Show release candidate versions of Kubernetes as an upgrade alternative and allow upgrading to a release candidate versions of Kubernetes.")
|
||||||
cmd.PersistentFlags().BoolVar(&flags.printConfig, "print-config", flags.printConfig, "Specifies whether the configuration file that will be used in the upgrade should be printed or not.")
|
cmd.PersistentFlags().BoolVar(&flags.printConfig, "print-config", flags.printConfig, "Specifies whether the configuration file that will be used in the upgrade should be printed or not.")
|
||||||
|
cmd.PersistentFlags().StringSliceVar(&flags.ignoreChecksErrors, "ignore-checks-errors", flags.ignoreChecksErrors, "A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.")
|
||||||
cmd.PersistentFlags().BoolVar(&flags.skipPreFlight, "skip-preflight-checks", flags.skipPreFlight, "Skip preflight checks that normally run before modifying the system.")
|
cmd.PersistentFlags().BoolVar(&flags.skipPreFlight, "skip-preflight-checks", flags.skipPreFlight, "Skip preflight checks that normally run before modifying the system.")
|
||||||
|
cmd.PersistentFlags().MarkDeprecated("skip-preflight-checks", "it is now equivalent to --ignore-checks-errors=all")
|
||||||
|
|
||||||
cmd.AddCommand(NewCmdApply(flags))
|
cmd.AddCommand(NewCmdApply(flags))
|
||||||
cmd.AddCommand(NewCmdPlan(flags))
|
cmd.AddCommand(NewCmdPlan(flags))
|
||||||
|
|
|
@ -36,6 +36,7 @@ go_library(
|
||||||
"//vendor/github.com/blang/semver:go_default_library",
|
"//vendor/github.com/blang/semver:go_default_library",
|
||||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -51,6 +52,7 @@ go_test(
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
"//vendor/github.com/renstrom/dedent:go_default_library",
|
"//vendor/github.com/renstrom/dedent:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -41,6 +41,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
netutil "k8s.io/apimachinery/pkg/util/net"
|
netutil "k8s.io/apimachinery/pkg/util/net"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
apiservoptions "k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
apiservoptions "k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||||
cmoptions "k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
cmoptions "k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
@ -74,13 +75,14 @@ type Error struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
func (e *Error) Error() string {
|
||||||
return fmt.Sprintf("[preflight] Some fatal errors occurred:\n%s%s", e.Msg, "[preflight] If you know what you are doing, you can skip pre-flight checks with `--skip-preflight-checks`")
|
return fmt.Sprintf("[preflight] Some fatal errors occurred:\n%s%s", e.Msg, "[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-checks-errors=...`")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checker validates the state of the system to ensure kubeadm will be
|
// Checker validates the state of the system to ensure kubeadm will be
|
||||||
// successful as often as possilble.
|
// successful as often as possilble.
|
||||||
type Checker interface {
|
type Checker interface {
|
||||||
Check() (warnings, errors []error)
|
Check() (warnings, errors []error)
|
||||||
|
Name() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// CRICheck verifies the container runtime through the CRI.
|
// CRICheck verifies the container runtime through the CRI.
|
||||||
|
@ -89,6 +91,11 @@ type CRICheck struct {
|
||||||
exec utilsexec.Interface
|
exec utilsexec.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns label for CRICheck.
|
||||||
|
func (CRICheck) Name() string {
|
||||||
|
return "CRI"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates the container runtime through the CRI.
|
// Check validates the container runtime through the CRI.
|
||||||
func (criCheck CRICheck) Check() (warnings, errors []error) {
|
func (criCheck CRICheck) Check() (warnings, errors []error) {
|
||||||
if err := criCheck.exec.Command("sh", "-c", fmt.Sprintf("crictl -r %s info", criCheck.socket)).Run(); err != nil {
|
if err := criCheck.exec.Command("sh", "-c", fmt.Sprintf("crictl -r %s info", criCheck.socket)).Run(); err != nil {
|
||||||
|
@ -104,6 +111,15 @@ func (criCheck CRICheck) Check() (warnings, errors []error) {
|
||||||
type ServiceCheck struct {
|
type ServiceCheck struct {
|
||||||
Service string
|
Service string
|
||||||
CheckIfActive bool
|
CheckIfActive bool
|
||||||
|
Label string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns label for ServiceCheck. If not provided, will return based on the service parameter
|
||||||
|
func (sc ServiceCheck) Name() string {
|
||||||
|
if sc.Label != "" {
|
||||||
|
return sc.Label
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Service-%s", strings.Title(sc.Service))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validates if the service is enabled and active.
|
// Check validates if the service is enabled and active.
|
||||||
|
@ -141,6 +157,11 @@ type FirewalldCheck struct {
|
||||||
ports []int
|
ports []int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns label for FirewalldCheck.
|
||||||
|
func (FirewalldCheck) Name() string {
|
||||||
|
return "Firewalld"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates if the firewall is enabled and active.
|
// Check validates if the firewall is enabled and active.
|
||||||
func (fc FirewalldCheck) Check() (warnings, errors []error) {
|
func (fc FirewalldCheck) Check() (warnings, errors []error) {
|
||||||
initSystem, err := initsystem.GetInitSystem()
|
initSystem, err := initsystem.GetInitSystem()
|
||||||
|
@ -165,7 +186,16 @@ func (fc FirewalldCheck) Check() (warnings, errors []error) {
|
||||||
|
|
||||||
// PortOpenCheck ensures the given port is available for use.
|
// PortOpenCheck ensures the given port is available for use.
|
||||||
type PortOpenCheck struct {
|
type PortOpenCheck struct {
|
||||||
port int
|
port int
|
||||||
|
label string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns name for PortOpenCheck. If not known, will return "PortXXXX" based on port number
|
||||||
|
func (poc PortOpenCheck) Name() string {
|
||||||
|
if poc.label != "" {
|
||||||
|
return poc.label
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Port-%d", poc.port)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validates if the particular port is available.
|
// Check validates if the particular port is available.
|
||||||
|
@ -185,9 +215,23 @@ func (poc PortOpenCheck) Check() (warnings, errors []error) {
|
||||||
// IsPrivilegedUserCheck verifies user is privileged (linux - root, windows - Administrator)
|
// IsPrivilegedUserCheck verifies user is privileged (linux - root, windows - Administrator)
|
||||||
type IsPrivilegedUserCheck struct{}
|
type IsPrivilegedUserCheck struct{}
|
||||||
|
|
||||||
|
// Name returns name for IsPrivilegedUserCheck
|
||||||
|
func (IsPrivilegedUserCheck) Name() string {
|
||||||
|
return "IsPrivilegedUser"
|
||||||
|
}
|
||||||
|
|
||||||
// DirAvailableCheck checks if the given directory either does not exist, or is empty.
|
// DirAvailableCheck checks if the given directory either does not exist, or is empty.
|
||||||
type DirAvailableCheck struct {
|
type DirAvailableCheck struct {
|
||||||
Path string
|
Path string
|
||||||
|
Label string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns label for individual DirAvailableChecks. If not known, will return based on path.
|
||||||
|
func (dac DirAvailableCheck) Name() string {
|
||||||
|
if dac.Label != "" {
|
||||||
|
return dac.Label
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("DirAvailable-%s", strings.Replace(dac.Path, "/", "-", -1))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validates if a directory does not exist or empty.
|
// Check validates if a directory does not exist or empty.
|
||||||
|
@ -215,7 +259,16 @@ func (dac DirAvailableCheck) Check() (warnings, errors []error) {
|
||||||
|
|
||||||
// FileAvailableCheck checks that the given file does not already exist.
|
// FileAvailableCheck checks that the given file does not already exist.
|
||||||
type FileAvailableCheck struct {
|
type FileAvailableCheck struct {
|
||||||
Path string
|
Path string
|
||||||
|
Label string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns label for individual FileAvailableChecks. If not known, will return based on path.
|
||||||
|
func (fac FileAvailableCheck) Name() string {
|
||||||
|
if fac.Label != "" {
|
||||||
|
return fac.Label
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("FileAvailable-%s", strings.Replace(fac.Path, "/", "-", -1))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validates if the given file does not already exist.
|
// Check validates if the given file does not already exist.
|
||||||
|
@ -229,7 +282,16 @@ func (fac FileAvailableCheck) Check() (warnings, errors []error) {
|
||||||
|
|
||||||
// FileExistingCheck checks that the given file does not already exist.
|
// FileExistingCheck checks that the given file does not already exist.
|
||||||
type FileExistingCheck struct {
|
type FileExistingCheck struct {
|
||||||
Path string
|
Path string
|
||||||
|
Label string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns label for individual FileExistingChecks. If not known, will return based on path.
|
||||||
|
func (fac FileExistingCheck) Name() string {
|
||||||
|
if fac.Label != "" {
|
||||||
|
return fac.Label
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("FileExisting-%s", strings.Replace(fac.Path, "/", "-", -1))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validates if the given file already exists.
|
// Check validates if the given file already exists.
|
||||||
|
@ -245,6 +307,15 @@ func (fac FileExistingCheck) Check() (warnings, errors []error) {
|
||||||
type FileContentCheck struct {
|
type FileContentCheck struct {
|
||||||
Path string
|
Path string
|
||||||
Content []byte
|
Content []byte
|
||||||
|
Label string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns label for individual FileContentChecks. If not known, will return based on path.
|
||||||
|
func (fcc FileContentCheck) Name() string {
|
||||||
|
if fcc.Label != "" {
|
||||||
|
return fcc.Label
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("FileContent-%s", strings.Replace(fcc.Path, "/", "-", -1))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validates if the given file contains the given content.
|
// Check validates if the given file contains the given content.
|
||||||
|
@ -275,6 +346,15 @@ type InPathCheck struct {
|
||||||
executable string
|
executable string
|
||||||
mandatory bool
|
mandatory bool
|
||||||
exec utilsexec.Interface
|
exec utilsexec.Interface
|
||||||
|
label string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns label for individual InPathCheck. If not known, will return based on path.
|
||||||
|
func (ipc InPathCheck) Name() string {
|
||||||
|
if ipc.label != "" {
|
||||||
|
return ipc.label
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("FileExisting-%s", strings.Replace(ipc.executable, "/", "-", -1))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validates if the given executable is present in the path.
|
// Check validates if the given executable is present in the path.
|
||||||
|
@ -297,6 +377,11 @@ type HostnameCheck struct {
|
||||||
nodeName string
|
nodeName string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name will return Hostname as name for HostnameCheck
|
||||||
|
func (HostnameCheck) Name() string {
|
||||||
|
return "Hostname"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates if hostname match dns sub domain regex.
|
// Check validates if hostname match dns sub domain regex.
|
||||||
func (hc HostnameCheck) Check() (warnings, errors []error) {
|
func (hc HostnameCheck) Check() (warnings, errors []error) {
|
||||||
errors = []error{}
|
errors = []error{}
|
||||||
|
@ -322,6 +407,11 @@ type HTTPProxyCheck struct {
|
||||||
Port int
|
Port int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns HTTPProxy as name for HTTPProxyCheck
|
||||||
|
func (hst HTTPProxyCheck) Name() string {
|
||||||
|
return "HTTPProxy"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates http connectivity type, direct or via proxy.
|
// Check validates http connectivity type, direct or via proxy.
|
||||||
func (hst HTTPProxyCheck) Check() (warnings, errors []error) {
|
func (hst HTTPProxyCheck) Check() (warnings, errors []error) {
|
||||||
|
|
||||||
|
@ -352,6 +442,11 @@ type HTTPProxyCIDRCheck struct {
|
||||||
CIDR string
|
CIDR string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name will return HTTPProxyCIDR as name for HTTPProxyCIDRCheck
|
||||||
|
func (HTTPProxyCIDRCheck) Name() string {
|
||||||
|
return "HTTPProxyCIDR"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates http connectivity to first IP address in the CIDR.
|
// Check validates http connectivity to first IP address in the CIDR.
|
||||||
// If it is not directly connected and goes via proxy it will produce warning.
|
// If it is not directly connected and goes via proxy it will produce warning.
|
||||||
func (subnet HTTPProxyCIDRCheck) Check() (warnings, errors []error) {
|
func (subnet HTTPProxyCIDRCheck) Check() (warnings, errors []error) {
|
||||||
|
@ -399,6 +494,11 @@ type ExtraArgsCheck struct {
|
||||||
SchedulerExtraArgs map[string]string
|
SchedulerExtraArgs map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name will return ExtraArgs as name for ExtraArgsCheck
|
||||||
|
func (ExtraArgsCheck) Name() string {
|
||||||
|
return "ExtraArgs"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates additional arguments of the control plane components.
|
// Check validates additional arguments of the control plane components.
|
||||||
func (eac ExtraArgsCheck) Check() (warnings, errors []error) {
|
func (eac ExtraArgsCheck) Check() (warnings, errors []error) {
|
||||||
argsCheck := func(name string, args map[string]string, f *pflag.FlagSet) []error {
|
argsCheck := func(name string, args map[string]string, f *pflag.FlagSet) []error {
|
||||||
|
@ -438,6 +538,11 @@ type SystemVerificationCheck struct {
|
||||||
CRISocket string
|
CRISocket string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name will return SystemVerification as name for SystemVerificationCheck
|
||||||
|
func (SystemVerificationCheck) Name() string {
|
||||||
|
return "SystemVerification"
|
||||||
|
}
|
||||||
|
|
||||||
// Check runs all individual checks
|
// Check runs all individual checks
|
||||||
func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
|
func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
|
||||||
// Create a buffered writer and choose a quite large value (1M) and suppose the output from the system verification test won't exceed the limit
|
// Create a buffered writer and choose a quite large value (1M) and suppose the output from the system verification test won't exceed the limit
|
||||||
|
@ -490,6 +595,11 @@ type KubernetesVersionCheck struct {
|
||||||
KubernetesVersion string
|
KubernetesVersion string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name will return KubernetesVersion as name for KubernetesVersionCheck
|
||||||
|
func (KubernetesVersionCheck) Name() string {
|
||||||
|
return "KubernetesVersion"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates kubernetes and kubeadm versions
|
// Check validates kubernetes and kubeadm versions
|
||||||
func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) {
|
func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) {
|
||||||
|
|
||||||
|
@ -525,6 +635,11 @@ type KubeletVersionCheck struct {
|
||||||
KubernetesVersion string
|
KubernetesVersion string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name will return KubeletVersion as name for KubeletVersionCheck
|
||||||
|
func (KubeletVersionCheck) Name() string {
|
||||||
|
return "KubeletVersion"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates kubelet version. It should be not less than minimal supported version
|
// Check validates kubelet version. It should be not less than minimal supported version
|
||||||
func (kubever KubeletVersionCheck) Check() (warnings, errors []error) {
|
func (kubever KubeletVersionCheck) Check() (warnings, errors []error) {
|
||||||
kubeletVersion, err := GetKubeletVersion()
|
kubeletVersion, err := GetKubeletVersion()
|
||||||
|
@ -550,6 +665,11 @@ func (kubever KubeletVersionCheck) Check() (warnings, errors []error) {
|
||||||
// SwapCheck warns if swap is enabled
|
// SwapCheck warns if swap is enabled
|
||||||
type SwapCheck struct{}
|
type SwapCheck struct{}
|
||||||
|
|
||||||
|
// Name will return Swap as name for SwapCheck
|
||||||
|
func (SwapCheck) Name() string {
|
||||||
|
return "Swap"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates whether swap is enabled or not
|
// Check validates whether swap is enabled or not
|
||||||
func (swc SwapCheck) Check() (warnings, errors []error) {
|
func (swc SwapCheck) Check() (warnings, errors []error) {
|
||||||
f, err := os.Open("/proc/swaps")
|
f, err := os.Open("/proc/swaps")
|
||||||
|
@ -584,6 +704,11 @@ type ExternalEtcdVersionCheck struct {
|
||||||
Etcd kubeadmapi.Etcd
|
Etcd kubeadmapi.Etcd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name will return ExternalEtcdVersion as name for ExternalEtcdVersionCheck
|
||||||
|
func (ExternalEtcdVersionCheck) Name() string {
|
||||||
|
return "ExternalEtcdVersion"
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates external etcd version
|
// Check validates external etcd version
|
||||||
func (evc ExternalEtcdVersionCheck) Check() (warnings, errors []error) {
|
func (evc ExternalEtcdVersionCheck) Check() (warnings, errors []error) {
|
||||||
var config *tls.Config
|
var config *tls.Config
|
||||||
|
@ -712,9 +837,9 @@ func getEtcdVersionResponse(client *http.Client, url string, target interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunInitMasterChecks executes all individual, applicable to Master node checks.
|
// RunInitMasterChecks executes all individual, applicable to Master node checks.
|
||||||
func RunInitMasterChecks(execer utilsexec.Interface, cfg *kubeadmapi.MasterConfiguration, criSocket string) error {
|
func RunInitMasterChecks(execer utilsexec.Interface, cfg *kubeadmapi.MasterConfiguration, criSocket string, ignoreChecksErrors sets.String) error {
|
||||||
// First, check if we're root separately from the other preflight checks and fail fast
|
// First, check if we're root separately from the other preflight checks and fail fast
|
||||||
if err := RunRootCheckOnly(); err != nil {
|
if err := RunRootCheckOnly(ignoreChecksErrors); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,13 +929,13 @@ func RunInitMasterChecks(execer utilsexec.Interface, cfg *kubeadmapi.MasterConfi
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return RunChecks(checks, os.Stderr)
|
return RunChecks(checks, os.Stderr, ignoreChecksErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunJoinNodeChecks executes all individual, applicable to node checks.
|
// RunJoinNodeChecks executes all individual, applicable to node checks.
|
||||||
func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.NodeConfiguration, criSocket string) error {
|
func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.NodeConfiguration, criSocket string, ignoreChecksErrors sets.String) error {
|
||||||
// First, check if we're root separately from the other preflight checks and fail fast
|
// First, check if we're root separately from the other preflight checks and fail fast
|
||||||
if err := RunRootCheckOnly(); err != nil {
|
if err := RunRootCheckOnly(ignoreChecksErrors); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,33 +987,50 @@ func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.NodeConfigura
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return RunChecks(checks, os.Stderr)
|
return RunChecks(checks, os.Stderr, ignoreChecksErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunRootCheckOnly initializes checks slice of structs and call RunChecks
|
// RunRootCheckOnly initializes checks slice of structs and call RunChecks
|
||||||
func RunRootCheckOnly() error {
|
func RunRootCheckOnly(ignoreChecksErrors sets.String) error {
|
||||||
checks := []Checker{
|
checks := []Checker{
|
||||||
IsPrivilegedUserCheck{},
|
IsPrivilegedUserCheck{},
|
||||||
}
|
}
|
||||||
|
|
||||||
return RunChecks(checks, os.Stderr)
|
return RunChecks(checks, os.Stderr, ignoreChecksErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunChecks runs each check, displays it's warnings/errors, and once all
|
// RunChecks runs each check, displays it's warnings/errors, and once all
|
||||||
// are processed will exit if any errors occurred.
|
// are processed will exit if any errors occurred.
|
||||||
func RunChecks(checks []Checker, ww io.Writer) error {
|
func RunChecks(checks []Checker, ww io.Writer, ignoreChecksErrors sets.String) error {
|
||||||
found := []error{}
|
type checkErrors struct {
|
||||||
|
Name string
|
||||||
|
Errors []error
|
||||||
|
}
|
||||||
|
found := []checkErrors{}
|
||||||
|
|
||||||
for _, c := range checks {
|
for _, c := range checks {
|
||||||
|
name := c.Name()
|
||||||
warnings, errs := c.Check()
|
warnings, errs := c.Check()
|
||||||
for _, w := range warnings {
|
|
||||||
io.WriteString(ww, fmt.Sprintf("[preflight] WARNING: %v\n", w))
|
if setHasItemOrAll(ignoreChecksErrors, name) {
|
||||||
|
// Decrease severity of errors to warnings for this check
|
||||||
|
warnings = append(warnings, errs...)
|
||||||
|
errs = []error{}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, w := range warnings {
|
||||||
|
io.WriteString(ww, fmt.Sprintf("\t[WARNING %s]: %v\n", name, w))
|
||||||
|
}
|
||||||
|
if len(errs) > 0 {
|
||||||
|
found = append(found, checkErrors{Name: name, Errors: errs})
|
||||||
}
|
}
|
||||||
found = append(found, errs...)
|
|
||||||
}
|
}
|
||||||
if len(found) > 0 {
|
if len(found) > 0 {
|
||||||
var errs bytes.Buffer
|
var errs bytes.Buffer
|
||||||
for _, i := range found {
|
for _, c := range found {
|
||||||
errs.WriteString("\t" + i.Error() + "\n")
|
for _, i := range c.Errors {
|
||||||
|
errs.WriteString(fmt.Sprintf("\t[ERROR %s]: %v\n", c.Name, i.Error()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &Error{Msg: errs.String()}
|
return &Error{Msg: errs.String()}
|
||||||
}
|
}
|
||||||
|
@ -896,7 +1038,10 @@ func RunChecks(checks []Checker, ww io.Writer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryStartKubelet attempts to bring up kubelet service
|
// TryStartKubelet attempts to bring up kubelet service
|
||||||
func TryStartKubelet() {
|
func TryStartKubelet(ignoreChecksErrors sets.String) {
|
||||||
|
if setHasItemOrAll(ignoreChecksErrors, "StartKubelet") {
|
||||||
|
return
|
||||||
|
}
|
||||||
// If we notice that the kubelet service is inactive, try to start it
|
// If we notice that the kubelet service is inactive, try to start it
|
||||||
initSystem, err := initsystem.GetInitSystem()
|
initSystem, err := initsystem.GetInitSystem()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -910,3 +1055,11 @@ func TryStartKubelet() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setHasItemOrAll is helper function that return true if item is present in the set (case insensitive) or special key 'all' is present
|
||||||
|
func setHasItemOrAll(s sets.String, item string) bool {
|
||||||
|
if s.Has("all") || s.Has(strings.ToLower(item)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
"k8s.io/utils/exec"
|
"k8s.io/utils/exec"
|
||||||
)
|
)
|
||||||
|
@ -166,6 +167,10 @@ type preflightCheckTest struct {
|
||||||
msg string
|
msg string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pfct preflightCheckTest) Name() string {
|
||||||
|
return "preflightCheckTest"
|
||||||
|
}
|
||||||
|
|
||||||
func (pfct preflightCheckTest) Check() (warning, errors []error) {
|
func (pfct preflightCheckTest) Check() (warning, errors []error) {
|
||||||
if pfct.msg == "warning" {
|
if pfct.msg == "warning" {
|
||||||
return []error{fmt.Errorf("warning")}, nil
|
return []error{fmt.Errorf("warning")}, nil
|
||||||
|
@ -218,7 +223,7 @@ func TestRunInitMasterChecks(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
actual := RunInitMasterChecks(exec.New(), rt.cfg, "")
|
actual := RunInitMasterChecks(exec.New(), rt.cfg, "", sets.NewString())
|
||||||
if (actual == nil) != rt.expected {
|
if (actual == nil) != rt.expected {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed RunInitMasterChecks:\n\texpected: %t\n\t actual: %t\n\t error: %v",
|
"failed RunInitMasterChecks:\n\texpected: %t\n\t actual: %t\n\t error: %v",
|
||||||
|
@ -254,7 +259,7 @@ func TestRunJoinNodeChecks(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
actual := RunJoinNodeChecks(exec.New(), rt.cfg, "")
|
actual := RunJoinNodeChecks(exec.New(), rt.cfg, "", sets.NewString())
|
||||||
if (actual == nil) != rt.expected {
|
if (actual == nil) != rt.expected {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed RunJoinNodeChecks:\n\texpected: %t\n\t actual: %t",
|
"failed RunJoinNodeChecks:\n\texpected: %t\n\t actual: %t",
|
||||||
|
@ -272,7 +277,7 @@ func TestRunChecks(t *testing.T) {
|
||||||
output string
|
output string
|
||||||
}{
|
}{
|
||||||
{[]Checker{}, true, ""},
|
{[]Checker{}, true, ""},
|
||||||
{[]Checker{preflightCheckTest{"warning"}}, true, "[preflight] WARNING: warning\n"}, // should just print warning
|
{[]Checker{preflightCheckTest{"warning"}}, true, "\t[WARNING preflightCheckTest]: warning\n"}, // should just print warning
|
||||||
{[]Checker{preflightCheckTest{"error"}}, false, ""},
|
{[]Checker{preflightCheckTest{"error"}}, false, ""},
|
||||||
{[]Checker{preflightCheckTest{"test"}}, false, ""},
|
{[]Checker{preflightCheckTest{"test"}}, false, ""},
|
||||||
{[]Checker{DirAvailableCheck{Path: "/does/not/exist"}}, true, ""},
|
{[]Checker{DirAvailableCheck{Path: "/does/not/exist"}}, true, ""},
|
||||||
|
@ -281,7 +286,7 @@ func TestRunChecks(t *testing.T) {
|
||||||
{[]Checker{FileContentCheck{Path: "/does/not/exist"}}, false, ""},
|
{[]Checker{FileContentCheck{Path: "/does/not/exist"}}, false, ""},
|
||||||
{[]Checker{FileContentCheck{Path: "/"}}, true, ""},
|
{[]Checker{FileContentCheck{Path: "/"}}, true, ""},
|
||||||
{[]Checker{FileContentCheck{Path: "/", Content: []byte("does not exist")}}, false, ""},
|
{[]Checker{FileContentCheck{Path: "/", Content: []byte("does not exist")}}, false, ""},
|
||||||
{[]Checker{InPathCheck{executable: "foobarbaz", exec: exec.New()}}, true, "[preflight] WARNING: foobarbaz not found in system path\n"},
|
{[]Checker{InPathCheck{executable: "foobarbaz", exec: exec.New()}}, true, "\t[WARNING FileExisting-foobarbaz]: foobarbaz not found in system path\n"},
|
||||||
{[]Checker{InPathCheck{executable: "foobarbaz", mandatory: true, exec: exec.New()}}, false, ""},
|
{[]Checker{InPathCheck{executable: "foobarbaz", mandatory: true, exec: exec.New()}}, false, ""},
|
||||||
{[]Checker{ExtraArgsCheck{
|
{[]Checker{ExtraArgsCheck{
|
||||||
APIServerExtraArgs: map[string]string{"secure-port": "1234"},
|
APIServerExtraArgs: map[string]string{"secure-port": "1234"},
|
||||||
|
@ -290,14 +295,14 @@ func TestRunChecks(t *testing.T) {
|
||||||
}}, true, ""},
|
}}, true, ""},
|
||||||
{[]Checker{ExtraArgsCheck{
|
{[]Checker{ExtraArgsCheck{
|
||||||
APIServerExtraArgs: map[string]string{"secure-port": "foo"},
|
APIServerExtraArgs: map[string]string{"secure-port": "foo"},
|
||||||
}}, true, "[preflight] WARNING: kube-apiserver: failed to parse extra argument --secure-port=foo\n"},
|
}}, true, "\t[WARNING ExtraArgs]: kube-apiserver: failed to parse extra argument --secure-port=foo\n"},
|
||||||
{[]Checker{ExtraArgsCheck{
|
{[]Checker{ExtraArgsCheck{
|
||||||
APIServerExtraArgs: map[string]string{"invalid-argument": "foo"},
|
APIServerExtraArgs: map[string]string{"invalid-argument": "foo"},
|
||||||
}}, true, "[preflight] WARNING: kube-apiserver: failed to parse extra argument --invalid-argument=foo\n"},
|
}}, true, "\t[WARNING ExtraArgs]: kube-apiserver: failed to parse extra argument --invalid-argument=foo\n"},
|
||||||
}
|
}
|
||||||
for _, rt := range tokenTest {
|
for _, rt := range tokenTest {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
actual := RunChecks(rt.p, buf)
|
actual := RunChecks(rt.p, buf, sets.NewString())
|
||||||
if (actual == nil) != rt.expected {
|
if (actual == nil) != rt.expected {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed RunChecks:\n\texpected: %t\n\t actual: %t",
|
"failed RunChecks:\n\texpected: %t\n\t actual: %t",
|
||||||
|
|
Loading…
Reference in New Issue