Repository: kubernetes/minikube
Pull request #15646 (2023-01-13 22:10:54)

Add check for Docker Desktop 4.16.0
```
$ docker version --format {{.Server.Platform.Name}}
Docker Desktop 4.16.0 (95345)

$ ./out/minikube start --driver docker
😄  minikube v1.28.0 on Darwin 13.1 (arm64)
✨  Using the docker driver based on user configuration

💣  Exiting due to PROVIDER_DOCKER_DESKTOP_VERSION_BAD: Docker Desktop 4.16.0 has a regression that prevents minikube from starting
💡  Suggestion: Update Docker Desktop to 4.16.1 or greater

```


Patch:
diff --git a/pkg/minikube/registry/drvs/docker/docker.go b/pkg/minikube/registry/drvs/docker/docker.go
index fdbddb462..45bcc90bf 100644
--- a/pkg/minikube/registry/drvs/docker/docker.go
+++ b/pkg/minikube/registry/drvs/docker/docker.go
@@ -102,7 +102,7 @@ func status() (retState registry.State) {
 	ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second)
 	defer cancel()
 
-	cmd := exec.CommandContext(ctx, oci.Docker, "version", "--format", "{{.Server.Os}}-{{.Server.Version}}")
+	cmd := exec.CommandContext(ctx, oci.Docker, "version", "--format", "{{.Server.Os}}-{{.Server.Version}}:{{.Server.Platform.Name}}")
 	o, err := cmd.Output()
 	if err != nil {
 		reason := ""
@@ -135,9 +135,15 @@ func status() (retState registry.State) {
 		}
 	}()
 
+	versions := strings.Split(string(o), ":")
+	dockerEngineVersion := versions[0]
+	dockerPlatformVersion := versions[1]
 	klog.Infof("docker version: %s", o)
 	if !viper.GetBool("force") {
-		s := checkDockerVersion(strings.TrimSpace(string(o))) // remove '\n' from o at the end
+		if s := checkDockerDesktopVersion(dockerPlatformVersion); s != nil {
+			return *s
+		}
+		s := checkDockerEngineVersion(strings.TrimSpace(dockerEngineVersion)) // remove '\n' from o at the end
 		if s.Error != nil {
 			return s
 		}
@@ -159,7 +165,7 @@ func status() (retState registry.State) {
 	return checkNeedsImprovement()
 }
 
-func checkDockerVersion(o string) registry.State {
+func checkDockerEngineVersion(o string) registry.State {
 	parts := strings.SplitN(o, "-", 2)
 	if len(parts) != 2 {
 		return registry.State{
@@ -240,6 +246,27 @@ func checkDockerVersion(o string) registry.State {
 		Doc:              docURL + "#requirements"}
 }
 
+func checkDockerDesktopVersion(version string) *registry.State {
+	fields := strings.Fields(version)
+	if len(fields) < 3 || fields[0] != "Docker" || fields[1] != "Desktop" {
+		return nil
+	}
+	currSemver, err := semver.Parse(fields[2])
+	if err != nil {
+		return nil
+	}
+	if currSemver.EQ(semver.MustParse("4.16.0")) {
+		return &registry.State{
+			Reason:    "PROVIDER_DOCKER_DESKTOP_VERSION_BAD",
+			Running:   true,
+			Error:     errors.New("Docker Desktop 4.16.0 has a regression that prevents minikube from starting"),
+			Installed: true,
+			Fix:       "Update Docker Desktop to 4.16.1 or greater",
+		}
+	}
+	return nil
+}
+
 // checkNeedsImprovement if overlay mod is installed on a system
 func checkNeedsImprovement() registry.State {
 	if runtime.GOOS == "linux" {


Test patch:
diff --git a/pkg/minikube/registry/drvs/docker/docker_test.go b/pkg/minikube/registry/drvs/docker/docker_test.go
index 3d03231f3..995160382 100644
--- a/pkg/minikube/registry/drvs/docker/docker_test.go
+++ b/pkg/minikube/registry/drvs/docker/docker_test.go
@@ -64,7 +64,7 @@ func stringToIntSlice(t *testing.T, s string) []int {
 	return []int{int(sem.Major), int(sem.Minor), int(sem.Patch)}
 }
 
-func TestCheckDockerVersion(t *testing.T) {
+func TestCheckDockerEngineVersion(t *testing.T) {
 	recParts := stringToIntSlice(t, recommendedDockerVersion)
 	minParts := stringToIntSlice(t, minDockerVersion)
 
@@ -135,8 +135,8 @@ func TestCheckDockerVersion(t *testing.T) {
 	}...)
 
 	for _, c := range tc {
-		t.Run("checkDockerVersion test", func(t *testing.T) {
-			s := checkDockerVersion(c.version)
+		t.Run("checkDockerEngineVersion test", func(t *testing.T) {
+			s := checkDockerEngineVersion(c.version)
 			if s.Error != nil {
 				if c.expect != s.Reason {
 					t.Errorf("Error %v expected. but got %q. (version string : %s)", c.expect, s.Reason, c.version)
@@ -150,3 +150,23 @@ func TestCheckDockerVersion(t *testing.T) {
 		})
 	}
 }
+
+func TestCheckDockerDesktopVersion(t *testing.T) {
+	tests := []struct {
+		input             string
+		shouldReturnState bool
+	}{
+		{"Docker Desktop", false},
+		{"Cat Desktop 4.16.0", false},
+		{"Docker Playground 4.16.0", false},
+		{"Docker Desktop 4.15.0", false},
+		{"Docker Desktop 4.16.0", true},
+		{"  Docker  Desktop  4.16.0  ", true},
+	}
+	for _, tt := range tests {
+		state := checkDockerDesktopVersion(tt.input)
+		if (state == nil && tt.shouldReturnState) || (state != nil && !tt.shouldReturnState) {
+			t.Errorf("checkDockerDesktopVersion(%q) = %v; expected shouldRetunState = %t", tt.input, state, tt.shouldReturnState)
+		}
+	}
+}