#!/usr/bin/env bash # scripts/install/client.sh - install and setup all client related apps and environments set -euo pipefail ORIG_USER=${SUDO_USER:-$(id -un)} REF=${LESAVKA_REF:-master} SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) SCRIPT_REPO_ROOT=$(cd -- "$SCRIPT_DIR/../.." && pwd) DEFAULT_REPO_URL=ssh://git@scm.bstein.dev:2242/bstein/lesavka.git REPO_URL=${LESAVKA_REPO_URL:-} SRC=/var/src/lesavka export TMPDIR=${TMPDIR:-/var/tmp} USER_HOME=$(getent passwd "$ORIG_USER" | cut -d: -f6) log() { printf '==> %s\n' "$*" } require_command() { local cmd=$1 local pkg_hint=$2 if command -v "$cmd" >/dev/null 2>&1; then return 0 fi echo "❌ required command '$cmd' is unavailable after install (expected via $pkg_hint)" >&2 exit 1 } run_as_user() { sudo -u "$ORIG_USER" env HOME="$USER_HOME" SSH_AUTH_SOCK="${SSH_AUTH_SOCK:-}" "$@" } mkdir -p "$TMPDIR" if [[ -z $REPO_URL ]] && [[ -d $SCRIPT_REPO_ROOT/.git ]]; then REPO_URL=$(git -C "$SCRIPT_REPO_ROOT" config --get remote.origin.url || true) fi REPO_URL=${REPO_URL:-$DEFAULT_REPO_URL} log "1. Installing base packages" # Intentionally leave the host audio stack alone. Workstations often carry # tightly versioned PipeWire packages, and Lesavka should not force an audio # stack upgrade just to install the client. sudo pacman -Sq --needed --noconfirm \ git rustup protobuf abseil-cpp gcc clang evtest base-devel libpulse \ gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav \ wmctrl qt6-tools wl-clipboard xclip xsel desktop-file-utils ensure_yay() { if command -v yay >/dev/null 2>&1; then if run_as_user yay --version >/dev/null 2>&1; then return fi fi run_as_user env TMPDIR="$TMPDIR" bash -c 'rm -rf "$TMPDIR/yay" && cd "$TMPDIR" && git clone --depth 1 https://aur.archlinux.org/yay.git && cd yay && makepkg -si --noconfirm' } log "1b. Installing grpcurl" if sudo pacman -Si grpcurl >/dev/null 2>&1; then sudo pacman -Sq --needed --noconfirm grpcurl else ensure_yay if ! run_as_user yay -S --needed --noconfirm grpcurl-bin; then log "grpcurl AUR install failed once, rebuilding yay and retrying" ensure_yay run_as_user yay -S --needed --noconfirm grpcurl-bin fi fi # 1c. input access log "1c. Ensuring input group access for $ORIG_USER" sudo usermod -aG input "$ORIG_USER" log "1d. Verifying runtime tools" require_command pactl "libpulse" require_command wmctrl "wmctrl" require_command qdbus6 "qt6-tools" if ! command -v wl-paste >/dev/null 2>&1 \ && ! command -v xclip >/dev/null 2>&1 \ && ! command -v xsel >/dev/null 2>&1; then echo "❌ no clipboard reader found after install (expected one of wl-clipboard/xclip/xsel)" >&2 exit 1 fi if ! run_as_user pactl info >/dev/null 2>&1; then echo "⚠️ pactl is installed, but no PulseAudio/PipeWire Pulse server is reachable right now." echo " Lesavka will still install, but local speaker/mic staging may stay empty until the host audio session is up." fi # 2. Rust tool-chain for both root & user log "2. Ensuring Rust toolchain" sudo rustup default stable run_as_user rustup default stable # 3. clone / update into a canonical workspace checkout log "3. Syncing source checkout for ref ${REF}" if [[ ! -d /var/src ]]; then sudo mkdir -p /var/src fi sudo chown "$ORIG_USER":"$ORIG_USER" /var/src if [[ -d $SRC/.git ]]; then run_as_user git -C "$SRC" fetch --all --tags --prune else run_as_user git clone "$REPO_URL" "$SRC" fi if run_as_user git -C "$SRC" rev-parse --verify --quiet "origin/$REF" >/dev/null; then run_as_user git -C "$SRC" checkout -B "$REF" "origin/$REF" else run_as_user git -C "$SRC" checkout --force "$REF" fi # 4. build log "4. Building client release binary" run_as_user env TMPDIR="$TMPDIR" bash -c "cd '$SRC/client' && cargo clean && cargo build --release" # 5. install binary log "5. Installing launchable client binaries" sudo install -Dm755 "$SRC/target/release/lesavka-client" /usr/local/bin/lesavka-client sudo ln -sf /usr/local/bin/lesavka-client /usr/local/bin/lesavka log "6. Registering desktop application" sudo install -Dm644 "$SRC/client/assets/icons/hicolor/1024x1024/apps/lesavka.png" \ /usr/share/icons/hicolor/1024x1024/apps/lesavka.png sudo install -Dm644 "$SRC/client/assets/icons/hicolor/1024x1024/apps/lesavka.png" \ /usr/share/pixmaps/lesavka.png sudo install -Dm644 "$SRC/client/assets/linux/lesavka.desktop" \ /usr/share/applications/lesavka.desktop if command -v update-desktop-database >/dev/null 2>&1; then sudo update-desktop-database /usr/share/applications fi if command -v gtk-update-icon-cache >/dev/null 2>&1; then sudo gtk-update-icon-cache -f /usr/share/icons/hicolor >/dev/null 2>&1 || true fi log "7. Removing legacy auto-start service" sudo systemctl disable --now lesavka-client.service >/dev/null 2>&1 || true sudo rm -f /etc/systemd/system/lesavka-client.service sudo systemctl daemon-reload echo echo "✅ lesavka-client install complete" echo " Binary: /usr/local/bin/lesavka-client" echo " Launch alias: /usr/local/bin/lesavka" echo " Desktop entry: /usr/share/applications/lesavka.desktop" echo " Build source: $SRC/target/release/lesavka-client" echo echo "Quick start:" echo " KDE menu: search for Lesavka" echo " Terminal: /usr/local/bin/lesavka"