Repository: code-ready/crc
Pull request #1815 (2021-01-05 10:11:01)

Remove kubelet status check from start
It made sense before to check the status before perfoming some of
the cluster specific tasks since we were stopping/starting kubelet
service many time but now we just start the service and then do all
the cluster specific operations. If there is any issue with kubelet
service it is failed in early stage.




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

This pull-request has been approved by: *<a href="https://github.com/code-ready/crc/pull/1815#" title="Author self-approved">praveenkumar</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)~~ [praveenkumar]

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":[]} -->
guillaumerose: Good! Should we also change the returned struct and remove the boolean KubeletStarted ?
gbraad: > remove KubeletStarted 

most likely
cfergeau: > > remove KubeletStarted
> 
> most likely

Wouldn't this be useful when podman support comes back?

Patch:
diff --git a/cmd/crc/cmd/config/config.go b/cmd/crc/cmd/config/config.go
index 6a191653b..4aa2e4cdb 100644
--- a/cmd/crc/cmd/config/config.go
+++ b/cmd/crc/cmd/config/config.go
@@ -52,22 +52,15 @@ func RegisterSettings(cfg *config.Config) {
 }
 
 func isPreflightKey(key string) bool {
-	return strings.HasPrefix(key, "skip-") || strings.HasPrefix(key, "warn-")
+	return strings.HasPrefix(key, "skip-")
 }
 
 // less is used to sort the config keys. We want to sort first the regular keys, and
