From 6391fe6db08fc4e5bee122afb801a9ab6a485b46 Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Thu, 23 Jul 2026 14:06:32 +0530 Subject: [PATCH 1/2] Fix Vorpal issue for windows machine. --- internal/commands/asca/asca_test.go | 6 +++--- internal/commands/scarealtime/sca-realtime.go | 2 +- internal/services/asca.go | 6 ++---- internal/services/osinstaller/os-installer.go | 8 +++++++- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/internal/commands/asca/asca_test.go b/internal/commands/asca/asca_test.go index 9fc1b2d24..363ea71a3 100644 --- a/internal/commands/asca/asca_test.go +++ b/internal/commands/asca/asca_test.go @@ -21,14 +21,14 @@ func TestInstallOrUpgrade_firstInstallation_Success(t *testing.T) { func firstInstallation() error { os.RemoveAll(ascaconfig.Params.WorkingDir()) - _, err := osinstaller.InstallOrUpgrade(&ascaconfig.Params) + _, err := osinstaller.InstallOrUpgrade(&ascaconfig.Params, nil) return err } func TestInstallOrUpgrade_installationIsUpToDate_Success(t *testing.T) { err := firstInstallation() assert.NilError(t, err, "Error on first installation of asca") - _, err = osinstaller.InstallOrUpgrade(&ascaconfig.Params) + _, err = osinstaller.InstallOrUpgrade(&ascaconfig.Params, nil) assert.NilError(t, err, "Error when not need to upgrade") } @@ -36,7 +36,7 @@ func TestInstallOrUpgrade_installationIsNotUpToDate_Success(t *testing.T) { err := firstInstallation() assert.NilError(t, err, "Error on first installation of asca") changeHashFile() - _, err = osinstaller.InstallOrUpgrade(&ascaconfig.Params) + _, err = osinstaller.InstallOrUpgrade(&ascaconfig.Params, nil) assert.NilError(t, err, "Error when need to upgrade") fileExists, _ := osinstaller.FileExists(ascaconfig.Params.ExecutableFilePath()) assert.Assert(t, fileExists, "Executable file not found") diff --git a/internal/commands/scarealtime/sca-realtime.go b/internal/commands/scarealtime/sca-realtime.go index 197603117..495cd85b2 100644 --- a/internal/commands/scarealtime/sca-realtime.go +++ b/internal/commands/scarealtime/sca-realtime.go @@ -75,7 +75,7 @@ func RunScaRealtime(scaRealTimeWrapper wrappers.ScaRealTimeWrapper) func(*cobra. fmt.Println("Running SCA Realtime...") // Handle SCA Resolver. Checks if it already exists and if it is in the latest version - _, err = osinstaller.InstallOrUpgrade(&scaconfig.Params) + _, err = osinstaller.InstallOrUpgrade(&scaconfig.Params, nil) if err != nil { return err } diff --git a/internal/services/asca.go b/internal/services/asca.go index fb55c664e..9bb61b74c 100644 --- a/internal/services/asca.go +++ b/internal/services/asca.go @@ -200,13 +200,11 @@ func manageASCAInstallation(ascaParams AscaScanParams, ascaWrappers AscaWrappers _ = ascaWrappers.ASCAWrapper.ShutDown() return err } - newInstallation, err := osinstaller.InstallOrUpgrade(&ascaconfig.Params) + _, err := osinstaller.InstallOrUpgrade(&ascaconfig.Params, ascaWrappers.ASCAWrapper) if err != nil { return err } - if newInstallation { - _ = ascaWrappers.ASCAWrapper.ShutDown() - } + } return nil } diff --git a/internal/services/osinstaller/os-installer.go b/internal/services/osinstaller/os-installer.go index 82994a457..c6a0c19cb 100644 --- a/internal/services/osinstaller/os-installer.go +++ b/internal/services/osinstaller/os-installer.go @@ -12,6 +12,7 @@ import ( "github.com/checkmarx/ast-cli/internal/logger" "github.com/checkmarx/ast-cli/internal/wrappers" + grpcs "github.com/checkmarx/ast-cli/internal/wrappers/grpcs" "github.com/pkg/errors" ) @@ -52,7 +53,7 @@ func downloadFile(downloadURLPath, filePath string) error { // InstallOrUpgrade Checks the version according to the hash file, // downloads the RealTime installation if the version is not up-to-date, // Extracts the RealTime installation according to the operating system type -func InstallOrUpgrade(installationConfiguration *InstallationConfiguration) (NewSuccessfulInstallation, error) { +func InstallOrUpgrade(installationConfiguration *InstallationConfiguration, ascaWrapper grpcs.AscaWrapper) (NewSuccessfulInstallation, error) { logger.PrintIfVerbose("Handling RealTime Installation...") if downloadNotNeeded(installationConfiguration) { logger.PrintIfVerbose("RealTime installation already exists and is up to date. Skipping download.") @@ -77,6 +78,11 @@ func InstallOrUpgrade(installationConfiguration *InstallationConfiguration) (New return false, err } + if ascaWrapper != nil { + logger.PrintIfVerbose("Shutting down ASCA wrapper before unzipping or extracting files...") + _ = ascaWrapper.ShutDown() + } + // Unzip or extract downloaded zip depending on which OS is running err = UnzipOrExtractFiles(installationConfiguration) if err != nil { From d997ef3393d1480eb5746280c1f052d8405df9ef Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Thu, 23 Jul 2026 17:08:30 +0530 Subject: [PATCH 2/2] Fixed Vorpal Binary update issue on windows machine --- internal/services/osinstaller/os-installer.go | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/internal/services/osinstaller/os-installer.go b/internal/services/osinstaller/os-installer.go index c6a0c19cb..f686cbf9c 100644 --- a/internal/services/osinstaller/os-installer.go +++ b/internal/services/osinstaller/os-installer.go @@ -9,6 +9,7 @@ import ( "net/http" "os" "path/filepath" + "time" "github.com/checkmarx/ast-cli/internal/logger" "github.com/checkmarx/ast-cli/internal/wrappers" @@ -79,8 +80,7 @@ func InstallOrUpgrade(installationConfiguration *InstallationConfiguration, asca } if ascaWrapper != nil { - logger.PrintIfVerbose("Shutting down ASCA wrapper before unzipping or extracting files...") - _ = ascaWrapper.ShutDown() + shutDownAndWait(ascaWrapper) } // Unzip or extract downloaded zip depending on which OS is running @@ -173,3 +173,27 @@ func downloadHashFile(hashURL, zipFileNameHash string) error { return nil } + +// shutDownAndWait sends a shutdown signal and polls until the service is no longer reachable, +// ensuring the process has released its file handles before the caller replaces the binary. +func shutDownAndWait(ascaWrapper grpcs.AscaWrapper) { + const ( + maxAttempts = 20 + pollInterval = 500 * time.Millisecond + ) + + logger.PrintIfVerbose("Shutting down Vorpal service before replacing binary...") + _ = ascaWrapper.ShutDown() + + port := ascaWrapper.GetPort() + for i := 0; i < maxAttempts; i++ { + // ConfigurePort resets the cached 'serving' flag, forcing a live connection attempt. + ascaWrapper.ConfigurePort(port) + if err := ascaWrapper.HealthCheck(); err != nil { + logger.PrintIfVerbose("Vorpal service has stopped.") + return + } + time.Sleep(pollInterval) + } + logger.PrintIfVerbose("Timed out waiting for Vorpal service to stop; proceeding anyway.") +}