#!/usr/bin/env bash # Minimal KVM + Cockpit setup for RHEL-family 8/9 (Alma/RHEL/Rocky/CentOS Stream) # Run as root GREEN='\033[0;32m' YELLOW='\033[0;33m' RED='\033[0;31m' GRAY='\033[0;37m' NC='\033[0m' echo # 1) Проверка принадлежности к семейству RHEL if [[ -f /etc/redhat-release ]] || grep -q 'ID_LIKE=.*rhel' /etc/os-release 2>/dev/null; then : else echo -e "${RED}Система НЕ относится к семейству RHEL. Выходим.${NC}" exit 1 fi # 2) Проверка версии (>=8) source /etc/os-release if [[ "${VERSION_ID%%.*}" -lt 8 ]]; then echo -e "${RED}Требуется RHEL-семейство версии 8 или старше. Обнаружено: ${VERSION_ID}.${NC}" exit 1 fi # 3) Проверка root if [[ $EUID -ne 0 ]]; then echo -e "${RED}Запусти скрипт от root (sudo).${NC}" exit 1 fi echo -e "${GRAY}Обновляю систему перед установкой...${NC}" dnf -y update echo -e "${GRAY}Обновляю метаданные DNF...${NC}" dnf -y makecache # 4) Установка необходимых пакетов echo -e "${GRAY}Устанавливаю KVM, libvirt и Cockpit...${NC}" dnf -y install \ qemu-kvm qemu-img \ libvirt libvirt-daemon libvirt-daemon-config-network libvirt-client \ virt-install virt-viewer \ NetworkManager-wifi \ cockpit cockpit-machines cockpit-storaged # 5) Включение и запуск служб echo -e "${GRAY}Включаю и запускаю libvirtd и cockpit.socket...${NC}" systemctl enable --now libvirtd systemctl enable --now cockpit.socket # 6) Открытие порта Cockpit if systemctl is-active --quiet firewalld; then if ! firewall-cmd --list-services --permanent | grep -qw cockpit; then echo -e "${GRAY}Открываю доступ к Cockpit в firewalld...${NC}" firewall-cmd --add-service=cockpit --permanent firewall-cmd --reload else echo -e "${GRAY}Порт Cockpit уже открыт в firewalld. Пропускаю.${NC}" fi fi # 7) Проверка готовности KVM if command -v virt-host-validate &>/dev/null; then echo echo -e "${GRAY}Проверяю готовность хоста к KVM...${NC}" virt-host-validate fi dnf -y install epel-release dnf -y install mc wget htop yum-utils echo -e "${GRAY}Проверяю наличие пользователей в группе wheel...${NC}" # Получаем GID группы wheel WHEEL_GID=$(getent group wheel | awk -F: '{print $3}') wheel_users=$( { getent group wheel | awk -F: '{print $4}' | tr ',' '\n'; \ getent passwd | awk -F: -v gid="$WHEEL_GID" '$4==gid{print $1}'; } \ | awk 'NF' | sort -u ) if [[ -z "$wheel_users" ]]; then echo "В группе wheel нет ни одного пользователя (root не считается)." echo -e "Создаю пользователя ${YELLOW}user${NC} для входа в Cockpit и управления через sudo." if ! id user &>/dev/null; then useradd -m -G wheel user else echo -e "Пользователь ${YELLOW}user${NC} уже существует. Добавляю его в группу wheel." usermod -aG wheel user fi # Проверяем, есть ли TTY (интерактивный терминал) if [[ -t 0 ]]; then echo -e "Введите пароль для пользователя ${YELLOW}user${NC}:" if passwd user; then echo "Пароль успешно установлен." else echo -e "Не удалось установить ${RED}пароль${NC}. Установите вручную командой: ${YELLOW}passwd user${NC}" fi else NEWPASS=$(openssl rand -base64 12) echo "user:${NEWPASS}" | chpasswd echo "Пароль не мог быть введён интерактивно и был сгенерирован." echo -e "Для входа в Cockpit используйте логин ${YELLOW}user${NC} и пароль: ${GREEN}${NEWPASS}${NC}" fi else echo "В группе wheel уже есть пользователи. Пропускаю." fi # 8) Финальное сообщение echo echo -e "${GREEN}Готово!${NC}" # 1) Пытаемся получить исходящий IPv4 через дефолтный маршрут SERVER_IP=$(ip -4 route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}') # 2) Фоллбэк: берём первый доступный IP (кроме 127.0.0.1) [[ -z "$SERVER_IP" ]] && SERVER_IP=$(hostname -I 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i!="127.0.0.1") {print $i; exit}}') # 3) Финальный фоллбэк [[ -z "$SERVER_IP" ]] && SERVER_IP="127.0.0.1" # Если вдруг попался IPv6, обернём в [] HOST_FOR_URL="$SERVER_IP" [[ "$SERVER_IP" == *:* ]] && HOST_FOR_URL="[${SERVER_IP}]" echo -e "• Адрес для входа в панель управления: ${GREEN}https://${HOST_FOR_URL}:9090/${NC}" echo -e "• Разделы Cockpit: «Виртуальные машины» и «Хранилища» готовы." echo -e "• Wi-Fi управление доступно (NetworkManager-wifi установлен)." echo -e "Перед началом использования перезагрузите сервер командой ${GREEN}reboot${NC}."