From 5fed9cc5073cb990a67e24a77685d99a1aba016c Mon Sep 17 00:00:00 2001 From: Matthias Bertschy Date: Mon, 15 Dec 2025 08:52:05 +0100 Subject: [PATCH] Enhance installation scripts for cross-platform support and improve error handling Signed-off-by: Matthias Bertschy --- .goreleaser.yaml | 4 +- install.ps1 | 105 ++++++++++++++++++++++++++++++++++++----------- install.sh | 58 +++++++++++++++++++++----- 3 files changed, 131 insertions(+), 36 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 48ed5e50..62008406 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -29,6 +29,8 @@ builds: - CGO_ENABLED=0 goos: - linux + - darwin + - windows goarch: - amd64 - arm64 @@ -136,7 +138,7 @@ krews: short_description: Scan resources and cluster configs against security frameworks. release: - draft: true + draft: false footer: >- --- diff --git a/install.ps1 b/install.ps1 index 2d5e55c5..d2934296 100644 --- a/install.ps1 +++ b/install.ps1 @@ -1,39 +1,96 @@ Write-Host "Installing Kubescape..." -ForegroundColor Cyan -$BASE_DIR=$env:USERPROFILE + "\.kubescape" -$packageName = "/kubescape.exe" +$BASE_DIR = "$env:USERPROFILE\.kubescape" +$KUBESCAPE_EXEC = "kubescape.exe" -# Get latest release url -$config = Invoke-WebRequest -UseBasicParsing "https://api.github.com/repos/kubescape/kubescape/releases/latest" | ConvertFrom-Json -$url = $config.html_url.Replace("/tag/","/download/") -$fullUrl = $url + $packageName +# Determine architecture +$arch = if ([Environment]::Is64BitOperatingSystem) { + if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "amd64" } +} else { + Write-Host "Error: 32-bit systems are not supported" -ForegroundColor Red + exit 1 +} -# Create a new directory if needed -New-Item -Path $BASE_DIR -ItemType "directory" -ErrorAction SilentlyContinue +# Get latest release version from GitHub API +function Get-LatestVersion { + try { + $release = Invoke-RestMethod -Uri "https://api.github.com/repos/kubescape/kubescape/releases/latest" -UseBasicParsing + return $release.tag_name + } catch { + Write-Host "Error: Failed to fetch latest release version" -ForegroundColor Red + exit 1 + } +} + +# Parse command line arguments for version +$version = $null +for ($i = 0; $i -lt $args.Count; $i++) { + if ($args[$i] -eq "-v" -and $i + 1 -lt $args.Count) { + $version = $args[$i + 1] + } +} + +# Get version (use provided or fetch latest) +if (-not $version) { + $version = Get-LatestVersion + Write-Host "Latest version: $version" -ForegroundColor Cyan +} + +# Remove 'v' prefix if present for the filename +$versionNum = $version -replace '^v', '' + +# Create installation directory if needed +New-Item -Path $BASE_DIR -ItemType "directory" -ErrorAction SilentlyContinue | Out-Null + +# Build download URL with new naming pattern: kubescape_{version}_windows_{arch}.exe +$downloadUrl = "https://github.com/kubescape/kubescape/releases/download/$version/kubescape_${versionNum}_windows_${arch}.exe" + +Write-Host "Downloading from: $downloadUrl" -ForegroundColor Cyan + +$outputPath = Join-Path $BASE_DIR $KUBESCAPE_EXEC # Download the binary -$useBitTransfer = $null -ne (Get-Module -Name BitsTransfer -ListAvailable) -and ($PSVersionTable.PSVersion.Major -le 5) -if ($useBitTransfer) - { - Write-Information -MessageData 'Using a fallback BitTransfer method since you are running Windows PowerShell' - Start-BitsTransfer -Source $fullUrl -Destination $BASE_DIR\kubescape.exe - - } - else - { - Invoke-WebRequest -Uri $fullUrl -OutFile $BASE_DIR\kubescape.exe +try { + $useBitTransfer = $null -ne (Get-Module -Name BitsTransfer -ListAvailable) -and ($PSVersionTable.PSVersion.Major -le 5) + if ($useBitTransfer) { + Write-Host "Using BitsTransfer for download..." -ForegroundColor Gray + Start-BitsTransfer -Source $downloadUrl -Destination $outputPath + } else { + $ProgressPreference = 'SilentlyContinue' # Speeds up Invoke-WebRequest + Invoke-WebRequest -Uri $downloadUrl -OutFile $outputPath -UseBasicParsing } +} catch { + Write-Host "Error: Failed to download kubescape" -ForegroundColor Red + Write-Host $_.Exception.Message -ForegroundColor Red + exit 1 +} + +# Verify download was successful +if (-not (Test-Path $outputPath) -or (Get-Item $outputPath).Length -eq 0) { + Write-Host "Error: Download failed or file is empty" -ForegroundColor Red + Remove-Item $outputPath -ErrorAction SilentlyContinue + exit 1 +} # Update user PATH if needed $currentPath = [Environment]::GetEnvironmentVariable("Path", "User") if (-not $currentPath.Contains($BASE_DIR)) { - $confirmation = Read-Host "Add kubescape to user path? (y/n)" + $confirmation = Read-Host "Add kubescape to user PATH? (y/n)" if ($confirmation -eq 'y') { - $env:Path=[Environment]::GetEnvironmentVariable("Path", "User") + ";$BASE_DIR;" - [Environment]::SetEnvironmentVariable("Path", "${env:Path}", "User") + $newPath = $currentPath + ";$BASE_DIR" + [Environment]::SetEnvironmentVariable("Path", $newPath, "User") + $env:Path = $env:Path + ";$BASE_DIR" + Write-Host "Added $BASE_DIR to PATH" -ForegroundColor Green } } -Write-Host "Finished Installation.`n" -ForegroundColor Green -kubescape version -Write-Host "`nUsage: $ kubescape scan" -ForegroundColor Magenta +Write-Host "`nFinished Installation." -ForegroundColor Green + +# Try to run version command +try { + & $outputPath version +} catch { + Write-Host "Installed to: $outputPath" -ForegroundColor Green +} + +Write-Host "`nUsage: kubescape scan" -ForegroundColor Magenta diff --git a/install.sh b/install.sh index 75f6c2a0..5ddbff60 100755 --- a/install.sh +++ b/install.sh @@ -8,22 +8,41 @@ KUBESCAPE_EXEC=kubescape determine_os_and_arch() { osName=$(uname -s) case $osName in - *MINGW*) osName=windows ;; - Darwin*) osName=macos ;; - *) osName=ubuntu ;; + Linux*) osName=linux ;; + Darwin*) osName=darwin ;; + *MINGW*|*CYGWIN*|*MSYS*) + echo -e "\033[31mError: Windows is not supported by this script. Please use the PowerShell installer or download manually from:" + echo -e "\033[1;35;40mhttps://github.com/kubescape/kubescape/releases" + exit 1 + ;; + *) + echo -e "\033[31mError: Unsupported operating system: $osName" + exit 1 + ;; esac arch=$(uname -m) case $arch in - *aarch64*|*arm64*) arch="-arm64" ;; - *x86_64*) arch="" ;; + x86_64|amd64) arch="amd64" ;; + aarch64|arm64) arch="arm64" ;; *) - echo -e "\033[33mArchitecture $arch may be unsupported, will try to install the amd64 one anyway." - arch="" + echo -e "\033[31mError: Unsupported architecture: $arch" + exit 1 ;; esac } +# Function to get the latest release version from GitHub API +get_latest_version() { + local latest_release + latest_release=$(curl -s "https://api.github.com/repos/kubescape/kubescape/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + if [ -z "$latest_release" ]; then + echo -e "\033[31mError: Failed to fetch latest release version" + exit 1 + fi + echo "$latest_release" +} + # Function to remove old installations remove_old_install() { local exec_path=$1 @@ -33,26 +52,43 @@ remove_old_install() { } # Parse command-line arguments +VERSION="" while getopts v: option; do case ${option} in - v) RELEASE="download/${OPTARG}";; + v) VERSION="${OPTARG}";; *) ;; esac done -[ -z "${RELEASE}" ] && RELEASE="latest/download" - echo -e "\033[0;36mInstalling Kubescape..." determine_os_and_arch +# Get version (use provided or fetch latest) +if [ -z "${VERSION}" ]; then + VERSION=$(get_latest_version) + echo -e "\033[0;36mLatest version: $VERSION" +fi + +# Remove 'v' prefix if present for the filename +VERSION_NUM="${VERSION#v}" + mkdir -p $BASE_DIR OUTPUT=$BASE_DIR/$KUBESCAPE_EXEC -DOWNLOAD_URL="https://github.com/kubescape/kubescape/releases/${RELEASE}/kubescape${arch}-${osName}-latest" +# New URL pattern: kubescape_{version}_{os}_{arch} +DOWNLOAD_URL="https://github.com/kubescape/kubescape/releases/download/${VERSION}/kubescape_${VERSION_NUM}_${osName}_${arch}" +echo -e "\033[0;36mDownloading from: $DOWNLOAD_URL" curl --progress-bar -L $DOWNLOAD_URL -o $OUTPUT +# Verify download was successful +if [ ! -s "$OUTPUT" ]; then + echo -e "\033[31mError: Download failed or file is empty" + rm -f "$OUTPUT" + exit 1 +fi + # Determine install directory install_dir=/usr/local/bin [ "$(id -u)" -ne 0 ] && install_dir=$BASE_DIR/bin && export PATH=$PATH:$BASE_DIR/bin