Add sequential installation wizard (#2)
This commit is contained in:
parent
8dc95a9964
commit
a6f53d9ad5
2 changed files with 175 additions and 1 deletions
14
README.md
14
README.md
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
| Файл | Назначение | Можно запускать отдельно |
|
||||
| --- | --- | --- |
|
||||
| `ochenstarik-server-install.sh` | Единый пошаговый мастер: установить, пропустить или завершить на каждом этапе | Да; рекомендуемый способ полной настройки |
|
||||
| `ochenstarik-server-1.sh` | Предлагает выбрать часовой пояс и русификацию терминала, создаёт swap-файл 2 ГБ и задаёт `vm.swappiness=20` | Да |
|
||||
| `ochenstarik-server-2.sh` | Предлагает выбрать будущий SSH-порт и режим IPv4/IPv6, обновляет систему, ставит пакеты и настраивает UFW | Да |
|
||||
| `ochenstarik-server-user-3.sh` | Создаёт администратора, переносит SSH на порт из этапа 2, проверяет права и включает fail2ban | После установки необходимых пакетов; проще всего сначала запустить скрипт 2 |
|
||||
|
|
@ -312,7 +313,18 @@ zstd -dc /ПУТЬ/К/АРХИВУ.tar.zst | tar --acls --xattrs --numeric-owner
|
|||
|
||||
## Полная установка
|
||||
|
||||
Если нужны все модули, запускайте их по очереди:
|
||||
Рекомендуемый способ — единый мастер. Он показывает этапы по порядку и перед каждым предлагает установить его, пропустить либо завершить работу. Если остальные файлы находятся рядом, мастер использует их. Если какой-либо этап отсутствует, мастер безопасно загрузит его из основной ветки, проверит `bash -n` и только потом запустит.
|
||||
|
||||
```bash
|
||||
curl -fLO https://raw.githubusercontent.com/ochenstarik-ui/lightweight-server/main/ochenstarik-server-install.sh
|
||||
chmod 700 ochenstarik-server-install.sh
|
||||
bash -n ochenstarik-server-install.sh
|
||||
sudo ./ochenstarik-server-install.sh
|
||||
```
|
||||
|
||||
После ошибки этап можно повторить, пропустить или завершить весь мастер. Повторный запуск мастера разрешён: каждый модуль поддерживает повторную настройку.
|
||||
|
||||
Отдельные скрипты сохранены. При необходимости их по-прежнему можно запускать вручную по очереди:
|
||||
|
||||
```bash
|
||||
sudo ./ochenstarik-server-1.sh
|
||||
|
|
|
|||
162
ochenstarik-server-install.sh
Normal file
162
ochenstarik-server-install.sh
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
readonly REPO_RAW_BASE="https://raw.githubusercontent.com/ochenstarik-ui/lightweight-server/main"
|
||||
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
|
||||
declare -a STEP_FILES=(
|
||||
"ochenstarik-server-1.sh"
|
||||
"ochenstarik-server-2.sh"
|
||||
"ochenstarik-server-user-3.sh"
|
||||
"ochenstarik-server-tg-4.sh"
|
||||
"ochenstarik-server-vpn-5.sh"
|
||||
"ochenstarik-server-panel-warp-6.sh"
|
||||
"ochenstarik-server-backup-7.sh"
|
||||
)
|
||||
|
||||
declare -a STEP_TITLES=(
|
||||
"Часовой пояс, русификация терминала и swap"
|
||||
"Базовые пакеты, будущий SSH-порт, IPv4/IPv6 и UFW"
|
||||
"Администратор, перенос SSH и fail2ban"
|
||||
"Telegram-уведомления о входах по SSH"
|
||||
"Системный VPN через Xray"
|
||||
"Панель 3x-ui и Cloudflare WARP"
|
||||
"Первичный снимок и расписания резервного копирования"
|
||||
)
|
||||
|
||||
TEMP_FILE=""
|
||||
|
||||
log() { printf '[+] %s\n' "$*"; }
|
||||
warn() { printf '[!] %s\n' "$*" >&2; }
|
||||
die() { printf '[x] %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "$TEMP_FILE" && "$TEMP_FILE" == "$SCRIPT_DIR"/.ochenstarik-server-* \
|
||||
&& -f "$TEMP_FILE" && ! -L "$TEMP_FILE" ]]; then
|
||||
rm -f -- "$TEMP_FILE"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
ensure_step_script() {
|
||||
local filename="$1" result_variable="$2" target
|
||||
target="${SCRIPT_DIR}/${filename}"
|
||||
|
||||
if [[ -e "$target" ]]; then
|
||||
[[ -f "$target" && ! -L "$target" ]] \
|
||||
|| die "Отказ от запуска: $target должен быть обычным файлом"
|
||||
else
|
||||
command -v curl >/dev/null 2>&1 \
|
||||
|| die "Не найден curl: установите его командой apt-get install -y curl ca-certificates"
|
||||
[[ -d "$SCRIPT_DIR" && ! -L "$SCRIPT_DIR" && -w "$SCRIPT_DIR" ]] \
|
||||
|| die "Каталог $SCRIPT_DIR недоступен для безопасной загрузки"
|
||||
|
||||
log "Файл ${filename} отсутствует; загружаю его из основного репозитория"
|
||||
TEMP_FILE="$(mktemp "${SCRIPT_DIR}/.ochenstarik-server-download.XXXXXX")"
|
||||
chmod 600 "$TEMP_FILE"
|
||||
curl -fL --retry 5 --retry-delay 5 --connect-timeout 30 \
|
||||
--proto '=https' --tlsv1.2 "${REPO_RAW_BASE}/${filename}" -o "$TEMP_FILE"
|
||||
bash -n "$TEMP_FILE" || die "Загруженный файл ${filename} не прошёл проверку Bash"
|
||||
chmod 700 "$TEMP_FILE"
|
||||
mv -- "$TEMP_FILE" "$target"
|
||||
TEMP_FILE=""
|
||||
fi
|
||||
|
||||
chmod 700 "$target"
|
||||
bash -n "$target" || die "Синтаксическая ошибка в $target"
|
||||
printf -v "$result_variable" '%s' "$target"
|
||||
}
|
||||
|
||||
choose_step_action() {
|
||||
local step_number="$1" title="$2" result_variable="$3" answer
|
||||
while :; do
|
||||
printf '\n============================================================\n'
|
||||
printf 'Этап %s из %s: %s\n' "$step_number" "${#STEP_FILES[@]}" "$title"
|
||||
printf ' 1) Установить / запустить этот этап\n'
|
||||
printf ' 2) Пропустить и перейти к следующему\n'
|
||||
printf ' 3) Завершить мастер\n'
|
||||
read -rp 'Выберите действие: ' answer || die "Ввод прерван"
|
||||
case "$answer" in
|
||||
1|2|3) printf -v "$result_variable" '%s' "$answer"; return 0 ;;
|
||||
*) warn "Введите 1, 2 или 3" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
choose_after_failure() {
|
||||
local result_variable="$1" answer
|
||||
while :; do
|
||||
printf '\nЭтап завершился с ошибкой.\n'
|
||||
printf ' 1) Запустить этот этап повторно\n'
|
||||
printf ' 2) Пропустить и перейти к следующему\n'
|
||||
printf ' 3) Завершить мастер\n'
|
||||
read -rp 'Выберите действие: ' answer || die "Ввод прерван"
|
||||
case "$answer" in
|
||||
1|2|3) printf -v "$result_variable" '%s' "$answer"; return 0 ;;
|
||||
*) warn "Введите 1, 2 или 3" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
print_summary() {
|
||||
local completed="$1" skipped="$2"
|
||||
printf '\n============================================================\n'
|
||||
printf 'Мастер установки завершён.\n'
|
||||
printf 'Успешно выполнено этапов: %s\n' "$completed"
|
||||
printf 'Пропущено этапов: %s\n' "$skipped"
|
||||
printf '\nМастер можно запустить повторно: каждый этап поддерживает повторную настройку.\n'
|
||||
printf 'Для полного сброса используйте ochenstarik-server-uninstall.sh.\n'
|
||||
}
|
||||
|
||||
[[ "$EUID" -eq 0 ]] || die "Запустите мастер от имени root: sudo ./ochenstarik-server-install.sh"
|
||||
((${#STEP_FILES[@]} == ${#STEP_TITLES[@]})) || die "Некорректное описание этапов"
|
||||
|
||||
cat <<'INTRO'
|
||||
|
||||
Единый мастер установки lightweight-server
|
||||
|
||||
Этапы будут показаны по порядку. Каждый из них можно выполнить, пропустить
|
||||
или завершить весь мастер. Не закрывайте текущую SSH-сессию во время изменения
|
||||
порта SSH и проверяйте новый вход во втором терминале.
|
||||
INTRO
|
||||
|
||||
completed=0
|
||||
skipped=0
|
||||
|
||||
for index in "${!STEP_FILES[@]}"; do
|
||||
step_number="$((index + 1))"
|
||||
action=""
|
||||
choose_step_action "$step_number" "${STEP_TITLES[index]}" action
|
||||
case "$action" in
|
||||
2)
|
||||
skipped="$((skipped + 1))"
|
||||
continue
|
||||
;;
|
||||
3)
|
||||
print_summary "$completed" "$skipped"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
script_path=""
|
||||
ensure_step_script "${STEP_FILES[index]}" script_path
|
||||
while :; do
|
||||
log "Запуск этапа ${step_number}: ${STEP_TITLES[index]}"
|
||||
if bash -- "$script_path"; then
|
||||
completed="$((completed + 1))"
|
||||
log "Этап ${step_number} успешно завершён"
|
||||
break
|
||||
fi
|
||||
|
||||
warn "Этап ${step_number} вернул ошибку"
|
||||
failure_action=""
|
||||
choose_after_failure failure_action
|
||||
case "$failure_action" in
|
||||
1) continue ;;
|
||||
2) skipped="$((skipped + 1))"; break ;;
|
||||
3) print_summary "$completed" "$skipped"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
|
||||
print_summary "$completed" "$skipped"
|
||||
Loading…
Reference in a new issue