v1.8.97: add install.sh — CLI installer for headless Linux servers
Installs ssh.py, encryption.py, Claude Code skill, Python dependencies. Supports local source dir or downloads from Gitea. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
BIN
releases/ServerManager-v1.8.97-win-x64.exe
Normal file
BIN
releases/ServerManager-v1.8.97-win-x64.exe
Normal file
Binary file not shown.
276
tools/install.sh
Normal file
276
tools/install.sh
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ─────────────────────────────────────────────────────────────────────
|
||||||
|
# ServerManager CLI Installer for Linux (headless / no-GUI)
|
||||||
|
#
|
||||||
|
# Устанавливает:
|
||||||
|
# - ssh.py + encryption.py → ~/.server-connections/
|
||||||
|
# - servers.json + settings.json → ~/.server-connections/ (если есть)
|
||||||
|
# - CLAUDE.md → ~/.claude/
|
||||||
|
# - ssh.md (скилл) → ~/.claude/commands/
|
||||||
|
# - Python-зависимости для CLI (paramiko, cryptography, etc.)
|
||||||
|
#
|
||||||
|
# Запуск:
|
||||||
|
# curl -sSL https://git.sensey24.ru/aibot777/server-manager/raw/branch/master/tools/install.sh | bash
|
||||||
|
# или:
|
||||||
|
# bash install.sh
|
||||||
|
# или с указанием источника файлов:
|
||||||
|
# bash install.sh /path/to/server-manager/
|
||||||
|
# ─────────────────────────────────────────────────────────────────────
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ── Colors ──
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
||||||
|
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
|
||||||
|
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||||
|
error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
||||||
|
step() { echo -e "\n${CYAN}━━━ $* ━━━${NC}"; }
|
||||||
|
|
||||||
|
# ── Config ──
|
||||||
|
CONN_DIR="$HOME/.server-connections"
|
||||||
|
CLAUDE_DIR="$HOME/.claude"
|
||||||
|
COMMANDS_DIR="$CLAUDE_DIR/commands"
|
||||||
|
GITEA_RAW="https://git.sensey24.ru/aibot777/server-manager/raw/branch/master"
|
||||||
|
|
||||||
|
# Source directory (optional argument)
|
||||||
|
SRC_DIR="${1:-}"
|
||||||
|
|
||||||
|
# ── Banner ──
|
||||||
|
echo -e "${CYAN}"
|
||||||
|
echo "╔══════════════════════════════════════════════╗"
|
||||||
|
echo "║ ServerManager CLI Installer for Linux ║"
|
||||||
|
echo "║ github: git.sensey24.ru/aibot777 ║"
|
||||||
|
echo "╚══════════════════════════════════════════════╝"
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
# ── Step 1: Check Python ──
|
||||||
|
step "1/5 Проверка Python"
|
||||||
|
|
||||||
|
PYTHON=""
|
||||||
|
for cmd in python3 python; do
|
||||||
|
if command -v "$cmd" &>/dev/null; then
|
||||||
|
ver=$("$cmd" --version 2>&1 | grep -oP '\d+\.\d+')
|
||||||
|
major=$(echo "$ver" | cut -d. -f1)
|
||||||
|
minor=$(echo "$ver" | cut -d. -f2)
|
||||||
|
if [ "$major" -ge 3 ] && [ "$minor" -ge 8 ]; then
|
||||||
|
PYTHON="$cmd"
|
||||||
|
ok "Python найден: $($cmd --version)"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$PYTHON" ]; then
|
||||||
|
error "Python 3.8+ не найден!"
|
||||||
|
echo " Установите: sudo apt install python3 python3-pip"
|
||||||
|
echo " или: sudo yum install python3 python3-pip"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check pip
|
||||||
|
PIP=""
|
||||||
|
for cmd in pip3 pip; do
|
||||||
|
if command -v "$cmd" &>/dev/null; then
|
||||||
|
PIP="$cmd"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$PIP" ]; then
|
||||||
|
# Try python -m pip
|
||||||
|
if $PYTHON -m pip --version &>/dev/null; then
|
||||||
|
PIP="$PYTHON -m pip"
|
||||||
|
else
|
||||||
|
error "pip не найден!"
|
||||||
|
echo " Установите: sudo apt install python3-pip"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
ok "pip найден: $($PIP --version 2>&1 | head -1)"
|
||||||
|
|
||||||
|
# ── Step 2: Install Python dependencies ──
|
||||||
|
step "2/5 Установка Python-зависимостей"
|
||||||
|
|
||||||
|
CLI_DEPS=(
|
||||||
|
"paramiko>=3.4.0"
|
||||||
|
"cryptography>=41.0.0"
|
||||||
|
"pymysql>=1.1.0"
|
||||||
|
"psycopg2-binary>=2.9.9"
|
||||||
|
"redis>=5.0.0"
|
||||||
|
"requests>=2.31.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
for dep in "${CLI_DEPS[@]}"; do
|
||||||
|
pkg=$(echo "$dep" | sed 's/[>=<].*//')
|
||||||
|
if $PYTHON -c "import $pkg" 2>/dev/null; then
|
||||||
|
ok "$pkg уже установлен"
|
||||||
|
else
|
||||||
|
info "Устанавливаю $dep..."
|
||||||
|
if $PIP install "$dep" --quiet 2>/dev/null; then
|
||||||
|
ok "$dep установлен"
|
||||||
|
else
|
||||||
|
warn "Не удалось установить $dep (попробуйте: $PIP install $dep)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# ── Step 3: Create directories ──
|
||||||
|
step "3/5 Создание директорий"
|
||||||
|
|
||||||
|
mkdir -p "$CONN_DIR" "$COMMANDS_DIR"
|
||||||
|
chmod 700 "$CONN_DIR"
|
||||||
|
ok "$CONN_DIR"
|
||||||
|
ok "$COMMANDS_DIR"
|
||||||
|
|
||||||
|
# ── Step 4: Copy/Download files ──
|
||||||
|
step "4/5 Установка файлов"
|
||||||
|
|
||||||
|
copy_or_download() {
|
||||||
|
local src_relative="$1"
|
||||||
|
local dst="$2"
|
||||||
|
local perms="$3"
|
||||||
|
local desc="$4"
|
||||||
|
|
||||||
|
# Try local source first
|
||||||
|
if [ -n "$SRC_DIR" ] && [ -f "$SRC_DIR/$src_relative" ]; then
|
||||||
|
cp "$SRC_DIR/$src_relative" "$dst"
|
||||||
|
chmod "$perms" "$dst"
|
||||||
|
ok "$desc (из $SRC_DIR)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Try download from Gitea
|
||||||
|
local url="$GITEA_RAW/$src_relative"
|
||||||
|
if command -v curl &>/dev/null; then
|
||||||
|
if curl -sSL -o "$dst" "$url" 2>/dev/null; then
|
||||||
|
# Verify not empty and not HTML error page
|
||||||
|
if [ -s "$dst" ] && ! head -1 "$dst" | grep -qi '<!doctype\|<html'; then
|
||||||
|
chmod "$perms" "$dst"
|
||||||
|
ok "$desc (скачан с Gitea)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
rm -f "$dst"
|
||||||
|
fi
|
||||||
|
elif command -v wget &>/dev/null; then
|
||||||
|
if wget -q -O "$dst" "$url" 2>/dev/null; then
|
||||||
|
if [ -s "$dst" ] && ! head -1 "$dst" | grep -qi '<!doctype\|<html'; then
|
||||||
|
chmod "$perms" "$dst"
|
||||||
|
ok "$desc (скачан с Gitea)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
rm -f "$dst"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
warn "$desc — не удалось скачать. Скопируйте вручную."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Core files (always install)
|
||||||
|
copy_or_download "tools/ssh.py" "$CONN_DIR/ssh.py" "755" "ssh.py"
|
||||||
|
copy_or_download "core/encryption.py" "$CONN_DIR/encryption.py" "644" "encryption.py"
|
||||||
|
|
||||||
|
# Claude Code skill
|
||||||
|
copy_or_download "tools/skill-ssh.md" "$COMMANDS_DIR/ssh.md" "644" "ssh.md (скилл /ssh)"
|
||||||
|
|
||||||
|
# CLAUDE.md
|
||||||
|
if [ -n "$SRC_DIR" ] && [ -f "$SRC_DIR/CLAUDE.md" ]; then
|
||||||
|
cp "$SRC_DIR/CLAUDE.md" "$CLAUDE_DIR/CLAUDE.md"
|
||||||
|
chmod 644 "$CLAUDE_DIR/CLAUDE.md"
|
||||||
|
ok "CLAUDE.md"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# servers.json — only copy if exists locally, never download (contains encrypted creds)
|
||||||
|
if [ -n "$SRC_DIR" ] && [ -f "$SRC_DIR/servers.json" ]; then
|
||||||
|
cp "$SRC_DIR/servers.json" "$CONN_DIR/servers.json"
|
||||||
|
chmod 600 "$CONN_DIR/servers.json"
|
||||||
|
ok "servers.json (зашифрованный)"
|
||||||
|
elif [ ! -f "$CONN_DIR/servers.json" ]; then
|
||||||
|
warn "servers.json не найден — скопируйте с основной машины:"
|
||||||
|
echo " scp user@main:~/.server-connections/servers.json $CONN_DIR/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# settings.json
|
||||||
|
if [ -n "$SRC_DIR" ] && [ -f "$SRC_DIR/settings.json" ]; then
|
||||||
|
cp "$SRC_DIR/settings.json" "$CONN_DIR/settings.json"
|
||||||
|
chmod 600 "$CONN_DIR/settings.json"
|
||||||
|
ok "settings.json"
|
||||||
|
elif [ ! -f "$CONN_DIR/settings.json" ]; then
|
||||||
|
# Create minimal settings
|
||||||
|
echo '{"language":"en","check_interval":60}' > "$CONN_DIR/settings.json"
|
||||||
|
chmod 600 "$CONN_DIR/settings.json"
|
||||||
|
ok "settings.json (создан по умолчанию)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Step 5: Verify ──
|
||||||
|
step "5/5 Проверка установки"
|
||||||
|
|
||||||
|
ALL_OK=true
|
||||||
|
|
||||||
|
if [ -f "$CONN_DIR/ssh.py" ] && [ -x "$CONN_DIR/ssh.py" ]; then
|
||||||
|
ok "ssh.py — исполняемый"
|
||||||
|
else
|
||||||
|
error "ssh.py — не найден или не исполняемый"
|
||||||
|
ALL_OK=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$CONN_DIR/encryption.py" ]; then
|
||||||
|
ok "encryption.py"
|
||||||
|
else
|
||||||
|
error "encryption.py — не найден"
|
||||||
|
ALL_OK=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$COMMANDS_DIR/ssh.md" ]; then
|
||||||
|
ok "ssh.md скилл"
|
||||||
|
else
|
||||||
|
warn "ssh.md скилл — не найден"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$CONN_DIR/servers.json" ]; then
|
||||||
|
ok "servers.json"
|
||||||
|
else
|
||||||
|
warn "servers.json — отсутствует (нужно скопировать вручную)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test ssh.py
|
||||||
|
info "Тест ssh.py..."
|
||||||
|
if $PYTHON "$CONN_DIR/ssh.py" --list &>/dev/null; then
|
||||||
|
ok "ssh.py --list работает"
|
||||||
|
else
|
||||||
|
if [ ! -f "$CONN_DIR/servers.json" ]; then
|
||||||
|
warn "ssh.py не может запуститься (нет servers.json)"
|
||||||
|
else
|
||||||
|
warn "ssh.py вернул ошибку — проверьте зависимости"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Summary ──
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}━━━ Готово ━━━${NC}"
|
||||||
|
echo ""
|
||||||
|
if $ALL_OK; then
|
||||||
|
echo -e "${GREEN}Установка завершена успешно!${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}Установка завершена с предупреждениями.${NC}"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "Файлы:"
|
||||||
|
echo " $CONN_DIR/ssh.py — CLI-утилита"
|
||||||
|
echo " $CONN_DIR/encryption.py — модуль шифрования"
|
||||||
|
echo " $CONN_DIR/servers.json — серверы (зашифрованные)"
|
||||||
|
echo " $COMMANDS_DIR/ssh.md — скилл /ssh для Claude Code"
|
||||||
|
echo ""
|
||||||
|
echo "Использование:"
|
||||||
|
echo " python3 ~/.server-connections/ssh.py --list"
|
||||||
|
echo " python3 ~/.server-connections/ssh.py --info ALIAS"
|
||||||
|
echo " python3 ~/.server-connections/ssh.py ALIAS \"command\""
|
||||||
|
echo ""
|
||||||
|
echo "Claude Code скилл: /ssh"
|
||||||
|
echo ""
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Version info for ServerManager."""
|
"""Version info for ServerManager."""
|
||||||
|
|
||||||
__version__ = "1.8.96"
|
__version__ = "1.8.97"
|
||||||
__app_name__ = "ServerManager"
|
__app_name__ = "ServerManager"
|
||||||
__author__ = "aibot777"
|
__author__ = "aibot777"
|
||||||
__description__ = "Desktop GUI for managing remote servers"
|
__description__ = "Desktop GUI for managing remote servers"
|
||||||
|
|||||||
Reference in New Issue
Block a user