-// then the keys related to preflight starting with a skip- or warn- prefix. We want
-// these preflight keys to be grouped by pair: 'skip-bar', 'warn-bar', 'skip-foo', 'warn-foo'
-// would be sorted in that order.
+// then the keys related to preflight starting with a skip- prefix.
 func less(lhsKey, rhsKey string) bool {
 	if isPreflightKey(lhsKey) {
 		if isPreflightKey(rhsKey) {
-			// lhs is preflight, rhs is preflight
-			if lhsKey[4:] == rhsKey[4:] {
-				// we want skip-foo before warn-foo
-				return lhsKey < rhsKey
-			}
-			// ignore skip-/warn- prefix
+			// ignore skip prefix
 			return lhsKey[4:] < rhsKey[4:]
 		}
 		// lhs is preflight, rhs is not preflight
diff --git a/cmd/crc/cmd/root.go b/cmd/crc/cmd/root.go
index deac2af5f..1c2b96adf 100644
--- a/cmd/crc/cmd/root.go
+++ b/cmd/crc/cmd/root.go
@@ -5,6 +5,7 @@ import (
 	"io/ioutil"
 	"os"
 	"strings"
+	"time"
 
 	cmdConfig "github.com/code-ready/crc/cmd/crc/cmd/config"
 	crcConfig "github.com/code-ready/crc/pkg/crc/config"
@@ -174,13 +175,13 @@ func addForceFlag(cmd *cobra.Command) {
 
 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
+		logging.Debugf("Running '%s'", fullCmd)
+		startTime := time.Now()
+		err := input(cmd, args)
+		if serr := segmentClient.Upload(fullCmd, time.Since(startTime), err); serr != nil {
+			logging.Debugf("Cannot send data to telemetry: %v", serr)
 		}
-		return nil
+		return err
 	}
 }
 
diff --git a/docs/source/topics/con_about-codeready-containers-configuration.adoc b/docs/source/topics/con_about-codeready-containers-configuration.adoc
index 160bc0043..8c858f24c 100644
--- a/docs/source/topics/con_about-codeready-containers-configuration.adoc
+++ b/docs/source/topics/con_about-codeready-containers-configuration.adoc
@@ -9,4 +9,4 @@ Run the [command]`{bin} config --help` command to list the available properties.
 
 You can also use the [command]`{bin} config` command to configure the behavior of the startup checks for the [command]`{bin} start` and [command]`{bin} setup` commands.
 By default, startup checks report an error and stop execution when their conditions are not met.
-Set the value of a property starting with `skip-check` or `warn-check` to `true` to skip the check or report a warning rather than an error, respectively.
+Set the value of a property starting with `skip-check` to `true` to skip the check.
diff --git a/pkg/crc/machine/start.go b/pkg/crc/machine/start.go
index ad4b6b641..545c51c18 100644
--- a/pkg/crc/machine/start.go
+++ b/pkg/crc/machine/start.go
@@ -23,7 +23,6 @@ import (
 	"github.com/code-ready/crc/pkg/crc/ssh"
 	crcssh "github.com/code-ready/crc/pkg/crc/ssh"
 	"github.com/code-ready/crc/pkg/crc/systemd"
-	"github.com/code-ready/crc/pkg/crc/systemd/states"
 	crcos "github.com/code-ready/crc/pkg/os"
 	"github.com/code-ready/machine/libmachine"
 	"github.com/code-ready/machine/libmachine/drivers"
@@ -350,12 +349,6 @@ func (client *client) Start(startConfig StartConfig) (*StartResult, error) {
 		}
 	}
 
-	// Check if kubelet service is running inside the VM
-	kubeletStatus, err := sd.Status("kubelet")
-	if err != nil || kubeletStatus != states.Running {
-		return nil, errors.Wrap(err, "kubelet service is not running")
-	}
-
 	// In Openshift 4.3, when cluster comes up, the following happens
 	// 1. After the openshift-apiserver pod is started, its log contains multiple occurrences of `certificate has expired or is not yet valid`
 	// 2. Initially there is no request-header's client-ca crt available to `extension-apiserver-authentication` configmap
diff --git a/pkg/crc/preflight/preflight.go b/pkg/crc/preflight/preflight.go
index 7652758ab..ada6d0e19 100644
--- a/pkg/crc/preflight/preflight.go
+++ b/pkg/crc/preflight/preflight.go
@@ -50,20 +50,6 @@ func (check *Check) shouldSkip(config config.Storage) bool {
 	return config.Get(check.getSkipConfigName()).AsBool()
 }
 
-func (check *Check) getWarnConfigName() string {
-	if check.configKeySuffix == "" {
-		return ""
-	}
-	return "warn-" + check.configKeySuffix
-}
-
-func (check *Check) shouldWarn(config config.Storage) bool {
-	if check.configKeySuffix == "" {
-		return false
-	}
-	return config.Get(check.getWarnConfigName()).AsBool()
-}
-
 func (check *Check) doCheck(config config.Storage) error {
 	if check.checkDescription == "" {
 		panic(fmt.Sprintf("Should not happen, empty description for check '%s'", check.configKeySuffix))
@@ -110,13 +96,8 @@ func doPreflightChecks(config config.Storage, checks []Check) error {
 		if check.flags&SetupOnly == SetupOnly || check.flags&CleanUpOnly == CleanUpOnly {
 			continue
 		}
-		err := check.doCheck(config)
-		if err != nil {
-			if check.shouldWarn(config) {
-				logging.Warn(err.Error())
-			} else {
-				return err
-			}
+		if err := check.doCheck(config); err != nil {
+			return err
 		}
 	}
 	return nil
@@ -131,13 +112,8 @@ func doFixPreflightChecks(config config.Storage, checks []Check) error {
 		if err == nil {
 			continue
 		}
-		err = check.doFix()
-		if err != nil {
-			if check.shouldWarn(config) {
-				logging.Warn(err.Error())
-			} else {
-				return err
-			}
+		if err = check.doFix(); err != nil {
+			return err
 		}
 	}
 	return nil
@@ -169,7 +145,6 @@ func doRegisterSettings(cfg config.Schema, checks []Check) {
 	for _, check := range checks {
 		if check.configKeySuffix != "" {
 			cfg.AddSetting(check.getSkipConfigName(), false, config.ValidateBool, config.SuccessfullyApplied)
-			cfg.AddSetting(check.getWarnConfigName(), false, config.ValidateBool, config.SuccessfullyApplied)
 		}
 	}
 }
diff --git a/pkg/crc/preflight/preflight_checks_linux.go b/pkg/crc/preflight/preflight_checks_linux.go
index eda0353fb..41b03a9a3 100644
--- a/pkg/crc/preflight/preflight_checks_linux.go
+++ b/pkg/crc/preflight/preflight_checks_linux.go
@@ -144,10 +144,10 @@ func fixLibvirtInstalled(distro *linux.OsRelease) func() error {
 
 func installLibvirtCommand(distro *linux.OsRelease) string {
 	yumCommand := "yum install -y libvirt libvirt-daemon-kvm qemu-kvm"
-	switch distroID(distro) {
-	case linux.Ubuntu:
+	switch {
+	case distroIsLike(distro, linux.Ubuntu):
 		return "apt-get update && apt-get install -y libvirt-daemon libvirt-daemon-system libvirt-clients"
-	case linux.RHEL, linux.CentOS, linux.Fedora:
+	case distroIsLike(distro, linux.Fedora):
 		return yumCommand
 	default:
 		logging.Warnf("unsupported distribution %s, trying to install libvirt with yum", distro)
diff --git a/pkg/crc/preflight/preflight_checks_network_linux.go b/pkg/crc/preflight/preflight_checks_network_linux.go
index bc78d6802..ca22b3ea9 100644
--- a/pkg/crc/preflight/preflight_checks_network_linux.go
+++ b/pkg/crc/preflight/preflight_checks_network_linux.go
@@ -72,22 +72,27 @@ server=/crc.testing/192.168.130.11
 dns=dnsmasq
 `
 
-	crcNetworkManagerDispatcherPath   = filepath.Join(crcNetworkManagerRootPath, "dispatcher.d", "pre-up.d", "99-crc.sh")
-	crcNetworkManagerDispatcherConfig = `#!/bin/sh
+	crcNetworkManagerOldDispatcherPath = filepath.Join(crcNetworkManagerRootPath, "dispatcher.d", "pre-up.d", "99-crc.sh")
+	crcNetworkManagerDispatcherPath    = filepath.Join(crcNetworkManagerRootPath, "dispatcher.d", "99-crc.sh")
+	crcNetworkManagerDispatcherConfig  = `#!/bin/sh
 # This is a NetworkManager dispatcher script to configure split DNS for
 # the 'crc' libvirt network.
-# The corresponding crc bridge is recreated each time the system reboots, so
-# it cannot be configured permanently through NetworkManager.
-# Changing DNS settings with nmcli requires the connection to go down/up,
-# so we directly make the change using resolvectl
+#
+# The corresponding crc bridge is not created through NetworkManager, so
+# it cannot be configured permanently through NetworkManager. We make the
+# change directly using resolvectl instead.
+#
+# NetworkManager will overwrite this resolvectl configuration every time a
+# network connection goes up/down, so we run this script on each of these events
+# to restore our settings. This is a NetworkManager bug which is fixed in
+# version 1.26.6 by this commit:
+# https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=ee4e679bc7479de42780ebd8e3a4d74afa2b2ebe
 
 export LC_ALL=C
 
-if [ "$1" = crc ]; then
-        resolvectl domain "$1" ~testing
-        resolvectl dns "$1" 192.168.130.11
-        resolvectl default-route "$1" false
-fi
+resolvectl domain crc ~testing
+resolvectl dns crc 192.168.130.11
+resolvectl default-route crc false
 
 exit 0
 `
@@ -266,6 +271,10 @@ func checkCrcNetworkManagerDispatcherFile() error {
 
 func fixCrcNetworkManagerDispatcherFile() error {
 	logging.Debug("Fixing NetworkManager dispatcher configuration")
+
+	// Remove dispatcher script which was used in crc 1.20 - it's been moved to a new location
+	_ = removeNetworkManagerConfigFile(crcNetworkManagerOldDispatcherPath)
+
 	err := fixNetworkManagerConfigFile(crcNetworkManagerDispatcherPath, crcNetworkManagerDispatcherConfig, 0755)
 	if err != nil {
 		return err
@@ -276,6 +285,9 @@ func fixCrcNetworkManagerDispatcherFile() error {
 }
 
 func removeCrcNetworkManagerDispatcherFile() error {
+	// Remove dispatcher script which was used in crc 1.20 - it's been moved to a new location
+	_ = removeNetworkManagerConfigFile(crcNetworkManagerOldDispatcherPath)
+
 	return removeNetworkManagerConfigFile(crcNetworkManagerDispatcherPath)
 }
 
diff --git a/pkg/crc/preflight/preflight_checks_tray_darwin.go b/pkg/crc/preflight/preflight_checks_tray_darwin.go
index 05961eee0..ee31ee2fd 100644
--- a/pkg/crc/preflight/preflight_checks_tray_darwin.go
+++ b/pkg/crc/preflight/preflight_checks_tray_darwin.go
@@ -195,7 +195,9 @@ func downloadOrExtractTrayApp() error {
 	}()
 
 	logging.Debug("Trying to extract tray from crc executable")
-	err = embed.Extract(filepath.Base(constants.GetCRCMacTrayDownloadURL()), tmpArchivePath)
+	trayFileName := filepath.Base(constants.GetCRCMacTrayDownloadURL())
+	trayDestFileName := filepath.Join(tmpArchivePath, trayFileName)
+	err = embed.Extract(trayFileName, trayDestFileName)
 	if err != nil {
 		logging.Debug("Could not extract tray from crc executable", err)
 		logging.Debug("Downloading crc tray")
@@ -204,15 +206,14 @@ func downloadOrExtractTrayApp() error {
 			return err
 		}
 	}
-	archivePath := filepath.Join(tmpArchivePath, filepath.Base(constants.GetCRCMacTrayDownloadURL()))
 	outputPath := constants.CrcBinDir
 	err = goos.MkdirAll(outputPath, 0750)
 	if err != nil {
 		return errors.Wrap(err, "Cannot create the target directory.")
 	}
-	_, err = extract.Uncompress(archivePath, outputPath, false)
+	_, err = extract.Uncompress(trayDestFileName, outputPath, false)
 	if err != nil {
-		return errors.Wrapf(err, "Cannot uncompress '%s'", archivePath)
+		return errors.Wrapf(err, "Cannot uncompress '%s'", trayDestFileName)
 	}
 	return nil
 }
diff --git a/pkg/crc/preflight/preflight_checks_tray_windows.go b/pkg/crc/preflight/preflight_checks_tray_windows.go
index 501984608..d2493018d 100644
--- a/pkg/crc/preflight/preflight_checks_tray_windows.go
+++ b/pkg/crc/preflight/preflight_checks_tray_windows.go
@@ -161,7 +161,9 @@ func fixTrayExecutableExists() error {
 	}()
 
 	logging.Debug("Trying to extract tray from crc executable")
-	err = embed.Extract(filepath.Base(constants.GetCRCWindowsTrayDownloadURL()), tmpArchivePath)
+	trayFileName := filepath.Base(constants.GetCRCWindowsTrayDownloadURL())
+	trayDestFileName := filepath.Join(tmpArchivePath, trayFileName)
+	err = embed.Extract(trayFileName, trayDestFileName)
 	if err != nil {
 		logging.Debug("Could not extract tray from crc executable", err)
 		logging.Debug("Downloading crc tray")
@@ -170,10 +172,9 @@ func fixTrayExecutableExists() error {
 			return err
 		}
 	}
-	archivePath := filepath.Join(tmpArchivePath, filepath.Base(constants.GetCRCWindowsTrayDownloadURL()))
-	_, err = extract.Uncompress(archivePath, constants.TrayExecutableDir, false)
+	_, err = extract.Uncompress(trayDestFileName, constants.TrayExecutableDir, false)
 	if err != nil {
-		return fmt.Errorf("Cannot uncompress '%s': %v", archivePath, err)
+		return fmt.Errorf("Cannot uncompress '%s': %v", trayDestFileName, err)
 	}
 
 	return nil
diff --git a/pkg/crc/preflight/preflight_linux.go b/pkg/crc/preflight/preflight_linux.go
index c62be4746..e2587c8c1 100644
--- a/pkg/crc/preflight/preflight_linux.go
+++ b/pkg/crc/preflight/preflight_linux.go
@@ -8,6 +8,7 @@ import (
 	"strings"
 	"syscall"
 
+	crcErrors "github.com/code-ready/crc/pkg/crc/errors"
 	"github.com/code-ready/crc/pkg/crc/logging"
 	"github.com/code-ready/crc/pkg/crc/network"
 	crcos "github.com/code-ready/crc/pkg/os"
@@ -71,7 +72,7 @@ func libvirtPreflightChecks(distro *linux.OsRelease) []Check {
 			flags:              CleanUpOnly,
 		},
 	}
-	if distroID(distro) == linux.Ubuntu {
+	if distroIsLike(distro, linux.Ubuntu) {
 		checks = append(checks, ubuntuPreflightChecks...)
 	}
 	return checks
@@ -97,13 +98,20 @@ var libvirtNetworkPreflightChecks = [...]Check{
 }
 
 var vsockPreflightChecks = Check{
-	configKeySuffix:  "check-vsock",
-	checkDescription: "Checking if vsock is correctly configured",
-	check:            checkVsock,
-	fixDescription:   "Checking if vsock is correctly configured",
-	fix:              fixVsock,
+	configKeySuffix:    "check-vsock",
+	checkDescription:   "Checking if vsock is correctly configured",
+	check:              checkVsock,
+	fixDescription:     "Checking if vsock is correctly configured",
+	fix:                fixVsock,
+	cleanupDescription: "Removing vsock configuration",
+	cleanup:            removeVsockCrcSettings,
 }
 
+const (
+	vsockUdevRulesPath          = "/usr/lib/udev/rules.d/99-crc-vsock.rules"
+	vsockModuleAutoLoadConfPath = "/etc/modules-load.d/vhost_vsock.conf"
+)
+
 func checkVsock() error {
 	executable, err := os.Executable()
 	if err != nil {
@@ -126,7 +134,7 @@ func checkVsock() error {
 			return err
 		}
 		if group.Name != "libvirt" {
-			return errors.New("/dev/vsock is not is the right group")
+			return errors.New("/dev/vsock is not in the right group")
 		}
 	} else {
 		return errors.New("cannot cast info")
@@ -146,21 +154,39 @@ func fixVsock() error {
 	if err != nil {
 		return err
 	}
-	_, _, err = crcos.RunWithPrivilege("modprobe vhost_vsock", "modprobe", "vhost_vsock")
+
+	udevRule := `KERNEL=="vsock", MODE="0660", OWNER="root", GROUP="libvirt"`
+	err = crcos.WriteToFileAsRoot("Create udev rule for /dev/vsock", udevRule, vsockUdevRulesPath, 0644)
 	if err != nil {
 		return err
 	}
-	_, _, err = crcos.RunWithPrivilege("chown /dev/vsock", "chown", "root:libvirt", "/dev/vsock")
+	err = crcos.WriteToFileAsRoot(fmt.Sprintf("Create file %s", vsockModuleAutoLoadConfPath), "vhost_vsock", vsockModuleAutoLoadConfPath, 0644)
 	if err != nil {
 		return err
 	}
-	_, _, err = crcos.RunWithPrivilege("chmod /dev/vsock", "chmod", "g+rw", "/dev/vsock")
+	_, _, err = crcos.RunWithPrivilege("modprobe vhost_vsock", "modprobe", "vhost_vsock")
 	if err != nil {
 		return err
 	}
 	return nil
 }
 
+func removeVsockCrcSettings() error {
+	var mErr crcErrors.MultiError
+	_, _, err := crcos.RunWithPrivilege(fmt.Sprintf("rm %s", vsockUdevRulesPath), "rm", "-f", vsockUdevRulesPath)
+	if err != nil {
+		mErr.Collect(err)
+	}
+	_, _, err = crcos.RunWithPrivilege(fmt.Sprintf("rm %s", vsockModuleAutoLoadConfPath), "rm", "-f", vsockModuleAutoLoadConfPath)
+	if err != nil {
+		mErr.Collect(err)
+	}
+	if len(mErr.Errors) == 0 {
+		return nil
+	}
+	return mErr
+}
+
 func getAllPreflightChecks() []Check {
 	checks := getPreflightChecksForDistro(distro(), network.DefaultMode)
 	checks = append(checks, vsockPreflightChecks)
@@ -180,7 +206,7 @@ func getNetworkChecksForDistro(distro *linux.OsRelease, networkMode network.Mode
 
 	switch {
 	default:
-		logging.Warnf("distribution-specific preflight checks are not implemented for '%s'", distroID(distro))
+		logging.Warnf("distribution-specific preflight checks are not implemented for '%s'", distro.ID)
 		fallthrough
 	case distroIsLike(distro, linux.Ubuntu), distroIsLike(distro, linux.Fedora):
 		checks = append(checks, nmPreflightChecks[:]...)
@@ -207,25 +233,17 @@ func getPreflightChecksForDistro(distro *linux.OsRelease, networkMode network.Mo
 	return checks
 }
 
-func usesSystemdResolved(osRelease *linux.OsRelease) bool {
-	switch distroID(osRelease) {
-	case linux.Ubuntu:
+func usesSystemdResolved(distro *linux.OsRelease) bool {
+	switch {
+	case distroIsLike(distro, linux.Ubuntu):
 		return true
-	case linux.Fedora:
-		return osRelease.VersionID >= "33"
+	case distro.ID == linux.Fedora:
+		return distro.VersionID >= "33"
 	default:
 		return false
 	}
 }
 
-func distroID(osRelease *linux.OsRelease) linux.OsType {
-	if osRelease == nil {
-		return "unknown"
-	}
-	// FIXME: should also use IDLike
-	return osRelease.ID
-}
-
 func distroIsLike(osRelease *linux.OsRelease, osType linux.OsType) bool {
 	if osRelease == nil {
 		return false
@@ -246,8 +264,10 @@ func distroIsLike(osRelease *linux.OsRelease, osType linux.OsType) bool {
 func distro() *linux.OsRelease {
 	distro, err := linux.GetOsRelease()
 	if err != nil {
-		logging.Warnf("cannot get distribution name: %v", err)
-		return nil
+		logging.Errorf("cannot get distribution name: %v", err)
+		return &linux.OsRelease{
+			ID: "unknown",
+		}
 	}
 	return distro
 }
diff --git a/pkg/crc/segment/segment.go b/pkg/crc/segment/segment.go
index 254dfb386..e9ac423c4 100644
--- a/pkg/crc/segment/segment.go
+++ b/pkg/crc/segment/segment.go
@@ -4,7 +4,9 @@ import (
 	"io/ioutil"
 	"os"
 	"path/filepath"
+	"runtime"
 	"strings"
+	"time"
 
 	"github.com/code-ready/crc/cmd/crc/cmd/config"
 	crcConfig "github.com/code-ready/crc/pkg/crc/config"
@@ -53,24 +55,35 @@ func (c *Client) Close() error {
 	return c.segmentClient.Close()
 }
 
-func (c *Client) Upload(action string, err error) error {
+func (c *Client) Upload(action string, duration time.Duration, err error) error {
 	if !c.config.Get(config.ConsentTelemetry).AsBool() {
 		return nil
 	}
-	logging.Debug("Uploading the error to segment")
 
 	anonymousID, uerr := getUserIdentity(c.telemetryFilePath)
 	if uerr != nil {
 		return uerr
 	}
 
-	t := analytics.NewTraits().
-		Set("action", action).
-		Set("error", err.Error())
+	if err := c.segmentClient.Enqueue(analytics.Identify{
+		AnonymousId: anonymousID,
+		Traits: analytics.NewTraits().
+			Set("os", runtime.GOOS),
+	}); err != nil {
+		return err
+	}
+
+	properties := analytics.NewProperties().
+		Set("success", err == nil).
+		Set("duration", duration.Milliseconds())
+	if err != nil {
+		properties = properties.Set("error", err.Error())
+	}
 
-	return c.segmentClient.Enqueue(analytics.Identify{
+	return c.segmentClient.Enqueue(analytics.Track{
 		AnonymousId: anonymousID,
-		Traits:      t,
+		Event:       action,
+		Properties:  properties,
 	})
 }
 
diff --git a/pkg/os/linux/release_info.go b/pkg/os/linux/release_info.go
index bd951be21..836a6e8ce 100644
--- a/pkg/os/linux/release_info.go
+++ b/pkg/os/linux/release_info.go
@@ -92,9 +92,7 @@ func UnmarshalOsRelease(osReleaseContents []byte, release *OsRelease) error {
 			logging.Warnf("Warning: got an invalid line error parsing /etc/os-release: %s", err)
 			continue
 		}
-		if err := release.setIfPossible(key, val); err != nil {
-			logging.Debug(err)
-		}
+		_ = release.setIfPossible(key, val)
 	}
 	return nil
 }
@@ -102,7 +100,7 @@ func UnmarshalOsRelease(osReleaseContents []byte, release *OsRelease) error {
 func GetOsRelease() (*OsRelease, error) {
 	// Check if release file exist
 	if _, err := os.Stat(releaseFile); os.IsNotExist(err) {
-		return nil, fmt.Errorf("%s not exist", releaseFile)
+		return nil, fmt.Errorf("%s doesn't exist", releaseFile)
 	}
 	content, err := ioutil.ReadFile(releaseFile)
 	if err != nil {


Test patch:
diff --git a/pkg/crc/preflight/preflight_darwin_test.go b/pkg/crc/preflight/preflight_darwin_test.go
index 9b0b840c6..5f94d8c75 100644
--- a/pkg/crc/preflight/preflight_darwin_test.go
+++ b/pkg/crc/preflight/preflight_darwin_test.go
@@ -12,7 +12,7 @@ import (
 func TestCountConfigurationOptions(t *testing.T) {
 	cfg := config.New(config.NewEmptyInMemoryStorage())
 	RegisterSettings(cfg)
-	assert.Len(t, cfg.AllConfigs(), 18)
+	assert.Len(t, cfg.AllConfigs(), 9)
 }
 
 func TestCountPreflights(t *testing.T) {
diff --git a/pkg/crc/preflight/preflight_linux_test.go b/pkg/crc/preflight/preflight_linux_test.go
index c0cd327ac..3b9e22649 100644
--- a/pkg/crc/preflight/preflight_linux_test.go
+++ b/pkg/crc/preflight/preflight_linux_test.go
@@ -21,7 +21,7 @@ func TestCountConfigurationOptions(t *testing.T) {
 	var preflightChecksCount int
 	for _, check := range getAllPreflightChecks() {
 		if check.configKeySuffix != "" {
-			preflightChecksCount += 2
+			preflightChecksCount++
 		}
 	}
 	assert.True(t, options == preflightChecksCount, "Unexpected number of preflight configuration flags, got %d, expected %d", options, preflightChecksCount)
diff --git a/pkg/crc/preflight/preflight_test.go b/pkg/crc/preflight/preflight_test.go
index 47726a8b0..c624566ca 100644
--- a/pkg/crc/preflight/preflight_test.go
+++ b/pkg/crc/preflight/preflight_test.go
@@ -39,18 +39,6 @@ func TestFixPreflight(t *testing.T) {
 	assert.True(t, calls.fixed)
 }
 
-func TestWarnPreflight(t *testing.T) {
-	check, calls := sampleCheck(errors.New("check failed"), errors.New("fix failed"))
-	cfg := config.New(config.NewEmptyInMemoryStorage())
-	doRegisterSettings(cfg, []Check{*check})
-	_, err := cfg.Set("warn-sample", true)
-	assert.NoError(t, err)
-
-	assert.NoError(t, doFixPreflightChecks(cfg, []Check{*check}))
-	assert.True(t, calls.checked)
-	assert.True(t, calls.fixed)
-}
-
 func sampleCheck(checkErr, fixErr error) (*Check, *status) {
 	status := &status{}
 	return &Check{
diff --git a/pkg/crc/preflight/preflight_windows_test.go b/pkg/crc/preflight/preflight_windows_test.go
index b9e84e819..ac08d4bda 100644
--- a/pkg/crc/preflight/preflight_windows_test.go
+++ b/pkg/crc/preflight/preflight_windows_test.go
@@ -11,7 +11,7 @@ import (
 func TestCountConfigurationOptions(t *testing.T) {
 	cfg := config.New(config.NewEmptyInMemoryStorage())
 	RegisterSettings(cfg)
-	assert.Len(t, cfg.AllConfigs(), 24)
+	assert.Len(t, cfg.AllConfigs(), 12)
 }
 
 func TestCountPreflights(t *testing.T) {
diff --git a/pkg/crc/segment/segment_test.go b/pkg/crc/segment/segment_test.go
index cdf4faa22..abc799f97 100644
--- a/pkg/crc/segment/segment_test.go
+++ b/pkg/crc/segment/segment_test.go
@@ -8,7 +8,9 @@ import (
 	"net/http/httptest"
 	"os"
 	"path/filepath"
+	"runtime"
 	"testing"
+	"time"
 
 	cmdConfig "github.com/code-ready/crc/cmd/crc/cmd/config"
 	crcConfig "github.com/code-ready/crc/pkg/crc/config"
@@ -22,8 +24,11 @@ type segmentResponse struct {
 		AnonymousID string `json:"anonymousId"`
 		MessageID   string `json:"messageId"`
 		Traits      struct {
-			Error string `json:"error"`
+			OS string `json:"os"`
 		} `json:"traits"`
+		Properties struct {
+			Error string `json:"error"`
+		} `json:"properties"`
 		Type string `json:"type"`
 	} `json:"batch"`
 	Context struct {
@@ -81,14 +86,17 @@ func TestClientUploadWithConsent(t *testing.T) {
 	c, err := newCustomClient(config, filepath.Join(dir, "telemetry"), server.URL)
 	require.NoError(t, err)
 
-	require.NoError(t, c.Upload("start", errors.New("an error occurred")))
+	require.NoError(t, c.Upload("start", time.Minute, errors.New("an error occurred")))
 	require.NoError(t, c.Close())
 
 	select {
 	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.Batch[0].Type, "identify")
+		require.Equal(t, s.Batch[0].Traits.OS, runtime.GOOS)
+		require.Equal(t, s.Batch[1].Type, "track")
+		require.Equal(t, s.Batch[1].Properties.Error, "an error occurred")
 		require.Equal(t, s.Context.App.Name, "crc")
 		require.Equal(t, s.Context.App.Version, version.GetCRCVersion())
 	default:
@@ -111,7 +119,7 @@ func TestClientUploadWithOutConsent(t *testing.T) {
 	c, err := newCustomClient(config, filepath.Join(dir, "telemetry"), server.URL)
 	require.NoError(t, err)
 
-	require.NoError(t, c.Upload("start", errors.New("an error occurred")))
+	require.NoError(t, c.Upload("start", time.Second, errors.New("an error occurred")))
 	require.NoError(t, c.Close())
 
 	select {
diff --git a/test/integration/features/config.feature b/test/integration/features/config.feature
index dd323b76c..8ce0c47b3 100644
--- a/test/integration/features/config.feature
+++ b/test/integration/features/config.feature
@@ -56,55 +56,6 @@ Feature: Test configuration settings
         When unsetting config property "disable-update-check" succeeds
         Then "JSON" config file "crc.json" in CRC home folder does not contain key "disable-update-check"
 
-    # WARNINGS
-
-    Scenario Outline: CRC config checks (warnings)
-        When setting config property "<property>" to value "<value1>" succeeds
-        Then "JSON" config file "crc.json" in CRC home folder contains key "<property>" with value matching "<value1>"
-        When setting config property "<property>" to value "<value2>" succeeds
-        Then "JSON" config file "crc.json" in CRC home folder contains key "<property>" with value matching "<value2>"
-        When unsetting config property "<property>" succeeds
-        Then "JSON" config file "crc.json" in CRC home folder does not contain key "<property>"
-
-        @darwin
-        Examples: Config warnings on Mac
-            | property                             | value1 | value2 |
-            | warn-check-bundle-extracted          | true   | false  |
-            | warn-check-hosts-file-permissions    | true   | false  |
-            | warn-check-hyperkit-driver           | true   | false  |
-            | warn-check-hyperkit-installed        | true   | false  |
-            | warn-check-resolver-file-permissions | true   | false  |
-            | warn-check-root-user                 | true   | false  |
-
-        @linux
-        Examples: Config warnings on Linux
-            | property                             | value1 | value2 |
-            | warn-check-bundle-extracted          | true   | false  |
-            | warn-check-crc-dnsmasq-file          | true   | false  |
-            | warn-check-crc-network               | true   | false  |
-            | warn-check-crc-network-active        | true   | false  |
-            | warn-check-kvm-enabled               | true   | false  |
-            | warn-check-libvirt-driver            | true   | false  |
-            | warn-check-libvirt-installed         | true   | false  |
-            | warn-check-libvirt-running           | true   | false  |
-            | warn-check-libvirt-version           | true   | false  |
-            | warn-check-network-manager-config    | true   | false  |
-            | warn-check-network-manager-installed | true   | false  |
-            | warn-check-network-manager-running   | true   | false  |
-            | warn-check-root-user                 | true   | false  |
-            | warn-check-user-in-libvirt-group     | true   | false  |
-            | warn-check-virt-enabled              | true   | false  |
-
-        @windows
-        Examples: Config warnings on Windows
-            | property                        | value1 | value2 |
-            | warn-check-administrator-user   | true   | false  |
-            | warn-check-bundle-extracted     | true   | false  |
-            | warn-check-hyperv-installed     | true   | false  |
-            | warn-check-hyperv-switch        | true   | false  |
-            | warn-check-user-in-hyperv-group | true   | false  |
-            | warn-check-windows-version      | true   | false  |
-
     # SKIP
 
     Scenario Outline: CRC config checks (skips)