#!/bin/sh # ============================================================================= # Void Linux + Labwc + SDDM installer # # Запуск: # sudo sh void-labwc-install.sh # # Цель: # - Wayland # - Labwc # - SDDM # - seatd # - elogind # - D-Bus # - PipeWire/WirePlumber в пользовательской сессии # # ВАЖНО: # Скрипт НЕ устанавливает NVIDIA-драйвер автоматически. # Драйвер GPU лучше определить отдельно. # ============================================================================= 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 } run() { "$@" || error "Команда завершилась с ошибкой: $*" } # ============================================================================= # Проверка 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_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 + Labwc + SDDM installer" echo "============================================================" echo "" echo "Пользователь: $REAL_USER" echo "HOME: $USER_HOME" echo "" # ============================================================================= # ЭТАП 1. Репозитории # ============================================================================= log "Этап 1/7: настройка репозиториев..." if ! xbps-query -Rs '^void-repo-nonfree$' 2>/dev/null | grep -q void-repo-nonfree; then xbps-install -Sy void-repo-nonfree || \ warn "Не удалось установить void-repo-nonfree." else log "void-repo-nonfree уже доступен." fi # ============================================================================= # ЭТАП 2. Обновление системы # ============================================================================= log "Этап 2/7: обновление системы..." run xbps-install -Syu # ============================================================================= # ЭТАП 3. Основные пакеты # ============================================================================= log "Этап 3/7: установка графического стека..." PACKAGES=" labwc sddm seatd elogind dbus xorg-minimal xorg-server-xwayland mesa-dri waybar swaylock swayidle swaybg mako wofi wl-clipboard cliphist grim slurp xdg-desktop-portal xdg-desktop-portal-wlr xdg-desktop-portal-gtk pipewire wireplumber alsa-pipewire polkit polkit-gnome qt5-wayland qt6-wayland qt5ct qt6ct dolphin kate firefox kitty mpv ristretto pavucontrol easyeffects gparted htop qdirstat curl wget tar unar unzip zip p7zip nodejs npm ffmpeg libnotify xdg-utils fuse fuse-common ca-certificates fontconfig noto-fonts-ttf ttf-dejavu ttf-jetbrains-mono ttf-font-awesome breeze-icons adwaita-icon-theme linux-firmware " # Установка по одному. # # Это специально сделано вместо одного xargs: # если один необязательный пакет отсутствует в репозитории, # это не должно ломать весь графический стек. for pkg in $PACKAGES; do if xbps-query -Rs "^${pkg}$" 2>/dev/null | grep -q "$pkg"; then if xbps-query -p pkgver "$pkg" >/dev/null 2>&1; then log "Уже установлен: $pkg" else info "Устанавливаю: $pkg" xbps-install -y "$pkg" || warn "Не удалось установить $pkg" fi else warn "Пакет отсутствует в репозиториях: $pkg" fi done # ============================================================================= # ЭТАП 4. Пользователь и группы # ============================================================================= log "Этап 4/7: настройка пользователя..." # seatd if getent group _seatd >/dev/null 2>&1; then usermod -aG _seatd "$REAL_USER" log "$REAL_USER добавлен в группу _seatd" else warn "Группа _seatd не найдена." fi # audio if getent group audio >/dev/null 2>&1; then usermod -aG audio "$REAL_USER" log "$REAL_USER добавлен в группу audio" fi # video if getent group video >/dev/null 2>&1; then usermod -aG video "$REAL_USER" log "$REAL_USER добавлен в группу video" fi # wheel if getent group wheel >/dev/null 2>&1; then usermod -aG wheel "$REAL_USER" log "$REAL_USER добавлен в группу wheel" fi # ============================================================================= # ЭТАП 5. Системные сервисы # ============================================================================= log "Этап 5/7: настройка 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" } # Системный D-Bus enable_service dbus # Seat management для wlroots/Labwc enable_service seatd # Session management / XDG_RUNTIME_DIR enable_service elogind # Display manager enable_service sddm # НЕ включаем: # # pipewire # wireplumber # # Они должны работать в пользовательской графической сессии, # а не как обычные system-wide runit services. # ============================================================================= # ЭТАП 6. Wayland session для SDDM # ============================================================================= log "Этап 6/7: настройка Labwc + SDDM..." mkdir -p /usr/share/wayland-sessions SESSION_FILE="/usr/share/wayland-sessions/labwc.desktop" cat > "$SESSION_FILE" << 'EOF' [Desktop Entry] Name=Labwc Comment=Wayland window-stacking compositor Exec=labwc Type=Application DesktopNames=labwc EOF chmod 644 "$SESSION_FILE" log "Создана SDDM-сессия: $SESSION_FILE" # ============================================================================= # SDDM configuration # ============================================================================= mkdir -p /etc/sddm.conf.d cat > /etc/sddm.conf.d/10-wayland.conf << 'EOF' [General] DisplayServer=wayland [Wayland] SessionDir=/usr/share/wayland-sessions EOF log "SDDM настроен на Wayland." # ============================================================================= # PipeWire ALSA # ============================================================================= if [ -d /usr/share/alsa/alsa.conf.d ]; then 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 настроен." fi # ============================================================================= # Пользовательский Labwc config # ============================================================================= USER_CONFIG="$USER_HOME/.config/labwc" if [ ! -d "$USER_CONFIG" ]; then mkdir -p "$USER_CONFIG" chown -R "$REAL_USER":"$(id -gn "$REAL_USER")" \ "$USER_HOME/.config" log "Создан $USER_CONFIG" else log "$USER_CONFIG уже существует." fi # ============================================================================= # Минимальный autostart # ============================================================================= AUTOSTART="$USER_CONFIG/autostart" if [ ! -f "$AUTOSTART" ]; then cat > "$AUTOSTART" << 'EOF' #!/bin/sh # Waybar waybar & # Notification daemon mako & # PolicyKit authentication agent if command -v /usr/libexec/polkit-gnome-authentication-agent-1 >/dev/null 2>&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 # PipeWire / WirePlumber # Они обычно активируются через user/session environment. EOF chmod +x "$AUTOSTART" chown "$REAL_USER":"$(id -gn "$REAL_USER")" "$AUTOSTART" log "Создан минимальный Labwc autostart." else log "Существующий autostart не изменён." fi # ============================================================================= # Права на конфигурацию # ============================================================================= chown -R "$REAL_USER":"$(id -gn "$REAL_USER")" \ "$USER_HOME/.config" # ============================================================================= # НЕ устанавливаем NVIDIA автоматически # ============================================================================= echo "" info "Проверяем GPU..." if command -v lspci >/dev/null 2>&1; then GPU="$(lspci | grep -Ei 'VGA|3D|Display' || true)" if [ -n "$GPU" ]; then echo "$GPU" echo "" case "$GPU" in *NVIDIA*) warn "Обнаружена NVIDIA." warn "NVIDIA-драйвер НЕ устанавливался автоматически." warn "Сначала определите поколение GPU." ;; *AMD*) log "Обнаружена AMD GPU." ;; *Intel*) log "Обнаружена Intel GPU." ;; *) info "GPU не удалось определить автоматически." ;; esac else warn "GPU через lspci определить не удалось." fi else warn "lspci отсутствует." fi # ============================================================================= # Проверка сервисов # ============================================================================= log "Этап 7/7: проверка сервисов..." sleep 2 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: включён, но НЕ RUNNING" sv status "$svc" 2>&1 || true fi } check_service dbus check_service seatd check_service elogind check_service sddm # ============================================================================= # Проверка Labwc # ============================================================================= echo "" info "Проверка установки Labwc..." if command -v labwc >/dev/null 2>&1; then log "labwc найден: $(command -v labwc)" else warn "Команда labwc не найдена." fi if command -v sddm >/dev/null 2>&1; then log "sddm найден: $(command -v sddm)" else warn "Команда sddm не найдена." fi # ============================================================================= # Проверка Wayland session # ============================================================================= if [ -f "$SESSION_FILE" ]; then log "Wayland session существует: $SESSION_FILE" else warn "Wayland session НЕ найдена." fi # ============================================================================= # Финальная информация # ============================================================================= echo "" echo "============================================================" printf "${GREEN}Установка завершена.${NC}\n" echo "============================================================" echo "" echo "Сервисы:" echo " dbus: /var/service/dbus" echo " seatd: /var/service/seatd" echo " elogind: /var/service/elogind" echo " sddm: /var/service/sddm" echo "" echo "Labwc session:" echo " $SESSION_FILE" echo "" echo "Конфигурация:" echo " $USER_CONFIG" echo "" echo "============================================================" echo " ВАЖНО" echo "============================================================" echo "" echo "1. Перезагрузите компьютер:" echo "" echo " reboot" echo "" echo "2. После перезагрузки должен появиться SDDM." echo "" echo "3. В SDDM выберите:" echo "" echo " Labwc" echo "" echo "4. Если SDDM НЕ появился, войдите в 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 "5. Логи SDDM:" echo "" echo " sudo sv status sddm" echo " sudo tail -100 /var/log/sddm/current" echo "" echo "6. Проверка GPU:" echo "" echo " lspci -k -d ::03xx" echo "" echo "============================================================"