Repository: code-ready/crc
Pull request #2322 (2021-05-10 07:22:28)

telemetry: send the status of the cluster with action
It allows to us to understand why a user clicked on a particular button.

Example:
action="click start" status="stopped"
action="click stop" status="starting" // aborting

It also allows new event "status changed". For each cluster status
change, we can receive an event like:

action="status changed" status="starting"
action="status changed" status="running"



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

This pull-request has been approved by: *<a href="https://github.com/code-ready/crc/pull/2322#" 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":[]} -->

Patch:
diff --git a/Makefile b/Makefile
index 619a6260f..08699bd49 100644
--- a/Makefile
+++ b/Makefile
@@ -301,30 +301,34 @@ $(GOPATH)/bin/gomod2rpmdeps:
 $(HOST_BUILD_DIR)/split: packaging/windows/split.go
 	go build -o $(HOST_BUILD_DIR)/split packaging/windows/split.go
 
+CRC_EXE=crc.exe
+BUNDLE_NAME=crc_hyperv_$(BUNDLE_VERSION).$(BUNDLE_EXTENSION)
+
 .PHONY: msidir
-msidir: CRC_EXE = crc.exe
+msidir: LDFLAGS+= -X '$(REPOPATH)/pkg/crc/version.msiBuild=true' $(RELEASE_VERSION_VARIABLES)
 msidir: clean $(HOST_BUILD_DIR)/crc-embedder $(HOST_BUILD_DIR)/split $(BUILD_DIR)/windows-amd64/crc.exe check_bundledir $(PACKAGE_DIR)/product.wxs
 	mkdir -p $(PACKAGE_DIR)/msi
-	$(HOST_BUILD_DIR)/crc-embedder embed --goos windows --log-level debug --bundle-dir $(BUNDLE_DIR) $(BUILD_DIR)/windows-amd64/crc.exe
+	$(HOST_BUILD_DIR)/crc-embedder download $(PACKAGE_DIR)/msi 
 	cp $(HOST_BUILD_DIR)/crc.exe $(PACKAGE_DIR)/msi/$(CRC_EXE)
+	pwsh -NoProfile -Command "cd $(PACKAGE_DIR)/msi; Expand-Archive crc-tray-windows.zip -DestinationPath .\; Remove-Item crc-tray-windows.zip"
 ifeq ($(MOCK_BUNDLE),true)
-	mv $(PACKAGE_DIR)/msi/$(CRC_EXE) $(PACKAGE_DIR)/msi/$(CRC_EXE).0
-	touch $(PACKAGE_DIR)/msi/$(CRC_EXE).1 $(PACKAGE_DIR)/msi/$(CRC_EXE).2
+	touch $(PACKAGE_DIR)/msi/$(BUNDLE_NAME).0 $(PACKAGE_DIR)/msi/$(BUNDLE_NAME).1 $(PACKAGE_DIR)/msi/$(BUNDLE_NAME).2
 else
