diff --git a/cmd/kubeadm/app/preflight/checks.go b/cmd/kubeadm/app/preflight/checks.go index 9c4c49f3022..723b5bd44e0 100644 --- a/cmd/kubeadm/app/preflight/checks.go +++ b/cmd/kubeadm/app/preflight/checks.go @@ -833,6 +833,14 @@ func (ImagePullCheck) Name() string { // Check pulls images required by kubeadm. This is a mutating check func (ipc ImagePullCheck) Check() (warnings, errorList []error) { for _, image := range ipc.imageList { + ret, err := ipc.runtime.ImageExists(image) + if ret && err == nil { + klog.V(1).Infof("image exists: %s", image) + continue + } + if err != nil { + errorList = append(errorList, errors.Wrapf(err, "failed to check if image %s exists", image)) + } klog.V(1).Infof("pulling %s", image) if err := ipc.runtime.PullImage(image); err != nil { errorList = append(errorList, errors.Wrapf(err, "failed to pull image %s", image)) diff --git a/cmd/kubeadm/app/preflight/checks_test.go b/cmd/kubeadm/app/preflight/checks_test.go index 798a1f9e89c..fd66fbe28b4 100644 --- a/cmd/kubeadm/app/preflight/checks_test.go +++ b/cmd/kubeadm/app/preflight/checks_test.go @@ -753,20 +753,18 @@ func TestSetHasItemOrAll(t *testing.T) { func TestImagePullCheck(t *testing.T) { fcmd := fakeexec.FakeCmd{ RunScript: []fakeexec.FakeRunAction{ - // Test case 1: pull 3 images successfully - func() ([]byte, []byte, error) { return nil, nil, nil }, + // Test case 1: img1 and img2 exist, img3 doesn't exist func() ([]byte, []byte, error) { return nil, nil, nil }, func() ([]byte, []byte, error) { return nil, nil, nil }, + func() ([]byte, []byte, error) { return nil, nil, &fakeexec.FakeExitError{Status: 1} }, - // Test case 2: image pull errors - func() ([]byte, []byte, error) { return nil, nil, nil }, + // Test case 2: images don't exist + func() ([]byte, []byte, error) { return nil, nil, &fakeexec.FakeExitError{Status: 1} }, func() ([]byte, []byte, error) { return nil, nil, &fakeexec.FakeExitError{Status: 1} }, func() ([]byte, []byte, error) { return nil, nil, &fakeexec.FakeExitError{Status: 1} }, }, CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{ - // Test case1: pull 3 images - func() ([]byte, error) { return nil, nil }, - func() ([]byte, error) { return nil, nil }, + // Test case1: pull only img3 func() ([]byte, error) { return nil, nil }, // Test case 2: fail to pull image2 and image3 func() ([]byte, error) { return nil, nil }, @@ -783,6 +781,10 @@ func TestImagePullCheck(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) }, func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) }, func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) }, }, LookPathFunc: func(cmd string) (string, error) { return "/usr/bin/docker", nil }, } @@ -801,7 +803,7 @@ func TestImagePullCheck(t *testing.T) { t.Fatalf("did not expect any warnings but got %q", warnings) } if len(errors) != 0 { - t.Fatalf("expected 0 errors but got %d: %q", len(errors), errors) + t.Fatalf("expected 1 errors but got %d: %q", len(errors), errors) } warnings, errors = check.Check()