Files

735 lines
19 KiB
Bash
Raw Permalink Normal View History

2026-09-02 14:57:47 +06:00
#!/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 ""