-	$(HOST_BUILD_DIR)/split $(PACKAGE_DIR)/msi/$(CRC_EXE)
-	rm $(PACKAGE_DIR)/msi/$(CRC_EXE)
+	cp $(HYPERV_BUNDLENAME) $(PACKAGE_DIR)/msi
+	$(HOST_BUILD_DIR)/split $(PACKAGE_DIR)/msi/$(BUNDLE_NAME)
+	rm $(PACKAGE_DIR)/msi/$(BUNDLE_NAME)
 endif
 	cp -r $(PACKAGE_DIR)/Resources $(PACKAGE_DIR)/msi/
 	cp $(PACKAGE_DIR)/*.wxs $(PACKAGE_DIR)/msi
 	rm $(PACKAGE_DIR)/product.wxs
 
 $(BUILD_DIR)/windows-amd64/crc-windows-amd64.msi: msidir
-	candle.exe -arch x64 -o $(PACKAGE_DIR)/msi/ $(PACKAGE_DIR)/msi/*.wxs
+	candle.exe -arch x64 -ext WixUtilExtension -o $(PACKAGE_DIR)/msi/ $(PACKAGE_DIR)/msi/*.wxs
 	cd $(PACKAGE_DIR)/msi && light.exe -ext WixUIExtension -ext WixUtilExtension -sacl -spdb -sice:ICE61 -out ../../../$@ *.wixobj
 
 CABS_MSI = "cab1.cab,cab2.cab,cab3.cab,crc-windows-amd64.msi"
-$(BUILD_DIR)/windows-amd64/crc-installer.zip: $(BUILD_DIR)/windows-amd64/crc-windows-amd64.msi
+$(BUILD_DIR)/windows-amd64/crc-windows-installer.zip: $(BUILD_DIR)/windows-amd64/crc-windows-amd64.msi
 	rm -f $(HOST_BUILD_DIR)/crc.exe
 	rm -f $(HOST_BUILD_DIR)/crc-embedder
 	rm -f $(HOST_BUILD_DIR)/split
-	pwsh -NoProfile -Command "cd $(HOST_BUILD_DIR); Compress-Archive -LiteralPath $(CABS_MSI) -DestinationPath crc-installer.zip"
+	pwsh -NoProfile -Command "cd $(HOST_BUILD_DIR); Compress-Archive -LiteralPath $(CABS_MSI) -DestinationPath crc-windows-installer.zip"
diff --git a/appveyor.yml b/appveyor.yml
index f2d675de5..a4f3850af 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -8,7 +8,7 @@ before_test:
   - choco install make
   - choco install wixtoolset
   - set PATH=%PATH%;"C:\Program Files (x86)\WiX Toolset v3.11\bin"
-  - make MOCK_BUNDLE=true BUNDLE_DIR=./ out/windows-amd64/crc-installer.zip
+  - make MOCK_BUNDLE=true BUNDLE_DIR=./ out/windows-amd64/crc-windows-installer.zip
   - make cross
 test_script:
   - make test
@@ -23,6 +23,6 @@ artifacts:
   - path: out\windows-amd64\crc.exe
     name: crc windows executable
     type: File
-  - path: out\windows-amd64\crc-installer.zip
+  - path: out\windows-amd64\crc-windows-installer.zip
     name: crc windows installer
     type: Zip
diff --git a/cmd/crc/cmd/oc_env.go b/cmd/crc/cmd/oc_env.go
index e16ec100e..04b5e0614 100644
--- a/cmd/crc/cmd/oc_env.go
+++ b/cmd/crc/cmd/oc_env.go
@@ -28,6 +28,10 @@ func runOcEnv(args []string) error {
 	}
 
 	client := newMachine()
+	if err := checkIfMachineMissing(client); err != nil {
+		return err
+	}
+
 	consoleResult, err := client.GetConsoleURL()
 	if err != nil {
 		return err
diff --git a/packaging/windows/product.wxs.in b/packaging/windows/product.wxs.in
index 4fb627a7e..90909679d 100755
--- a/packaging/windows/product.wxs.in
+++ b/packaging/windows/product.wxs.in
@@ -1,88 +1,96 @@
 <?xml version="1.0"?>
-
-<?define crcPart0="crc.exe.0"?>
-<?define crcPart1="crc.exe.1"?>
-<?define crcPart2="crc.exe.2"?>
-<?define crcExeName="crc.exe"?>
-
+<?define crcBundlePart0="crc_hyperv___OPENSHIFT_VERSION__.crcbundle.0"?>
+<?define crcBundlePart1="crc_hyperv___OPENSHIFT_VERSION__.crcbundle.1"?>
+<?define crcBundlePart2="crc_hyperv___OPENSHIFT_VERSION__.crcbundle.2"?>
+<?define crcBundleName="crc_hyperv___OPENSHIFT_VERSION__.crcbundle"?>
 <Wix
-	xmlns="http://schemas.microsoft.com/wix/2006/wi">
-	<Product Id="*" UpgradeCode="53DE5BFA-0E53-44E7-8D4F-07E37E59A9AB"
+    xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
+    <Product Id="*" UpgradeCode="53DE5BFA-0E53-44E7-8D4F-07E37E59A9AB"
             Name="CodeReady Containers"
             Version="__VERSION__"
             Manufacturer="Red Hat Inc."
             Language="1033">
-		<Package Id ="*" InstallerVersion="300" 
+        <Package Id ="*" InstallerVersion="300" 
 			Compressed="yes" 
 			Description="CodeReady Containers __VERSION__"
             Comments="This installs CodeReady Containers __VERSION__" 
 			InstallScope="perMachine" />
-		
-		<Media Id="1" EmbedCab="no" Cabinet="cab1.cab" />
-		<Media Id="2" EmbedCab="no" Cabinet="cab2.cab" />
-		<Media Id="3" EmbedCab="no" Cabinet="cab3.cab" />
-
-		<MajorUpgrade AllowDowngrades="yes" />
-		<WixVariable Id="WixUIBannerBmp" Value=".\Resources\banner.png"/>
-		<WixVariable Id="WixUIDialogBmp" Value=".\Resources\background.png"/>
-		<Icon Id="crcicon.ico" SourceFile=".\Resources\icon.ico"/>
-		<Property Id="ARPPRODUCTICON" Value="crcicon.ico"/>
-		<Property Id="CURRENTBUILD">
-			<RegistrySearch Id="CURRENTBUILDSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion"
+        <Media Id="1" EmbedCab="no" Cabinet="cab1.cab" />
+        <Media Id="2" EmbedCab="no" Cabinet="cab2.cab" />
+        <Media Id="3" EmbedCab="no" Cabinet="cab3.cab" />
+        <MajorUpgrade AllowDowngrades="yes" />
+        <WixVariable Id="WixUIBannerBmp" Value=".\Resources\banner.png"/>
+        <WixVariable Id="WixUIDialogBmp" Value=".\Resources\background.png"/>
+        <Icon Id="crcicon.ico" SourceFile=".\Resources\icon.ico"/>
+        <Property Id="ARPPRODUCTICON" Value="crcicon.ico"/>
+        <Property Id="CURRENTBUILD">
+            <RegistrySearch Id="CURRENTBUILDSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion"
              Name="CurrentBuild"  Type="raw"/>
-		</Property>
-		<Property Id="MINIMUMBUILD" Value="1709" Secure="yes"></Property>
-		<Condition Message="CodeReady Containers requires the Windows 10 Fall Creators Update (version 1709) or newer.">
-			<![CDATA[Installed OR (CURRENTBUILD > MINIMUMBUILD)]]>
-		</Condition>
-		<Directory Id="TARGETDIR" Name="SourceDir">
-			<Directory Id="ProgramFiles64Folder">
-				<Directory Id="INSTALLDIR" Name="CodeReady Containers">
-                    <Component Id="CrcExePart1" Guid="*">
-                        <File Id="CrcExePart1" Source="$(var.crcPart0)" KeyPath="yes" DiskId="1" />
+        </Property>
+        <Property Id="MINIMUMBUILD" Value="1709" Secure="yes"></Property>
+        <Condition Message="CodeReady Containers requires the Windows 10 Fall Creators Update (version 1709) or newer.">
+            <![CDATA[Installed OR (CURRENTBUILD > MINIMUMBUILD)]]>
+        </Condition>
+        <Directory Id="TARGETDIR" Name="SourceDir">
+            <Directory Id="ProgramFiles64Folder">
+                <Directory Id="INSTALLDIR" Name="CodeReady Containers">
+                    <Component Id="CrcBundlePart1" Guid="*">
+                        <File Id="CrcBundlePart1" Source="SourceDir\$(var.crcBundlePart0)" KeyPath="yes" DiskId="1" />
+                    </Component>
+                    <Component Id="CrcBundlePart2" Guid="*">
+                        <File Id="CrcBundlePart2" Source="SourceDir\$(var.crcBundlePart1)" KeyPath="yes" DiskId="2" />
                     </Component>
-                    <Component Id="CrcExePart2" Guid="*">
-                        <File Id="CrcExePart2" Source="$(var.crcPart1)" KeyPath="yes" DiskId="2" />
+                    <Component Id="CrcBundlePart3" Guid="*">
+                        <File Id="CrcBundlePart3" Source="SourceDir\$(var.crcBundlePart2)" KeyPath="yes" DiskId="3" />
                     </Component>
-                    <Component Id="CrcExePart3" Guid="*">
-                        <File Id="CrcExePart3" Source="$(var.crcPart2)" KeyPath="yes" DiskId="3" />
+                    <Component Id="CrcExe" Guid="*">
+                        <File Id="CrcExe" Source="SourceDir\crc.exe" KeyPath="yes" DiskId="3" />
+                    </Component>
+                    <Component Id="AdminHelper" Guid="*">
+                        <File Id="AdminHelper" Source="SourceDir\admin-helper-windows.exe" KeyPath="yes" DiskId="3" />
+                    </Component>
+                    <Component Id="CrcTray" Guid="*">
+                        <File Id="CrcTray" Source="SourceDir\crc-tray.exe" KeyPath="yes" DiskId="3" />
                     </Component>
                     <Component Id="AddToPath" Guid="09C1E713-44DE-44C3-BDAD-72BE10C10542">
                         <CreateFolder />
                         <Environment Id="PATH" Name="PATH" Value="[INSTALLDIR]" Permanent="no" Part="last" Action="set" />
                     </Component>
-				</Directory>
-			</Directory>
-		</Directory>
-		
-		<SetProperty Action="CAJoinCrc"  Id="JoinCrc"  Value='"[WindowsFolder]\System32\cmd.exe" /c cd "[INSTALLDIR]" &amp;&amp; copy /b $(var.crcPart0)+$(var.crcPart1)+$(var.crcPart2) $(var.crcExeName)' Before="JoinCrc" Sequence="execute"/>
-		<CustomAction Id="JoinCrc" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Impersonate="no" />
-
-		<SetProperty Action="CARemoveParts"  Id="RemoveParts"  Value='"[WindowsFolder]\System32\cmd.exe" /c cd "[INSTALLDIR]" &amp;&amp; del /f /q $(var.crcPart0) $(var.crcPart1) $(var.crcPart2)' Before="RemoveParts" Sequence="execute"/>
-		<CustomAction Id="RemoveParts" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Impersonate="no" />
+                </Directory>
+            </Directory>
+        </Directory>
+        <SetProperty Action="CAJoinBundle"  Id="JoinBundle"  Value='"[WindowsFolder]\System32\cmd.exe" /c cd "[INSTALLDIR]" &amp;&amp; copy /b $(var.crcBundlePart0)+$(var.crcBundlePart1)+$(var.crcBundlePart2) $(var.crcBundleName)' Before="JoinBundle" Sequence="execute"/>
+        <CustomAction Id="JoinBundle" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Impersonate="no" />
+        <SetProperty Action="CARemoveParts"  Id="RemoveParts"  Value='"[WindowsFolder]\System32\cmd.exe" /c cd "[INSTALLDIR]" &amp;&amp; del /f /q $(var.crcBundlePart0) $(var.crcBundlePart1) $(var.crcBundlePart2)' Before="RemoveParts" Sequence="execute"/>
+        <CustomAction Id="RemoveParts" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Impersonate="no" />
+        <SetProperty Action="CAUninstall"  Id="Uninstall"  Value='"[WindowsFolder]\System32\cmd.exe" /c rmdir /S /Q "[INSTALLDIR]"' Before="Uninstall" Sequence="execute"/>
+        <CustomAction Id="Uninstall" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Impersonate="no" />
 
-		<SetProperty Action="CAUninstall"  Id="Uninstall"  Value='"[WindowsFolder]\System32\cmd.exe" /c rmdir /S /Q "[INSTALLDIR]"' Before="Uninstall" Sequence="execute"/>
-		<CustomAction Id="Uninstall" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Impersonate="no" />
+        <util:CloseApplication Id = "TrayRunning" Description="Please exit CodeReady Containers from tray and run the installation again."
+            Target="crc-tray.exe" RebootPrompt="no"
+            PromptToContinue="yes" />
 
-		<InstallExecuteSequence>
-			<Custom Action="JoinCrc"  After="InstallFiles" >NOT Installed AND NOT PATCH</Custom>
-			<Custom Action="RemoveParts"  After="JoinCrc" >NOT Installed AND NOT PATCH</Custom>
-			<Custom Action="Uninstall"  After="RemoveFolders" >REMOVE~="ALL"</Custom>
-		</InstallExecuteSequence>
-		
-		<Feature Id="DefaultFeature" Level="1">
-			<ComponentRef Id="CrcExePart1"/>
-            <ComponentRef Id="CrcExePart2"/>
-            <ComponentRef Id="CrcExePart3"/>
+        <InstallExecuteSequence>
+            <Custom Action="JoinBundle"  After="InstallFiles" >NOT Installed AND NOT PATCH</Custom>
+            <Custom Action="RemoveParts"  After="JoinBundle" >NOT Installed AND NOT PATCH</Custom>
+            <Custom Action="Uninstall"  After="RemoveFolders" >REMOVE~="ALL"</Custom>
+        </InstallExecuteSequence>
+        <Feature Id="DefaultFeature" Level="1">
+            <ComponentRef Id="CrcBundlePart1"/>
+            <ComponentRef Id="CrcBundlePart2"/>
+            <ComponentRef Id="CrcBundlePart3"/>
+            <ComponentRef Id="CrcExe" />
+            <ComponentRef Id="CrcTray" />
+            <ComponentRef Id="AdminHelper" />
             <ComponentRef Id="AddToPath"/>
-		</Feature>
-		<UI>
-			<UIRef Id="WixUI_ErrorProgressText"/>
-			<!-- Define the installer UI -->
-			<UIRef Id="WixUI_HK"/>
-		</UI>
-		<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
-		<!-- this should help to propagate env var changes -->
-		<CustomActionRef Id="WixBroadcastEnvironmentChange" />
-	</Product>
-</Wix>
+        </Feature>
+        <UI>
+            <UIRef Id="WixUI_ErrorProgressText"/>
+            <!-- Define the installer UI -->
+            <UIRef Id="WixUI_HK"/>
+        </UI>
+        <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
+        <!-- this should help to propagate env var changes -->
+        <CustomActionRef Id="WixBroadcastEnvironmentChange" />
+    </Product>
+</Wix>
\ No newline at end of file
diff --git a/pkg/crc/api/client/types.go b/pkg/crc/api/client/types.go
index 4c8cd354a..7bd0ff8c4 100644
--- a/pkg/crc/api/client/types.go
+++ b/pkg/crc/api/client/types.go
@@ -70,4 +70,5 @@ type getOrUnsetConfigRequest struct {
 type TelemetryRequest struct {
 	Action string `json:"action"`
 	Source string `json:"source"`
+	Status string `json:"status"`
 }
diff --git a/pkg/crc/api/handlers.go b/pkg/crc/api/handlers.go
index d16d65af6..8be6b74a3 100644
--- a/pkg/crc/api/handlers.go
+++ b/pkg/crc/api/handlers.go
@@ -29,7 +29,7 @@ type Logger interface {
 }
 
 type Telemetry interface {
-	UploadAction(action, source string) error
+	UploadAction(action, source, status string) error
 }
 
 func (h *Handler) Logs() string {
@@ -249,7 +249,7 @@ func (h *Handler) UploadTelemetry(args json.RawMessage) string {
 	if err := json.Unmarshal(args, &req); err != nil {
 		return encodeErrorToJSON(err.Error())
 	}
-	if err := h.Telemetry.UploadAction(req.Action, req.Source); err != nil {
+	if err := h.Telemetry.UploadAction(req.Action, req.Source, req.Status); err != nil {
 		return encodeErrorToJSON(err.Error())
 	}
 	return encodeStructToJSON(client.Result{
diff --git a/pkg/crc/constants/constants.go b/pkg/crc/constants/constants.go
index 3d034d347..e7a126dcb 100644
--- a/pkg/crc/constants/constants.go
+++ b/pkg/crc/constants/constants.go
@@ -97,6 +97,12 @@ func defaultBundlePath() string {
 			return path
 		}
 	}
+	if runtime.GOOS == "windows" && version.IsMsiBuild() {
+		path := filepath.Join(GetMsiInstallPath(), GetDefaultBundle())
+		if _, err := os.Stat(path); err == nil {
+			return path
+		}
+	}
 	return filepath.Join(MachineCacheDir, GetDefaultBundle())
 }
 
@@ -104,6 +110,9 @@ func BinDir() string {
 	if runtime.GOOS == "darwin" && version.IsMacosInstallPathSet() {
 		return version.GetMacosInstallPath()
 	}
+	if runtime.GOOS == "windows" && version.IsMsiBuild() {
+		return GetMsiInstallPath()
+	}
 	return CrcBinDir
 }
 
@@ -144,7 +153,7 @@ func BundleEmbedded() bool {
 }
 
 func IsRelease() bool {
-	return BundleEmbedded() || version.IsMacosInstallPathSet()
+	return BundleEmbedded() || version.IsMacosInstallPathSet() || version.IsMsiBuild()
 }
 
 func contains(arr []string, str string) bool {
@@ -181,3 +190,7 @@ func GetCRCMacTrayDownloadURL() string {
 func GetCRCWindowsTrayDownloadURL() string {
 	return fmt.Sprintf(CRCWindowsTrayDownloadURL, version.GetCRCWindowsTrayVersion())
 }
+
+func GetMsiInstallPath() string {
+	return filepath.Join(os.Getenv("PROGRAMFILES"), "CodeReady Containers")
+}
diff --git a/pkg/crc/machine/machine.go b/pkg/crc/machine/machine.go
index 478c37b85..bc37c3596 100644
--- a/pkg/crc/machine/machine.go
+++ b/pkg/crc/machine/machine.go
@@ -51,7 +51,7 @@ func getBundleMetadataFromDriver(driver drivers.Driver) (*bundle.CrcBundleInfo,
 	return metadata, err
 }
 
-func createLibMachineClient() (*libmachine.Client, func()) {
+func createLibMachineClient() (libmachine.API, func()) {
 	client := libmachine.NewClient(constants.MachineBaseDir)
 	return client, func() {
 		client.Close()
diff --git a/pkg/crc/machine/start.go b/pkg/crc/machine/start.go
index c4ec0b265..8c1cfa571 100644
--- a/pkg/crc/machine/start.go
+++ b/pkg/crc/machine/start.go
@@ -508,7 +508,7 @@ func makeDaemonVisibleToHyperkit(name string) error {
 	return nil
 }
 
-func createHost(api *libmachine.Client, machineConfig config.MachineConfig) error {
+func createHost(api libmachine.API, machineConfig config.MachineConfig) error {
 	vm, err := newHost(api, machineConfig)
 	if err != nil {
 		return fmt.Errorf("Error creating new host: %s", err)
@@ -530,11 +530,15 @@ func createHost(api *libmachine.Client, machineConfig config.MachineConfig) erro
 		return fmt.Errorf("Error in driver during machine creation: %s", err)
 	}
 
+	if err := api.SetExists(vm.Name); err != nil {
+		return fmt.Errorf("Failed to record VM existence: %s", err)
+	}
+
 	logging.Debug("Machine successfully created")
 	return nil
 }
 
-func startHost(ctx context.Context, api *libmachine.Client, vm *host.Host) error {
+func startHost(ctx context.Context, api libmachine.API, vm *host.Host) error {
 	if err := vm.Driver.Start(); err != nil {
 		return fmt.Errorf("Error in driver during machine start: %s", err)
 	}
@@ -550,10 +554,6 @@ func startHost(ctx context.Context, api *libmachine.Client, vm *host.Host) error
 
 	logging.Debug("Machine is up and running!")
 
-	if err := api.SetExists(vm.Name); err != nil {
-		logging.Debug("Failed to record VM existence")
-	}
-
 	return nil
 }
 
diff --git a/pkg/crc/preflight/preflight_checks_common.go b/pkg/crc/preflight/preflight_checks_common.go
index 99c5f8a3a..2cdb89e5b 100644
--- a/pkg/crc/preflight/preflight_checks_common.go
+++ b/pkg/crc/preflight/preflight_checks_common.go
@@ -135,7 +135,7 @@ func fixBundleExtracted() error {
 
 // Check if helper executable is cached or not
 func checkAdminHelperExecutableCached() error {
-	if version.IsMacosInstallPathSet() {
+	if version.IsMacosInstallPathSet() || version.IsMsiBuild() {
 		return nil
 	}
 
@@ -151,7 +151,7 @@ func checkAdminHelperExecutableCached() error {
 }
 
 func fixAdminHelperExecutableCached() error {
-	if version.IsMacosInstallPathSet() {
+	if version.IsMacosInstallPathSet() || version.IsMsiBuild() {
 		return nil
 	}
 
diff --git a/pkg/crc/segment/segment.go b/pkg/crc/segment/segment.go
index 05886c4f0..84c309ed5 100644
--- a/pkg/crc/segment/segment.go
+++ b/pkg/crc/segment/segment.go
@@ -59,8 +59,9 @@ func (c *Client) Close() error {
 	return c.segmentClient.Close()
 }
 
-func (c *Client) UploadAction(action, source string) error {
-	return c.upload(action, baseProperties(source))
+func (c *Client) UploadAction(action, source, status string) error {
+	return c.upload(action, baseProperties(source).
+		Set("status", status))
 }
 
 func (c *Client) UploadCmd(ctx context.Context, action string, duration time.Duration, err error) error {
diff --git a/pkg/crc/version/version.go b/pkg/crc/version/version.go
index 7d791c283..260e03c76 100644
--- a/pkg/crc/version/version.go
+++ b/pkg/crc/version/version.go
@@ -24,6 +24,8 @@ var (
 	okdBuild = "false"
 
 	macosInstallPath = "/unset"
+
+	msiBuild = "false"
 )
 
 const (
@@ -72,6 +74,10 @@ func IsMacosInstallPathSet() bool {
 	return macosInstallPath != "/unset"
 }
 
+func IsMsiBuild() bool {
+	return msiBuild != "false"
+}
+
 func getCRCLatestVersionFromMirror() (*semver.Version, error) {
 	var releaseInfo CrcReleaseInfo
 	client := &http.Client{
diff --git a/pkg/embed/embed.go b/pkg/embed/embed.go
index e9512ef4e..ba5bc4890 100644
--- a/pkg/embed/embed.go
+++ b/pkg/embed/embed.go
@@ -8,6 +8,7 @@ import (
 	"runtime"
 
 	"github.com/YourFin/binappend"
+	"github.com/code-ready/crc/pkg/crc/constants"
 	"github.com/code-ready/crc/pkg/crc/logging"
 	"github.com/code-ready/crc/pkg/crc/version"
 )
@@ -20,6 +21,13 @@ func openEmbeddedFile(executablePath, embedName string) (io.ReadCloser, error) {
 		}
 	}
 
+	if runtime.GOOS == "windows" && version.IsMsiBuild() {
+		path := filepath.Join(constants.GetMsiInstallPath(), embedName)
+		if _, err := os.Stat(path); err == nil {
+			return os.Open(path)
+		}
+	}
+
 	extractor, err := binappend.MakeExtractor(executablePath)
 	if err != nil {
 		return nil, fmt.Errorf("Could not data embedded in %s: %v", executablePath, err)
diff --git a/pkg/libmachine/persist/store.go b/pkg/libmachine/persist/store.go
index 4bee232e4..5b89c16d8 100644
--- a/pkg/libmachine/persist/store.go
+++ b/pkg/libmachine/persist/store.go
@@ -5,6 +5,9 @@ import (
 )
 
 type Store interface {
+	// SetExists defines whether a machine exists or not
+	SetExists(name string) error
+
 	// Exists returns whether a machine exists or not
 	Exists(name string) (bool, error)
 


Test patch:
diff --git a/pkg/crc/api/helpers_test.go b/pkg/crc/api/helpers_test.go
index 8db8f654d..af5f082b0 100644
--- a/pkg/crc/api/helpers_test.go
+++ b/pkg/crc/api/helpers_test.go
@@ -48,7 +48,7 @@ type mockTelemetry struct {
 	actions []string
 }
 
-func (m *mockTelemetry) UploadAction(action, _ string) error {
+func (m *mockTelemetry) UploadAction(action, _, _ string) error {
 	m.actions = append(m.actions, action)
 	return nil
 }