#Requires -Version 5.1 <# .SYNOPSIS Installs Lablup all-smi (Cross-platform Unified GPU/NPU Monitor) for Windows. .DESCRIPTION GitHub Releases에서 제공하는 Windows용 네이티브 바이너리(.zip)를 다운로드하고 $env:USERPROFILE\.local\bin\all-smi.exe 경로에 설치합니다. 공식 레포지토리: https://github.com/lablup/all-smi .EXAMPLE .\install-all-smi.ps1 #> Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' # HTTPS 다운로드를 위해 TLS 1.2+ 강제 설정 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # ──────────────────────────────────────────── # 상수 정의 # ──────────────────────────────────────────── $REPO = "lablup/all-smi" $API_URL = "https://api.github.com/repos/$REPO/releases/latest" $INSTALL_DIR = Join-Path $env:USERPROFILE ".local\bin" $FALLBACK_VERSION = "v0.25.0" # ──────────────────────────────────────────── # 유틸리티 함수 (영문 메시지 출력, 인코딩 문제 차단) # ──────────────────────────────────────────── function Info { Write-Host "[INFO] $args" -ForegroundColor Cyan } function Warn { Write-Host "[WARN] $args" -ForegroundColor Yellow } function Success { Write-Host "[OK] $args" -ForegroundColor Green } function ErrExit { Write-Host "[ERROR] $args" -ForegroundColor Red; exit 1 } # ──────────────────────────────────────────── # 아키텍처 감지 # ──────────────────────────────────────────── $arch = $env:PROCESSOR_ARCHITECTURE Info "Detected CPU Architecture: $arch" $assetName = "all-smi-windows-x86_64.zip" if ($arch -ne "AMD64" -and $arch -ne "ARM64") { Warn "Architecture '$arch' may not be fully supported. Attempting installation with x86_64 binary." } # ──────────────────────────────────────────── # 최신 릴리즈 태그 가져오기 # ──────────────────────────────────────────── $tag = $null try { Info "Fetching latest release tag from GitHub API..." $response = Invoke-RestMethod -Uri $API_URL -Headers @{ 'User-Agent' = 'install-all-smi-ps1' } -TimeoutSec 10 if ($response -and $response.assets -and $response.assets.Count -gt 0) { $tag = $response.tag_name } } catch { Warn "Failed to retrieve the latest version from GitHub API. Using fallback version: $FALLBACK_VERSION" $tag = $FALLBACK_VERSION } if (-not $tag) { $tag = $FALLBACK_VERSION } $downloadUrl = "https://github.com/$REPO/releases/download/$tag/$assetName" $fallbackUrl = "https://github.com/$REPO/releases/download/$FALLBACK_VERSION/$assetName" Info "Resolved download URL: $downloadUrl" # ──────────────────────────────────────────── # 다운로드, 압축 해제 및 설치 # ──────────────────────────────────────────── # 설치 폴더 생성 if (-not (Test-Path $INSTALL_DIR)) { New-Item -ItemType Directory -Path $INSTALL_DIR | Out-Null Info "Created installation directory: $INSTALL_DIR" } $tempZip = Join-Path $env:TEMP "all_smi_temp.zip" $tempExtractDir = Join-Path $env:TEMP "all_smi_temp_extract" $destFile = Join-Path $INSTALL_DIR "all-smi.exe" try { Info "Downloading binary archive..." try { Invoke-WebRequest -Uri $downloadUrl -OutFile $tempZip -UseBasicParsing } catch { if ($downloadUrl -ne $fallbackUrl) { Warn "Primary download failed. Retrying with fallback version ($FALLBACK_VERSION): $fallbackUrl" Invoke-WebRequest -Uri $fallbackUrl -OutFile $tempZip -UseBasicParsing } else { throw } } if (Test-Path $tempExtractDir) { Remove-Item $tempExtractDir -Recurse -Force } Info "Extracting archive..." Expand-Archive -Path $tempZip -DestinationPath $tempExtractDir -Force $extractedBin = Get-ChildItem -Path $tempExtractDir -Recurse -Filter "all-smi.exe" | Select-Object -First 1 if (-not $extractedBin) { ErrExit "Could not find 'all-smi.exe' in extracted files." } if (Test-Path $destFile) { Remove-Item $destFile -Force } Move-Item -Path $extractedBin.FullName -Destination $destFile -Force Success "Binary installed to $destFile" } catch { ErrExit "Failed to download or install the binary: $_" } finally { if (Test-Path $tempZip) { Remove-Item $tempZip -ErrorAction SilentlyContinue } if (Test-Path $tempExtractDir) { Remove-Item $tempExtractDir -Recurse -ErrorAction SilentlyContinue } } # ──────────────────────────────────────────── # PATH 환경 변수 설정 # ──────────────────────────────────────────── $userPath = [System.Environment]::GetEnvironmentVariable('Path', 'User') $normalizedInstallDir = $INSTALL_DIR.TrimEnd('\') # 현재 세션 PATH 확인 및 반영 if ($env:Path -notlike "*$normalizedInstallDir*") { $env:Path = "$normalizedInstallDir;$env:Path" Info "Added $normalizedInstallDir to current session PATH." } # 사용자 PATH 레지스트리 영구 등록 확인 $pathList = $userPath -split ';' $alreadyInPath = $false foreach ($p in $pathList) { if ($p.Trim().TrimEnd('\') -eq $normalizedInstallDir) { $alreadyInPath = $true break } } if (-not $alreadyInPath) { $newUserPath = "$normalizedInstallDir;$userPath" [System.Environment]::SetEnvironmentVariable('Path', $newUserPath, 'User') Success "Added $normalizedInstallDir to User PATH environment variable permanently." Info "Note: You need to restart your terminal/IDE to apply PATH changes." } else { Info "$normalizedInstallDir is already in User PATH." } # ──────────────────────────────────────────── # 설치 완료 정보 출력 # ──────────────────────────────────────────── Info "" Info "==================================================" Success "Lablup all-smi installation complete!" Info "==================================================" Info "" Info "How to run:" Info " all-smi" Info "" Info "For more information, visit: https://github.com/lablup/all-smi"