Добавить этап установки популярных AI-агентов #10
15 changed files with 325 additions and 20 deletions
3
.github/workflows/bash-syntax.yml
vendored
3
.github/workflows/bash-syntax.yml
vendored
|
|
@ -34,3 +34,6 @@ jobs:
|
|||
|
||||
- name: Test step 3 SSH configuration parsing
|
||||
run: bash tests/test-step3-sshd-parsing.sh
|
||||
|
||||
- name: Test step 8 AI agent catalog
|
||||
run: bash tests/test-step8-agent-catalog.sh
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -32,7 +32,7 @@ chmod 700 ./*.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
The first wizard prompt selects the dialog language. English is the default; Russian, Spanish, German, French, Portuguese, Simplified Chinese, Japanese, Arabic, and Hindi are also available. The wizard then presents steps 1–7 in order. Each step can be installed, skipped, or used to exit the wizard.
|
||||
The first wizard prompt selects the dialog language. English is the default; Russian, Spanish, German, French, Portuguese, Simplified Chinese, Japanese, Arabic, and Hindi are also available. The wizard then presents steps 1–8 in order. Each step can be installed, skipped, or used to exit the wizard.
|
||||
|
||||
Keep the current SSH session open while changing the SSH port. Test the new login in a second terminal before disconnecting.
|
||||
|
||||
|
|
@ -66,6 +66,7 @@ The wizard downloads any missing module from the `main` branch and validates it
|
|||
| `ochenstarik-server-vpn-5.sh` | System VPN through Xray with a selectable subscription port | Optional |
|
||||
| `ochenstarik-server-panel-warp-6.sh` | 3x-ui panel and local Cloudflare WARP proxy | Optional |
|
||||
| `ochenstarik-server-backup-7.sh` | Protected initial snapshot and selected daily, weekly, or monthly schedules | Optional |
|
||||
| `ochenstarik-server-ai-agents-8.sh` | Installs selected AI agents for a regular user: Hermes, OpenClaw, OpenHands, OpenCode, or Aider | Optional |
|
||||
| `ochenstarik-server-uninstall.sh` | Removes project-managed settings so installation can start again | Use carefully |
|
||||
|
||||
Every module can be downloaded and run independently:
|
||||
|
|
@ -89,6 +90,13 @@ Replace `SCRIPT_NAME.sh` with the required filename from the table.
|
|||
6. Optionally configure the system VPN and subscription port.
|
||||
7. Optionally deploy 3x-ui and Cloudflare WARP with selected panel and subscription ports.
|
||||
8. Optionally create the permanent initial backup and configure rotating schedules.
|
||||
9. Optionally install one or more AI agents for the administrative user.
|
||||
|
||||
## Optional AI agents
|
||||
|
||||
Step 8 offers a multiple selection of five popular agents: Hermes Agent, OpenClaw, OpenHands, OpenCode, and Aider. Installers are downloaded only from each project's official HTTPS endpoint, checked with `bash -n`, and executed as the selected regular user rather than `root`.
|
||||
|
||||
The script does not request or store model-provider API keys. After installation, log in as the selected user and run the displayed onboarding command. AI agents can execute commands, access files, install plugins, and use network services; review their permissions and sandbox settings before connecting production data or secrets.
|
||||
|
||||
## Firewall and SSH notes
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ chmod 700 ochenstarik-server-install.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
السؤال الأول يحدد لغة المثبت، واللغة الافتراضية هي English. بعد ذلك يمكن تشغيل كل مرحلة من المراحل السبع أو تخطيها أو إنهاء المثبت.
|
||||
السؤال الأول يحدد لغة المثبت، واللغة الافتراضية هي English. بعد ذلك يمكن تشغيل كل مرحلة من المراحل الثماني أو تخطيها أو إنهاء المثبت.
|
||||
|
||||
## المراحل
|
||||
|
||||
|
|
@ -28,5 +28,6 @@ sudo ./ochenstarik-server-install.sh
|
|||
5. VPN للنظام باستخدام Xray.
|
||||
6. لوحة 3x-ui ووكيل Cloudflare WARP المحلي.
|
||||
7. النسخة الأولية والنسخ اليومية أو الأسبوعية أو الشهرية.
|
||||
8. وكلاء ذكاء اصطناعي اختياريون: Hermes أو OpenClaw أو OpenHands أو OpenCode أو Aider.
|
||||
|
||||
لا تغلق جلسة SSH الحالية أثناء تغيير المنفذ. اختبر الاتصال الجديد أولاً في طرفية أخرى. راجع [الوثائق الإنجليزية الرئيسية](../../README.md) لمزيد من التفاصيل.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ chmod 700 ochenstarik-server-install.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
Die erste Frage wählt die Sprache des Installers; English ist voreingestellt. Danach kann jeder der sieben Schritte ausgeführt, übersprungen oder zum Beenden verwendet werden.
|
||||
Die erste Frage wählt die Sprache des Installers; English ist voreingestellt. Danach kann jeder der acht Schritte ausgeführt, übersprungen oder zum Beenden verwendet werden.
|
||||
|
||||
## Schritte
|
||||
|
||||
|
|
@ -28,5 +28,6 @@ Die erste Frage wählt die Sprache des Installers; English ist voreingestellt. D
|
|||
5. System-VPN über Xray.
|
||||
6. 3x-ui und lokaler Cloudflare-WARP-Proxy.
|
||||
7. Erstsicherung sowie tägliche, wöchentliche oder monatliche Sicherungen.
|
||||
8. Optionale KI-Agenten: Hermes, OpenClaw, OpenHands, OpenCode oder Aider.
|
||||
|
||||
Schließen Sie die aktuelle SSH-Sitzung während der Portänderung nicht. Testen Sie zuerst die neue Anmeldung in einem zweiten Terminal. Weitere Hinweise enthält die [englische Hauptdokumentation](../../README.md).
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ chmod 700 ochenstarik-server-install.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
La primera pregunta selecciona el idioma del instalador; English es el valor predeterminado. Después puede instalar, omitir o detener cada una de las siete etapas.
|
||||
La primera pregunta selecciona el idioma del instalador; English es el valor predeterminado. Después puede instalar, omitir o detener cada una de las ocho etapas.
|
||||
|
||||
## Etapas
|
||||
|
||||
|
|
@ -28,5 +28,6 @@ La primera pregunta selecciona el idioma del instalador; English es el valor pre
|
|||
5. VPN del sistema mediante Xray.
|
||||
6. Panel 3x-ui y proxy local Cloudflare WARP.
|
||||
7. Instantánea inicial y copias diarias, semanales o mensuales.
|
||||
8. Agentes de IA opcionales: Hermes, OpenClaw, OpenHands, OpenCode o Aider.
|
||||
|
||||
No cierre la sesión SSH actual durante el cambio de puerto. Pruebe primero el nuevo acceso en otro terminal. Consulte la [documentación principal en inglés](../../README.md) para la instalación por archivo, actualización y restablecimiento.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ chmod 700 ochenstarik-server-install.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
La première question sélectionne la langue de l’installateur ; English est la valeur par défaut. Chacune des sept étapes peut ensuite être installée, ignorée ou utilisée pour quitter.
|
||||
La première question sélectionne la langue de l’installateur ; English est la valeur par défaut. Chacune des huit étapes peut ensuite être installée, ignorée ou utilisée pour quitter.
|
||||
|
||||
## Étapes
|
||||
|
||||
|
|
@ -28,5 +28,6 @@ La première question sélectionne la langue de l’installateur ; English est l
|
|||
5. VPN système via Xray.
|
||||
6. Panneau 3x-ui et proxy local Cloudflare WARP.
|
||||
7. Instantané initial et sauvegardes quotidiennes, hebdomadaires ou mensuelles.
|
||||
8. Agents IA facultatifs : Hermes, OpenClaw, OpenHands, OpenCode ou Aider.
|
||||
|
||||
Ne fermez pas la session SSH actuelle pendant le changement de port. Testez d’abord la nouvelle connexion dans un autre terminal. Consultez la [documentation principale en anglais](../../README.md) pour plus de détails.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ chmod 700 ochenstarik-server-install.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
पहला प्रश्न इंस्टॉलर की भाषा चुनता है; डिफ़ॉल्ट English है। इसके बाद सातों चरणों को चलाया, छोड़ा या इंस्टॉलर बंद किया जा सकता है।
|
||||
पहला प्रश्न इंस्टॉलर की भाषा चुनता है; डिफ़ॉल्ट English है। इसके बाद आठों चरणों को चलाया, छोड़ा या इंस्टॉलर बंद किया जा सकता है।
|
||||
|
||||
## चरण
|
||||
|
||||
|
|
@ -28,5 +28,6 @@ sudo ./ochenstarik-server-install.sh
|
|||
5. Xray के माध्यम से सिस्टम VPN।
|
||||
6. 3x-ui पैनल और स्थानीय Cloudflare WARP प्रॉक्सी।
|
||||
7. प्रारंभिक स्नैपशॉट और दैनिक, साप्ताहिक या मासिक बैकअप।
|
||||
8. वैकल्पिक AI एजेंट: Hermes, OpenClaw, OpenHands, OpenCode या Aider।
|
||||
|
||||
SSH पोर्ट बदलते समय मौजूदा सत्र बंद न करें। पहले दूसरे टर्मिनल में नया लॉगिन जाँचें। अधिक जानकारी के लिए [मुख्य अंग्रेज़ी दस्तावेज़](../../README.md) देखें।
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ chmod 700 ochenstarik-server-install.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
最初の質問でインストーラーの言語を選択します。既定値は English です。その後、7 つの各ステップを実行、スキップ、または終了できます。
|
||||
最初の質問でインストーラーの言語を選択します。既定値は English です。その後、8 つの各ステップを実行、スキップ、または終了できます。
|
||||
|
||||
## ステップ
|
||||
|
||||
|
|
@ -28,5 +28,6 @@ sudo ./ochenstarik-server-install.sh
|
|||
5. Xray によるシステム VPN。
|
||||
6. 3x-ui パネルとローカル Cloudflare WARP プロキシ。
|
||||
7. 初回スナップショットと日次、週次、月次バックアップ。
|
||||
8. オプションの AI エージェント:Hermes、OpenClaw、OpenHands、OpenCode、Aider。
|
||||
|
||||
SSH ポートの変更中は現在のセッションを閉じないでください。別のターミナルで新しい接続を先に確認してください。詳細は[英語のメイン文書](../../README.md)を参照してください。
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ chmod 700 ochenstarik-server-install.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
A primeira pergunta seleciona o idioma do instalador; English é o padrão. Depois, cada uma das sete etapas pode ser instalada, ignorada ou usada para sair.
|
||||
A primeira pergunta seleciona o idioma do instalador; English é o padrão. Depois, cada uma das oito etapas pode ser instalada, ignorada ou usada para sair.
|
||||
|
||||
## Etapas
|
||||
|
||||
|
|
@ -28,5 +28,6 @@ A primeira pergunta seleciona o idioma do instalador; English é o padrão. Depo
|
|||
5. VPN do sistema por Xray.
|
||||
6. Painel 3x-ui e proxy local Cloudflare WARP.
|
||||
7. Snapshot inicial e backups diários, semanais ou mensais.
|
||||
8. Agentes de IA opcionais: Hermes, OpenClaw, OpenHands, OpenCode ou Aider.
|
||||
|
||||
Não feche a sessão SSH atual durante a alteração da porta. Teste primeiro o novo login em outro terminal. Consulte a [documentação principal em inglês](../../README.md) para obter detalhes adicionais.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ chmod 700 ./*.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
Первым запросом мастер предлагает выбрать язык диалога и только затем показывает этапы 1–7 по порядку. На каждом этапе можно выбрать установку, пропуск или завершение. В первом этапе пустой ввод устанавливает все рекомендуемые наборы программ. Во время изменения SSH-порта не закрывайте текущую сессию — сначала проверьте новый вход во втором терминале.
|
||||
Первым запросом мастер предлагает выбрать язык диалога и только затем показывает этапы 1–8 по порядку. На каждом этапе можно выбрать установку, пропуск или завершение. В первом этапе пустой ввод устанавливает все рекомендуемые наборы программ. Во время изменения SSH-порта не закрывайте текущую сессию — сначала проверьте новый вход во втором терминале.
|
||||
|
||||
Если нужен только мастер без скачивания полного архива:
|
||||
|
||||
|
|
@ -62,6 +62,7 @@ sudo ./ochenstarik-server-install.sh
|
|||
| `ochenstarik-server-vpn-5.sh` | Устанавливает Xray и направляет системный трафик через VLESS + REALITY | Да; зависимости устанавливаются автоматически |
|
||||
| `ochenstarik-server-panel-warp-6.sh` | Устанавливает 3x-ui и Cloudflare WARP, настраивает и проверяет их порты | Ubuntu 22.04/24.04/26.04 или Debian 12/13 |
|
||||
| `ochenstarik-server-backup-7.sh` | Создаёт неизменяемый первичный снимок и настраивает выбранные расписания резервного копирования | Да; зависимости устанавливаются автоматически |
|
||||
| `ochenstarik-server-ai-agents-8.sh` | Устанавливает выбранных AI-агентов для обычного пользователя: Hermes, OpenClaw, OpenHands, OpenCode или Aider | Да; API-ключи настраиваются отдельно |
|
||||
| `ochenstarik-server-uninstall.sh` | Удаляет настройки, службы и данные проекта для повторной установки с начала | Да; запускать только из сохранённой SSH-сессии |
|
||||
|
||||
Файлы `*.env.example` являются только примерами. Не записывайте настоящие пароли, токены и приватные SSH-ключи в Git.
|
||||
|
|
@ -398,9 +399,25 @@ sudo ./ochenstarik-server-tg-4.sh
|
|||
sudo ./ochenstarik-server-vpn-5.sh
|
||||
sudo ./ochenstarik-server-panel-warp-6.sh
|
||||
sudo ./ochenstarik-server-backup-7.sh
|
||||
sudo ./ochenstarik-server-ai-agents-8.sh
|
||||
```
|
||||
|
||||
VPN, 3x-ui, WARP, Telegram-уведомления и автоматические расписания резервного копирования являются необязательными этапами.
|
||||
## 8. AI-агенты на выбор
|
||||
|
||||
Файл: `ochenstarik-server-ai-agents-8.sh`.
|
||||
|
||||
Скрипт предлагает множественный выбор из Hermes Agent, OpenClaw, OpenHands, OpenCode и Aider. Агенты устанавливаются только для выбранного обычного пользователя, а не для `root`. Каждый официальный установщик сначала загружается по HTTPS во временный файл и проходит проверку `bash -n`.
|
||||
|
||||
API-ключи скрипт не запрашивает и не сохраняет. После установки нужно войти под выбранным пользователем и выполнить показанную команду первоначальной настройки. AI-агенты могут запускать команды, изменять файлы, использовать сеть и устанавливать плагины, поэтому перед подключением рабочих данных необходимо проверить разрешения, песочницу и доступ к секретам.
|
||||
|
||||
```bash
|
||||
curl -fLO https://raw.githubusercontent.com/ochenstarik-ui/lightweight-server/main/ochenstarik-server-ai-agents-8.sh
|
||||
chmod 700 ochenstarik-server-ai-agents-8.sh
|
||||
bash -n ochenstarik-server-ai-agents-8.sh
|
||||
sudo ./ochenstarik-server-ai-agents-8.sh
|
||||
```
|
||||
|
||||
VPN, 3x-ui, WARP, Telegram-уведомления, автоматические расписания резервного копирования и AI-агенты являются необязательными этапами.
|
||||
|
||||
## Удаление и повторная установка с начала
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ chmod 700 ochenstarik-server-install.sh
|
|||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
安装程序的第一个问题用于选择界面语言,默认是 English。随后七个步骤都可以运行、跳过或用于退出安装程序。
|
||||
安装程序的第一个问题用于选择界面语言,默认是 English。随后八个步骤都可以运行、跳过或用于退出安装程序。
|
||||
|
||||
## 安装步骤
|
||||
|
||||
|
|
@ -28,5 +28,6 @@ sudo ./ochenstarik-server-install.sh
|
|||
5. 通过 Xray 配置系统 VPN。
|
||||
6. 3x-ui 面板和本地 Cloudflare WARP 代理。
|
||||
7. 初始快照以及每日、每周或每月备份。
|
||||
8. 可选 AI 代理:Hermes、OpenClaw、OpenHands、OpenCode 或 Aider。
|
||||
|
||||
更改 SSH 端口时不要关闭当前会话。请先在另一个终端中测试新连接。更多说明请参阅[英文主文档](../../README.md)。
|
||||
|
|
|
|||
231
ochenstarik-server-ai-agents-8.sh
Normal file
231
ochenstarik-server-ai-agents-8.sh
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
readonly CONFIG_DIR="/etc/ochenstarik-server"
|
||||
readonly AGENT_CONFIG="${CONFIG_DIR}/ai-agents.conf"
|
||||
readonly STEP3_ENV="/root/setup-data/env.txt"
|
||||
|
||||
readonly -a AGENT_IDS=(hermes openclaw openhands opencode aider)
|
||||
readonly -a AGENT_NAMES=(
|
||||
"Hermes Agent"
|
||||
"OpenClaw"
|
||||
"OpenHands"
|
||||
"OpenCode"
|
||||
"Aider"
|
||||
)
|
||||
readonly -a AGENT_DESCRIPTIONS=(
|
||||
"Personal self-improving agent with memory, skills, schedules, and messaging gateways"
|
||||
"Personal assistant with persistent memory and Telegram, WhatsApp, Discord, Slack, and other channels"
|
||||
"Software-development agent with terminal, headless, web, and IDE modes"
|
||||
"Terminal coding agent with multiple model providers and parallel sessions"
|
||||
"Git-oriented coding agent for editing and reviewing an existing repository"
|
||||
)
|
||||
readonly -a AGENT_INSTALL_URLS=(
|
||||
"https://hermes-agent.nousresearch.com/install.sh"
|
||||
"https://openclaw.ai/install.sh"
|
||||
"https://install.openhands.dev/install.sh"
|
||||
"https://opencode.ai/install"
|
||||
"https://aider.chat/install.sh"
|
||||
)
|
||||
readonly -a AGENT_COMMANDS=(hermes openclaw openhands opencode aider)
|
||||
readonly -a AGENT_SETUP_HINTS=(
|
||||
"hermes setup"
|
||||
"openclaw onboard --install-daemon"
|
||||
"openhands"
|
||||
"opencode"
|
||||
"aider"
|
||||
)
|
||||
|
||||
TEMP_INSTALLER=""
|
||||
|
||||
log() { printf '[+] %s\n' "$*"; }
|
||||
warn() { printf '[!] %s\n' "$*" >&2; }
|
||||
die() { printf '[x] %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "$TEMP_INSTALLER" && "$TEMP_INSTALLER" == /tmp/ochenstarik-ai-installer.* \
|
||||
&& -f "$TEMP_INSTALLER" && ! -L "$TEMP_INSTALLER" ]]; then
|
||||
rm -f -- "$TEMP_INSTALLER"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
require_command() {
|
||||
command -v "$1" >/dev/null 2>&1 || die "Required command not found: $1"
|
||||
}
|
||||
|
||||
default_target_user() {
|
||||
local username=""
|
||||
if [[ -f "$STEP3_ENV" && ! -L "$STEP3_ENV" ]]; then
|
||||
username="$(awk -F= '$1 == "NEW_USERNAME" && !found { sub(/\r$/, "", $2); print $2; found=1 }' "$STEP3_ENV")"
|
||||
if [[ "$username" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] && id "$username" >/dev/null 2>&1; then
|
||||
printf '%s' "$username"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
getent passwd | awk -F: '$3 >= 1000 && $3 != 65534 && $1 != "nobody" && !found { print $1; found=1 }'
|
||||
}
|
||||
|
||||
select_target_user() {
|
||||
local default_user username uid home owner
|
||||
default_user="$(default_target_user)"
|
||||
|
||||
printf '\nAI agents must be installed for a regular user, never for root.\n'
|
||||
while :; do
|
||||
if [[ -n "$default_user" ]]; then
|
||||
read -rp "Installation user [${default_user}]: " username || die "Input was interrupted"
|
||||
username="${username:-$default_user}"
|
||||
else
|
||||
read -rp 'Installation user: ' username || die "Input was interrupted"
|
||||
fi
|
||||
|
||||
[[ "$username" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] || { warn "Invalid username"; continue; }
|
||||
[[ "$username" != root ]] || { warn "Root cannot be used for AI agents"; continue; }
|
||||
id "$username" >/dev/null 2>&1 || { warn "User does not exist: $username"; continue; }
|
||||
uid="$(id -u "$username")"
|
||||
((uid >= 1000 && uid != 65534)) || { warn "System accounts are not allowed"; continue; }
|
||||
home="$(getent passwd "$username" | cut -d: -f6)"
|
||||
[[ -n "$home" && "$home" == /* && -d "$home" && ! -L "$home" ]] \
|
||||
|| { warn "A safe home directory was not found for $username"; continue; }
|
||||
owner="$(stat -c %U "$home")"
|
||||
[[ "$owner" == "$username" ]] || { warn "$home must be owned by $username"; continue; }
|
||||
|
||||
TARGET_USER="$username"
|
||||
TARGET_HOME="$home"
|
||||
TARGET_GROUP="$(id -gn "$username")"
|
||||
return 0
|
||||
done
|
||||
}
|
||||
|
||||
select_agents() {
|
||||
local input token index
|
||||
local -A seen=()
|
||||
SELECTED_INDEXES=()
|
||||
|
||||
printf '\nSelect one or more AI agents to install:\n'
|
||||
for index in "${!AGENT_IDS[@]}"; do
|
||||
printf ' %d) %s\n %s\n Official installer: %s\n' \
|
||||
"$((index + 1))" "${AGENT_NAMES[index]}" "${AGENT_DESCRIPTIONS[index]}" \
|
||||
"${AGENT_INSTALL_URLS[index]}"
|
||||
done
|
||||
printf ' 0) Do not install AI agents\n'
|
||||
printf '\nEnter numbers separated by spaces, for example: 1 2 4.\n'
|
||||
|
||||
while :; do
|
||||
read -rp 'Selection [0]: ' input || die "Input was interrupted"
|
||||
input="${input//,/ }"
|
||||
input="${input:-0}"
|
||||
if [[ "$input" =~ ^[[:space:]]*0[[:space:]]*$ ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
SELECTED_INDEXES=()
|
||||
seen=()
|
||||
for token in $input; do
|
||||
if [[ ! "$token" =~ ^[1-5]$ ]]; then
|
||||
warn "Enter agent numbers from 1 to 5, or 0 to skip"
|
||||
SELECTED_INDEXES=()
|
||||
break
|
||||
fi
|
||||
index="$((token - 1))"
|
||||
if [[ -z "${seen[$index]:-}" ]]; then
|
||||
SELECTED_INDEXES+=("$index")
|
||||
seen["$index"]=1
|
||||
fi
|
||||
done
|
||||
((${#SELECTED_INDEXES[@]} > 0)) && return 0
|
||||
done
|
||||
}
|
||||
|
||||
install_agent() {
|
||||
local index="$1" name url command_name path_value
|
||||
name="${AGENT_NAMES[index]}"
|
||||
url="${AGENT_INSTALL_URLS[index]}"
|
||||
command_name="${AGENT_COMMANDS[index]}"
|
||||
path_value="${TARGET_HOME}/.local/bin:${TARGET_HOME}/.opencode/bin:${TARGET_HOME}/.hermes/bin:${TARGET_HOME}/.local/share/pnpm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
log "Downloading the official ${name} installer"
|
||||
TEMP_INSTALLER="$(mktemp /tmp/ochenstarik-ai-installer.XXXXXX)"
|
||||
chmod 600 "$TEMP_INSTALLER"
|
||||
curl -fL --retry 5 --retry-delay 5 --connect-timeout 30 \
|
||||
--proto '=https' --tlsv1.2 "$url" -o "$TEMP_INSTALLER"
|
||||
[[ -s "$TEMP_INSTALLER" && ! -L "$TEMP_INSTALLER" ]] \
|
||||
|| die "The downloaded ${name} installer is empty or unsafe"
|
||||
bash -n "$TEMP_INSTALLER" || die "The official ${name} installer failed Bash syntax validation"
|
||||
|
||||
# Keep the validated file root-owned until execution so the target account
|
||||
# cannot replace it between validation and launch.
|
||||
chown root:root "$TEMP_INSTALLER"
|
||||
chmod 555 "$TEMP_INSTALLER"
|
||||
log "Installing ${name} for ${TARGET_USER}"
|
||||
runuser -u "$TARGET_USER" -- env \
|
||||
HOME="$TARGET_HOME" USER="$TARGET_USER" LOGNAME="$TARGET_USER" SHELL=/bin/bash PATH="$path_value" \
|
||||
bash "$TEMP_INSTALLER"
|
||||
|
||||
rm -f -- "$TEMP_INSTALLER"
|
||||
TEMP_INSTALLER=""
|
||||
|
||||
if runuser -u "$TARGET_USER" -- env HOME="$TARGET_HOME" PATH="$path_value" \
|
||||
bash -lc "command -v '$command_name' >/dev/null 2>&1"; then
|
||||
log "${name} command is available: ${command_name}"
|
||||
else
|
||||
warn "${name} installer completed, but ${command_name} is not visible in a new login shell yet"
|
||||
warn "Log in again or reload the user's shell configuration before running it"
|
||||
fi
|
||||
}
|
||||
|
||||
write_state() {
|
||||
local ids="" index
|
||||
install -d -m 700 -o root -g root "$CONFIG_DIR"
|
||||
[[ ! -L "$AGENT_CONFIG" ]] || die "$AGENT_CONFIG must not be a symbolic link"
|
||||
for index in "${SELECTED_INDEXES[@]}"; do
|
||||
ids+="${ids:+ }${AGENT_IDS[index]}"
|
||||
done
|
||||
umask 077
|
||||
printf 'TARGET_USER=%s\nAGENTS=%s\n' "$TARGET_USER" "$ids" > "$AGENT_CONFIG"
|
||||
chown root:root "$AGENT_CONFIG"
|
||||
chmod 600 "$AGENT_CONFIG"
|
||||
}
|
||||
|
||||
[[ "$EUID" -eq 0 ]] || die "Run this script as root"
|
||||
require_command awk
|
||||
require_command apt-get
|
||||
require_command bash
|
||||
require_command getent
|
||||
require_command runuser
|
||||
require_command stat
|
||||
|
||||
((${#AGENT_IDS[@]} == 5 && ${#AGENT_NAMES[@]} == 5 \
|
||||
&& ${#AGENT_DESCRIPTIONS[@]} == 5 && ${#AGENT_INSTALL_URLS[@]} == 5 \
|
||||
&& ${#AGENT_COMMANDS[@]} == 5 && ${#AGENT_SETUP_HINTS[@]} == 5)) \
|
||||
|| die "Invalid AI agent catalog"
|
||||
|
||||
select_target_user
|
||||
select_agents
|
||||
if ((${#SELECTED_INDEXES[@]} == 0)); then
|
||||
log "AI agent installation was skipped"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y curl ca-certificates git
|
||||
require_command curl
|
||||
|
||||
printf '\nThe selected agents can execute commands, access files, and use network services.\n'
|
||||
printf 'Review permissions, tools, plugins, mounted directories, and API-key access during onboarding.\n'
|
||||
read -rp "Type INSTALL to continue for user ${TARGET_USER}: " confirmation || die "Input was interrupted"
|
||||
[[ "$confirmation" == INSTALL ]] || die "AI agent installation was cancelled"
|
||||
|
||||
for selected_index in "${SELECTED_INDEXES[@]}"; do
|
||||
install_agent "$selected_index"
|
||||
done
|
||||
write_state
|
||||
|
||||
printf '\nInstalled AI agents for %s:\n' "$TARGET_USER"
|
||||
for selected_index in "${SELECTED_INDEXES[@]}"; do
|
||||
printf ' - %s\n Next step: %s\n' \
|
||||
"${AGENT_NAMES[selected_index]}" "${AGENT_SETUP_HINTS[selected_index]}"
|
||||
done
|
||||
printf '\nRun the setup commands while logged in as %s, not as root.\n' "$TARGET_USER"
|
||||
printf 'API keys are managed by each agent and were not requested or stored by this script.\n'
|
||||
|
|
@ -12,6 +12,7 @@ declare -a STEP_FILES=(
|
|||
"ochenstarik-server-vpn-5.sh"
|
||||
"ochenstarik-server-panel-warp-6.sh"
|
||||
"ochenstarik-server-backup-7.sh"
|
||||
"ochenstarik-server-ai-agents-8.sh"
|
||||
)
|
||||
|
||||
declare -a STEP_TITLES=(
|
||||
|
|
@ -22,6 +23,7 @@ declare -a STEP_TITLES=(
|
|||
"System VPN through Xray"
|
||||
"3x-ui panel and Cloudflare WARP"
|
||||
"Initial snapshot and backup schedules"
|
||||
"Optional AI agents for a regular user"
|
||||
)
|
||||
|
||||
TEMP_FILE=""
|
||||
|
|
@ -156,15 +158,15 @@ master_msg() {
|
|||
|
||||
localize_step_titles() {
|
||||
case "$UI_LANG" in
|
||||
ru) STEP_TITLES=("Часовой пояс, язык терминала, программы и swap" "Базовые пакеты, SSH-порт, IPv4/IPv6 и UFW" "Администратор, перенос SSH и fail2ban" "Telegram-уведомления о входах по SSH" "Системный VPN через Xray" "Панель 3x-ui и Cloudflare WARP" "Первичный снимок и расписания бэкапов") ;;
|
||||
es) STEP_TITLES=("Zona horaria, idioma del terminal, programas y swap" "Paquetes base, puerto SSH, IPv4/IPv6 y UFW" "Administrador, migración SSH y fail2ban" "Notificaciones de Telegram para accesos SSH" "VPN del sistema mediante Xray" "Panel 3x-ui y Cloudflare WARP" "Instantánea inicial y copias programadas") ;;
|
||||
de) STEP_TITLES=("Zeitzone, Terminalsprache, Programme und Swap" "Basispakete, SSH-Port, IPv4/IPv6 und UFW" "Administrator, SSH-Umstellung und fail2ban" "Telegram-Benachrichtigungen für SSH-Anmeldungen" "System-VPN über Xray" "3x-ui und Cloudflare WARP" "Erstsicherung und Sicherungspläne") ;;
|
||||
fr) STEP_TITLES=("Fuseau horaire, langue du terminal, programmes et swap" "Paquets de base, port SSH, IPv4/IPv6 et UFW" "Administrateur, migration SSH et fail2ban" "Notifications Telegram des connexions SSH" "VPN système via Xray" "Panneau 3x-ui et Cloudflare WARP" "Instantané initial et sauvegardes planifiées") ;;
|
||||
pt) STEP_TITLES=("Fuso horário, idioma do terminal, programas e swap" "Pacotes básicos, porta SSH, IPv4/IPv6 e UFW" "Administrador, migração SSH e fail2ban" "Notificações Telegram de logins SSH" "VPN do sistema via Xray" "Painel 3x-ui e Cloudflare WARP" "Snapshot inicial e backups agendados") ;;
|
||||
zh) STEP_TITLES=("时区、终端语言、程序和交换文件" "基础软件包、SSH 端口、IPv4/IPv6 和 UFW" "管理员、SSH 迁移和 fail2ban" "SSH 登录的 Telegram 通知" "通过 Xray 的系统 VPN" "3x-ui 面板和 Cloudflare WARP" "初始快照和备份计划") ;;
|
||||
ja) STEP_TITLES=("タイムゾーン、端末言語、プログラム、スワップ" "基本パッケージ、SSH ポート、IPv4/IPv6、UFW" "管理者、SSH 移行、fail2ban" "SSH ログインの Telegram 通知" "Xray によるシステム VPN" "3x-ui パネルと Cloudflare WARP" "初回スナップショットとバックアップ予定") ;;
|
||||
ar) STEP_TITLES=("المنطقة الزمنية ولغة الطرفية والبرامج وswap" "الحزم الأساسية ومنفذ SSH وIPv4/IPv6 وUFW" "المسؤول ونقل SSH وfail2ban" "إشعارات Telegram لدخول SSH" "VPN للنظام عبر Xray" "لوحة 3x-ui وCloudflare WARP" "النسخة الأولية وجداول النسخ الاحتياطي") ;;
|
||||
hi) STEP_TITLES=("समय क्षेत्र, टर्मिनल भाषा, प्रोग्राम और swap" "मूल पैकेज, SSH पोर्ट, IPv4/IPv6 और UFW" "प्रशासक, SSH स्थानांतरण और fail2ban" "SSH लॉगिन की Telegram सूचनाएँ" "Xray द्वारा सिस्टम VPN" "3x-ui पैनल और Cloudflare WARP" "प्रारंभिक स्नैपशॉट और बैकअप अनुसूचियाँ") ;;
|
||||
ru) STEP_TITLES=("Часовой пояс, язык терминала, программы и swap" "Базовые пакеты, SSH-порт, IPv4/IPv6 и UFW" "Администратор, перенос SSH и fail2ban" "Telegram-уведомления о входах по SSH" "Системный VPN через Xray" "Панель 3x-ui и Cloudflare WARP" "Первичный снимок и расписания бэкапов" "AI-агенты на выбор для обычного пользователя") ;;
|
||||
es) STEP_TITLES=("Zona horaria, idioma del terminal, programas y swap" "Paquetes base, puerto SSH, IPv4/IPv6 y UFW" "Administrador, migración SSH y fail2ban" "Notificaciones de Telegram para accesos SSH" "VPN del sistema mediante Xray" "Panel 3x-ui y Cloudflare WARP" "Instantánea inicial y copias programadas" "Agentes de IA opcionales para un usuario normal") ;;
|
||||
de) STEP_TITLES=("Zeitzone, Terminalsprache, Programme und Swap" "Basispakete, SSH-Port, IPv4/IPv6 und UFW" "Administrator, SSH-Umstellung und fail2ban" "Telegram-Benachrichtigungen für SSH-Anmeldungen" "System-VPN über Xray" "3x-ui und Cloudflare WARP" "Erstsicherung und Sicherungspläne" "Optionale KI-Agenten für einen normalen Benutzer") ;;
|
||||
fr) STEP_TITLES=("Fuseau horaire, langue du terminal, programmes et swap" "Paquets de base, port SSH, IPv4/IPv6 et UFW" "Administrateur, migration SSH et fail2ban" "Notifications Telegram des connexions SSH" "VPN système via Xray" "Panneau 3x-ui et Cloudflare WARP" "Instantané initial et sauvegardes planifiées" "Agents IA facultatifs pour un utilisateur standard") ;;
|
||||
pt) STEP_TITLES=("Fuso horário, idioma do terminal, programas e swap" "Pacotes básicos, porta SSH, IPv4/IPv6 e UFW" "Administrador, migração SSH e fail2ban" "Notificações Telegram de logins SSH" "VPN do sistema via Xray" "Painel 3x-ui e Cloudflare WARP" "Snapshot inicial e backups agendados" "Agentes de IA opcionais para um usuário comum") ;;
|
||||
zh) STEP_TITLES=("时区、终端语言、程序和交换文件" "基础软件包、SSH 端口、IPv4/IPv6 和 UFW" "管理员、SSH 迁移和 fail2ban" "SSH 登录的 Telegram 通知" "通过 Xray 的系统 VPN" "3x-ui 面板和 Cloudflare WARP" "初始快照和备份计划" "为普通用户安装可选 AI 代理") ;;
|
||||
ja) STEP_TITLES=("タイムゾーン、端末言語、プログラム、スワップ" "基本パッケージ、SSH ポート、IPv4/IPv6、UFW" "管理者、SSH 移行、fail2ban" "SSH ログインの Telegram 通知" "Xray によるシステム VPN" "3x-ui パネルと Cloudflare WARP" "初回スナップショットとバックアップ予定" "一般ユーザー向けのオプション AI エージェント") ;;
|
||||
ar) STEP_TITLES=("المنطقة الزمنية ولغة الطرفية والبرامج وswap" "الحزم الأساسية ومنفذ SSH وIPv4/IPv6 وUFW" "المسؤول ونقل SSH وfail2ban" "إشعارات Telegram لدخول SSH" "VPN للنظام عبر Xray" "لوحة 3x-ui وCloudflare WARP" "النسخة الأولية وجداول النسخ الاحتياطي" "وكلاء ذكاء اصطناعي اختياريون لمستخدم عادي") ;;
|
||||
hi) STEP_TITLES=("समय क्षेत्र, टर्मिनल भाषा, प्रोग्राम और swap" "मूल पैकेज, SSH पोर्ट, IPv4/IPv6 और UFW" "प्रशासक, SSH स्थानांतरण और fail2ban" "SSH लॉगिन की Telegram सूचनाएँ" "Xray द्वारा सिस्टम VPN" "3x-ui पैनल और Cloudflare WARP" "प्रारंभिक स्नैपशॉट और बैकअप अनुसूचियाँ" "सामान्य उपयोगकर्ता के लिए वैकल्पिक AI एजेंट") ;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,5 +18,9 @@ choose_dialog_language <<< '' >/dev/null
|
|||
choose_dialog_language <<< '2' >/dev/null
|
||||
[[ "$(master_msg install)" == 'Установить / запустить этот этап' ]]
|
||||
[[ "${STEP_TITLES[0]}" == 'Часовой пояс, язык терминала, программы и swap' ]]
|
||||
[[ "${#STEP_FILES[@]}" == 8 ]]
|
||||
[[ "${#STEP_TITLES[@]}" == 8 ]]
|
||||
[[ "${STEP_FILES[7]}" == 'ochenstarik-server-ai-agents-8.sh' ]]
|
||||
[[ "${STEP_TITLES[7]}" == 'AI-агенты на выбор для обычного пользователя' ]]
|
||||
|
||||
printf 'Master language selection tests passed.\n'
|
||||
|
|
|
|||
32
tests/test-step8-agent-catalog.sh
Normal file
32
tests/test-step8-agent-catalog.sh
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.."
|
||||
source <(awk '/^\[\[ "\$EUID"/{exit} {print}' ochenstarik-server-ai-agents-8.sh)
|
||||
|
||||
[[ "${#AGENT_IDS[@]}" == 5 ]]
|
||||
[[ "${AGENT_IDS[*]}" == 'hermes openclaw openhands opencode aider' ]]
|
||||
|
||||
expected_urls=(
|
||||
'https://hermes-agent.nousresearch.com/install.sh'
|
||||
'https://openclaw.ai/install.sh'
|
||||
'https://install.openhands.dev/install.sh'
|
||||
'https://opencode.ai/install'
|
||||
'https://aider.chat/install.sh'
|
||||
)
|
||||
|
||||
for index in "${!expected_urls[@]}"; do
|
||||
[[ "${AGENT_INSTALL_URLS[index]}" == "${expected_urls[index]}" ]]
|
||||
done
|
||||
|
||||
select_agents <<< '1 3 5' >/dev/null
|
||||
[[ "${SELECTED_INDEXES[*]}" == '0 2 4' ]]
|
||||
select_agents <<< '' >/dev/null
|
||||
[[ "${#SELECTED_INDEXES[@]}" == 0 ]]
|
||||
|
||||
if grep -E 'curl[^|]*\|[[:space:]]*(ba)?sh' ochenstarik-server-ai-agents-8.sh; then
|
||||
printf 'Direct curl-to-shell execution found.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf 'Step 8 AI agent catalog tests passed.\n'
|
||||
Loading…
Reference in a new issue