Files
install-sh/install-all-smi.sh

169 lines
7.1 KiB
Bash

#!/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-musl.tar.gz:tar.gz" ;;
aarch64|arm64) echo "all-smi-linux-aarch64-musl.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 -H "User-Agent: install-all-smi-sh" --connect-timeout 10 "${API_URL}" 2>/dev/null); then
if command -v jq &>/dev/null; then
tag=$(echo "$json" | jq -r 'select((.assets | length) > 0) | .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 fallback_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}"
fallback_url="https://github.com/${REPO}/releases/download/${FALLBACK_VERSION}/${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
if [[ "$tag" != "$FALLBACK_VERSION" ]]; then
warn "최신 버전(${tag}) 다운로드 실패. 검증된 폴백 버전(${FALLBACK_VERSION})으로 재시도합니다: $fallback_url"
curl -fsSL --progress-bar -o "$archive_file" "$fallback_url" || error "다운로드 실패: $fallback_url"
else
error "다운로드 실패: $url"
fi
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 "$@"