Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions internal/commands/asca/asca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ 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")
}

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")
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/scarealtime/sca-realtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
6 changes: 2 additions & 4 deletions internal/services/asca.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
32 changes: 31 additions & 1 deletion internal/services/osinstaller/os-installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import (
"net/http"
"os"
"path/filepath"
"time"

"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"
)

Expand Down Expand Up @@ -52,7 +54,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.")
Expand All @@ -77,6 +79,10 @@ func InstallOrUpgrade(installationConfiguration *InstallationConfiguration) (New
return false, err
}

if ascaWrapper != nil {
shutDownAndWait(ascaWrapper)
}

// Unzip or extract downloaded zip depending on which OS is running
err = UnzipOrExtractFiles(installationConfiguration)
if err != nil {
Expand Down Expand Up @@ -167,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.")
}
Loading