Repository: code-ready/crc
Pull request #1787 (2020-12-17 09:14:53)

Remove start flag for monitoring, keep only config prop. Check monitoring in crc status
Follow up of the monitoring PR.

openshift-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/code-ready/crc/pull/1787#" title="Author self-approved">guillaumerose</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=code-ready%2Fcrc).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/code-ready/crc/blob/master/OWNERS)~~ [guillaumerose]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
openshift-merge-robot: @guillaumerose: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/e2e-crc | ffe617e0f87ca06c923dc4e549a7aa7f80c3745f | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/code-ready_crc/1787/pull-ci-code-ready-crc-master-e2e-crc/1339499302061346816) | `/test e2e-crc`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=code-ready&repo=crc&pr=1787). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:guillaumerose).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
openshift-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/code-ready/crc/pull/1787#" title="Author self-approved">guillaumerose</a>*, *<a href="https://github.com/code-ready/crc/pull/1787#pullrequestreview-554607708" title="Approved">jsliacan</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=code-ready%2Fcrc).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/code-ready/crc/blob/master/OWNERS)~~ [guillaumerose,jsliacan]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
praveenkumar: /need-rebase
openshift-ci-robot: New changes are detected. LGTM label has been removed.
praveenkumar: /need-rebase

Patch:
diff --git a/Makefile b/Makefile
index f2ec45bc7..00a35abd5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 SHELL := /bin/bash
 
-BUNDLE_VERSION = 4.6.6
+BUNDLE_VERSION = 4.6.9
 BUNDLE_EXTENSION = crcbundle
 CRC_VERSION = 1.20.0
 COMMIT_SHA=$(shell git rev-parse --short HEAD)
diff --git a/centos_ci.sh b/centos_ci.sh
index 12e49cc65..469aebe22 100644
--- a/centos_ci.sh
+++ b/centos_ci.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 # bundle location
-BUNDLE_VERSION=4.6.6
+BUNDLE_VERSION=4.6.9
 BUNDLE=crc_libvirt_$BUNDLE_VERSION.crcbundle
 GO_VERSION=1.14.13
 
diff --git a/cmd/crc/cmd/cleanup.go b/cmd/crc/cmd/cleanup.go
index 854504fbd..c443917b8 100644
--- a/cmd/crc/cmd/cleanup.go
+++ b/cmd/crc/cmd/cleanup.go
@@ -6,7 +6,6 @@ import (
 	"io"
 	"os"
 
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/preflight"
 	"github.com/spf13/cobra"
 )
