#!/bin/sh # ============================================================================= # Void Linux + SDDM + Labwc # ============================================================================= # # Целевая схема: # # BIOS/UEFI # | # v # runit # | # +---- dbus # | # +---- seatd # | # +---- elogind # | # +---- sddm # | # +---- Xorg # | # v # SDDM # | # v # Labwc (Wayland) # # Подходит для: # - чистой установки Void Linux # - KVM/QEMU + QXL # - KVM/QEMU + VirtIO GPU # - Intel # - AMD # # NVIDIA намеренно НЕ настраивается автоматически. # # Запуск: # # sudo sh void-labwc-install.sh # # ============================================================================= set -eu # ============================================================================= # Цвета / вывод # ============================================================================= RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log() { printf "${GREEN}[✓]${NC} %s\n" "$1" } info() { printf "${BLUE}[i]${NC} %s\n" "$1" } warn() { printf "${YELLOW}[!]${NC} %s\n" "$1" } error() { printf "${RED}[✗]${NC} %s\n" "$1" exit 1 } # ============================================================================= # Проверка root # ============================================================================= if [ "$(id -u)" -ne 0 ]; then error "Скрипт необходимо запускать через sudo: sudo sh $0" fi # ============================================================================= # Определение обычного пользователя # ============================================================================= REAL_USER="${SUDO_USER:-}" if [ -z "$REAL_USER" ] || [ "$REAL_USER" = "root" ]; then error "Не удалось определить обычного пользователя. Запусти скрипт так: sudo sh $0 а не из root shell." fi if ! id "$REAL_USER" >/dev/null 2>&1; then error "Пользователь '$REAL_USER' не существует." fi USER_UID="$(id -u "$REAL_USER")" USER_GID="$(id -g "$REAL_USER")" USER_GROUP="$(id -gn "$REAL_USER")" USER_HOME="$(getent passwd "$REAL_USER" | cut -d: -f6)" if [ -z "$USER_HOME" ] || [ ! -d "$USER_HOME" ]; then error "Не удалось определить HOME пользователя '$REAL_USER'." fi echo "" echo "============================================================" echo " Void Linux + SDDM + Labwc installer" echo "============================================================" echo "" echo "Пользователь : $REAL_USER" echo "UID : $USER_UID" echo "HOME : $USER_HOME" echo "" # ============================================================================= # Проверка архитектуры # ============================================================================= info "Архитектура системы: $(uname -m)" # ============================================================================= # ЭТАП 1 — Репозитории # ============================================================================= echo "" log "Этап 1/8: настройка репозиториев..." # Nonfree нужен для части firmware/драйверов и некоторых пакетов. if xbps-query -Rs '^void-repo-nonfree$' 2>/dev/null | \ grep -q 'void-repo-nonfree'; then log "void-repo-nonfree доступен." else info "Устанавливаю void-repo-nonfree..." xbps-install -Sy void-repo-nonfree fi # ============================================================================= # ЭТАП 2 — Обновление системы # ============================================================================= echo "" log "Этап 2/8: обновление системы..." xbps-install -Syu # ============================================================================= # ЭТАП 3 — Базовые пакеты # ============================================================================= echo "" log "Этап 3/8: установка базовой системы..." BASE_PACKAGES=" base-system dbus elogind seatd sudo ca-certificates curl wget tar unzip zip p7zip unar fuse fuse-common xdg-utils " for pkg in $BASE_PACKAGES; do info "Установка: $pkg" xbps-install -y "$pkg" || warn "Не удалось установить $pkg" done # ============================================================================= # ЭТАП 4 — Графический стек # ============================================================================= echo "" log "Этап 4/8: установка графического стека..." GRAPHICS_PACKAGES=" xorg xorg-server-xwayland mesa-dri sddm labwc waybar wofi mako swaylock swayidle swaybg wl-clipboard cliphist grim slurp xdg-desktop-portal xdg-desktop-portal-wlr xdg-desktop-portal-gtk polkit polkit-gnome qt5-wayland qt6-wayland qt5ct qt6ct pipewire wireplumber alsa-pipewire fontconfig noto-fonts-ttf ttf-dejavu ttf-jetbrains-mono ttf-font-awesome breeze-icons adwaita-icon-theme linux-firmware " for pkg in $GRAPHICS_PACKAGES; do info "Установка: $pkg" xbps-install -y "$pkg" || warn "Не удалось установить $pkg" done # ============================================================================= # QXL / KVM # ============================================================================= echo "" info "Проверка виртуальной/физической видеокарты..." if command -v lspci >/dev/null 2>&1; then GPU_INFO="$(lspci | grep -Ei 'VGA|3D|Display' || true)" if [ -n "$GPU_INFO" ]; then echo "" echo "$GPU_INFO" echo "" case "$GPU_INFO" in *QXL*|*Red\ Hat*QXL*) info "Обнаружена QXL GPU — устанавливаю Xorg QXL driver." xbps-install -y xf86-video-qxl || \ warn "xf86-video-qxl недоступен." ;; *Virtio*) info "Обнаружена VirtIO GPU." ;; *AMD*|*ATI*|*Radeon*) info "Обнаружена AMD/ATI GPU." ;; *Intel*) info "Обнаружена Intel GPU." ;; *NVIDIA*) warn "Обнаружена NVIDIA GPU." warn "NVIDIA driver намеренно НЕ устанавливается автоматически." ;; *) info "Неизвестный GPU — используются Mesa/Xorg по умолчанию." ;; esac else warn "Не удалось определить GPU через lspci." fi else warn "lspci не найден." fi # ============================================================================= # Дополнительные пользовательские приложения # ============================================================================= echo "" log "Установка пользовательских приложений..." OPTIONAL_PACKAGES=" dolphin kate firefox kitty mpv ristretto pavucontrol easyeffects gparted htop qdirstat ffmpeg libnotify nodejs npm " for pkg in $OPTIONAL_PACKAGES; do info "Установка: $pkg" xbps-install -y "$pkg" || warn "Пропущен пакет: $pkg" done # ============================================================================= # ЭТАП 5 — Пользовательские группы # ============================================================================= echo "" log "Этап 5/8: настройка групп пользователя..." add_group() { group="$1" if getent group "$group" >/dev/null 2>&1; then usermod -aG "$group" "$REAL_USER" log "$REAL_USER -> $group" else warn "Группа '$group' отсутствует." fi } add_group "_seatd" add_group "audio" add_group "video" add_group "wheel" # ============================================================================= # ЭТАП 6 — Runit services # ============================================================================= echo "" log "Этап 6/8: настройка системных сервисов runit..." enable_service() { svc="$1" if [ ! -d "/etc/sv/$svc" ]; then warn "Сервис отсутствует: /etc/sv/$svc" return 0 fi if [ -L "/var/service/$svc" ]; then log "Уже включён: $svc" return 0 fi ln -s "/etc/sv/$svc" "/var/service/$svc" log "Включён: $svc" } enable_service dbus enable_service seatd enable_service elogind enable_service sddm # ============================================================================= # ВАЖНО: # # НЕ включаем: # # pipewire # wireplumber # # как system-wide runit services. # # Они должны работать в пользовательской сессии. # ============================================================================= if [ -L "/var/service/pipewire" ]; then warn "Обнаружен system-wide pipewire service." warn "Отключаю его — PipeWire будет работать в user session." rm -f /var/service/pipewire fi if [ -L "/var/service/wireplumber" ]; then warn "Обнаружен system-wide wireplumber service." warn "Отключаю его — WirePlumber будет работать в user session." rm -f /var/service/wireplumber fi # ============================================================================= # elogind vs acpid # ============================================================================= # # elogind сам занимается session/power management. # Поэтому не включаем acpid. # ============================================================================= if [ -L "/var/service/acpid" ]; then warn "Отключаю acpid, поскольку используется elogind." rm -f /var/service/acpid fi # ============================================================================= # ЭТАП 7 — SDDM # ============================================================================= echo "" log "Этап 7/8: настройка SDDM..." mkdir -p /etc/sddm.conf.d # ------------------------------------------------------------------------- # ВАЖНО: # # НЕ заставляем SDDM работать как Wayland compositor. # # SDDM использует Xorg для своего login screen. # # После авторизации SDDM запускает Labwc как Wayland session. # ------------------------------------------------------------------------- rm -f /etc/sddm.conf.d/10-wayland.conf cat > /etc/sddm.conf.d/10-display.conf << 'EOF' [General] DisplayServer=x11 EOF log "SDDM настроен на X11/Xorg." # ============================================================================= # Labwc Wayland session # ============================================================================= mkdir -p /usr/share/wayland-sessions cat > /usr/share/wayland-sessions/labwc.desktop << 'EOF' [Desktop Entry] Name=Labwc Comment=Wayland window-stacking compositor Exec=labwc Type=Application DesktopNames=labwc EOF chmod 644 /usr/share/wayland-sessions/labwc.desktop log "Создана Wayland-сессия Labwc." # ============================================================================= # SDDM autologin НЕ включаем. # ============================================================================= # Пользователь сам выбирает Labwc на экране SDDM. # ============================================================================= # ЭТАП 8 — Labwc config # ============================================================================= echo "" log "Этап 8/8: создание базовой конфигурации Labwc..." LABWC_DIR="$USER_HOME/.config/labwc" mkdir -p "$LABWC_DIR" # ------------------------------------------------------------------------- # autostart # ------------------------------------------------------------------------- AUTOSTART="$LABWC_DIR/autostart" if [ ! -f "$AUTOSTART" ]; then cat > "$AUTOSTART" << 'EOF' #!/bin/sh # --------------------------------------------------------- # Labwc autostart # --------------------------------------------------------- # Waybar if command -v waybar >/dev/null 2>&1; then waybar & fi # Notification daemon if command -v mako >/dev/null 2>&1; then mako & fi # PolicyKit authentication agent if [ -x /usr/libexec/polkit-gnome-authentication-agent-1 ]; then /usr/libexec/polkit-gnome-authentication-agent-1 & elif command -v polkit-gnome-authentication-agent-1 >/dev/null 2>&1; then polkit-gnome-authentication-agent-1 & fi EOF chmod +x "$AUTOSTART" log "Создан Labwc autostart." else info "Существующий Labwc autostart не изменён." fi # ============================================================================= # ALSA / PipeWire # ============================================================================= info "Настройка ALSA → PipeWire..." mkdir -p /etc/alsa/conf.d if [ -f /usr/share/alsa/alsa.conf.d/50-pipewire.conf ]; then ln -sf \ /usr/share/alsa/alsa.conf.d/50-pipewire.conf \ /etc/alsa/conf.d/50-pipewire.conf fi if [ -f /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf ]; then ln -sf \ /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf \ /etc/alsa/conf.d/99-pipewire-default.conf fi log "ALSA/PipeWire настроен." # ============================================================================= # Права пользователя # ============================================================================= chown -R "$REAL_USER":"$USER_GROUP" \ "$USER_HOME/.config" # ============================================================================= # Проверка установки # ============================================================================= echo "" log "Проверка установленного ПО..." check_command() { cmd="$1" if command -v "$cmd" >/dev/null 2>&1; then log "$cmd: $(command -v "$cmd")" else warn "$cmd: НЕ НАЙДЕН" fi } check_command labwc check_command sddm check_command Xorg check_command dbus-run-session check_command pipewire check_command wireplumber # ============================================================================= # Проверка session file # ============================================================================= if [ -f /usr/share/wayland-sessions/labwc.desktop ]; then log "Labwc session file: OK" else warn "Labwc session file отсутствует!" fi # ============================================================================= # Ожидание запуска runit services # ============================================================================= echo "" info "Ожидание запуска сервисов..." sleep 3 # ============================================================================= # Проверка сервисов # ============================================================================= check_service() { svc="$1" if [ ! -L "/var/service/$svc" ]; then warn "$svc: НЕ ВКЛЮЧЁН" return 0 fi if sv status "$svc" 2>/dev/null | grep -q '^run:'; then log "$svc: RUNNING" else warn "$svc: НЕ ЗАПУЩЕН" sv status "$svc" 2>&1 || true fi } echo "" info "Статус системных сервисов:" check_service dbus check_service seatd check_service elogind check_service sddm # ============================================================================= # Проверка Xorg # ============================================================================= echo "" info "Проверка Xorg..." if [ -x /usr/bin/X ]; then log "Xorg найден: /usr/bin/X" else warn "Xorg /usr/bin/X не найден!" fi # ============================================================================= # Финальная информация # ============================================================================= echo "" echo "============================================================" printf "${GREEN}✓ УСТАНОВКА ЗАВЕРШЕНА${NC}\n" echo "============================================================" echo "" echo "Архитектура:" echo " SDDM -> Xorg" echo " SDDM -> Labwc" echo " Labwc -> Wayland" echo "" echo "Сервисы:" echo " dbus" echo " seatd" echo " elogind" echo " sddm" echo "" echo "Labwc:" echo " $LABWC_DIR" echo "" echo "SDDM session:" echo " /usr/share/wayland-sessions/labwc.desktop" echo "" echo "============================================================" echo " ЧТО ДЕЛАТЬ ДАЛЬШЕ" echo "============================================================" echo "" echo "1. Перезагрузиться:" echo "" echo " sudo reboot" echo "" echo "2. Дождаться экрана SDDM." echo "" echo "3. Выбрать сессию:" echo "" echo " Labwc" echo "" echo "4. Войти под пользователем:" echo "" echo " $REAL_USER" echo "" echo "============================================================" echo " ЕСЛИ ЧТО-ТО НЕ ЗАПУСТИЛОСЬ" echo "============================================================" echo "" echo "Перейти в TTY:" echo "" echo " Ctrl + Alt + F2" echo "" echo "Проверить сервисы:" echo "" echo " sudo sv status dbus" echo " sudo sv status seatd" echo " sudo sv status elogind" echo " sudo sv status sddm" echo "" echo "Проверить SDDM:" echo "" echo " ps aux | grep -E 'sddm|Xorg' | grep -v grep" echo "" echo "Проверить Xorg:" echo "" echo " sudo tail -100 /var/log/Xorg.0.log" echo "" echo "Проверить GPU:" echo "" echo " lspci -k -d ::03xx" echo "" echo "Проверить XDG_RUNTIME_DIR после входа:" echo "" echo " echo \"\$XDG_RUNTIME_DIR\"" echo "" echo "============================================================" echo "" warn "После добавления пользователя в группы требуется новая" warn "login-сессия. Поэтому после установки ОБЯЗАТЕЛЬНО reboot." echo ""