diff --git a/README.md b/README.md index 4ce6011..d6819ef 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ ### 🐳 2. μ‹œμŠ€ν…œ & μ»¨ν…Œμ΄λ„ˆ DevOps * **[bottom](https://github.com/ClementTsang/bottom)** - CPU, λ©”λͺ¨λ¦¬, λ„€νŠΈμ›Œν¬ 등을 μ‹€μ‹œκ°„ λͺ¨λ‹ˆν„°λ§ν•˜λŠ” TUI +* **[all-smi](https://github.com/lablup/all-smi)** - 이쒅 GPU/NPU 가속기 및 λ¦¬μ†ŒμŠ€λ₯Ό μ‹€μ‹œκ°„ λͺ¨λ‹ˆν„°λ§ν•˜λŠ” 톡합 TUI * **[Docker](https://www.docker.com/)** - μ»¨ν…Œμ΄λ„ˆ ν”Œλž«νΌ (Linux μžλ™ μ„€μΉ˜ 지원, Mac/Windows κ°€μ΄λ“œ 제곡) * **[lazydocker](https://github.com/jesseduffield/lazydocker)** - 도컀 μ»¨ν…Œμ΄λ„ˆ, 이미지, λ³Όλ₯¨μ„ μ‹œκ°μ μœΌλ‘œ μ œμ–΄ν•˜λŠ” TUI * **[ctop](https://github.com/bcicen/ctop)** - μ‹€μ‹œκ°„ μ»¨ν…Œμ΄λ„ˆ λ©”νŠΈλ¦­ 및 μžμ› λͺ¨λ‹ˆν„°λ§ TUI @@ -75,6 +76,11 @@ curl -fsSL "https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-bottom.sh?ref_type=heads" | bash ``` +* **all-smi:** + ```bash + curl -fsSL "https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-all-smi.sh?ref_type=heads" | bash + ``` + * **ctop:** ```bash curl -fsSL "https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-ctop.sh?ref_type=heads" | bash @@ -202,6 +208,20 @@ $t="$env:TEMP\install-bottom.ps1"; iwr -useb 'https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-bottom.ps1' -OutFile $t; powershell -ExecutionPolicy Bypass -File $t ``` +* **all-smi:** + * **CMD μ°½μ—μ„œ μ„€μΉ˜ μ‹œ (.ps1 μ‹€ν–‰ λ˜λŠ” .bat μ‹€ν–‰):** + ```cmd + powershell -ExecutionPolicy Bypass -c "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $t=\"$env:TEMP\install-all-smi.ps1\"; iwr -useb 'https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-all-smi.ps1' -OutFile $t; & $t" + ``` + 배치 파일(.bat) λ‹€μš΄λ‘œλ“œ 및 μ‹€ν–‰: + ```cmd + curl -fsSL "https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-all-smi.bat" -o "%TEMP%\install-all-smi.bat" && "%TEMP%\install-all-smi.bat" + ``` + * **νŒŒμ›Œμ‰˜ μ°½μ—μ„œ μ„€μΉ˜ μ‹œ:** + ```powershell + $t="$env:TEMP\install-all-smi.ps1"; iwr -useb 'https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-all-smi.ps1' -OutFile $t; powershell -ExecutionPolicy Bypass -File $t + ``` + * **ctop:** * **CMD μ°½μ—μ„œ μ„€μΉ˜ μ‹œ:** ```cmd @@ -457,7 +477,19 @@ btm # μ‹€ν–‰ λͺ…λ Ήμ–΄ | `k` | μ„ νƒν•œ λŒ€μƒ ν”„λ‘œμ„ΈμŠ€ κ°•μ œ μ’…λ£Œ (Kill) | | `/` | μ‹€μ‹œκ°„ ν”„λ‘œμ„ΈμŠ€λͺ… 검색 필터링 | -#### 2.2. Docker +#### 2.2. all-smi +Lablupμ—μ„œ κ°œλ°œν•œ 이쒅(Heterogeneous) 가속기 및 GPU/NPU μžμ› 톡합 λͺ¨λ‹ˆν„°λ§ CLI/TUI λ„κ΅¬μž…λ‹ˆλ‹€. `nvidia-smi`λ₯Ό λŒ€μ²΄/ν™•μž₯ν•˜μ—¬ λ‹€μ–‘ν•œ AI 가속기 및 ν΄λŸ¬μŠ€ν„° λ…Έλ“œ κ΄€μ œλ₯Ό μ§€μ›ν•©λ‹ˆλ‹€. + +* **이쒅 가속기 지원** β€” NVIDIA GPU, Apple Silicon, Intel Gaudi, Google TPU, Rebellions NPU, Furiosa NPU, Tenstorrent NPU λ“± λͺ¨λ‹ˆν„°λ§ 지원 +* **μ‹€μ‹œκ°„ μΈν„°λž™ν‹°λΈŒ TUI** β€” GPU/NPU μ‚¬μš©λ₯ , λ©”λͺ¨λ¦¬, μ˜¨λ„, μ „λ ₯ μ†Œλͺ¨λŸ‰ μ‹€μ‹œκ°„ κ·Έλž˜ν”„ μ‹œκ°ν™” +* **ν΄λŸ¬μŠ€ν„° λ©”νŠΈλ¦­ κ΄€μ œ** β€” 원격 μ‹œμŠ€ν…œ κ΄€μ œ 및 ν”„λ‘œλ©”ν…Œμš°μŠ€(Prometheus) λ©”νŠΈλ¦­ μΆ”μΆœ κΈ°λŠ₯ 연동 지원 + +```bash +all-smi # μΈν„°λž™ν‹°λΈŒ λͺ¨λ‹ˆν„°λ§ TUI μ„Έμ…˜ μ‹œμž‘ +all-smi --help # 도움말 및 μ‚¬μš© κ°€λŠ₯ μ˜΅μ…˜ 확인 +``` + +#### 2.3. Docker μ»¨ν…Œμ΄λ„ˆ 기반 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 가상화 ν”Œλž«νΌμž…λ‹ˆλ‹€. * **μžλ™ μ„€μΉ˜ 지원:** `install-docker.sh`λŠ” Linux ν™˜κ²½μ— ν•„μˆ˜μ μΈ Docker Engine 및 Composeλ₯Ό 무인 μ„€μΉ˜ν•©λ‹ˆλ‹€. diff --git a/install-all-smi.bat b/install-all-smi.bat new file mode 100644 index 0000000..69a2e4e --- /dev/null +++ b/install-all-smi.bat @@ -0,0 +1,27 @@ +@echo off +rem Lablup all-smi (Cross-platform Unified GPU/NPU Monitor) Windows 배치 μ„€μΉ˜ 슀크립트 +rem PowerShell 슀크립트(install-all-smi.ps1)λ₯Ό ν˜ΈμΆœν•˜μ—¬ λ°”μ΄λ„ˆλ¦¬λ₯Ό λ‹€μš΄λ‘œλ“œν•˜κ³  μ„€μΉ˜ν•©λ‹ˆλ‹€. + +setlocal + +echo [INFO] Starting Lablup all-smi installation... + +rem 슀크립트 μœ„μΉ˜ 확인 및 ps1 파일 탐색 +set "SCRIPT_DIR=%~dp0" +set "PS1_FILE=%SCRIPT_DIR%install-all-smi.ps1" + +if exist "%PS1_FILE%" ( + echo [INFO] Running local install-all-smi.ps1 script... + powershell -NoProfile -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; & '%PS1_FILE%'" +) else ( + echo [INFO] Local install-all-smi.ps1 not found. Downloading and executing remote installer... + powershell -NoProfile -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $t=\"%TEMP%\install-all-smi.ps1\"; iwr -useb 'https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-all-smi.ps1' -OutFile $t; & $t" +) + +if %ERRORLEVEL% NEQ 0 ( + echo [ERROR] all-smi installation failed with error code %ERRORLEVEL%. + exit /b %ERRORLEVEL% +) + +echo [OK] Installation completed successfully. +endlocal diff --git a/install-all-smi.ps1 b/install-all-smi.ps1 new file mode 100644 index 0000000..2e5d802 --- /dev/null +++ b/install-all-smi.ps1 @@ -0,0 +1,151 @@ +#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 -TimeoutSec 10 + $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" +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..." + Invoke-WebRequest -Uri $downloadUrl -OutFile $tempZip -UseBasicParsing + + 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" diff --git a/install-all-smi.sh b/install-all-smi.sh new file mode 100644 index 0000000..90b96bb --- /dev/null +++ b/install-all-smi.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2086 + +# Lablup all-smi (Cross-platform Unified GPU/NPU Monitor) μ„€μΉ˜ 슀크립트 +# +# macOS, Linux ν™˜κ²½μ—μ„œ GitHub Releases에 배포된 μ΅œμ‹  λ°”μ΄λ„ˆλ¦¬λ₯Ό λ‹€μš΄λ‘œλ“œν•˜μ—¬ μ„€μΉ˜ν•©λ‹ˆλ‹€. +# 곡식 κ°€μ΄λ“œ: https://github.com/lablup/all-smi +# +# 지원 μ•„ν‚€ν…μ²˜: +# macOS : Apple Silicon (arm64), Intel (x86_64) +# Linux : x86_64 (amd64), ARM64 (aarch64) + +set -euo pipefail + +# ──────────────────────────────────────────── +# μƒμˆ˜ μ •μ˜ +# ──────────────────────────────────────────── +REPO="lablup/all-smi" +API_URL="https://api.github.com/repos/${REPO}/releases/latest" +INSTALL_DIR="${HOME}/.local/bin" +FALLBACK_VERSION="v0.25.0" + +# ──────────────────────────────────────────── +# μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜ (λͺ¨λ‘ stderr 좜λ ₯) +# ──────────────────────────────────────────── +info() { echo "[INFO] $*" >&2; } +warn() { echo "[WARN] $*" >&2; } +error() { echo "[ERROR] $*" >&2; exit 1; } +success() { echo "[OK] $*" >&2; } + +# ──────────────────────────────────────────── +# ν•„μˆ˜ λͺ…λ Ήμ–΄ 확인 +# ──────────────────────────────────────────── +for cmd in curl uname; do + command -v "$cmd" &>/dev/null || error "'$cmd' λͺ…λ Ήμ–΄κ°€ ν•„μš”ν•©λ‹ˆλ‹€." +done + +# ──────────────────────────────────────────── +# OS / μ•„ν‚€ν…μ²˜ 감지 및 파일λͺ… κ²°μ • +# λ°˜ν™˜κ°’ ν˜•μ‹: "<μ—μ…‹νŒŒμΌλͺ…>:<압좕포맷>" +# ──────────────────────────────────────────── +detect_platform() { + local os arch + os="$(uname -s)" + arch="$(uname -m)" + + case "$os" in + Darwin) + case "$arch" in + arm64|x86_64) echo "all-smi-macos-aarch64.zip:zip" ;; + *) error "μ§€μ›ν•˜μ§€ μ•ŠλŠ” macOS μ•„ν‚€ν…μ²˜: $arch" ;; + esac + ;; + Linux) + case "$arch" in + x86_64|amd64) echo "all-smi-linux-x86_64.tar.gz:tar.gz" ;; + aarch64|arm64) echo "all-smi-linux-aarch64.tar.gz:tar.gz" ;; + *) error "μ§€μ›ν•˜μ§€ μ•ŠλŠ” Linux μ•„ν‚€ν…μ²˜: $arch" ;; + esac + ;; + *) + error "μ§€μ›ν•˜μ§€ μ•ŠλŠ” OSμž…λ‹ˆλ‹€: $os. Windows인 경우 install-all-smi.ps1 λ˜λŠ” install-all-smi.bat을 μ‚¬μš©ν•˜μ„Έμš”." + ;; + esac +} + +# ──────────────────────────────────────────── +# μ΅œμ‹  릴리즈 νƒœκ·Έ κ°€μ Έμ˜€κΈ° +# ──────────────────────────────────────────── +get_latest_tag() { + local json tag + info "GitHub APIμ—μ„œ all-smi μ΅œμ‹  릴리즈 정보λ₯Ό κ°€μ Έμ˜€λŠ” 쀑..." + + if json=$(curl -fsSL --connect-timeout 10 "${API_URL}" 2>/dev/null); then + if command -v jq &>/dev/null; then + tag=$(echo "$json" | jq -r '.tag_name') + else + # jqκ°€ μ—†λŠ” 경우 grep & sed μ‚¬μš© + tag=$(echo "$json" | grep '"tag_name":' | head -n 1 | sed -E 's/.*"tag_name": *"([^"]+)".*/\1/') + fi + fi + + if [[ -z "${tag:-}" || "${tag}" == "null" ]]; then + warn "μ΅œμ‹  νƒœκ·Έ 정보λ₯Ό κ°€μ Έμ˜€μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€. κΈ°λ³Έ 버전(${FALLBACK_VERSION})을 μ‚¬μš©ν•©λ‹ˆλ‹€." + echo "${FALLBACK_VERSION}" + else + echo "${tag}" + fi +} + +# ──────────────────────────────────────────── +# 메인 μ„€μΉ˜ ν•¨μˆ˜ +# ──────────────────────────────────────────── +main() { + local platform_info asset_name format tag url tmpdir archive_file bin_src + + platform_info="$(detect_platform)" + asset_name="${platform_info%%:*}" + format="${platform_info##*:}" + + info "κ°μ§€λœ ν”Œλž«νΌ 에셋: $asset_name (포맷: $format)" + + tag="$(get_latest_tag)" + info "μ μš©ν•  버전 νƒœκ·Έ: $tag" + + url="https://github.com/${REPO}/releases/download/${tag}/${asset_name}" + + # μž„μ‹œ 디렉토리 생성 + tmpdir="$(mktemp -d)" + trap '[[ -d "${tmpdir:-}" ]] && rm -rf "$tmpdir"' EXIT + + archive_file="${tmpdir}/${asset_name}" + + info "λ°”μ΄λ„ˆλ¦¬ μ•„μΉ΄μ΄λΈŒ λ‹€μš΄λ‘œλ“œ 쀑: $url" + if ! curl -fsSL --progress-bar -o "$archive_file" "$url"; then + error "λ‹€μš΄λ‘œλ“œ μ‹€νŒ¨: $url" + fi + + info "μ••μΆ• ν•΄μ œ 쀑..." + case "$format" in + zip) + command -v unzip &>/dev/null || error "'unzip' λͺ…λ Ήμ–΄κ°€ ν•„μš”ν•©λ‹ˆλ‹€." + unzip -q "$archive_file" -d "$tmpdir" + ;; + tar.gz) + command -v tar &>/dev/null || error "'tar' λͺ…λ Ήμ–΄κ°€ ν•„μš”ν•©λ‹ˆλ‹€." + tar -xzf "$archive_file" -C "$tmpdir" + ;; + *) + error "μ§€μ›ν•˜μ§€ μ•ŠλŠ” μ••μΆ• 포맷: $format" + ;; + esac + + bin_src="$(find "$tmpdir" -maxdepth 2 -type f -name "all-smi" | head -1)" + [[ -z "$bin_src" ]] && error "μ•„μΉ΄μ΄λΈŒ λ‚΄μ—μ„œ 'all-smi' λ°”μ΄λ„ˆλ¦¬λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€." + + # μ„€μΉ˜ 디렉토리 확보 + mkdir -p "$INSTALL_DIR" + + local install_path="${INSTALL_DIR}/all-smi" + info "μ„€μΉ˜ 경둜둜 볡사 쀑: ${install_path}" + cp "$bin_src" "$install_path" + chmod +x "$install_path" + + success "Lablup all-smi μ„€μΉ˜κ°€ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€!" + + # 버전 정보 좜λ ₯ ν…ŒμŠ€νŠΈ + if "$install_path" --version &>/dev/null; then + info "버전 확인: $("$install_path" --version)" + elif "$install_path" -V &>/dev/null; then + info "버전 확인: $("$install_path" -V)" + fi + + # PATH ν™˜κ²½ λ³€μˆ˜ 체크 및 κ°€μ΄λ“œ + if ! echo ":${PATH}:" | grep -q ":${INSTALL_DIR}:"; then + warn "'${INSTALL_DIR}' κ²½λ‘œκ°€ PATH ν™˜κ²½ λ³€μˆ˜μ— μΆ”κ°€λ˜μ–΄ μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€." + warn "λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό 톡해 μ‰˜ μ„€μ • 파일(~/.bashrc λ˜λŠ” ~/.zshrc)에 PATHλ₯Ό μΆ”κ°€ν•˜μ„Έμš”:" + warn " echo 'export PATH=\"\$HOME/.local/bin:\$PATH\"' >> ~/.zshrc && source ~/.zshrc" + fi +} + +main "$@"