@@ -20,10 +19,8 @@ var cleanupCmd = &cobra.Command{
 	Use:   "cleanup",
 	Short: "Undo config changes",
 	Long:  "Undo all the configuration changes done by 'crc setup' command",
-	Run: func(cmd *cobra.Command, args []string) {
-		if err := runCleanup(); err != nil {
-			exit.WithMessage(1, err.Error())
-		}
+	RunE: func(cmd *cobra.Command, args []string) error {
+		return runCleanup()
 	},
 }
 
diff --git a/cmd/crc/cmd/config/config.go b/cmd/crc/cmd/config/config.go
index fe9c3304e..6a191653b 100644
--- a/cmd/crc/cmd/config/config.go
+++ b/cmd/crc/cmd/config/config.go
@@ -11,21 +11,21 @@ import (
 )
 
 const (
-	Bundle               = "bundle"
-	CPUs                 = "cpus"
-	Memory               = "memory"
-	DiskSize             = "disk-size"
-	NameServer           = "nameserver"
-	PullSecretFile       = "pull-secret-file"
-	DisableUpdateCheck   = "disable-update-check"
-	ExperimentalFeatures = "enable-experimental-features"
-	NetworkMode          = "network-mode"
-	HTTPProxy            = "http-proxy"
-	HTTPSProxy           = "https-proxy"
-	NoProxy              = "no-proxy"
-	ProxyCAFile          = "proxy-ca-file"
-	EnableMonitoring     = "enable-monitoring"
-	ConsentTelemetry     = "consent-telemetry"
+	Bundle                  = "bundle"
+	CPUs                    = "cpus"
+	Memory                  = "memory"
+	DiskSize                = "disk-size"
+	NameServer              = "nameserver"
+	PullSecretFile          = "pull-secret-file"
+	DisableUpdateCheck      = "disable-update-check"
+	ExperimentalFeatures    = "enable-experimental-features"
+	NetworkMode             = "network-mode"
+	HTTPProxy               = "http-proxy"
+	HTTPSProxy              = "https-proxy"
+	NoProxy                 = "no-proxy"
+	ProxyCAFile             = "proxy-ca-file"
+	ConsentTelemetry        = "consent-telemetry"
+	EnableClusterMonitoring = "enable-cluster-monitoring"
 )
 
 func RegisterSettings(cfg *config.Config) {
@@ -45,7 +45,7 @@ func RegisterSettings(cfg *config.Config) {
 	cfg.AddSetting(NoProxy, "", config.ValidateNoProxy, config.SuccessfullyApplied)
 	cfg.AddSetting(ProxyCAFile, "", config.ValidatePath, config.SuccessfullyApplied)
 
-	cfg.AddSetting(EnableMonitoring, false, config.ValidateBool, config.SuccessfullyApplied)
+	cfg.AddSetting(EnableClusterMonitoring, false, config.ValidateBool, config.SuccessfullyApplied)
 
 	// Telemeter Configuration
 	cfg.AddSetting(ConsentTelemetry, false, config.ValidateBool, config.SuccessfullyApplied)
diff --git a/cmd/crc/cmd/config/get.go b/cmd/crc/cmd/config/get.go
index 1acb8cdc2..2a6cb92f7 100644
--- a/cmd/crc/cmd/config/get.go
+++ b/cmd/crc/cmd/config/get.go
@@ -1,10 +1,10 @@
 package config
 
 import (
+	"errors"
 	"fmt"
 
 	"github.com/code-ready/crc/pkg/crc/config"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/output"
 	"github.com/spf13/cobra"
 )
@@ -14,20 +14,21 @@ func configGetCmd(config config.Storage) *cobra.Command {
 		Use:   "get CONFIG-KEY",
 		Short: "Get a crc configuration property",
 		Long:  `Gets a crc configuration property.`,
-		Run: func(cmd *cobra.Command, args []string) {
+		RunE: func(cmd *cobra.Command, args []string) error {
 			if len(args) < 1 {
-				exit.WithMessage(1, "Please provide a configuration property to get")
+				return errors.New("Please provide a configuration property to get")
 			}
 			key := args[0]
 			v := config.Get(key)
 			switch {
 			case v.Invalid:
-				exit.WithMessage(1, fmt.Sprintf("Configuration property '%s' does not exist", key))
+				return fmt.Errorf("Configuration property '%s' does not exist", key)
 			case v.IsDefault:
-				exit.WithMessage(1, fmt.Sprintf("Configuration property '%s' is not set. Default value is '%s'", key, v.AsString()))
+				return fmt.Errorf("Configuration property '%s' is not set. Default value is '%s'", key, v.AsString())
 			default:
 				output.Outln(key, ":", v.AsString())
 			}
+			return nil
 		},
 	}
 }
diff --git a/cmd/crc/cmd/config/set.go b/cmd/crc/cmd/config/set.go
index 3325855a2..f6b356b20 100644
--- a/cmd/crc/cmd/config/set.go
+++ b/cmd/crc/cmd/config/set.go
@@ -1,8 +1,9 @@
 package config
 
 import (
+	"errors"
+
 	"github.com/code-ready/crc/pkg/crc/config"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/output"
 	"github.com/spf13/cobra"
 )
@@ -12,18 +13,19 @@ func configSetCmd(config config.Storage) *cobra.Command {
 		Use:   "set CONFIG-KEY VALUE",
 		Short: "Set a crc configuration property",
 		Long:  `Sets a crc configuration property.`,
-		Run: func(cmd *cobra.Command, args []string) {
+		RunE: func(cmd *cobra.Command, args []string) error {
 			if len(args) < 2 {
-				exit.WithMessage(1, "Please provide a configuration property and its value as in 'crc config set KEY VALUE'")
+				return errors.New("Please provide a configuration property and its value as in 'crc config set KEY VALUE'")
 			}
 			setMessage, err := config.Set(args[0], args[1])
 			if err != nil {
-				exit.WithMessage(1, err.Error())
+				return err
 			}
 
 			if setMessage != "" {
 				output.Outln(setMessage)
 			}
+			return nil
 		},
 	}
 }
diff --git a/cmd/crc/cmd/config/unset.go b/cmd/crc/cmd/config/unset.go
index 16a0bf9c7..cfbe6484b 100644
--- a/cmd/crc/cmd/config/unset.go
+++ b/cmd/crc/cmd/config/unset.go
@@ -1,8 +1,9 @@
 package config
 
 import (
+	"errors"
+
 	"github.com/code-ready/crc/pkg/crc/config"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/output"
 	"github.com/spf13/cobra"
 )
@@ -12,17 +13,18 @@ func configUnsetCmd(config config.Storage) *cobra.Command {
 		Use:   "unset CONFIG-KEY",
 		Short: "Unset a crc configuration property",
 		Long:  `Unsets a crc configuration property.`,
-		Run: func(cmd *cobra.Command, args []string) {
+		RunE: func(cmd *cobra.Command, args []string) error {
 			if len(args) != 1 {
-				exit.WithMessage(1, "Please provide a configuration property to unset")
+				return errors.New("Please provide a configuration property to unset")
 			}
 			unsetMessage, err := config.Unset(args[0])
 			if err != nil {
-				exit.WithMessage(1, err.Error())
+				return err
 			}
 			if unsetMessage != "" {
 				output.Outln(unsetMessage)
 			}
+			return nil
 		},
 	}
 }
diff --git a/cmd/crc/cmd/config/view.go b/cmd/crc/cmd/config/view.go
index 3905d73f6..f574e3f1a 100644
--- a/cmd/crc/cmd/config/view.go
+++ b/cmd/crc/cmd/config/view.go
@@ -9,7 +9,6 @@ import (
 	"text/template"
 
 	"github.com/code-ready/crc/pkg/crc/config"
-	"github.com/code-ready/crc/pkg/crc/logging"
 	"github.com/spf13/cobra"
 )
 
@@ -29,14 +28,12 @@ func configViewCmd(config config.Storage) *cobra.Command {
 		Use:   "view",
 		Short: "Display all assigned crc configuration properties",
 		Long:  `Displays all assigned crc configuration properties and their values.`,
-		Run: func(cmd *cobra.Command, args []string) {
+		RunE: func(cmd *cobra.Command, args []string) error {
 			tmpl, err := determineTemplate(configViewFormat)
 			if err != nil {
-				logging.Fatal(err)
-			}
-			if err := runConfigView(config.AllConfigs(), tmpl, os.Stdout); err != nil {
-				logging.Fatal(err)
+				return err
 			}
+			return runConfigView(config.AllConfigs(), tmpl, os.Stdout)
 		},
 	}
 	configViewCmd.Flags().StringVar(&configViewFormat, "format", DefaultConfigViewFormat,
diff --git a/cmd/crc/cmd/console.go b/cmd/crc/cmd/console.go
index 7a28e002b..ef5831c7c 100644
--- a/cmd/crc/cmd/console.go
+++ b/cmd/crc/cmd/console.go
@@ -6,7 +6,6 @@ import (
 	"io"
 	"os"
 
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/machine"
 	"github.com/code-ready/machine/libmachine/state"
 	"github.com/pkg/browser"
@@ -31,10 +30,8 @@ var consoleCmd = &cobra.Command{
 	Aliases: []string{"dashboard"},
 	Short:   "Open the OpenShift Web Console in the default browser",
 	Long:    `Open the OpenShift Web Console in the default browser or print its URL or credentials`,
-	Run: func(cmd *cobra.Command, args []string) {
-		if renderErr := runConsole(os.Stdout, newMachine(), consolePrintURL, consolePrintCredentials, outputFormat); renderErr != nil {
-			exit.WithMessage(1, renderErr.Error())
-		}
+	RunE: func(cmd *cobra.Command, args []string) error {
+		return runConsole(os.Stdout, newMachine(), consolePrintURL, consolePrintCredentials, outputFormat)
 	},
 }
 
diff --git a/cmd/crc/cmd/daemon.go b/cmd/crc/cmd/daemon.go
index ab33bea91..f20530cbd 100644
--- a/cmd/crc/cmd/daemon.go
+++ b/cmd/crc/cmd/daemon.go
@@ -12,7 +12,6 @@ import (
 
 	crcConfig "github.com/code-ready/crc/pkg/crc/config"
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/logging"
 	"github.com/code-ready/gvisor-tap-vsock/pkg/transport"
 	"github.com/code-ready/gvisor-tap-vsock/pkg/types"
@@ -32,7 +31,7 @@ var daemonCmd = &cobra.Command{
 	Short:  "Run the crc daemon",
 	Long:   "Run the crc daemon",
 	Hidden: true,
-	Run: func(cmd *cobra.Command, args []string) {
+	RunE: func(cmd *cobra.Command, args []string) error {
 		// setup separate logging for daemon
 		logging.CloseLogging()
 		logging.InitLogrus(logging.LogLevel, constants.DaemonLogFilePath)
@@ -50,7 +49,7 @@ var daemonCmd = &cobra.Command{
 			}
 		}
 
-		if err := run(&types.Configuration{
+		err := run(&types.Configuration{
 			Debug:             false, // never log packets
 			CaptureFile:       captureFile(),
 			MTU:               4000, // Large packets slightly improve the performance. Less small packets.
@@ -89,9 +88,8 @@ var daemonCmd = &cobra.Command{
 				":6443": "192.168.127.2:6443",
 				":443":  "192.168.127.2:443",
 			},
-		}, endpoints); err != nil {
-			exit.WithMessage(1, err.Error())
-		}
+		}, endpoints)
+		return err
 	},
 }
 
diff --git a/cmd/crc/cmd/delete.go b/cmd/crc/cmd/delete.go
index 0abb8d699..48ac6f6ec 100644
--- a/cmd/crc/cmd/delete.go
+++ b/cmd/crc/cmd/delete.go
@@ -7,7 +7,6 @@ import (
 	"os"
 
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/input"
 	"github.com/code-ready/crc/pkg/crc/machine"
 	"github.com/spf13/cobra"
@@ -27,10 +26,8 @@ var deleteCmd = &cobra.Command{
 	Use:   "delete",
 	Short: "Delete the OpenShift cluster",
 	Long:  "Delete the OpenShift cluster",
-	Run: func(cmd *cobra.Command, args []string) {
-		if err := runDelete(os.Stdout, newMachine(), clearCache, constants.MachineCacheDir, outputFormat != jsonFormat, globalForce, outputFormat); err != nil {
-			exit.WithMessage(1, err.Error())
-		}
+	RunE: func(cmd *cobra.Command, args []string) error {
+		return runDelete(os.Stdout, newMachine(), clearCache, constants.MachineCacheDir, outputFormat != jsonFormat, globalForce, outputFormat)
 	},
 }
 
diff --git a/cmd/crc/cmd/ip.go b/cmd/crc/cmd/ip.go
index e7db5a68f..576178ac0 100644
--- a/cmd/crc/cmd/ip.go
+++ b/cmd/crc/cmd/ip.go
@@ -1,7 +1,6 @@
 package cmd
 
 import (
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/output"
 	"github.com/spf13/cobra"
 )
@@ -14,10 +13,8 @@ var ipCmd = &cobra.Command{
 	Use:   "ip",
 	Short: "Get IP address of the running OpenShift cluster",
 	Long:  "Get IP address of the running OpenShift cluster",
-	Run: func(cmd *cobra.Command, args []string) {
-		if err := runIP(args); err != nil {
-			exit.WithMessage(1, err.Error())
-		}
+	RunE: func(cmd *cobra.Command, args []string) error {
+		return runIP(args)
 	},
 }
 
diff --git a/cmd/crc/cmd/oc_env.go b/cmd/crc/cmd/oc_env.go
index aea0177bc..09495bf92 100644
--- a/cmd/crc/cmd/oc_env.go
+++ b/cmd/crc/cmd/oc_env.go
@@ -4,7 +4,6 @@ import (
 	"fmt"
 
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/output"
 	"github.com/code-ready/crc/pkg/os/shell"
 	"github.com/spf13/cobra"
@@ -18,10 +17,8 @@ var ocEnvCmd = &cobra.Command{
 	Use:   "oc-env",
 	Short: "Add the 'oc' executable to PATH",
 	Long:  `Add the OpenShift client executable 'oc' to PATH`,
-	Run: func(cmd *cobra.Command, args []string) {
-		if err := runOcEnv(args); err != nil {
-			exit.WithMessage(1, err.Error())
-		}
+	RunE: func(cmd *cobra.Command, args []string) error {
+		return runOcEnv(args)
 	},
 }
 
diff --git a/cmd/crc/cmd/podman_env.go b/cmd/crc/cmd/podman_env.go
index e422ab619..ad37ea0f4 100644
--- a/cmd/crc/cmd/podman_env.go
+++ b/cmd/crc/cmd/podman_env.go
@@ -1,10 +1,10 @@
 package cmd
 
 import (
+	"errors"
 	"fmt"
 
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/output"
 	"github.com/code-ready/crc/pkg/os/shell"
 	"github.com/spf13/cobra"
@@ -14,17 +14,13 @@ var podmanEnvCmd = &cobra.Command{
 	Use:   "podman-env",
 	Short: "Setup podman environment",
 	Long:  `Setup environment for 'podman' executable to access podman on CRC VM`,
-	Run: func(cmd *cobra.Command, args []string) {
-		if err := runPodmanEnv(args); err != nil {
-			exit.WithMessage(1, err.Error())
-		}
+	RunE: func(cmd *cobra.Command, args []string) error {
+		// See issue #961; Currently does not work on Windows in combination with the CRC vm.
+		return errors.New("currently not supported")
 	},
 }
 
-func runPodmanEnv(args []string) error {
-	// See issue #961; Currently does not work on Windows in combination with the CRC vm.
-	exit.WithMessage(1, "Currently not supported.")
-
+func RunPodmanEnv(args []string) error {
 	userShell, err := shell.GetShell(forceShell)
 	if err != nil {
 		return fmt.Errorf("Error running the podman-env command: %s", err.Error())
diff --git a/cmd/crc/cmd/root.go b/cmd/crc/cmd/root.go
index b300b358b..deac2af5f 100644
--- a/cmd/crc/cmd/root.go
+++ b/cmd/crc/cmd/root.go
@@ -3,12 +3,12 @@ package cmd
 import (
 	"fmt"
 	"io/ioutil"
+	"os"
 	"strings"
 
 	cmdConfig "github.com/code-ready/crc/cmd/crc/cmd/config"
 	crcConfig "github.com/code-ready/crc/pkg/crc/config"
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/logging"
 	"github.com/code-ready/crc/pkg/crc/machine"
 	"github.com/code-ready/crc/pkg/crc/network"
@@ -22,16 +22,15 @@ var rootCmd = &cobra.Command{
 	Use:   commandName,
 	Short: descriptionShort,
 	Long:  descriptionLong,
-	PersistentPreRun: func(cmd *cobra.Command, args []string) {
-		runPrerun()
+	PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
+		return runPrerun()
 	},
 	Run: func(cmd *cobra.Command, args []string) {
 		runRoot()
 		_ = cmd.Help()
 	},
-	PersistentPostRun: func(cmd *cobra.Command, args []string) {
-		runPostrun()
-	},
+	SilenceUsage:  true,
+	SilenceErrors: true,
 }
 
 var (
@@ -61,18 +60,22 @@ func init() {
 	rootCmd.PersistentFlags().StringVar(&logging.LogLevel, "log-level", constants.DefaultLogLevel, "log level (e.g. \"debug | info | warn | error\")")
 }
 
-func runPrerun() {
+func runPrerun() error {
 	// Setting up logrus
 	logging.InitLogrus(logging.LogLevel, constants.LogFilePath)
-	setProxyDefaults()
+	if err := setProxyDefaults(); err != nil {
+		return err
+	}
 
 	for _, str := range defaultVersion().lines() {
 		logging.Debugf(str)
 	}
+	return nil
 }
 
 func runPostrun() {
 	logging.CloseLogging()
+	segmentClient.Close()
 }
 
 func runRoot() {
@@ -80,9 +83,14 @@ func runRoot() {
 }
 
 func Execute() {
+	attachMiddleware([]string{}, rootCmd)
+
 	if err := rootCmd.Execute(); err != nil {
-		logging.Fatal(err)
+		runPostrun()
+		_, _ = fmt.Fprintln(os.Stderr, err.Error())
+		os.Exit(1)
 	}
+	runPostrun()
 }
 
 func checkIfMachineMissing(client machine.Client) error {
@@ -96,7 +104,7 @@ func checkIfMachineMissing(client machine.Client) error {
 	return nil
 }
 
-func setProxyDefaults() {
+func setProxyDefaults() error {
 	httpProxy := config.Get(cmdConfig.HTTPProxy).AsString()
 	httpsProxy := config.Get(cmdConfig.HTTPSProxy).AsString()
 	noProxy := config.Get(cmdConfig.NoProxy).AsString()
@@ -104,12 +112,12 @@ func setProxyDefaults() {
 
 	proxyCAData, err := getProxyCAData(proxyCAFile)
 	if err != nil {
-		exit.WithMessage(1, fmt.Sprintf("not able to read proxyCAFile %s: %v", proxyCAFile, err.Error()))
+		return fmt.Errorf("not able to read proxyCAFile %s: %v", proxyCAFile, err.Error())
 	}
 
 	proxyConfig, err := network.NewProxyDefaults(httpProxy, httpsProxy, noProxy, proxyCAData)
 	if err != nil {
-		exit.WithMessage(1, err.Error())
+		return err
 	}
 
 	if proxyConfig.IsEnabled() {
@@ -117,6 +125,7 @@ func setProxyDefaults() {
 			proxyConfig.HTTPSProxyForDisplay(), proxyConfig.GetNoProxyString(), proxyCAFile)
 		proxyConfig.ApplyToEnvironment()
 	}
+	return nil
 }
 
 func getProxyCAData(proxyCAFile string) (string, error) {
@@ -151,9 +160,38 @@ func newMachine() machine.Client {
 }
 
 func newMachineWithConfig(config crcConfig.Storage) machine.Client {
-	return machine.NewClient(constants.DefaultName, isDebugLog(), network.ParseMode(config.Get(cmdConfig.NetworkMode).AsString()))
+	return machine.NewClient(
+		constants.DefaultName,
+		isDebugLog(),
+		network.ParseMode(config.Get(cmdConfig.NetworkMode).AsString()),
+		config.Get(cmdConfig.EnableClusterMonitoring).AsBool(),
+	)
 }
 
 func addForceFlag(cmd *cobra.Command) {
 	cmd.PersistentFlags().BoolVarP(&globalForce, "force", "f", false, "Forcefully perform this action")
 }
+
+func executeWithLogging(fullCmd string, input func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error {
+	return func(cmd *cobra.Command, args []string) error {
+		if err := input(cmd, args); err != nil {
+			if serr := segmentClient.Upload(fullCmd, err); serr != nil {
+				fmt.Println(serr.Error())
+			}
+			return err
+		}
+		return nil
+	}
+}
+
+func attachMiddleware(names []string, cmd *cobra.Command) {
+	if cmd.HasSubCommands() {
+		for _, command := range cmd.Commands() {
+			attachMiddleware(append(names, cmd.Name()), command)
+		}
+	} else if cmd.RunE != nil {
+		fullCmd := strings.Join(append(names, cmd.Name()), " ")
+		src := cmd.RunE
+		cmd.RunE = executeWithLogging(fullCmd, src)
+	}
+}
diff --git a/cmd/crc/cmd/setup.go b/cmd/crc/cmd/setup.go
index f6b356ce5..d8b5ace93 100644
--- a/cmd/crc/cmd/setup.go
+++ b/cmd/crc/cmd/setup.go
@@ -8,7 +8,6 @@ import (
 
 	cmdConfig "github.com/code-ready/crc/cmd/crc/cmd/config"
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/preflight"
 	"github.com/spf13/cobra"
 )
@@ -23,13 +22,11 @@ var setupCmd = &cobra.Command{
 	Use:   "setup",
 	Short: "Set up prerequisites for the OpenShift cluster",
 	Long:  "Set up local virtualization and networking infrastructure for the OpenShift cluster",
-	Run: func(cmd *cobra.Command, args []string) {
+	RunE: func(cmd *cobra.Command, args []string) error {
 		if err := viper.BindFlagSet(cmd.Flags()); err != nil {
-			exit.WithMessage(1, err.Error())
-		}
-		if err := runSetup(args); err != nil {
-			exit.WithMessage(1, err.Error())
+			return err
 		}
+		return runSetup(args)
 	},
 }
 
diff --git a/cmd/crc/cmd/start.go b/cmd/crc/cmd/start.go
index 90c95d202..c63b97377 100644
--- a/cmd/crc/cmd/start.go
+++ b/cmd/crc/cmd/start.go
@@ -11,7 +11,6 @@ import (
 	cmdConfig "github.com/code-ready/crc/cmd/crc/cmd/config"
 	"github.com/code-ready/crc/pkg/crc/cluster"
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/input"
 	"github.com/code-ready/crc/pkg/crc/logging"
 	"github.com/code-ready/crc/pkg/crc/machine"
@@ -34,7 +33,6 @@ func init() {
 	flagSet.UintP(cmdConfig.DiskSize, "d", constants.DefaultDiskSize, "Total size in GiB of the disk used by the OpenShift cluster")
 	flagSet.StringP(cmdConfig.NameServer, "n", "", "IPv4 address of nameserver to use for the OpenShift cluster")
 	flagSet.Bool(cmdConfig.DisableUpdateCheck, false, "Don't check for update")
-	flagSet.Bool(cmdConfig.EnableMonitoring, false, "Enable monitoring stack")
 
 	startCmd.Flags().AddFlagSet(flagSet)
 }
@@ -43,16 +41,14 @@ var startCmd = &cobra.Command{
 	Use:   "start",
 	Short: "Start the OpenShift cluster",
 	Long:  "Start the OpenShift cluster",
-	Run: func(cmd *cobra.Command, args []string) {
+	RunE: func(cmd *cobra.Command, args []string) error {
 		if err := viper.BindFlagSet(cmd.Flags()); err != nil {
-			exit.WithMessage(1, err.Error())
+			return err
 		}
 		if err := renderStartResult(runStart(args)); err != nil {
-			if serr := segmentClient.Upload(err); serr != nil {
-				fmt.Println(serr.Error())
-			}
-			exit.WithMessage(1, err.Error())
+			return err
 		}
+		return nil
 	},
 }
 
@@ -76,7 +72,6 @@ func runStart(arguments []string) (*machine.StartResult, error) {
 		PullSecret: &cluster.PullSecret{
 			Getter: getPullSecretFileContent,
 		},
-		EnableMonitoring: config.Get(cmdConfig.EnableMonitoring).AsBool(),
 	}
 
 	client := newMachine()
diff --git a/cmd/crc/cmd/status.go b/cmd/crc/cmd/status.go
index e9f8c60ef..10b05b555 100644
--- a/cmd/crc/cmd/status.go
+++ b/cmd/crc/cmd/status.go
@@ -8,7 +8,6 @@ import (
 	"text/tabwriter"
 
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/machine"
 	"github.com/docker/go-units"
 	"github.com/spf13/cobra"
@@ -23,10 +22,8 @@ var statusCmd = &cobra.Command{
 	Use:   "status",
 	Short: "Display status of the OpenShift cluster",
 	Long:  "Show details about the OpenShift cluster",
-	Run: func(cmd *cobra.Command, args []string) {
-		if err := runStatus(os.Stdout, newMachine(), constants.MachineCacheDir, outputFormat); err != nil {
-			exit.WithMessage(1, err.Error())
-		}
+	RunE: func(cmd *cobra.Command, args []string) error {
+		return runStatus(os.Stdout, newMachine(), constants.MachineCacheDir, outputFormat)
 	},
 }
 
diff --git a/cmd/crc/cmd/stop.go b/cmd/crc/cmd/stop.go
index cf1cce9f4..61d533123 100644
--- a/cmd/crc/cmd/stop.go
+++ b/cmd/crc/cmd/stop.go
@@ -6,7 +6,6 @@ import (
 	"io"
 	"os"
 
-	"github.com/code-ready/crc/pkg/crc/exit"
 	"github.com/code-ready/crc/pkg/crc/input"
 	"github.com/code-ready/crc/pkg/crc/machine"
 	"github.com/code-ready/machine/libmachine/state"
@@ -23,10 +22,8 @@ var stopCmd = &cobra.Command{
 	Use:   "stop",
 	Short: "Stop the OpenShift cluster",
 	Long:  "Stop the OpenShift cluster",
-	Run: func(cmd *cobra.Command, args []string) {
-		if renderErr := runStop(os.Stdout, newMachine(), outputFormat != jsonFormat, globalForce, outputFormat); renderErr != nil {
-			exit.WithMessage(1, renderErr.Error())
-		}
+	RunE: func(cmd *cobra.Command, args []string) error {
+		return runStop(os.Stdout, newMachine(), outputFormat != jsonFormat, globalForce, outputFormat)
 	},
 }
 
diff --git a/cmd/crc/cmd/version.go b/cmd/crc/cmd/version.go
index bb770709b..2d8a414ce 100644
--- a/cmd/crc/cmd/version.go
+++ b/cmd/crc/cmd/version.go
@@ -6,7 +6,6 @@ import (
 	"os"
 
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/exit"
 	crcversion "github.com/code-ready/crc/pkg/crc/version"
 	"github.com/spf13/cobra"
 )
@@ -20,10 +19,8 @@ var versionCmd = &cobra.Command{
 	Use:   "version",
 	Short: "Print version information",
 	Long:  "Print version information",
-	Run: func(cmd *cobra.Command, args []string) {
-		if err := runPrintVersion(os.Stdout, defaultVersion(), outputFormat); err != nil {
-			exit.WithMessage(1, err.Error())
-		}
+	RunE: func(cmd *cobra.Command, args []string) error {
+		return runPrintVersion(os.Stdout, defaultVersion(), outputFormat)
 	},
 }
 
diff --git a/pkg/crc/cluster/clusteroperator.go b/pkg/crc/cluster/clusteroperator.go
index b4775902f..aaee8ec0f 100644
--- a/pkg/crc/cluster/clusteroperator.go
+++ b/pkg/crc/cluster/clusteroperator.go
@@ -10,7 +10,7 @@ import (
 	openshiftapi "github.com/openshift/api/config/v1"
 )
 
-var ignoreClusterOperators = []string{"monitoring", "machine-config", "marketplace", "insights"}
+var defaultIgnoredClusterOperators = []string{"machine-config", "marketplace", "insights"}
 
 // https://github.com/openshift/cluster-version-operator/blob/master/docs/dev/clusteroperator.md#what-should-an-operator-report-with-clusteroperator-custom-resource
 type Status struct {
@@ -21,14 +21,18 @@ type Status struct {
 }
 
 func GetClusterOperatorStatus(ocConfig oc.Config, operator string) (*Status, error) {
-	return getStatus(ocConfig, []string{operator})
+	return getStatus(ocConfig, defaultIgnoredClusterOperators, []string{operator})
 }
 
-func GetClusterOperatorsStatus(ocConfig oc.Config) (*Status, error) {
-	return getStatus(ocConfig, []string{})
+func GetClusterOperatorsStatus(ocConfig oc.Config, monitoringEnabled bool) (*Status, error) {
+	ignoredOperators := defaultIgnoredClusterOperators
+	if !monitoringEnabled {
+		ignoredOperators = append(ignoredOperators, "monitoring")
+	}
+	return getStatus(ocConfig, ignoredOperators, []string{})
 }
 
-func getStatus(ocConfig oc.Config, selector []string) (*Status, error) {
+func getStatus(ocConfig oc.Config, ignoreClusterOperators, selector []string) (*Status, error) {
 	cs := &Status{
 		Available: true,
 	}
diff --git a/pkg/crc/exit/atexit.go b/pkg/crc/exit/atexit.go
deleted file mode 100644
index 0c657ec34..000000000
--- a/pkg/crc/exit/atexit.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package exit
-
-import (
-	"fmt"
-	"os"
-
-	"github.com/code-ready/crc/pkg/crc/output"
-)
-
-// WithMessage prints the specified message and then exits the program with the specified exit code.
-// If the exit code is 0, the message is prints to stdout, otherwise to stderr.
-func WithMessage(code int, text string, args ...interface{}) {
-	if code == 0 {
-		_, _ = output.Fout(os.Stdout, fmt.Sprintf(text, args...))
-	} else {
-		_, _ = output.Fout(os.Stderr, fmt.Sprintf(text, args...))
-	}
-	os.Exit(code)
-}
diff --git a/pkg/crc/machine/client.go b/pkg/crc/machine/client.go
index 627c6172c..a6bb181f5 100644
--- a/pkg/crc/machine/client.go
+++ b/pkg/crc/machine/client.go
@@ -19,16 +19,18 @@ type Client interface {
 }
 
 type client struct {
-	name        string
-	debug       bool
-	networkMode network.Mode
+	name              string
+	debug             bool
+	networkMode       network.Mode
+	monitoringEnabled bool
 }
 
-func NewClient(name string, debug bool, networkMode network.Mode) Client {
+func NewClient(name string, debug bool, networkMode network.Mode, monitoringEnabled bool) Client {
 	return &client{
-		name:        name,
-		debug:       debug,
-		networkMode: networkMode,
+		name:              name,
+		debug:             debug,
+		networkMode:       networkMode,
+		monitoringEnabled: monitoringEnabled,
 	}
 }
 
diff --git a/pkg/crc/machine/start.go b/pkg/crc/machine/start.go
index c750dd070..ad4b6b641 100644
--- a/pkg/crc/machine/start.go
+++ b/pkg/crc/machine/start.go
@@ -90,7 +90,7 @@ func (client *client) updateVMConfig(startConfig StartConfig, api libmachine.API
 }
 
 func (client *client) Start(startConfig StartConfig) (*StartResult, error) {
-	if err := validateStartConfig(startConfig); err != nil {
+	if err := client.validateStartConfig(startConfig); err != nil {
 		return nil, err
 	}
 
@@ -343,6 +343,13 @@ func (client *client) Start(startConfig StartConfig) (*StartResult, error) {
 		return nil, errors.Wrap(err, "Failed to update cluster ID")
 	}
 
+	if client.monitoringEnabled {
+		logging.Info("Enabling cluster monitoring operator...")
+		if err := cluster.StartMonitoring(ocConfig); err != nil {
+			return nil, errors.Wrap(err, "Cannot start monitoring stack")
+		}
+	}
+
 	// Check if kubelet service is running inside the VM
 	kubeletStatus, err := sd.Status("kubelet")
 	if err != nil || kubeletStatus != states.Running {
@@ -381,13 +388,6 @@ func (client *client) Start(startConfig StartConfig) (*StartResult, error) {
 		log.Warnf("Cannot update kubeconfig: %v", err)
 	}
 
-	if startConfig.EnableMonitoring {
-		logging.Info("Enabling cluster monitoring operator...")
-		if err := cluster.StartMonitoring(ocConfig); err != nil {
-			return nil, errors.Wrap(err, "Cannot start monitoring stack")
-		}
-	}
-
 	if proxyConfig.IsEnabled() {
 		logging.Info("Waiting for the proxy configuration to be applied ...")
 		waitForProxyPropagation(ocConfig, proxyConfig)
@@ -401,8 +401,8 @@ func (client *client) Start(startConfig StartConfig) (*StartResult, error) {
 	}, nil
 }
 
-func validateStartConfig(startConfig StartConfig) error {
-	if startConfig.EnableMonitoring && startConfig.Memory < minimumMemoryForMonitoring {
+func (client *client) validateStartConfig(startConfig StartConfig) error {
+	if client.monitoringEnabled && startConfig.Memory < minimumMemoryForMonitoring {
 		return fmt.Errorf("Too little memory (%s) allocated to the virtual machine to start the monitoring stack, %s is the minimum",
 			units.BytesSize(float64(startConfig.Memory)*1024*1024),
 			units.BytesSize(minimumMemoryForMonitoring*1024*1024))
diff --git a/pkg/crc/machine/status.go b/pkg/crc/machine/status.go
index a6d229a06..54467cf5c 100644
--- a/pkg/crc/machine/status.go
+++ b/pkg/crc/machine/status.go
@@ -64,15 +64,15 @@ func (client *client) Status() (*ClusterStatusResult, error) {
 	}
 	return &ClusterStatusResult{
 		CrcStatus:        state.Running,
-		OpenshiftStatus:  getOpenShiftStatus(sshRunner),
+		OpenshiftStatus:  getOpenShiftStatus(sshRunner, client.monitoringEnabled),
 		OpenshiftVersion: crcBundleMetadata.GetOpenshiftVersion(),
 		DiskUse:          diskUse,
 		DiskSize:         diskSize,
 	}, nil
 }
 
-func getOpenShiftStatus(sshRunner *crcssh.Runner) string {
-	status, err := cluster.GetClusterOperatorsStatus(oc.UseOCWithSSH(sshRunner))
+func getOpenShiftStatus(sshRunner *crcssh.Runner, monitoringEnabled bool) string {
+	status, err := cluster.GetClusterOperatorsStatus(oc.UseOCWithSSH(sshRunner), monitoringEnabled)
 	if err != nil {
 		logging.Debugf("cannot get OpenShift status: %v", err)
 		return "Not Reachable"
diff --git a/pkg/crc/machine/types.go b/pkg/crc/machine/types.go
index 081aacb8a..dfec555df 100644
--- a/pkg/crc/machine/types.go
+++ b/pkg/crc/machine/types.go
@@ -20,8 +20,6 @@ type StartConfig struct {
 
 	// User Pull secret
 	PullSecret *cluster.PullSecret
-
-	EnableMonitoring bool
 }
 
 type ClusterConfig struct {
diff --git a/pkg/crc/segment/segment.go b/pkg/crc/segment/segment.go
index 25c612184..254dfb386 100644
--- a/pkg/crc/segment/segment.go
+++ b/pkg/crc/segment/segment.go
@@ -22,8 +22,12 @@ type Client struct {
 }
 
 func NewClient(config *crcConfig.Config) (*Client, error) {
-	telemetryFilePath := filepath.Join(constants.GetHomeDir(), ".redhat", "anonymousId")
+	return newCustomClient(config,
+		filepath.Join(constants.GetHomeDir(), ".redhat", "anonymousId"),
+		analytics.DefaultEndpoint)
+}
 
+func newCustomClient(config *crcConfig.Config, telemetryFilePath, segmentEndpoint string) (*Client, error) {
 	client, err := analytics.NewWithConfig("cvpHsNcmGCJqVzf6YxrSnVlwFSAZaYtp", analytics.Config{
 		DefaultContext: &analytics.Context{
 			App: analytics.AppInfo{
@@ -31,28 +35,38 @@ func NewClient(config *crcConfig.Config) (*Client, error) {
 				Version: version.GetCRCVersion(),
 			},
 		},
+		Endpoint: segmentEndpoint,
+		Logger:   &loggingAdapter{},
 	})
 	if err != nil {
-		return &Client{}, err
+		return nil, err
 	}
 
-	return &Client{segmentClient: client, config: config, telemetryFilePath: telemetryFilePath}, nil
+	return &Client{
+		segmentClient:     client,
+		config:            config,
+		telemetryFilePath: telemetryFilePath,
+	}, nil
+}
+
+func (c *Client) Close() error {
+	return c.segmentClient.Close()
 }
 
-func (c *Client) Upload(err error) error {
-	defer c.segmentClient.Close()
+func (c *Client) Upload(action string, err error) error {
 	if !c.config.Get(config.ConsentTelemetry).AsBool() {
 		return nil
 	}
-	logging.Info("Uploading the error to segment")
+	logging.Debug("Uploading the error to segment")
 
 	anonymousID, uerr := getUserIdentity(c.telemetryFilePath)
 	if uerr != nil {
 		return uerr
 	}
 
-	t := analytics.NewTraits()
-	t = setError(t, err)
+	t := analytics.NewTraits().
+		Set("action", action).
+		Set("error", err.Error())
 
 	return c.segmentClient.Enqueue(analytics.Identify{
 		AnonymousId: anonymousID,
@@ -80,6 +94,12 @@ func getUserIdentity(telemetryFilePath string) (string, error) {
 	return strings.TrimSpace(string(id)), nil
 }
 
-func setError(t analytics.Traits, err error) analytics.Traits {
-	return t.Set("error", err.Error())
+type loggingAdapter struct{}
+
+func (l *loggingAdapter) Logf(format string, args ...interface{}) {
+	logging.Infof(format, args...)
+}
+
+func (l *loggingAdapter) Errorf(format string, args ...interface{}) {
+	logging.Errorf(format, args...)
 }


Test patch:
diff --git a/pkg/crc/cluster/clusteroperator_test.go b/pkg/crc/cluster/clusteroperator_test.go
index 17772f612..93491a6cc 100644
--- a/pkg/crc/cluster/clusteroperator_test.go
+++ b/pkg/crc/cluster/clusteroperator_test.go
@@ -20,13 +20,13 @@ var (
 )
 
 func TestGetClusterOperatorsStatus(t *testing.T) {
-	status, err := GetClusterOperatorsStatus(ocConfig("co.json"))
+	status, err := GetClusterOperatorsStatus(ocConfig("co.json"), false)
 	assert.NoError(t, err)
 	assert.Equal(t, available, status)
 }
 
 func TestGetClusterOperatorsStatusProgressing(t *testing.T) {
-	status, err := GetClusterOperatorsStatus(ocConfig("co-progressing.json"))
+	status, err := GetClusterOperatorsStatus(ocConfig("co-progressing.json"), false)
 	assert.NoError(t, err)
 	assert.Equal(t, progressing, status)
 }
diff --git a/pkg/crc/segment/segment_test.go b/pkg/crc/segment/segment_test.go
index 2f7acce08..cdf4faa22 100644
--- a/pkg/crc/segment/segment_test.go
+++ b/pkg/crc/segment/segment_test.go
@@ -1,10 +1,8 @@
 package segment
 
 import (
-	"bytes"
 	"encoding/json"
 	"errors"
-	"io"
 	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
@@ -12,15 +10,13 @@ import (
 	"path/filepath"
 	"testing"
 
+	cmdConfig "github.com/code-ready/crc/cmd/crc/cmd/config"
 	crcConfig "github.com/code-ready/crc/pkg/crc/config"
-	"github.com/segmentio/analytics-go"
+	"github.com/code-ready/crc/pkg/crc/logging"
+	"github.com/code-ready/crc/pkg/crc/version"
 	"github.com/stretchr/testify/require"
 )
 
-const (
-	ConsentTelemetry = "consent-telemetry"
-)
-
 type segmentResponse struct {
 	Batch []struct {
 		AnonymousID string `json:"anonymousId"`
@@ -47,21 +43,13 @@ func mockServer() (chan []byte, *httptest.Server) {
 	done := make(chan []byte, 1)
 
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		buf := bytes.NewBuffer(nil)
-		io.Copy(buf, r.Body) // nolint
-
-		var v interface{}
-		err := json.Unmarshal(buf.Bytes(), &v)
+		defer r.Body.Close()
+		bin, err := ioutil.ReadAll(r.Body)
 		if err != nil {
-			panic(err)
+			logging.Error(err)
+			return
 		}
-
-		b, err := json.MarshalIndent(v, "", "  ")
-		if err != nil {
-			panic(err)
-		}
-
-		done <- b
+		done <- bin
 	}))
 
 	return done, server
@@ -70,7 +58,11 @@ func mockServer() (chan []byte, *httptest.Server) {
 func newTestConfig(value bool) (*crcConfig.Config, error) {
 	storage := crcConfig.NewEmptyInMemoryStorage()
 	config := crcConfig.New(storage)
-	config.AddSetting(ConsentTelemetry, value, crcConfig.ValidateBool, crcConfig.SuccessfullyApplied)
+	cmdConfig.RegisterSettings(config)
+
+	if _, err := config.Set(cmdConfig.ConsentTelemetry, value); err != nil {
+		return nil, err
+	}
 	return config, nil
 }
 
@@ -79,17 +71,6 @@ func TestClientUploadWithConsent(t *testing.T) {
 	defer server.Close()
 	defer close(body)
 
-	client, err := analytics.NewWithConfig("dummykey", analytics.Config{
-		DefaultContext: &analytics.Context{
-			App: analytics.AppInfo{
-				Name:    "crc",
-				Version: "1.20.0",
-			},
-		},
-		Endpoint: server.URL,
-	})
-	require.NoError(t, err)
-
 	dir, err := ioutil.TempDir("", "cfg")
 	require.NoError(t, err)
 	defer os.RemoveAll(dir)
@@ -97,22 +78,22 @@ func TestClientUploadWithConsent(t *testing.T) {
 	config, err := newTestConfig(true)
 	require.NoError(t, err)
 
-	c := &Client{segmentClient: client, config: config, telemetryFilePath: filepath.Join(dir, "telemetry")}
+	c, err := newCustomClient(config, filepath.Join(dir, "telemetry"), server.URL)
+	require.NoError(t, err)
 
-	require.NoError(t, c.Upload(errors.New("an error occurred")))
+	require.NoError(t, c.Upload("start", errors.New("an error occurred")))
+	require.NoError(t, c.Close())
 
-	s := segmentResponse{}
 	select {
-	case x, ok := <-body:
-		if ok {
-			err = json.Unmarshal(x, &s)
-			require.NoError(t, err)
-		}
+	case x := <-body:
+		s := segmentResponse{}
+		require.NoError(t, json.Unmarshal(x, &s))
+		require.Equal(t, s.Batch[0].Traits.Error, "an error occurred")
+		require.Equal(t, s.Context.App.Name, "crc")
+		require.Equal(t, s.Context.App.Version, version.GetCRCVersion())
 	default:
+		require.Fail(t, "server should receive data")
 	}
-	require.Equal(t, s.Batch[0].Traits.Error, "an error occurred")
-	require.Equal(t, s.Context.App.Name, "crc")
-	require.Equal(t, s.Context.App.Version, "1.20.0")
 }
 
 func TestClientUploadWithOutConsent(t *testing.T) {
@@ -120,17 +101,6 @@ func TestClientUploadWithOutConsent(t *testing.T) {
 	defer server.Close()
 	defer close(body)
 
-	client, err := analytics.NewWithConfig("dummykey", analytics.Config{
-		DefaultContext: &analytics.Context{
-			App: analytics.AppInfo{
-				Name:    "crc",
-				Version: "1.20.0",
-			},
-		},
-		Endpoint: server.URL,
-	})
-	require.NoError(t, err)
-
 	dir, err := ioutil.TempDir("", "cfg")
 	require.NoError(t, err)
 	defer os.RemoveAll(dir)
@@ -138,19 +108,15 @@ func TestClientUploadWithOutConsent(t *testing.T) {
 	config, err := newTestConfig(false)
 	require.NoError(t, err)
 
-	c := &Client{segmentClient: client, config: config, telemetryFilePath: filepath.Join(dir, "telemetry")}
+	c, err := newCustomClient(config, filepath.Join(dir, "telemetry"), server.URL)
+	require.NoError(t, err)
 
-	require.NoError(t, c.Upload(errors.New("an error occurred")))
+	require.NoError(t, c.Upload("start", errors.New("an error occurred")))
+	require.NoError(t, c.Close())
 
-	s := segmentResponse{}
 	select {
-	case x, ok := <-body:
-		if ok {
-			err = json.Unmarshal(x, &s)
-			require.NoError(t, err)
-		}
+	case <-body:
+		require.Fail(t, "server should not receive data")
 	default:
 	}
-
-	require.Len(t, s.Batch, 0)
 }
diff --git a/test/integration/crcsuite/collect.go b/test/integration/crcsuite/collect.go
index 230e7382e..f852b2231 100644
--- a/test/integration/crcsuite/collect.go
+++ b/test/integration/crcsuite/collect.go
@@ -177,7 +177,7 @@ type VMCommandCollector struct {
 }
 
 func (collector *VMCommandCollector) Collect(w Writer) error {
-	client := machine.NewClient(constants.DefaultName, true, network.DefaultMode)
+	client := machine.NewClient(constants.DefaultName, true, network.DefaultMode, false)
 	ip, err := client.IP()
 	if err != nil {
 		return err
@@ -198,7 +198,7 @@ type ContainerLogCollector struct {
 }
 
 func (collector *ContainerLogCollector) Collect(w Writer) error {
-	client := machine.NewClient(constants.DefaultName, true, network.DefaultMode)
+	client := machine.NewClient(constants.DefaultName, true, network.DefaultMode, false)
 	ip, err := client.IP()
 	if err != nil {
 		return err
diff --git a/test/integration/crcsuite/crcsuite.go b/test/integration/crcsuite/crcsuite.go
index 9e1ca7fca..d184aeb95 100644
--- a/test/integration/crcsuite/crcsuite.go
+++ b/test/integration/crcsuite/crcsuite.go
@@ -181,7 +181,7 @@ func CheckClusterOperatorsWithRetry(retryCount int, retryWait string) error {
 
 	ocConfig := oc.UseOCWithConfig("crc")
 	for i := 0; i < retryCount; i++ {
-		s, err := cluster.GetClusterOperatorsStatus(ocConfig)
+		s, err := cluster.GetClusterOperatorsStatus(ocConfig, false)
 		if err != nil {
 			return err
 		}
diff --git a/test/integration/features/story_health.feature b/test/integration/features/story_health.feature
index d4c1c21de..fea85eca7 100644
--- a/test/integration/features/story_health.feature
+++ b/test/integration/features/story_health.feature
@@ -45,14 +45,14 @@ Feature: End-to-end health check
 
     @darwin @linux @windows
     Scenario: Create and test app
-        When executing "oc new-app httpd-example" succeeds
-        Then stdout should contain "Creating resources"
-        And stdout should contain
-            """
-            service "httpd-example" created
-            """
-        When executing "oc rollout status dc/httpd-example || oc rollout status deployment httpd-example" succeeds
+        When executing "oc create deployment httpd-example --image=quay.io/bitnami/nginx --port=8080" succeeds
+        Then stdout should contain "deployment.apps/httpd-example created"
+        When executing "oc rollout status deployment httpd-example" succeeds
         Then stdout should contain "successfully rolled out"
+        When executing "oc expose deployment httpd-example --port 8080" succeeds
+        Then stdout should contain "httpd-example exposed"
+        When executing "oc expose svc httpd-example" succeeds
+        Then stdout should contain "httpd-example exposed"
 
     @darwin @linux @windows
     Scenario: Stop and start CRC, then check app still runs
@@ -66,6 +66,5 @@ Feature: End-to-end health check
     @darwin @linux @windows
     Scenario: Switch off CRC
         When executing "oc delete project testproj" succeeds
-        Then executing "crc stop -f" succeeds
         And executing "crc delete -f" succeeds
         And executing "crc cleanup" succeeds
diff --git a/test/integration/features/story_marketplace.feature b/test/integration/features/story_marketplace.feature
index c7eb28b96..ef05ffe2d 100644
--- a/test/integration/features/story_marketplace.feature
+++ b/test/integration/features/story_marketplace.feature
@@ -72,8 +72,6 @@ Feature: Operator from marketplace
         
     @darwin @linux @windows
     Scenario: Clean up
-        When executing "crc stop -f" succeeds
-        Then stdout should match "(.*)[Ss]topped the OpenShift cluster"
         When executing "crc delete -f" succeeds
         Then stdout should contain "Deleted the OpenShift cluster"
         When executing "crc cleanup" succeeds
diff --git a/test/integration/features/story_registry.feature b/test/integration/features/story_registry.feature
index 83d589722..f234b35dd 100644
--- a/test/integration/features/story_registry.feature
+++ b/test/integration/features/story_registry.feature
@@ -38,8 +38,6 @@ Feature: Local image to image-registry
         When stdout contains "localhost/hello"
         Then executing "sudo podman image rm localhost/hello:test" succeeds
         And executing "oc delete project testproj-img" succeeds
-        When executing "crc stop -f" succeeds
-        Then stdout should match "(.*)[Ss]topped the OpenShift cluster"
         And executing "crc delete -f" succeeds
         Then stdout should contain "Deleted the OpenShift cluster"
         When executing "crc cleanup" succeeds