Repository: kubernetes/minikube
Pull request #14000 (2022-04-21 18:42:36)

GUI: Add `/usr/local/bin` to `PATH` env on Mac
Fixes https://github.com/kubernetes/minikube/issues/13999

**Problem:**
On Mac, the `PATH` env doesn't point to `/user/local/bin` by default, so when starting minikube it can't find the binaries for the drivers.

**Solution:**
If on Mac, append `/usr/local/bin` to the `PATH` env.

Creating the `QProcessEnvironment` once and saving it since the documentation states:
`However, note that repeated calls to this function will recreate the QProcessEnvironment object, which is a non-trivial operation.`


Patch:
diff --git a/cmd/minikube/main.go b/cmd/minikube/main.go
index b7a56d375..6f12f844b 100644
--- a/cmd/minikube/main.go
+++ b/cmd/minikube/main.go
@@ -229,7 +229,7 @@ func setFlags(parse bool) {
 
 // setLastStartFlags sets the log_file flag to lastStart.txt if start command and user doesn't specify log_file or log_dir flags.
 func setLastStartFlags() {
-	if pflag.Arg(0) != "start" {
+	if len(os.Args) < 2 || os.Args[1] != "start" {
 		return
 	}
 	if pflag.CommandLine.Changed("log_file") || pflag.CommandLine.Changed("log_dir") {
diff --git a/gui/window.cpp b/gui/window.cpp
index 5ca295c2a..6fc3b8290 100644
--- a/gui/window.cpp
+++ b/gui/window.cpp
@@ -82,6 +82,7 @@
 #include <QDir>
 #include <QFontDialog>
 #include <QStackedWidget>
+#include <QProcessEnvironment>
 
 #ifndef QT_NO_TERMWIDGET
 #include <QApplication>
@@ -116,6 +117,14 @@ Window::Window()
     setWindowIcon(*trayIconIcon);
 }
 
+QProcessEnvironment Window::setMacEnv()
+{
+    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+    QString path = env.value("PATH");
+    env.insert("PATH", path + ":/usr/local/bin");
+    return env;
+}
+
 void Window::createBasicView()
 {
     basicStartButton = new QPushButton(tr("Start"));
@@ -523,6 +532,12 @@ bool Window::sendMinikubeCommand(QStringList cmds, QString &text)
     arguments << cmds;
 
     QProcess *process = new QProcess(this);
+#if __APPLE__
+    if (env.isEmpty()) {
+        env = setMacEnv();
+    }
+    process->setProcessEnvironment(env);
+#endif
     process->start(program, arguments);
     this->setCursor(Qt::WaitCursor);
     bool timedOut = process->waitForFinished(300 * 1000);
diff --git a/gui/window.h b/gui/window.h
index 95fc57b80..f4ea23064 100644
--- a/gui/window.h
+++ b/gui/window.h
@@ -57,6 +57,7 @@
 #include <QSystemTrayIcon>
 #include <QFormLayout>
 #include <QStackedWidget>
+#include <QProcessEnvironment>
 
 #ifndef QT_NO_SYSTEMTRAYICON
 
@@ -166,12 +167,14 @@ private:
     void dashboardBrowser();
     Cluster createClusterObject(QJsonObject obj);
     QProcess *dashboardProcess;
+    QProcessEnvironment env;
 
     // Error messaging
     void outputFailedStart(QString text);
     QLabel *createLabel(QString title, QString text, QFormLayout *form, bool isLink);
 
     void checkForMinikube();
+    QProcessEnvironment setMacEnv();
     QStackedWidget *stackedWidget;
     bool isBasicView;
 };
diff --git a/pkg/generate/docs.go b/pkg/generate/docs.go
index 437ae4195..de18e7ae8 100644
--- a/pkg/generate/docs.go
+++ b/pkg/generate/docs.go
@@ -51,7 +51,7 @@ func Docs(root *cobra.Command, path string, testPath string, codePath string) er
 		return errors.Wrap(err, "failed to generate test docs")
 	}
 
-	return ErrorCodes(codePath, []string{"pkg/minikube/reason/reason.go", "pkg/minikube/reason/exitcodes.go"})
+	return ErrorCodes(codePath, []string{"pkg/minikube/reason/exitcodes.go", "pkg/minikube/reason/reason.go"})
 }
 
 // DocForCommand returns the specific doc for that command
diff --git a/pkg/minikube/audit/audit.go b/pkg/minikube/audit/audit.go
index eb4b0ead7..7deb87972 100644
--- a/pkg/minikube/audit/audit.go
+++ b/pkg/minikube/audit/audit.go
@@ -22,7 +22,6 @@ import (
 	"strings"
 	"time"
 
-	"github.com/spf13/pflag"
 	"github.com/spf13/viper"
 	"k8s.io/klog/v2"
 	"k8s.io/minikube/pkg/minikube/config"
@@ -53,10 +52,10 @@ func args() string {
 
 // Log details about the executed command.
 func Log(startTime time.Time) {
-	if !shouldLog() {
+	if len(os.Args) < 2 || !shouldLog() {
 		return
 	}
-	r := newRow(pflag.Arg(0), args(), userName(), version.GetVersion(), startTime, time.Now())
+	r := newRow(os.Args[1], args(), userName(), version.GetVersion(), startTime, time.Now())
 	if err := appendToLog(r); err != nil {
 		klog.Warning(err)
 	}
@@ -65,7 +64,7 @@ func Log(startTime time.Time) {
 // shouldLog returns if the command should be logged.
 func shouldLog() bool {
 	// in rare chance we get here without a command, don't log
-	if pflag.NArg() == 0 {
+	if len(os.Args) < 2 {
 		return false
 	}
 
@@ -75,7 +74,7 @@ func shouldLog() bool {
 
 	// commands that should not be logged.
 	no := []string{"status", "version"}
-	a := pflag.Arg(0)
+	a := os.Args[1]
 	for _, c := range no {
 		if a == c {
 			return false
@@ -86,5 +85,17 @@ func shouldLog() bool {
 
 // isDeletePurge return true if command is delete with purge flag.
 func isDeletePurge() bool {
-	return pflag.Arg(0) == "delete" && viper.GetBool("purge")
+	args := os.Args
+	if len(args) < 2 {
+		return false
+	}
+	if args[1] != "delete" {
+		return false
+	}
+	for _, a := range args {
+		if a == "--purge" {
+			return true
+		}
+	}
+	return false
 }
diff --git a/pkg/minikube/reason/reason.go b/pkg/minikube/reason/reason.go
index 1b10ae3b6..b2fece017 100644
--- a/pkg/minikube/reason/reason.go
+++ b/pkg/minikube/reason/reason.go
@@ -95,7 +95,7 @@ var (
 	InternalConfigUnset = Kind{ID: "MK_CONFIG_UNSET", ExitCode: ExProgramError}
 	// minikube failed to view current config values
 	InternalConfigView = Kind{ID: "MK_CONFIG_VIEW", ExitCode: ExProgramError}
-	// minikube failed to delete an internal configuration, such as a cached image
+	// minikybe failed to delete an internal configuration, such as a cached image
 	InternalDelConfig = Kind{ID: "MK_DEL_CONFIG", ExitCode: ExProgramError}
 	// minikube failed to generate script to activate minikube docker-env
 	InternalDockerScript = Kind{ID: "MK_DOCKER_SCRIPT", ExitCode: ExProgramError}
diff --git a/site/content/en/docs/contrib/errorcodes.en.md b/site/content/en/docs/contrib/errorcodes.en.md
index 08e224a7b..b6ab67ce8 100644
--- a/site/content/en/docs/contrib/errorcodes.en.md
+++ b/site/content/en/docs/contrib/errorcodes.en.md
@@ -5,6 +5,116 @@ description: >
 ---
 
 
+## Error Codes
+
+
+### Generic Errors
+1: ExFailure  
+2: ExInterrupted  
+
+### Error codes specific to the minikube program
+10: ExProgramError  
+14: ExProgramUsage  
+11: ExProgramConflict  
+15: ExProgramNotFound  
+16: ExProgramUnsupported  
+18: ExProgramConfig  
+
+### Error codes specific to resource limits (exit code layout follows no rules)
+20: ExResourceError  
+23: ExInsufficientMemory  
+26: ExInsufficientStorage  
+27: ExInsufficientPermission  
+29: ExInsufficientCores  
+
+### Error codes specific to the host
+30: ExHostError  
+31: ExHostConflict  
+32: ExHostTimeout  
+34: ExHostUsage  
+35: ExHostNotFound  
+38: ExHostUnsupported  
+37: ExHostPermission  
+38: ExHostConfig  
+
+### Error codes specific to remote networking
+40: ExInternetError  
+41: ExInternetConflict  
+42: ExInternetTimeout  
+45: ExInternetNotFound  
+48: ExInternetConfig  
+49: ExInternetUnavailable  
+
+### Error codes specific to the libmachine driver
+50: ExDriverError  
+51: ExDriverConflict  
+52: ExDriverTimeout  
+54: ExDriverUsage  
+55: ExDriverNotFound  
+56: ExDriverUnsupported  
+57: ExDriverPermission  
+58: ExDriverConfig  
+59: ExDriverUnavailable  
+
+### Error codes specific to the driver provider
+60: ExProviderError  
+61: ExProviderConflict  
+62: ExProviderTimeout  
+63: ExProviderNotRunning  
+65: ExProviderNotFound  
+66: ExProviderUnsupported  
+67: ExProviderPermission  
+68: ExProviderConfig  
+69: ExProviderUnavailable  
+
+### Error codes specific to local networking
+70: ExLocalNetworkError  
+71: ExLocalNetworkConflict  
+72: ExLocalNetworkTimeout  
+75: ExLocalNetworkNotFound  
+77: ExLocalNetworkPermission  
+78: ExLocalNetworkConfig  
+79: ExLocalNetworkUnavailable  
+
+### Error codes specific to the guest host
+80: ExGuestError  
+81: ExGuestConflict  
+82: ExGuestTimeout  
+83: ExGuestNotRunning  
+85: ExGuestNotFound  
+86: ExGuestUnsupported  
+87: ExGuestPermission  
+88: ExGuestConfig  
+89: ExGuestUnavailable  
+
+### Error codes specific to the container runtime
+90: ExRuntimeError  
+93: ExRuntimeNotRunning  
+95: ExRuntimeNotFound  
+99: ExRuntimeUnavailable  
+
+### Error codes specific to the Kubernetes control plane
+100: ExControlPlaneError  
+101: ExControlPlaneConflict  
+102: ExControlPlaneTimeout  
+103: ExControlPlaneNotRunning  
+105: ExControlPlaneNotFound  
+106: ExControlPlaneUnsupported  
+108: ExControlPlaneConfig  
+109: ExControlPlaneUnavailable  
+
+### Error codes specific to a Kubernetes service
+110: ExSvcError  
+111: ExSvcConflict  
+112: ExSvcTimeout  
+113: ExSvcNotRunning  
+115: ExSvcNotFound  
+116: ExSvcUnsupported  
+117: ExSvcPermission  
+118: ExSvcConfig  
+119: ExSvcUnavailable  
+
+
 ## Error Strings
 
 "MK_USAGE" (Exit code ExProgramUsage)  
@@ -56,7 +166,7 @@ minikube failed to unset an internal config value
 minikube failed to view current config values  
 
 "MK_DEL_CONFIG" (Exit code ExProgramError)  
-minikube failed to delete an internal configuration, such as a cached image  
+minikybe failed to delete an internal configuration, such as a cached image  
 
 "MK_DOCKER_SCRIPT" (Exit code ExProgramError)  
 minikube failed to generate script to activate minikube docker-env  
@@ -433,113 +543,3 @@ a too new Kubernetes version was specified for minikube to use
 "K8S_DOWNGRADE_UNSUPPORTED" (Exit code ExControlPlaneUnsupported)  
 minikube was unable to safely downgrade installed Kubernetes version  
 
-## Error Codes
-
-
-### Generic Errors
-1: ExFailure  
-2: ExInterrupted  
-
-### Error codes specific to the minikube program
-10: ExProgramError  
-14: ExProgramUsage  
-11: ExProgramConflict  
-15: ExProgramNotFound  
-16: ExProgramUnsupported  
-18: ExProgramConfig  
-
-### Error codes specific to resource limits (exit code layout follows no rules)
-20: ExResourceError  
-23: ExInsufficientMemory  
-26: ExInsufficientStorage  
-27: ExInsufficientPermission  
-29: ExInsufficientCores  
-
-### Error codes specific to the host
-30: ExHostError  
-31: ExHostConflict  
-32: ExHostTimeout  
-34: ExHostUsage  
-35: ExHostNotFound  
-38: ExHostUnsupported  
-37: ExHostPermission  
-38: ExHostConfig  
-
-### Error codes specific to remote networking
-40: ExInternetError  
-41: ExInternetConflict  
-42: ExInternetTimeout  
-45: ExInternetNotFound  
-48: ExInternetConfig  
-49: ExInternetUnavailable  
-
-### Error codes specific to the libmachine driver
-50: ExDriverError  
-51: ExDriverConflict  
-52: ExDriverTimeout  
-54: ExDriverUsage  
-55: ExDriverNotFound  
-56: ExDriverUnsupported  
-57: ExDriverPermission  
-58: ExDriverConfig  
-59: ExDriverUnavailable  
-
-### Error codes specific to the driver provider
-60: ExProviderError  
-61: ExProviderConflict  
-62: ExProviderTimeout  
-63: ExProviderNotRunning  
-65: ExProviderNotFound  
-66: ExProviderUnsupported  
-67: ExProviderPermission  
-68: ExProviderConfig  
-69: ExProviderUnavailable  
-
-### Error codes specific to local networking
-70: ExLocalNetworkError  
-71: ExLocalNetworkConflict  
-72: ExLocalNetworkTimeout  
-75: ExLocalNetworkNotFound  
-77: ExLocalNetworkPermission  
-78: ExLocalNetworkConfig  
-79: ExLocalNetworkUnavailable  
-
-### Error codes specific to the guest host
-80: ExGuestError  
-81: ExGuestConflict  
-82: ExGuestTimeout  
-83: ExGuestNotRunning  
-85: ExGuestNotFound  
-86: ExGuestUnsupported  
-87: ExGuestPermission  
-88: ExGuestConfig  
-89: ExGuestUnavailable  
-
-### Error codes specific to the container runtime
-90: ExRuntimeError  
-93: ExRuntimeNotRunning  
-95: ExRuntimeNotFound  
-99: ExRuntimeUnavailable  
-
-### Error codes specific to the Kubernetes control plane
-100: ExControlPlaneError  
-101: ExControlPlaneConflict  
-102: ExControlPlaneTimeout  
-103: ExControlPlaneNotRunning  
-105: ExControlPlaneNotFound  
-106: ExControlPlaneUnsupported  
-108: ExControlPlaneConfig  
-109: ExControlPlaneUnavailable  
-
-### Error codes specific to a Kubernetes service
-110: ExSvcError  
-111: ExSvcConflict  
-112: ExSvcTimeout  
-113: ExSvcNotRunning  
-115: ExSvcNotFound  
-116: ExSvcUnsupported  
-117: ExSvcPermission  
-118: ExSvcConfig  
-119: ExSvcUnavailable  
-
-
diff --git a/site/content/en/docs/tutorials/setup_minikube_gui.md b/site/content/en/docs/tutorials/setup_minikube_gui.md
index 6a9131b85..538220e4d 100644
--- a/site/content/en/docs/tutorials/setup_minikube_gui.md
+++ b/site/content/en/docs/tutorials/setup_minikube_gui.md
@@ -21,7 +21,7 @@ date: 2022-02-25
 {{% tabs %}}
 {{% mactab %}}
 {{% tabs %}}
-{{% tab Alpha %}}
+{{% tab Stable %}}
 1. Download the zipped folder
 ```shell
 curl -LO https://storage.googleapis.com/minikube-gui/latest/minikube-gui-mac.zip
@@ -53,7 +53,7 @@ open dist/systray.app
 {{% /mactab %}}
 {{% windowstab %}}
 {{% tabs %}}
-{{% tab Alpha %}}
+{{% tab Stable %}}
 1. Download the zipped folder via PowerShell (below) or via your [browser](https://storage.googleapis.com/minikube-gui/latest/minikube-gui-windows.zip) (faster)
 ```shell
 Invoke-WebRequest -Uri 'https://storage.googleapis.com/minikube-gui/latest/minikube-gui-windows.zip' -UseBasicParsing
@@ -83,7 +83,7 @@ Expand-Archive minikube-gui-windows.zip
 {{% /windowstab %}}
 {{% linuxtab %}}
 {{% tabs %}}
-{{% tab Alpha %}}
+{{% tab Stable %}}
 1. Download the zipped folder
 ```shell
 curl -LO https://storage.googleapis.com/minikube-gui/latest/minikube-gui-linux.zip
diff --git a/translations/fr.json b/translations/fr.json
index 75b038f72..704e9ec1c 100644
--- a/translations/fr.json
+++ b/translations/fr.json
@@ -41,7 +41,7 @@
 	"Access the Kubernetes dashboard running within the minikube cluster": "Accéder au tableau de bord Kubernetes exécuté dans le cluster de minikube",
 	"Access to ports below 1024 may fail on Windows with OpenSSH clients older than v8.1. For more information, see: https://minikube.sigs.k8s.io/docs/handbook/accessing/#access-to-ports-1024-on-windows-requires-root-permission": "Accéder aux ports inférieurs à 1024 peut échouer sur Windows avec les clients OpenSSH antérieurs à v8.1. Pour plus d'information, voir: https://minikube.sigs.k8s.io/docs/handbook/accessing/#access-to-ports-1024-on-windows-requires-root-permission",
 	"Add SSH identity key to SSH authentication agent": "Ajouter la clé d'identité SSH à l'agent d'authentication SSH",
-	"Add an image into minikube as a local cache, or delete, reload the cached images": "Ajouter une image dans minikube en tant que cache local, ou supprimer, recharger les images en cache",
+	"Add an image into minikube as a local cache, or delete, reload the cached images": "",
 	"Add an image to local cache.": "Ajouter une image au cache local.",
 	"Add host key to SSH known_hosts file": "Ajouter la clé hôte au fichier SSH known_hosts",
 	"Add image to cache for all running minikube clusters": "Ajouter l'image au cache pour tous les cluster minikube en fonctionnement",
@@ -387,7 +387,7 @@
 	"Locations to fetch the minikube ISO from.": "Emplacements à partir desquels récupérer l'ISO minikube.",
 	"Log into or run a command on a machine with SSH; similar to 'docker-machine ssh'.": "Connectez-vous ou exécutez une commande sur une machine avec SSH ; similaire à 'docker-machine ssh'.",
 	"Log into the minikube environment (for debugging)": "Connectez-vous à l'environnement minikube (pour le débogage)",
-	"Manage cache for images": "Gérer le cache des images",
+	"Manage cache for images": "",
 	"Manage images": "Gérer les images",
 	"Message Size: {{.size}}": "Taille du message : {{.size}}",
 	"Minimum VirtualBox Version supported: {{.vers}}, current VirtualBox version: {{.cvers}}": "Version minimale de VirtualBox prise en charge : {{.vers}}, version actuelle de VirtualBox : {{.cvers}}",
@@ -613,7 +613,7 @@
 	"Target {{.path}} can not be empty": "La cible {{.path}} ne peut pas être vide",
 	"Test docs have been saved at - {{.path}}": "Les documents de test ont été enregistrés à - {{.path}}",
 	"The \"{{.driver_name}}\" driver should not be used with root privileges.": "Le pilote \"{{.driver_name}}\" ne doit pas être utilisé avec les privilèges root.",
-	"The \"{{.driver_name}}\" driver should not be used with root privileges. If you wish to continue as root, use --force.": "Le pilote \"{{.driver_name}}\" ne doit pas être utilisé avec les privilèges root. Si vous souhaitez continuer en tant que root, utilisez --force.",
+	"The \"{{.driver_name}}\" driver should not be used with root privileges. If you wish to continue as root, use --force.": "",
 	"The 'none' driver is designed for experts who need to integrate with an existing VM": "Le pilote 'none' est conçu pour les experts qui doivent s'intégrer à une machine virtuelle existante",
 	"The '{{.addonName}}' addon is enabled": "Le module '{{.addonName}}' est activé",
 	"The '{{.driver}}' driver requires elevated permissions. The following commands will be executed:\\n\\n{{ .example }}\\n": "Le pilote '{{.driver}}' nécessite des autorisations élevées. Les commandes suivantes seront exécutées :\\n\\n{{ .example }}\\n",
@@ -793,13 +793,13 @@
 	"Using image repository {{.name}}": "Utilisation du dépôt d'images {{.name}}…",
 	"Using image {{.registry}}{{.image}}": "Utilisation de l'image {{.registry}}{{.image}}",
 	"Using image {{.registry}}{{.image}} (global image repository)": "Utilisation de l'image {{.registry}}{{.image}} (référentiel d'images global)",
-	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "L'utilisation du pilote Docker sans root était nécessaire, mais le Docker actuel ne semble pas sans root. Essayez 'docker context use rootless' .",
-	"Using rootless driver was required, but the current driver does not seem rootless": "L'utilisation d'un pilote sans root était nécessaire, mais le pilote actuel ne semble pas sans root",
-	"Using rootless {{.driver_name}} driver": "Utilisation du pilote {{.driver_name}} sans root",
+	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "",
+	"Using rootless driver was required, but the current driver does not seem rootless": "",
+	"Using rootless {{.driver_name}} driver": "",
 	"Using the '{{.runtime}}' runtime with the 'none' driver is an untested configuration!": "L'utilisation du runtime '{{.runtime}}' avec le pilote 'none' est une configuration non testée !",
 	"Using the {{.driver}} driver based on existing profile": "Utilisation du pilote {{.driver}} basé sur le profil existant",
 	"Using the {{.driver}} driver based on user configuration": "Utilisation du pilote {{.driver}} basé sur la configuration de l'utilisateur",
-	"Using {{.driver_name}} driver with the root privilege": "Utilisation du pilote {{.driver_name}} avec le privilège root",
+	"Using {{.driver_name}} driver with the root privilege": "",
 	"Valid components are: {{.valid_extra_opts}}": "Les composants valides sont : {{.valid_extra_opts}}",
 	"Validate your KVM networks. Run: virt-host-validate and then virsh net-list --all": "Validez vos réseaux KVM. Exécutez : virt-host-validate puis virsh net-list --all",
 	"Verify that your HTTP_PROXY and HTTPS_PROXY environment variables are set correctly.": "Vérifiez que vos variables d'environnement HTTP_PROXY et HTTPS_PROXY sont correctement définies.",
@@ -830,7 +830,7 @@
 	"You cannot change the CPUs for an existing minikube cluster. Please first delete the cluster.": "Vous ne pouvez pas modifier les processeurs d'un cluster minikube existant. Veuillez d'abord supprimer le cluster.",
 	"You cannot change the disk size for an existing minikube cluster. Please first delete the cluster.": "Vous ne pouvez pas modifier la taille du disque pour un cluster minikube existant. Veuillez d'abord supprimer le cluster.",
 	"You cannot change the memory size for an existing minikube cluster. Please first delete the cluster.": "Vous ne pouvez pas modifier la taille de la mémoire d'un cluster minikube existant. Veuillez d'abord supprimer le cluster.",
-	"You have authenticated with a service account that does not have an associated JSON. The GCP Auth requires credentials with a JSON file in order to continue. The image pull secret has been imported.": "Vous vous êtes authentifié avec un compte de service qui n'a pas de JSON associé. L'authentification GCP nécessite des informations d'identification avec un fichier JSON pour continuer. Le secret d'extraction d'image a été importé.",
+	"You have authenticated with a service account that does not have an associated JSON. The GCP Auth requires credentials with a JSON file in order to continue. The image pull secret has been imported.": "",
 	"You have authenticated with a service account that does not have an associated JSON. The GCP Auth requires credentials with a JSON file to in order to continue. The image pull secret has been imported.": "Vous vous êtes authentifié avec un compte de service qui n'a pas de JSON associé. L'authentification GCP nécessite des informations d'identification avec un fichier JSON pour continuer. Le secret d'extraction d'image a été importé.",
 	"You have chosen to disable the CNI but the \\\"{{.name}}\\\" container runtime requires CNI": "Vous avez choisi de désactiver le CNI mais le runtime du conteneur \\\"{{.name}}\\\" nécessite CNI",
 	"You have selected \"virtualbox\" driver, but there are better options !\nFor better performance and support consider using a different driver: {{.drivers}}\n\nTo turn off this warning run:\n\n\t$ minikube config set WantVirtualBoxDriverWarning false\n\n\nTo learn more about on minikube drivers checkout https://minikube.sigs.k8s.io/docs/drivers/\nTo see benchmarks checkout https://minikube.sigs.k8s.io/docs/benchmarks/cpuusage/\n\n": "Vous avez sélectionné le pilote \"virtualbox\", mais il existe de meilleures options !\nPour de meilleures performances et une meilleure assistance, envisagez d'utiliser un autre pilote: {{.drivers}}\n\nPour désactiver cet avertissement, exécutez :\n\n\t $ minikube config set WantVirtualBoxDriverWarning false\n\n\nPour en savoir plus sur les pilotes minikube, consultez https://minikube.sigs.k8s.io/docs/drivers/\nPour voir les benchmarks, consultez https://minikube.sigs.k8s. io/docs/benchmarks/cpuusage/\n\n",


Test patch:
diff --git a/pkg/minikube/audit/audit_test.go b/pkg/minikube/audit/audit_test.go
index e91f7d972..7c36ae655 100644
--- a/pkg/minikube/audit/audit_test.go
+++ b/pkg/minikube/audit/audit_test.go
@@ -22,7 +22,6 @@ import (
 	"testing"
 	"time"
 
-	"github.com/spf13/pflag"
 	"github.com/spf13/viper"
 	"k8s.io/minikube/pkg/minikube/config"
 )
@@ -89,11 +88,8 @@ func TestAudit(t *testing.T) {
 	})
 
 	t.Run("shouldLog", func(t *testing.T) {
-		oldCommandLine := pflag.CommandLine
-		defer func() {
-			pflag.CommandLine = oldCommandLine
-			pflag.Parse()
-		}()
+		oldArgs := os.Args
+		defer func() { os.Args = oldArgs }()
 
 		tests := []struct {
 			args []string
@@ -126,22 +122,19 @@ func TestAudit(t *testing.T) {
 		}
 
 		for _, test := range tests {
-			mockArgs(t, test.args)
+			os.Args = test.args
 
 			got := shouldLog()
 
 			if got != test.want {
-				t.Errorf("test.args = %q; shouldLog() = %t; want %t", test.args, got, test.want)
+				t.Errorf("os.Args = %q; shouldLog() = %t; want %t", os.Args, got, test.want)
 			}
 		}
 	})
 
 	t.Run("isDeletePurge", func(t *testing.T) {
-		oldCommandLine := pflag.CommandLine
-		defer func() {
-			pflag.CommandLine = oldCommandLine
-			pflag.Parse()
-		}()
+		oldArgs := os.Args
+		defer func() { os.Args = oldArgs }()
 
 		tests := []struct {
 			args []string
@@ -166,12 +159,12 @@ func TestAudit(t *testing.T) {
 		}
 
 		for _, test := range tests {
-			mockArgs(t, test.args)
+			os.Args = test.args
 
 			got := isDeletePurge()
 
 			if got != test.want {
-				t.Errorf("test.args = %q; isDeletePurge() = %t; want %t", test.args, got, test.want)
+				t.Errorf("os.Args = %q; isDeletePurge() = %t; want %t", os.Args, got, test.want)
 			}
 		}
 	})
@@ -182,28 +175,6 @@ func TestAudit(t *testing.T) {
 		defer func() { os.Args = oldArgs }()
 		os.Args = []string{"minikube"}
 
-		oldCommandLine := pflag.CommandLine
-		defer func() {
-			pflag.CommandLine = oldCommandLine
-			pflag.Parse()
-		}()
-		mockArgs(t, os.Args)
-
 		Log(time.Now())
 	})
 }
-
-func mockArgs(t *testing.T, args []string) {
-	if len(args) == 0 {
-		t.Fatalf("cannot pass an empty slice to mockArgs")
-	}
-	fs := pflag.NewFlagSet(args[0], pflag.ExitOnError)
-	fs.Bool("purge", false, "")
-	if err := fs.Parse(args[1:]); err != nil {
-		t.Fatal(err)
-	}
-	pflag.CommandLine = fs
-	if err := viper.BindPFlags(pflag.CommandLine); err != nil {
-		t.Fatal(err)
-	}
-}