From 70be3f8f14e1e74fc6a32dddd232c024f9ba138b Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 23:32:40 +0000 Subject: [PATCH] refactor: improve and document all modules and Readme.md This is a major refactoring and documentation effort that touches every module in the project. - **Exhaustive In-Code Documentation:** Every module script in the `modules/` directory has been updated with detailed comments. This includes header descriptions, explanations for each function, and justifications for complex logic. This greatly improves the maintainability and readability of the code. - **Code Robustness and Optimization:** Several modules have been refactored to be more robust and efficient. This includes: - Optimizing package installations by grouping them into a single `pacman` command. - Improving dependency checks. - Standardizing the use of helper functions from `common.sh`. - Making network operations more resilient. - **Comprehensive `Readme.md` Update:** The main `Readme.md` has been rewritten to be a complete and professional guide to the project. It now includes: - A clear and detailed description of each module. - Information on what each module installs and how it works. - Instructions for installing the required Nerd Font for `oh-my-posh`. - An updated structure that is easier to navigate. --- Readme.md | 836 ++++++------------------------------- modules/apps.sh | 166 ++++++-- modules/common.sh | 118 +++++- modules/davinci-resolve.sh | 120 +++--- modules/disk-format.sh | 34 +- modules/docker.sh | 86 ++-- modules/hyprland-config.sh | 66 +-- modules/icon_manager.sh | 84 ++-- modules/mouse_cursor.sh | 132 ++++-- modules/printer.sh | 77 ++-- modules/ssh-keyring.sh | 97 +++-- modules/zerotier.sh | 53 ++- modules/zsh-config.sh | 271 ++++++------ omarchy-setup.sh | 33 +- 14 files changed, 986 insertions(+), 1187 deletions(-) diff --git a/Readme.md b/Readme.md index b60fbe4..f866aa7 100644 --- a/Readme.md +++ b/Readme.md @@ -1,747 +1,187 @@ -# 🚀 Omarchy Setup Script v3.0.0 +# 🚀 Omarchy Setup Script Script de instalación y configuración **modular** para **Arch Linux / Omarchy** con menú interactivo. ## 🎯 Características Principales -- **✅ Estructura Modular**: Scripts independientes para cada componente -- **🎨 Menú Interactivo**: Selecciona qué instalar según tus necesidades -- **🌀 Progreso Limpio**: Las tareas en background muestran el estado sin invadir los prompts interactivos -- **🔐 Sesión Sudo Persistente**: Reutiliza la contraseña durante toda la ejecución para evitar interrupciones -- **🔧 Fácil de Extender**: Agrega nuevos módulos fácilmente +- **✅ Estructura Modular**: Scripts independientes para cada componente. +- **🎨 Menú Interactivo**: Selecciona qué instalar según tus necesidades. +- **🌀 Progreso Limpio**: Las tareas en background muestran el estado sin invadir los prompts. +- **🔐 Sesión Sudo Persistente**: Reutiliza la contraseña durante toda la ejecución. +- **🔧 Fácil de Extender**: Agrega nuevos módulos fácilmente. ## ⚡ Instalación rápida ```bash -# Clonar el repositorio git clone https://github.com/marcogll/omarchy_setup.git cd omarchy_setup - -# Ejecutar el script maestro ./omarchy-setup.sh ``` -## 📦 Estructura Modular +## 📂 Estructura del Repositorio ``` -omarchy_zsh_setup/ -├── omarchy-setup.sh # Script maestro con menú interactivo -├── modules/ -│ ├── common.sh # Funciones comunes (colores, logging, etc.) -│ ├── apps.sh # Instalación de aplicaciones -│ ├── zsh-config.sh # Configuración de Zsh -│ ├── docker.sh # Docker y Portainer -│ ├── zerotier.sh # ZeroTier VPN -│ ├── printer.sh # Configuración de impresoras (CUPS) -│ ├── mouse_cursor.sh # Tema de cursor Bibata -│ ├── icon_manager.sh # Gestor de temas de iconos -│ ├── ssh-keyring.sh # Sincronización de claves SSH con GNOME Keyring -│ ├── davinci-resolve.sh # DaVinci Resolve (Intel Edition) -└── Readme.md +omarchy_setup/ +├── omarchy-setup.sh # Script principal con el menú interactivo. +├── modules/ # Directorio con todos los módulos de instalación. +│ ├── common.sh # Funciones compartidas por todos los módulos. +│ ├── apps.sh # Instalación de aplicaciones y herramientas. +│ ├── zsh-config.sh # Configuración de Zsh, Oh My Zsh y Oh My Posh. +│ └── ... # Otros módulos. +└── hypr_config/ # Configuración de Hyprland (copiada por el módulo). ``` -## 🎮 Uso del Menú Interactivo - -Al ejecutar `./omarchy-setup.sh`, verás un menú con las siguientes opciones: - -``` -╔════════════════════════════════════════════════════════════╗ -║ 🌀 Omarchy Setup Script — Configuración Modular ║ -╚════════════════════════════════════════════════════════════╝ - -Selecciona las opciones que deseas instalar: - - 1) 📦 Instalar Aplicaciones (VS Code, VLC, drivers, etc.) - 2) 🐚 Configurar Zsh (shell, plugins, config) - 3) 🐳 Instalar Docker y Portainer - 4) 🌐 Instalar ZeroTier VPN - 5) 🖨️ Configurar Impresoras (CUPS) - 6) 🖱️ Instalar Tema de Cursor (Bibata) - 7) 🎨 Gestionar Temas de Iconos (Papirus, Tela, etc.) - K) 🔐 Sincronizar claves SSH con GNOME Keyring - F) 💾 Habilitar Formatos FAT/exFAT/NTFS/ext4 - H) 🎨 Instalar Configuración de Hyprland - R) 🎬 Instalar DaVinci Resolve (Intel Edition) - A) ✅ Instalar Todo (opciones 1, 2, K, 3, 4, 5, 6, 7, F, H) - 0) 🚪 Salir -``` - -> ℹ️ **Nota:** La opción `A) Instalar Todo` ejecuta los módulos 1, 2, K, 3, 4, 5, 6, 7, F y H. DaVinci Resolve (`R`) no se incluye aquí; instálalo manualmente cuando ya tengas el ZIP en `~/Downloads/`. - -> 🌀 **Progreso limpio:** Los módulos en background informan su avance sin animaciones invasivas; toda la salida detallada se imprime limpia y se escribe en `./logs/`. +--- ## 📋 Módulos Disponibles -### 1. 📦 Aplicaciones (`apps.sh`) -- Editores como VS Code y Cursor (desde AUR) -- Configura GNOME Keyring como agente de contraseñas y SSH, iniciando el daemon y exportando `SSH_AUTH_SOCK` -- Detecta claves privadas en `~/.ssh` y las registra automáticamente con `ssh-add` -- Instala y habilita servicios complementarios (keyd, logiops, TeamViewer, etc.) +A continuación se describe cada uno de los módulos que puedes instalar. -### 2. 🐚 Zsh (`zsh-config.sh`) -- Instala Oh My Zsh y Oh My Posh (Catppuccin Frappe) con autocompletado -- Clona/actualiza plugins externos como `zsh-autosuggestions` y `zsh-syntax-highlighting` (con fallback al sistema) -- Modifica `.bashrc` para lanzar Zsh automáticamente +### 1. Aplicaciones (`apps.sh`) -### 3. 🐳 Docker (`docker.sh`) -- Instalación de Docker y Docker Compose -- Configuración de servicios -- Instalación de Portainer -- Agregar usuario al grupo docker +Este módulo instala un conjunto de aplicaciones y herramientas esenciales para un entorno de desarrollo y de escritorio completo. -### 4. 🌐 ZeroTier (`zerotier.sh`) -- Instalación de ZeroTier One -- Configuración de servicio -- Instrucciones para unirse a redes +- **Qué instala:** + - **Herramientas de sistema:** `git`, `curl`, `htop`, `fastfetch`, `stow`, `gnome-keyring`. + - **Editores de código:** Visual Studio Code (`visual-studio-code-bin`) y Cursor (`cursor-bin`) desde AUR. + - **Multimedia:** VLC, Audacity, Inkscape y `yt-dlp`. + - **Red:** FileZilla, Telegram y `speedtest-cli`. + - **Drivers de Intel:** Soporte completo para gráficos **Intel Iris Xe**, incluyendo Mesa, Vulkan, VA-API para aceleración de video y OpenCL. + - **Utilidades de AUR:** `keyd` (remapeo de teclado), `logiops` (configuración de ratones Logitech), `teamviewer`. -### 5. 🖨️ Impresoras (`printer.sh`) -- Instalación de CUPS -- Drivers comunes de impresora +- **Cómo funciona:** + - Instala paquetes desde los repositorios oficiales y AUR. + - Configura **GNOME Keyring** para actuar como agente de SSH, cargando automáticamente las claves que encuentre en `~/.ssh`. + - Habilita los servicios necesarios para `keyd`, `logiops` y `teamviewer`. -### 6. 🖱️ Tema de Cursor (`mouse_cursor.sh`) -- Instala el tema de cursor `Bibata-Modern-Ice`. -- Configura el cursor para Hyprland y aplicaciones GTK. +### 2. Zsh (`zsh-config.sh`) -### 7. 🎨 Gestor de Iconos (`icon_manager.sh`) -- Menú interactivo para instalar y cambiar entre temas de iconos como Papirus, Tela y Candy. +Transforma la terminal con Zsh, Oh My Zsh y Oh My Posh, junto con una configuración personalizada que incluye aliases y funciones útiles. -### K. 🔐 Sincronizar Claves SSH (`ssh-keyring.sh`) -- Inicia/activa GNOME Keyring para componentes `ssh` y `secrets` -- Exporta `SSH_AUTH_SOCK` y registra claves desde `~/.ssh` usando `ssh-add` -- Evita duplicados mediante fingerprints y muestra un resumen al finalizar +- **Qué instala:** + - `zsh` y plugins como `zsh-syntax-highlighting` y `zsh-autosuggestions`. + - **Oh My Zsh** para la gestión de la configuración de Zsh. + - **Oh My Posh** como motor para el prompt, con el tema **Catppuccin Frappe**. + - Herramientas de terminal como `zoxide` para una navegación rápida. -### F. 💾 Soporte de Formatos (`disk-format.sh`) -- Instala utilidades para FAT32, exFAT, NTFS y ext4 -- Añade herramientas gráficas (GParted, GNOME Disks) para formateo manual +- **Cómo funciona:** + - Instala todas las dependencias y clona los repositorios necesarios. + - Reemplaza tu `~/.zshrc` con una versión preconfigurada (creando una copia de seguridad). + - Cambia tu shell por defecto a Zsh. -### R. 🎬 DaVinci Resolve (`davinci-resolve.sh`) -- Configuración de librerías y wrapper +> **¡Importante!** Después de instalar este módulo, necesitarás instalar una **Nerd Font** para que el prompt se vea bien. El script te recomendará instalar la fuente **Meslo** con el comando: `oh-my-posh font install meslo`. -## 🔧 Ejecutar Módulos Individualmente +### 3. Docker (`docker.sh`) -Cada módulo puede ejecutarse de forma independiente: +Instala y configura Docker para la gestión de contenedores. -```bash -# Instalar solo aplicaciones -./modules/apps.sh +- **Qué instala:** + - `docker` y `docker-compose`. + - (Opcional) **Portainer**, una interfaz web para gestionar Docker. -# Configurar solo Zsh -./modules/zsh-config.sh +- **Cómo funciona:** + - Habilita el servicio de Docker. + - Añade tu usuario al grupo `docker`, lo que te permite ejecutar comandos de Docker sin `sudo` (requiere reiniciar sesión). + - Te pregunta si quieres instalar Portainer. -# Sincronizar claves SSH con GNOME Keyring -./modules/ssh-keyring.sh +### 4. ZeroTier (`zerotier.sh`) -# Instalar Docker -./modules/docker.sh -``` +Instala el cliente de ZeroTier, una herramienta para crear redes virtuales seguras. -## 🌐 Instalación desde URL +- **Qué instala:** + - El paquete `zerotier-one`. -**Nota**: El script requiere que los módulos estén presentes localmente. Se recomienda clonar el repositorio completo. +- **Cómo funciona:** + - Habilita el servicio de ZeroTier. + - Te ofrece unirte a una red de ZeroTier de forma interactiva después de la instalación. -```bash -# Clonar el repositorio -git clone https://github.com/marcogll/omarchy_setup.git -cd omarchy_setup -./omarchy-setup.sh -``` +### 5. Impresoras (`printer.sh`) + +Instala y configura el sistema de impresión CUPS. + +- **Qué instala:** + - `cups`, `cups-pdf` y filtros de impresión. + - Drivers de impresión genéricos (`gutenprint`, `foomatic-db`). + - Drivers para impresoras **Epson** desde AUR. + - `avahi` para la detección de impresoras en red. + +- **Cómo funciona:** + - Habilita los servicios de `cups` y `avahi`. + - Añade tu usuario al grupo `lp` para que puedas administrar impresoras (requiere reiniciar sesión). + +### 6. Tema de Cursor (`mouse_cursor.sh`) + +Instala un tema de cursor personalizado y lo configura para Hyprland y aplicaciones GTK. + +- **Qué instala:** + - El tema de cursor **Bibata-Modern-Ice**. + +- **Cómo funciona:** + - Descarga el tema y lo instala en `~/.icons`. + - Modifica los ficheros de configuración de Hyprland (`envs.conf`) y GTK (`gsettings`). + +### 7. Gestor de Iconos (`icon_manager.sh`) + +Un menú interactivo para instalar y cambiar entre diferentes temas de iconos. + +- **Qué instala (a elección):** + - **Tela** (variante Nord). + - **Papirus** (estándar o con colores Catppuccin). + - **Candy Icons**. + +- **Cómo funciona:** + - Clona los repositorios de los temas de iconos desde GitHub. + - Modifica la configuración de Hyprland (`autostart.conf`) para que el tema sea persistente. + +### 8. Sincronizar Claves SSH (`ssh-keyring.sh`) + +Añade tus claves SSH existentes al agente de GNOME Keyring para que no tengas que escribir tu passphrase repetidamente. + +- **Cómo funciona:** + - Inicia el `gnome-keyring-daemon`. + - Busca claves privadas en `~/.ssh` y las añade al agente usando `ssh-add`. + - Evita añadir claves que ya estén cargadas. + +### 9. Soporte de Formatos (`disk-format.sh`) + +Instala herramientas para poder leer, escribir y formatear particiones con los sistemas de archivos más comunes. + +- **Qué instala:** + - `dosfstools` (para FAT), `exfatprogs` (para exFAT) y `ntfs-3g` (para NTFS). + - Herramientas gráficas como **GParted** y **GNOME Disks**. + +### 10. DaVinci Resolve (`davinci-resolve.sh`) + +Un instalador especializado para DaVinci Resolve, enfocado en sistemas con GPUs de Intel. + +> **Nota:** Este módulo es complejo y requiere que hayas descargado previamente el fichero ZIP de DaVinci Resolve desde la web de Blackmagic y lo hayas colocado en tu carpeta de `~/Downloads`. + +- **Cómo funciona:** + - Instala todas las dependencias necesarias, incluyendo librerías de `ocl-icd` y `intel-compute-runtime`. + - Extrae el instalador, aplica parches a las librerías con `patchelf` y lo copia todo a `/opt/resolve`. + - Crea un script "wrapper" y un acceso directo en el menú de aplicaciones para lanzar el programa con la configuración correcta. + +### 11. Configuración de Hyprland (`hyprland-config.sh`) + +Instala una configuración personalizada para el gestor de ventanas Hyprland. + +- **Cómo funciona:** + - Hace una copia de seguridad de tu configuración actual en `~/.config/hypr`. + - Copia el contenido de la carpeta `hypr_config` del repositorio a `~/.config/hypr`. + - Establece el tema de iconos por defecto (Tela Nord) usando el módulo de gestión de iconos. --- -## ✨ Características de los Módulos +## 🔧 Extender el Script -### 📦 Aplicaciones -- **Herramientas base**: git, curl, wget, base-devel, stow -- **Editores**: - - VS Code (desde AUR: visual-studio-code-bin) - - Cursor (desde AUR: cursor-bin) -- **Multimedia**: - - VLC con todos los plugins (vlc-plugins-all) - - Audacity (editor de audio) - - Inkscape (editor gráfico vectorial) - - ffmpeg, gstreamer con plugins - - yt-dlp (descarga de videos) -- **Red y transferencia**: - - FileZilla (cliente FTP) - - Telegram Desktop - - scrcpy (control Android desde PC) -- **Utilidades**: neofetch, htop, fastfetch, btop, vim, nano, tmux -- **Seguridad y sincronización**: - - GNOME Keyring + libsecret + Seahorse - - Configuración automática del agente SSH y carga de claves en `~/.ssh` - - openssh, rsync -- Recomendado cerrar sesión tras la instalación para que las variables de entorno del keyring se apliquen a nuevas terminales -- **Flatpak**: Sistema de paquetes universal -- **Drivers Intel Iris Xe**: - - Mesa y Vulkan (gráficos 3D) - - Intel Media Driver (aceleración de video VA-API) - - OpenCL (Intel Compute Runtime desde AUR) - - Codecs y herramientas de hardware acceleration -- **Desde AUR**: - - keyd (remapeo de teclado) - - fragments (cliente BitTorrent) - - logiops (driver Logitech) - - ltunify (Logitech Unifying Receiver) - - TeamViewer (acceso remoto, con daemon habilitado) - - intel-compute-runtime (OpenCL para Intel) +Añadir un nuevo módulo es sencillo: -### 🐚 Zsh -- Oh My Zsh + Oh My Posh (tema Catppuccin Frappe) -- Plugins externos gestionados automáticamente (`zsh-autosuggestions`, `zsh-syntax-highlighting`) -- Genera el archivo de autocompletado `_oh-my-posh` en `~/.local/share/zsh/site-functions` -- Modifica `.bashrc` para lanzar Zsh automáticamente - -### 🔐 GNOME Keyring SSH -- Arranca el daemon de GNOME Keyring con componentes de `ssh` y `secrets` -- Garantiza que `SSH_AUTH_SOCK` apunte al socket del keyring (persistido en `~/.config/environment.d`) -- Busca claves privadas en `~/.ssh` (excluyendo `.pub` y certificados) y las registra con `ssh-add` -- Evita añadir claves duplicadas y muestra cómo verificar con `ssh-add -l` - -### 🐳 Docker -- Portainer (interfaz web de gestión) -- Usuario agregado al grupo docker -- Servicios habilitados y configurados - -### 🌐 ZeroTier -- ZeroTier One VPN -- Servicio configurado y habilitado -- Instrucciones para unirse a redes - -### 🖨️ Impresoras -- CUPS (Common Unix Printing System) -- Drivers comunes de impresora -- Interfaz web en http://localhost:631 -- Soporte para impresoras de red - -### 🎬 DaVinci Resolve -- Instalación para Intel GPU -- Configuración de OpenCL -- Ajuste de librerías del sistema -- Wrapper para ejecución - ---- - -## 📦 Paquetes instalados - -
-Ver lista completa (click para expandir) - -### Sistema Base -- **zsh**, **zsh-completions** -- **oh-my-posh-bin** (desde AUR) -- **git**, **curl**, **wget** -- **yay** (AUR helper, compilado desde AUR) - -### Desarrollo -- **python**, **python-pip**, **python-virtualenv** -- **nodejs**, **npm** -- **go** (Golang) -- **docker**, **docker-compose** -- **base-devel** (herramientas de compilación) - -### Utilidades de Terminal -- **eza** (ls mejorado) -- **bat** (cat mejorado) -- **zoxide** (cd inteligente) -- **fastfetch** (info del sistema) -- **htop**, **btop** (monitores del sistema) -- **tree** (visualización de directorios) - -### Multimedia y Control -- **yt-dlp**, **ffmpeg** -- **playerctl**, **brightnessctl**, **pamixer** -- **audacity**, **inkscape** - -### Red y Seguridad -- **zerotier-one** (desde AUR) -- **gnome-keyring**, **libsecret**, **seahorse** -- **lsof**, **net-tools** -- **teamviewer** - -### Utilidades del Sistema -- **nano**, **unzip**, **tar** -- **p7zip**, **unrar** - -### Instalaciones Adicionales -- **speedtest-cli** (vía pip) - -
- ---- - -## 🎯 Durante la instalación - -El script ejecuta los siguientes pasos: - -1. **Verificación de requerimientos** (root, Arch Linux, conexión a Internet) -2. **Instalación de paquetes base** desde repositorios oficiales -3. **Instalación de yay** desde AUR (si no está instalado) -4. **Configuración de Docker** (servicio y permisos de usuario) -5. **Instalación de Oh My Zsh y plugins** -6. **Configuración de .zshrc y tema Catppuccin** desde GitHub -7. **Configuración de TeamViewer** (servicio) -8. **Instalación de ZeroTier One** desde AUR (opcional) -9. **Configuración de GNOME Keyring** (opcional) -10. **Configuración de claves SSH** (opcional) - -### Preguntas interactivas: - -- **ZeroTier Network ID**: Si deseas unirte a una red ZeroTier (opcional) -- **GNOME Keyring**: Si deseas configurar el almacén de contraseñas -- **Claves SSH**: Si deseas añadir claves SSH existentes al agente - ---- - -## 🔑 GNOME Keyring - -El keyring guarda contraseñas de forma segura: -- **Git** (credential helper) -- **SSH keys** (almacenadas de forma segura) -- **Aplicaciones GNOME** - -### Configuración automática: - -El script configura automáticamente: -- PAM para auto-desbloqueo del keyring -- Inicio automático de gnome-keyring-daemon -- Integración con SSH agent - -### Comandos útiles: - -```bash -# Abrir gestor de contraseñas -seahorse - -# Ver estado del keyring -gnome-keyring-daemon --version - -# Comandos de ZeroTier (aliases en .zshrc) -zt # Alias de sudo zerotier-cli -ztstatus # Ver redes conectadas (listnetworks) -ztinfo # Info del nodo (info) -``` - ---- - -## ⚙️ Configuración incluida - -### Aliases de Arch Linux -```bash -pacu # Actualizar sistema -paci # Instalar paquete -pacr # Remover paquete -pacs # Buscar paquete -yayu # Actualizar AUR -yayi # Instalar desde AUR -``` - -### Git shortcuts -```bash -gs # git status -ga # git add -gc # git commit -gcm "msg" # git commit -m -gp # git push -gl # git pull -gco # git checkout -gcb # git checkout -b -glog # git log gráfico -gac "msg" # add + commit -``` - -### Docker -```bash -dc # docker compose -d # docker -dps # docker ps -a -di # docker images -dex sh # docker exec -it -dlog # docker logs -f -``` - -### Python -```bash -py # python -venv create # Crear .venv -venv on # Activar -venv off # Desactivar -pir # pip install -r requirements.txt -pipf # pip freeze > requirements.txt -``` - -### yt-dlp -```bash -ytm # Descargar audio MP3 320kbps -ytm "lofi beats" # Buscar y descargar -ytv # Descargar video MP4 (calidad por defecto) -ytv 1080 # Descargar video en 1080p -ytv 720 # Descargar video en 720p -ytls # Listar últimos descargas -``` - -Descargas en: `~/Videos/YouTube/{Music,Videos}/` - -### NPM -```bash -nrs # npm run start -nrd # npm run dev -nrb # npm run build -nrt # npm run test -ni # npm install -nid # npm install --save-dev -nig # npm install -g -``` - -### Utilidades -```bash -mkcd # mkdir + cd -extract # Extraer cualquier archivo -killport # Matar proceso en puerto -serve [port] # Servidor HTTP (default 8000) -clima # Ver clima Saltillo -``` - ---- - -## 🌐 ZeroTier Network ID - -Tu Network ID tiene formato: `a0cbf4b62a1234567` (16 caracteres hex) - -### Dónde encontrarlo: -1. Ve a https://my.zerotier.com -2. Selecciona tu red -3. Copia el Network ID - -### Después de la instalación: -1. Ve a tu panel de ZeroTier -2. Busca el nuevo dispositivo -3. **Autorízalo** marcando el checkbox - -### Comandos útiles: -```bash -# Ver redes -ztstatus - -# Unirse a red -sudo zerotier-cli join - -# Salir de red -sudo zerotier-cli leave - -# Info del nodo -ztinfo -``` - ---- - -## 📂 Estructura creada - -``` -$HOME/ -├── .zshrc # Configuración de Zsh (descargado desde GitHub) -├── .zshrc.local # Config local (opcional, no creado automáticamente) -├── .oh-my-zsh/ # Oh My Zsh -│ └── custom/plugins/ # Plugins adicionales -│ ├── zsh-autosuggestions/ -│ └── zsh-syntax-highlighting/ -├── .poshthemes/ # Temas Oh My Posh -│ └── catppuccin_frappe.omp.json # Tema Catppuccin Frappe -├── .zsh_functions/ # Funciones personalizadas (directorio creado) -├── Videos/YouTube/ # Descargas de yt-dlp -│ ├── Music/ # Audios MP3 -│ └── Videos/ # Videos MP4 -├── .ssh/ # Claves SSH (si existen) -└── omarchy-setup.log # Log de instalación -``` - ---- - -## 🔄 Después de la instalación - -### 1. Reiniciar sesión o terminal (IMPORTANTE) - -**⚠️ REINICIO REQUERIDO** si se instalaron servicios como TeamViewer o ZeroTier. - -```bash -# Cerrar y volver a abrir la terminal para usar Zsh -# O cerrar sesión y volver a entrar para aplicar: -# - Cambio de shell a Zsh -# - Grupos (docker) -# - Permisos del sistema -``` - -### 2. Verificar instalación - -```bash -# Ver versión de Zsh -zsh --version - -# Ver tema Oh My Posh -oh-my-posh version - -# Verificar Docker -docker ps - -# Ver ZeroTier (si se configuró) -ztstatus - -# Ver TeamViewer (si se instaló) -teamviewer info - -# Actualizar sistema -pacu -``` - -### 3. Configuraciones opcionales - -```bash -# Crear archivo de configuración local -nano ~/.zshrc.local - -# Ejemplo de contenido: -export OPENAI_API_KEY="sk-..." -export GITHUB_TOKEN="ghp_..." -alias miproyecto="cd ~/Projects/mi-app && code ." -``` - ---- - -## 🛠️ Solución de problemas - -### Docker no funciona sin sudo - -```bash -# Verificar que estás en el grupo docker -groups # Debe incluir 'docker' - -# Si no aparece, reinicia sesión o ejecuta: -newgrp docker - -# Verificar acceso -docker ps -``` - -### Git sigue pidiendo contraseña - -```bash -# Verificar credential helper -git config --global credential.helper - -# Debe ser: libsecret - -# Si no, configurar: -git config --global credential.helper libsecret - -# Abrir Seahorse y verificar keyring -seahorse - -# Verificar que el keyring está corriendo -pgrep -u "$USER" gnome-keyring-daemon -``` - -### ZeroTier no conecta - -```bash -# Verificar servicio -sudo systemctl status zerotier-one - -# Ver logs -sudo journalctl -u zerotier-one -f - -# Reiniciar servicio -sudo systemctl restart zerotier-one - -# Verificar que autorizaste el nodo en https://my.zerotier.com -ztinfo -ztstatus -``` - -### Oh My Posh no se muestra correctamente - -```bash -# Verificar instalación -which oh-my-posh -oh-my-posh version - -# Verificar que el tema existe -ls ~/.poshthemes/catppuccin_frappe.omp.json - -# Verificar que tienes una Nerd Font instalada -# (El script NO instala fuentes automáticamente) -fc-list | grep -i nerd - -# Si no tienes Nerd Font, instala una: -# - Nerd Fonts: https://www.nerdfonts.com/ -``` - -### El shell no cambió a Zsh - -```bash -# Verificar shell actual -echo $SHELL - -# Cambiar manualmente -chsh -s $(which zsh) - -# Cerrar y abrir nueva terminal -``` - ---- - -## 📚 Recursos - -- **Arch Wiki**: https://wiki.archlinux.org/ -- **Oh My Zsh**: https://ohmyz.sh/ -- **Oh My Posh**: https://ohmyposh.dev/ -- **Catppuccin Theme**: https://github.com/catppuccin/catppuccin -- **ZeroTier**: https://www.zerotier.com/ -- **yt-dlp**: https://github.com/yt-dlp/yt-dlp -- **Nerd Fonts**: https://www.nerdfonts.com/ (requerido para iconos del prompt) -- **yay AUR Helper**: https://github.com/Jguer/yay - ---- - -## 🆘 Soporte - -Si encuentras problemas: - -1. Revisa los mensajes de error durante la instalación -2. Verifica que cerraste sesión después de instalar (para aplicar grupos) -3. Comprueba que los grupos se aplicaron: `groups` -4. Verifica que los módulos están presentes: `ls modules/` -5. Ejecuta módulos individualmente para aislar problemas -6. Abre un issue en: https://github.com/marcogll/scripts_mg/issues - -### Verificar Instalación de Módulos - -```bash -# Verificar que todos los módulos existen -ls -la modules/ - -# Ejecutar un módulo individual para debug -bash -x modules/apps.sh -``` - ---- - -## 🔧 Agregar Nuevos Módulos - -Para agregar un nuevo módulo: - -1. Crea un archivo en `modules/nombre-modulo.sh`: - -```bash -#!/usr/bin/env bash -# =============================================================== -# nombre-modulo.sh - Descripción del módulo -# =============================================================== - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/common.sh" - -install_nombre_modulo() { - log_step "Instalación de Nombre Módulo" - - # Tu código aquí - log_info "Instalando paquetes..." - sudo pacman -S --noconfirm --needed paquete1 paquete2 || { - log_error "Error al instalar paquetes" - return 1 - } - - log_success "Módulo instalado correctamente" - return 0 -} - -# Ejecutar si se llama directamente -if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - install_nombre_modulo "$@" -fi -``` - -2. Agrega el módulo al menú en `omarchy-setup.sh`: - -Dentro del script `omarchy-setup.sh`, localiza el array asociativo `MODULES` y añade una nueva línea. - -```bash -# --- Definición de Módulos --- -# Clave: Opción del menú -# Valor: "Nombre del Fichero;Función Principal;Descripción;Tipo (bg/fg)" -declare -A MODULES -MODULES=( - ["1"]="apps;run_module_main;📦 Instalar Aplicaciones;bg" - # ... otros módulos ... - ["N"]="nombre-modulo;install_nombre_modulo;🚀 Mi Nuevo Módulo;fg" -) -``` - -- **Clave (`"N"`):** La tecla que el usuario presionará en el menú. -- **Valor:** Una cadena de texto con 4 partes separadas por punto y coma (`;`): - 1. `nombre-modulo`: El nombre del fichero `.sh` sin la extensión. - 2. `install_nombre_modulo`: La función dentro de ese fichero que se debe ejecutar. - 3. `🚀 Mi Nuevo Módulo`: La descripción que aparecerá en el menú. - 4. `fg` o `bg`: `fg` (foreground) para scripts interactivos, `bg` (background) para tareas que pueden usar un spinner. - -3. Si quieres incluirlo en la opción "Instalar Todo", añade la clave del menú (en este caso, `"N"`) al array `INSTALL_ALL_CHOICES`. - ---- - -## 📝 Changelog - -### v3.0.0 (2025-01-XX) -- ✨ **Nueva estructura modular**: Scripts independientes para cada componente -- 🎨 **Menú interactivo**: Selecciona qué instalar según tus necesidades -- 🎨 **Interfaz mejorada**: Colores y mensajes claros durante la instalación -- 📦 **Módulos disponibles**: - - Aplicaciones (apps.sh) - - Zsh (zsh-config.sh) - - Docker y Portainer (docker.sh) - - ZeroTier (zerotier.sh) - - Impresoras CUPS (printer.sh) - - Tema de Cursor (mouse_cursor.sh) - - DaVinci Resolve (davinci-resolve.sh) - - Gestor de Iconos (icon_manager.sh) - -### v2.8.1 (2025-11-02) -- Versión unificada con estética Catppuccin -- Instalación mejorada de paquetes con manejo de errores robusto -- **oh-my-posh** instalado desde AUR automáticamente -- Configuración `.zshrc` descargada desde GitHub +1. **Crea tu script** en la carpeta `modules/` (ej. `mi-modulo.sh`). Asegúrate de que tenga una función principal. +2. **Añádelo al menú** en `omarchy-setup.sh`, dentro del array `MODULES`. Sigue el formato: `"tecla"="nombre-fichero;nombre-funcion;Descripción;tipo"`. + - `tipo` puede ser `bg` (para tareas en segundo plano) o `fg` (para tareas interactivas). --- ## 📄 Licencia -MIT License - Libre de usar y modificar - ---- - -## 👤 Autor - -**Marco** -- GitHub: [@marcogll](https://github.com/marcogll) -- Repo: [scripts_mg](https://github.com/marcogll/scripts_mg) - ---- - - -```bash -# Instalar en una línea -bash <(curl -fsSL https://raw.githubusercontent.com/marcogll/scripts_mg/main/omarchy_zsh_setup/omarchy-setup.sh) -``` - -## 📝 Notas importantes - -- **Shell por defecto**: El módulo de Zsh modifica `.bashrc` para que las terminales nuevas usen Zsh. - -## 🚀 Próximos Pasos - -1. Ejecuta `./omarchy-setup.sh` para ver el menú interactivo -2. Selecciona los módulos que deseas instalar -3. Revisa los mensajes durante la instalación -4. Reinicia o cierra sesión después de instalar servicios -5. Disfruta de tu configuración personalizada - ---- - -🚀 **¡Disfruta tu nuevo setup modular de Omarchy!** +Este proyecto está bajo la Licencia MIT. diff --git a/modules/apps.sh b/modules/apps.sh index a9a6263..ae966f6 100755 --- a/modules/apps.sh +++ b/modules/apps.sh @@ -2,63 +2,161 @@ # =============================================================== # apps.sh - Instalación de aplicaciones esenciales # =============================================================== +# +# Este módulo se encarga de instalar y configurar una amplia gama +# de aplicaciones y herramientas de sistema. +# +# Funciones principales: +# - Instala Homebrew (Linuxbrew) para gestionar paquetes adicionales. +# - Instala paquetes desde los repositorios de Arch (pacman) y desde AUR. +# - Organiza los paquetes por categorías (base, multimedia, red, etc.). +# - Configura drivers para gráficos Intel Iris Xe. +# - Configura GNOME Keyring para la gestión de contraseñas y claves SSH. +# - Habilita servicios del sistema para aplicaciones como keyd, logiops y TeamViewer. +# +# =============================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" +# --------------------------------------------------------------- +# ensure_homebrew_env() +# --------------------------------------------------------------- +# Asegura que el entorno de Homebrew esté configurado correctamente. +# +# Esta función realiza dos tareas principales: +# 1. Carga Homebrew en la sesión de shell actual para que el comando `brew` +# esté disponible inmediatamente después de la instalación. +# 2. Añade la línea de inicialización de Homebrew a los ficheros de +# perfil del usuario (`.profile` y `.zprofile`) para que `brew` +# esté disponible en futuras sesiones de terminal. +# +# Parámetros: +# $1 - Ruta al ejecutable de brew. +# --------------------------------------------------------------- +ensure_homebrew_env() { + local brew_bin="$1" + if [[ ! -x "$brew_bin" ]]; then + return 1 + fi + + # Evalúa `shellenv` para que el resto del módulo pueda usar `brew` + # sin necesidad de reiniciar la shell. + eval "$("$brew_bin" shellenv)" || return 1 + + local shell_snippet='eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' + local -a appended=() + local -a rc_targets=("${HOME}/.profile") + + # Si el usuario utiliza Zsh, añade también la configuración a .zprofile. + if [[ -n "${SHELL:-}" && "$(basename "${SHELL}")" == "zsh" ]]; then + rc_targets+=("${HOME}/.zprofile") + fi + + for rc_file in "${rc_targets[@]}"; do + if [[ -f "$rc_file" ]] && grep -Fq "$shell_snippet" "$rc_file"; then + continue + fi + { + echo "" + echo "# Configuración añadida por Omarchy Setup para inicializar Homebrew" + echo "$shell_snippet" + } >> "$rc_file" + appended+=("$rc_file") + done + + if [[ ${#appended[@]} -gt 0 ]]; then + log_info "Se añadió la inicialización de Homebrew a: ${appended[*]}." + fi + + return 0 +} + +# --------------------------------------------------------------- +# install_homebrew() +# --------------------------------------------------------------- +# Instala Homebrew (conocido como Linuxbrew en Linux). +# +# Comprueba si Homebrew ya está instalado. Si no lo está, descarga y +# ejecuta el script de instalación oficial de forma no interactiva. +# Después de la instalación, llama a `ensure_homebrew_env` para +# configurar el entorno de shell. +# --------------------------------------------------------------- install_homebrew() { log_step "Instalación de Homebrew (Linuxbrew)" + local brew_path="/home/linuxbrew/.linuxbrew/bin/brew" if command_exists brew; then + brew_path="$(command -v brew)" + fi + + if command_exists brew || [[ -x "$brew_path" ]]; then log_success "Homebrew ya está instalado." + ensure_homebrew_env "${brew_path}" || true return 0 fi log_info "Instalando Homebrew..." - # Instalar de forma no interactiva + # Instala de forma no interactiva para evitar prompts. if NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then log_success "Homebrew instalado correctamente." + ensure_homebrew_env "${brew_path}" || log_warning "Homebrew se instaló pero no se pudo configurar la shell automáticamente." else log_error "Falló la instalación de Homebrew." return 1 fi } +# --------------------------------------------------------------- +# run_module_main() +# --------------------------------------------------------------- +# Función principal del módulo de instalación de aplicaciones. +# +# Ejecuta una secuencia de tareas para instalar y configurar +# aplicaciones esenciales del sistema. +# --------------------------------------------------------------- run_module_main() { log_step "Instalación de Aplicaciones" # --- Definición de Paquetes --- + # Paquetes base para el sistema y desarrollo. local PACMAN_BASE=( git curl wget base-devel unzip htop fastfetch btop vim nano tmux xdg-utils xdg-user-dirs stow gnome-keyring libsecret seahorse openssh rsync ) + # Paquetes para reproducción y edición multimedia. local PACMAN_MULTIMEDIA=( vlc vlc-plugins-all libdvdcss audacity inkscape ffmpeg gstreamer gst-plugins-good gst-plugins-bad gst-plugins-ugly yt-dlp ) + # Aplicaciones de red y conectividad. local PACMAN_NETWORK=( filezilla telegram-desktop scrcpy speedtest-cli ) + # Drivers para gráficos Intel (Mesa y Vulkan). local PACMAN_INTEL_GFX=( mesa vulkan-intel lib32-mesa lib32-vulkan-intel ) + # Drivers para aceleración de vídeo por hardware en Intel (VA-API). local PACMAN_INTEL_VIDEO=( intel-media-driver libva-utils libvdpau-va-gl libva-mesa-driver ) + # Soporte para computación GPGPU con OpenCL. local PACMAN_OPENCL=( ocl-icd libclc clinfo ) + # Paquetes a instalar desde el Arch User Repository (AUR). local AUR_PACKAGES=( "visual-studio-code-bin" "cursor-bin" "keyd" "fragments" "logiops" "ltunify" "teamviewer" "intel-compute-runtime" ) + # --- Instalación de Paquetes --- log_info "Actualizando el sistema para evitar conflictos de dependencias..." sudo pacman -Syu --noconfirm || { log_warning "No se pudo completar la actualización del sistema. Pueden ocurrir errores de dependencias." - # Continuamos de todos modos, pero con una advertencia. } log_info "Instalando herramientas base..." @@ -67,7 +165,7 @@ run_module_main() { return 1 } - # Instalar Homebrew + # Instalar Homebrew si no está presente. install_homebrew log_info "Instalando aplicaciones multimedia..." @@ -75,6 +173,7 @@ run_module_main() { log_warning "Algunos paquetes multimedia no se pudieron instalar" } + # Configura VLC como el reproductor por defecto para los tipos de archivo más comunes. log_info "Configurando VLC como reproductor predeterminado..." local mime_types=("audio/mpeg" "audio/mp4" "audio/x-wav" "video/mp4" "video/x-matroska" "video/x-msvideo" "video/x-ms-wmv" "video/webm") for type in "${mime_types[@]}"; do @@ -86,14 +185,15 @@ run_module_main() { log_warning "Algunos paquetes de red no se pudieron instalar" } - # Flatpak log_info "Instalando Flatpak..." sudo pacman -S --noconfirm --needed flatpak || { log_warning "Flatpak no se pudo instalar" } + # --- Configuración de Drivers Intel --- log_info "Instalando drivers y codecs para Intel Iris Xe..." + # Instala los headers del kernel si son necesarios para compilar módulos. KVER="$(uname -r)" if [[ ! -d "/usr/lib/modules/${KVER}/build" ]]; then log_info "Instalando headers de kernel..." @@ -117,15 +217,17 @@ run_module_main() { log_warning "Algunos paquetes OpenCL no se pudieron instalar" } + # Crea el fichero de configuración de OpenCL para los drivers de Intel. if [[ ! -f /etc/OpenCL/vendors/intel.icd ]] && [[ -f /usr/lib/intel-opencl/libigdrcl.so ]]; then log_info "Configurando OpenCL para Intel..." sudo mkdir -p /etc/OpenCL/vendors echo "/usr/lib/intel-opencl/libigdrcl.so" | sudo tee /etc/OpenCL/vendors/intel.icd >/dev/null fi + # Actualiza la caché de librerías compartidas. sudo ldconfig || true - # Verificar instalación de drivers + # --- Verificación de Drivers --- log_info "Verificando drivers Intel instalados..." if command_exists vainfo; then log_info "Información de VA-API:" @@ -137,25 +239,30 @@ run_module_main() { clinfo 2>/dev/null | grep -E "Platform Name|Device Name" || true fi + # --- Instalación desde AUR --- log_info "Instalando aplicaciones desde AUR..." log_warning "Este paso puede tardar varios minutos; qt5-webengine y teamviewer descargan y compilan bastante." if ! aur_install_packages "${AUR_PACKAGES[@]}"; then log_warning "Algunas aplicaciones de AUR no se pudieron instalar automáticamente." fi - # Configurar servicios - log_info "Configurando servicios..." + # --- Configuración de Servicios --- + log_info "Configurando servicios del sistema..." + # Configura GNOME Keyring para que actúe como agente de credenciales y SSH. log_info "Configurando GNOME Keyring como agente de credenciales..." mkdir -p "${HOME}/.config/environment.d" cat <<'EOF' > "${HOME}/.config/environment.d/10-gnome-keyring.conf" SSH_AUTH_SOCK=/run/user/$UID/keyring/ssh EOF + # Habilita el servicio de GNOME Keyring para el usuario actual. if systemctl --user enable --now gnome-keyring-daemon.socket gnome-keyring-daemon.service >/dev/null 2>&1; then log_success "GNOME Keyring listo para gestionar contraseñas y claves SSH." else log_warning "No se pudo habilitar gnome-keyring-daemon en systemd de usuario. Verifica que tu sesión use systemd (--user)." fi + + # Inicia el daemon de GNOME Keyring en la sesión actual para que `ssh-add` funcione. if command_exists gnome-keyring-daemon; then local keyring_eval keyring_eval="$(gnome-keyring-daemon --start --components=secrets,ssh 2>/dev/null)" || keyring_eval="" @@ -169,21 +276,16 @@ EOF fi log_info "Vuelve a iniciar sesión para que las variables de entorno del keyring se apliquen." + # Busca claves SSH en ~/.ssh y las añade al agente de GNOME Keyring. if command_exists ssh-add; then local ssh_dir="${HOME}/.ssh" if [[ -d "$ssh_dir" ]]; then + # Encuentra todas las claves privadas válidas. mapfile -t ssh_private_keys < <( find "$ssh_dir" -maxdepth 1 -type f -perm -u=r \ - ! -name "*.pub" \ - ! -name "*-cert.pub" \ - ! -name "known_hosts" \ - ! -name "known_hosts.*" \ - ! -name "authorized_keys" \ - ! -name "config" \ - ! -name "*.old" \ - ! -name "agent" \ - ! -name "*.bak" \ - 2>/dev/null + ! -name "*.pub" ! -name "*-cert.pub" ! -name "known_hosts" \ + ! -name "known_hosts.*" ! -name "authorized_keys" ! -name "config" \ + ! -name "*.old" ! -name "agent" ! -name "*.bak" 2>/dev/null ) if [[ ${#ssh_private_keys[@]} -gt 0 ]]; then log_info "Agregando claves SSH detectadas al keyring (se solicitará la passphrase si aplica)..." @@ -192,23 +294,20 @@ EOF log_warning "No se puede leer la clave $(basename "$key_path"); revísala manualmente." continue fi + # Intenta añadir la clave al agente. if ssh-keygen -y -f "$key_path" >/dev/null 2>&1; then log_info "Registrando clave $(basename "$key_path")..." local spinner_was_active=0 - if [[ ${SPINNER_ACTIVE:-0} -eq 1 ]]; then - spinner_was_active=1 - fi - if declare -F pause_spinner >/dev/null; then - pause_spinner - fi + if [[ ${SPINNER_ACTIVE:-0} -eq 1 ]]; then spinner_was_active=1; fi + if declare -F pause_spinner >/dev/null; then pause_spinner; fi + if SSH_AUTH_SOCK="$SSH_AUTH_SOCK" ssh-add "$key_path"; then log_success "Clave $(basename "$key_path") añadida al keyring." else log_warning "No se pudo añadir la clave $(basename "$key_path")." fi - if (( spinner_was_active )) && declare -F resume_spinner >/dev/null; then - resume_spinner - fi + + if (( spinner_was_active )) && declare -F resume_spinner >/dev/null; then resume_spinner; fi else log_warning "La clave $(basename "$key_path") parece inválida. Se omite." fi @@ -223,25 +322,20 @@ EOF log_warning "ssh-add no está disponible; no se pueden registrar claves en el keyring." fi - # Habilitar keyd si está instalado + # Habilita los servicios de las aplicaciones instaladas. if command_exists keyd; then log_info "Habilitando servicio keyd..." - sudo systemctl enable keyd.service 2>/dev/null || true - sudo systemctl start keyd.service 2>/dev/null || true + sudo systemctl enable --now keyd.service 2>/dev/null || true fi - # Habilitar logiops si está instalado if command_exists logiops; then log_info "Habilitando servicio logiops..." - sudo systemctl enable logiops.service 2>/dev/null || true - sudo systemctl start logiops.service 2>/dev/null || true + sudo systemctl enable --now logiops.service 2>/dev/null || true fi - # Habilitar TeamViewer daemon si está instalado if command_exists teamviewer; then log_info "Habilitando servicio TeamViewer..." - sudo systemctl enable teamviewerd.service 2>/dev/null || true - sudo systemctl start teamviewerd.service 2>/dev/null || true + sudo systemctl enable --now teamviewerd.service 2>/dev/null || true log_success "TeamViewer daemon habilitado e iniciado" fi @@ -249,7 +343,7 @@ EOF return 0 } -# Ejecutar si se llama directamente +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then run_module_main "$@" fi diff --git a/modules/common.sh b/modules/common.sh index dd1e828..006b4b9 100755 --- a/modules/common.sh +++ b/modules/common.sh @@ -1,53 +1,85 @@ #!/usr/bin/env bash # =============================================================== -# common.sh - Funciones comunes para los módulos +# common.sh - Funciones y variables comunes para los módulos +# =============================================================== +# +# Este script define un conjunto de funciones y variables de utilidad +# que son compartidas por todos los módulos de instalación. El objetivo +# es estandarizar tareas comunes como mostrar mensajes, manejar +# paquetes, crear copias de seguridad y gestionar el helper de AUR. +# +# No debe ser ejecutado directamente, sino incluido (`source`) por +# otros scripts. +# # =============================================================== -# Colores para output +# --- Definición de Colores --- +# Se definen códigos de escape ANSI para dar formato y color a la +# salida en la terminal, mejorando la legibilidad. RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' MAGENTA='\033[0;35m' CYAN='\033[0;36m' -NC='\033[0m' # No Color +NC='\033[0m' # No Color (resetea el formato) BOLD='\033[1m' -# Funciones de logging +# --- Funciones de Logging --- +# Proporcionan una manera estandarizada de mostrar mensajes al +# usuario, con diferentes niveles de severidad (info, éxito, +# advertencia, error) y formato. + +# Función interna para limpiar la línea del spinner si está activo. _maybe_clear_spinner() { if declare -F spinner_clear_line >/dev/null; then spinner_clear_line fi } +# Muestra un mensaje informativo. log_info() { _maybe_clear_spinner echo -e "${BLUE}▶${NC} ${BOLD}$1${NC}" } +# Muestra un mensaje de éxito. log_success() { _maybe_clear_spinner echo -e "${GREEN}✓${NC} ${GREEN}$1${NC}" } +# Muestra un mensaje de advertencia. log_warning() { _maybe_clear_spinner echo -e "${YELLOW}⚠${NC} ${YELLOW}$1${NC}" } +# Muestra un mensaje de error. log_error() { _maybe_clear_spinner echo -e "${RED}✗${NC} ${RED}$1${NC}" } +# Muestra un separador visual para marcar el inicio de un paso importante. log_step() { echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${CYAN}${BOLD} $1${NC}" echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n" } -# Función para crear una copia de seguridad de un archivo o directorio -# Uso: backup_file "/ruta/al/archivo" +# --- Funciones de Utilidad --- + +# --------------------------------------------------------------- +# backup_file(path) +# --------------------------------------------------------------- +# Crea una copia de seguridad de un archivo o directorio existente. +# Añade una marca de tiempo al nombre del backup para evitar +# sobrescribir copias anteriores. +# +# Parámetros: +# $1 - Ruta al archivo o directorio a respaldar. +# --------------------------------------------------------------- backup_file() { local path_to_backup="$1" if [[ -e "$path_to_backup" ]]; then @@ -64,17 +96,29 @@ backup_file() { return 0 } -# Función para verificar si un comando existe +# --------------------------------------------------------------- +# command_exists(command) +# --------------------------------------------------------------- +# Verifica si un comando está disponible en el PATH del sistema. +# +# Parámetros: +# $1 - Nombre del comando a verificar. +# --------------------------------------------------------------- command_exists() { command -v "$1" >/dev/null 2>&1 } -# Función para verificar e instalar un paquete con pacman -# Uso: check_and_install_pkg "nombre-del-paquete" +# --------------------------------------------------------------- +# check_and_install_pkg(package_name) +# --------------------------------------------------------------- +# Comprueba si un paquete ya está instalado con pacman. Si no lo +# está, intenta instalarlo. +# +# Parámetros: +# $1 - Nombre del paquete a instalar. +# --------------------------------------------------------------- check_and_install_pkg() { local pkg_name="$1" - # pacman -T es una forma de verificar sin instalar, pero no funciona bien con grupos. - # pacman -Q es más fiable para paquetes individuales. if ! pacman -Q "$pkg_name" &>/dev/null; then log_info "Instalando ${pkg_name}..." if sudo pacman -S --noconfirm --needed "$pkg_name"; then @@ -89,8 +133,13 @@ check_and_install_pkg() { return 0 } - -# Función para instalar helper AUR si no existe +# --------------------------------------------------------------- +# ensure_aur_helper() +# --------------------------------------------------------------- +# Asegura que un helper de AUR (yay o paru) esté instalado. +# Si no encuentra ninguno, procede a instalar `yay-bin` desde AUR. +# Devuelve el nombre del helper encontrado o instalado. +# --------------------------------------------------------------- ensure_aur_helper() { if command_exists yay; then echo "yay" @@ -100,6 +149,7 @@ ensure_aur_helper() { return 0 else log_warning "No se detectó yay ni paru. Instalando yay..." + # Instala `yay-bin` para evitar compilarlo desde cero, lo que es más rápido. cd /tmp git clone https://aur.archlinux.org/yay-bin.git cd yay-bin @@ -109,6 +159,17 @@ ensure_aur_helper() { fi } +# --------------------------------------------------------------- +# aur_install_packages(packages...) +# --------------------------------------------------------------- +# Instala una lista de paquetes desde el AUR. +# +# Utiliza el helper de AUR (yay o paru) que encuentre o instale. +# Pasa los flags necesarios para una instalación no interactiva. +# +# Parámetros: +# $@ - Lista de nombres de paquetes de AUR a instalar. +# --------------------------------------------------------------- aur_install_packages() { local packages=("$@") if [[ ${#packages[@]} -eq 0 ]]; then @@ -125,16 +186,26 @@ aur_install_packages() { return 1 fi - local -a base_flags=(--noconfirm --needed --noeditmenu --nodiffmenu --nocleanmenu) + local -a base_flags=(--noconfirm --needed) AUR_HELPER_CMD="$helper" local status=0 case "$helper" in yay) - "$helper" -S "${base_flags[@]}" --answerdiff None --answerclean All --answeredit None --mflags "--noconfirm" --cleanafter "${packages[@]}" + "$helper" -S "${base_flags[@]}" \ + --answerdiff None \ + --answerclean All \ + --answeredit None \ + --mflags "--noconfirm" \ + --cleanafter \ + "${packages[@]}" status=$? ;; paru) - "$helper" -S "${base_flags[@]}" --skipreview --cleanafter --mflags "--noconfirm" "${packages[@]}" + "$helper" -S "${base_flags[@]}" \ + --skipreview \ + --cleanafter \ + --mflags "--noconfirm" \ + "${packages[@]}" status=$? ;; *) @@ -145,7 +216,12 @@ aur_install_packages() { return $status } -# Función para actualizar sistema +# --------------------------------------------------------------- +# update_system() +# --------------------------------------------------------------- +# Sincroniza los repositorios y actualiza todos los paquetes del +# sistema usando `pacman`. +# --------------------------------------------------------------- update_system() { log_step "Actualizando sistema" log_info "Sincronizando repositorios y actualizando paquetes..." @@ -153,10 +229,16 @@ update_system() { log_success "Sistema actualizado" } -# Función para limpiar paquetes huérfanos +# --------------------------------------------------------------- +# cleanup_orphans() +# --------------------------------------------------------------- +# Elimina paquetes que fueron instalados como dependencias pero +# que ya no son requeridos por ningún paquete. +# --------------------------------------------------------------- cleanup_orphans() { log_step "Limpieza de paquetes huérfanos" log_info "Buscando paquetes huérfanos..." + # El `|| true` evita que el script falle si no se encuentran huérfanos. sudo pacman -Rns $(pacman -Qtdq) --noconfirm 2>/dev/null || true log_success "Limpieza completada" } diff --git a/modules/davinci-resolve.sh b/modules/davinci-resolve.sh index 94e35c8..b18f695 100755 --- a/modules/davinci-resolve.sh +++ b/modules/davinci-resolve.sh @@ -2,43 +2,64 @@ # =============================================================== # davinci-resolve.sh - Instalador de DaVinci Resolve (Intel Edition) # =============================================================== +# +# Este módulo automatiza la instalación y configuración de DaVinci +# Resolve en Arch Linux, con un enfoque específico en sistemas que +# utilizan GPUs de Intel. El proceso es complejo y requiere la +# instalación de múltiples dependencias, la configuración de +# librerías y la creación de un script "wrapper" para asegurar que +# la aplicación se ejecute con el entorno correcto. +# +# =============================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" # --- Definición de Dependencias --- -# Paquetes de los repositorios oficiales de Arch +# Paquetes de los repositorios oficiales de Arch necesarios para Resolve. PACMAN_DEPS=( - # Herramientas básicas + # Herramientas básicas para la instalación. unzip patchelf libarchive xdg-user-dirs desktop-file-utils file rsync - # Dependencias de Resolve + # Dependencias directas de Resolve. libpng libtiff libcurl ocl-icd libxcrypt-compat ffmpeg glu gtk2 fuse2 - # Dependencias de Qt + # Dependencias de Qt5, usadas por la interfaz de Resolve. qt5-base qt5-svg qt5-x11extras - # Drivers y herramientas Intel + # Drivers y herramientas de Intel para aceleración por hardware. intel-media-driver libva-utils libvdpau-va-gl clinfo ) -# Paquetes del AUR +# Paquetes del AUR. AUR_DEPS=( - "intel-compute-runtime" # Runtime OpenCL para GPUs Intel + # Runtime de OpenCL para GPUs de Intel. Esencial para el renderizado. + "intel-compute-runtime" ) -# Directorio de descargas y nombre del ejecutable +# --- Definición de Rutas --- DOWNLOADS_DIR="${HOME}/Downloads" INSTALL_DIR="/opt/resolve" WRAPPER_PATH="/usr/local/bin/resolve-intel" -# Función para mostrar una barra de progreso -# Uso: show_progress TOTAL_ITEMS CURRENT_ITEM "Mensaje" +# --------------------------------------------------------------- +# show_progress(total_items, current_item, message, last_percent) +# --------------------------------------------------------------- +# Muestra una barra de progreso simple en la terminal. +# Está diseñada para ser llamada en un bucle y actualiza la línea +# solo cuando el porcentaje cambia para ser más eficiente. +# +# Parámetros: +# $1 - Número total de ítems a procesar. +# $2 - Ítem actual que se está procesando. +# $3 - Mensaje a mostrar junto a la barra. +# $4 - (Opcional) El último porcentaje mostrado. +# --------------------------------------------------------------- show_progress() { local total=$1 local current=$2 local msg=$3 - local last_percent=${4:-"-1"} # Nuevo: Almacena el último porcentaje mostrado + local last_percent=${4:-"-1"} local percent=$((current * 100 / total)) - # Solo actualizar la barra si el porcentaje ha cambiado + # Solo actualiza si el porcentaje ha cambiado. if [[ "$percent" -gt "$last_percent" ]]; then local completed_len=$((percent / 2)) local bar="" @@ -46,25 +67,28 @@ show_progress() { local empty_len=$((50 - completed_len)) for ((i=0; i/dev/null; then log_warning "Se detectaron paquetes de NVIDIA. Resolve para Intel puede tener conflictos." read -p "¿Deseas intentar desinstalar los paquetes de NVIDIA? [s/N]: " confirm @@ -103,43 +127,41 @@ install_davinci_resolve() { # --- 2. Instalación de Dependencias --- log_info "Instalando dependencias necesarias..." - # Instalar headers del kernel correspondiente + # Instala los headers del kernel si son necesarios. local KERNEL_VERSION KERNEL_VERSION=$(uname -r) local KERNEL_PKG - # Extrae el nombre base del kernel (ej. 'linux', 'linux-zen', 'linux-lts') KERNEL_PKG=$(pacman -Qo "/boot/vmlinuz-${KERNEL_VERSION%%-*}" | awk '{print $1}') if [[ -n "$KERNEL_PKG" && ! -d "/usr/lib/modules/${KERNEL_VERSION}/build" ]]; then log_info "Instalando headers para el kernel actual (${KERNEL_PKG}-headers)..." sudo pacman -S --needed --noconfirm "${KERNEL_PKG}-headers" || log_warning "No se pudieron instalar los headers del kernel." fi - # Instalar dependencias de Pacman + # Instala dependencias desde los repositorios oficiales. start_spinner "Instalando dependencias de Pacman..." sudo pacman -S --needed --noconfirm "${PACMAN_DEPS[@]}" &> /dev/null stop_spinner $? "Dependencias de Pacman instaladas." - # Instalar dependencias de AUR + # Instala dependencias desde AUR. start_spinner "Instalando dependencias de AUR..." if aur_install_packages "${AUR_DEPS[@]}"; then stop_spinner 0 "Dependencias de AUR instaladas." else stop_spinner 1 "Falló la instalación de dependencias de AUR." - log_error "No se pudieron instalar paquetes como 'intel-compute-runtime' desde AUR." return 1 fi # --- 3. Configuración del Entorno --- log_info "Configurando el entorno para OpenCL..." - # Asegurar el archivo ICD para OpenCL de Intel + # Asegura que el fichero de configuración de OpenCL para Intel exista. if [[ ! -f /etc/OpenCL/vendors/intel.icd ]]; then log_info "Creando vendor file de OpenCL para Intel..." sudo mkdir -p /etc/OpenCL/vendors echo "/usr/lib/intel-opencl/libigdrcl.so" | sudo tee /etc/OpenCL/vendors/intel.icd >/dev/null fi - # Crear enlace /etc/pki/tls si es necesario + # Algunas aplicaciones antiguas esperan los certificados en /etc/pki/tls. if [[ ! -e /etc/pki/tls ]]; then log_info "Creando enlace /etc/pki/tls → /etc/ssl" sudo mkdir -p /etc/pki @@ -148,10 +170,9 @@ install_davinci_resolve() { sudo ldconfig || true - # Verificaciones + # Verifica que OpenCL y VA-API estén funcionando. log_info "Verificando OpenCL instalado..." clinfo | grep -E "Platform Name|Device Name" || true - log_info "Verificando soporte de decodificación VA-API para H264 / HEVC..." vainfo | grep -E "H264|HEVC" || true @@ -163,12 +184,10 @@ install_davinci_resolve() { unzip -q "${RESOLVE_ZIP}" -d "${WORKDIR}" stop_spinner $? "ZIP extraído." + # El ZIP contiene un archivo .run, que a su vez contiene un AppImage. local RUN_FILE RUN_FILE="$(find "${WORKDIR}" -maxdepth 2 -type f -name 'DaVinci_Resolve_*_Linux.run' -print -quit)" - if [[ -z "${RUN_FILE}" ]]; then - log_error "No se encontró el archivo .run dentro del ZIP." - return 1 - fi + if [[ -z "${RUN_FILE}" ]]; then log_error "No se encontró el archivo .run dentro del ZIP."; return 1; fi chmod +x "${RUN_FILE}" start_spinner "Extrayendo AppImage..." @@ -178,18 +197,13 @@ install_davinci_resolve() { stop_spinner $? "AppImage extraído." local APPDIR="${EX_DIR}/squashfs-root" - if [[ ! -d "${APPDIR}" ]]; then - log_error "No se extrajo correctamente la carpeta squashfs-root." - return 1 - fi + if [[ ! -d "${APPDIR}" ]]; then log_error "No se extrajo correctamente la carpeta squashfs-root."; return 1; fi chmod -R u+rwX,go+rX,go-w "${APPDIR}" - if [[ ! -x "${APPDIR}/bin/resolve" ]]; then - log_error "El binario resolve no existe o está vacío." - return 1 - fi + if [[ ! -x "${APPDIR}/bin/resolve" ]]; then log_error "El binario resolve no existe o está vacío."; return 1; fi - # Reemplazar librerías glib/gio/gmodule + # Resolve incluye sus propias versiones de librerías que pueden ser incompatibles. + # Se reemplazan por enlaces a las versiones del sistema. log_info "Ajustando bibliotecas glib/gio/gmodule para usar las del sistema..." pushd "${APPDIR}" >/dev/null rm -f libs/libglib-2.0.so.0 libs/libgio-2.0.so.0 libs/libgmodule-2.0.so.0 || true @@ -200,25 +214,16 @@ install_davinci_resolve() { # --- 5. Aplicar Patches y Copiar Archivos --- log_info "Aplicando RPATH con patchelf (esto puede tardar)..." - RPATH_DIRS=( - "libs" - "libs/plugins/sqldrivers" - "libs/plugins/xcbglintegrations" - "libs/plugins/imageformats" - "libs/plugins/platforms" - "libs/Fusion" - "plugins" - "bin" - ) + # Se modifica el RPATH de los binarios de Resolve para que busquen las librerías + # dentro de su propio directorio de instalación (/opt/resolve). + RPATH_DIRS=("libs" "libs/plugins/sqldrivers" "libs/plugins/xcbglintegrations" "libs/plugins/imageformats" "libs/plugins/platforms" "libs/Fusion" "plugins" "bin") RPATH_ABS="" for p in "${RPATH_DIRS[@]}"; do RPATH_ABS+="${INSTALL_DIR}/${p}:" done RPATH_ABS+="\$ORIGIN" - # Usar barra de progreso para patchelf if ! command_exists patchelf; then - log_warning "El comando 'patchelf' no está instalado. Es necesario para ajustar las librerías." start_spinner "Instalando patchelf..." sudo pacman -S --noconfirm --needed patchelf &> /dev/null stop_spinner $? "patchelf instalado." @@ -239,6 +244,7 @@ install_davinci_resolve() { log_success "RPATH aplicado a $total_files archivos." fi + # Copia los archivos de la aplicación a /opt/resolve. start_spinner "Copiando archivos a /opt/resolve..." sudo rm -rf "${INSTALL_DIR}" sudo mkdir -p "${INSTALL_DIR}" @@ -247,15 +253,15 @@ install_davinci_resolve() { sudo mkdir -p "${INSTALL_DIR}/.license" - # Enlazar libcrypt legado si es necesario + # Enlaza libcrypt.so.1 si es necesario. sudo ldconfig || true if [[ -e /usr/lib/libcrypt.so.1 ]]; then sudo ln -sf /usr/lib/libcrypt.so.1 "${INSTALL_DIR}/libs/libcrypt.so.1" fi # --- 6. Crear Wrapper y Acceso Directo --- - # Crear wrapper + acceso en escritorio log_info "Creando wrapper y acceso para DaVinci Resolve..." + # Se crea un script que establece variables de entorno necesarias antes de ejecutar Resolve. cat << EOF | sudo tee "${WRAPPER_PATH}" >/dev/null #!/usr/bin/env bash set -euo pipefail @@ -268,6 +274,7 @@ EOF sudo chmod +x "${WRAPPER_PATH}" + # Crea un archivo .desktop para que la aplicación aparezca en el menú de aplicaciones. mkdir -p "${HOME}/.local/share/applications" cat > "${HOME}/.local/share/applications/davinci-resolve-wrapper.desktop" << EOF [Desktop Entry] @@ -288,12 +295,11 @@ EOF log_success "DaVinci Resolve (Intel Edition) instalado en ${INSTALL_DIR}" log_info "Usa '${WRAPPER_PATH##*/}' para lanzar la aplicación" - log_info "Para verificar OpenCL: clinfo | grep -E 'Platform Name|Device Name'" return 0 } -# Ejecutar si se llama directamente +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then install_davinci_resolve "$@" fi diff --git a/modules/disk-format.sh b/modules/disk-format.sh index 3e73a41..f5fecfe 100755 --- a/modules/disk-format.sh +++ b/modules/disk-format.sh @@ -3,20 +3,32 @@ set -euo pipefail # =============================================================== # disk-format.sh - Soporte para FAT32 / exFAT / NTFS / ext4 # =============================================================== +# +# Este módulo instala las herramientas necesarias para trabajar +# con los sistemas de archivos más comunes, como FAT32, exFAT, +# NTFS y ext4. Además de las utilidades de línea de comandos, +# también instala herramientas gráficas como GParted y GNOME Disks +# para facilitar la gestión de discos y particiones. +# +# =============================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" run_module_main() { - log_step "Habilitar sistemas de archivos (FAT32 / exFAT / NTFS / ext4)" + log_step "Habilitar soporte para sistemas de archivos" + # --- Definición de Paquetes --- + # Se instalarán las siguientes herramientas: + # - dosfstools: Para crear y verificar sistemas de archivos FAT. + # - exfatprogs: Para sistemas de archivos exFAT. + # - ntfs-3g: Driver de código abierto para leer y escribir en NTFS. + # - e2fsprogs: Utilidades para el sistema de archivos ext2/3/4. + # - gparted: Editor de particiones gráfico. + # - gnome-disk-utility: Herramienta de discos de GNOME. local pkgs=( - dosfstools - exfatprogs - ntfs-3g - e2fsprogs - gparted - gnome-disk-utility + dosfstools exfatprogs ntfs-3g e2fsprogs + gparted gnome-disk-utility ) local failed=false @@ -30,18 +42,18 @@ run_module_main() { log_warning "Algunos paquetes no se pudieron instalar. Revisa los mensajes anteriores." fi - log_success "Soporte de sistemas de archivos habilitado." + log_success "Soporte para sistemas de archivos comunes habilitado." echo "" - log_info "Formatea manualmente con las utilidades instaladas:" + log_info "Para formatear discos desde la terminal, puedes usar:" echo " • FAT32 : sudo mkfs.fat -F32 /dev/sdXn" echo " • exFAT : sudo mkfs.exfat /dev/sdXn" echo " • NTFS : sudo mkfs.ntfs -f /dev/sdXn" echo " • ext4 : sudo mkfs.ext4 -F /dev/sdXn" - log_info "Alternativamente puedes usar GParted o GNOME Disks para un asistente gráfico." + log_info "También puedes usar 'gparted' o 'gnome-disks' para una gestión gráfica." return 0 } -# Ejecutar si se llama directamente +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then run_module_main "$@" fi diff --git a/modules/docker.sh b/modules/docker.sh index c45db61..ceb0f26 100755 --- a/modules/docker.sh +++ b/modules/docker.sh @@ -2,70 +2,96 @@ # =============================================================== # docker.sh - Configuración de Docker y Portainer # =============================================================== +# +# Este módulo se encarga de la instalación y configuración de Docker +# y, opcionalmente, de Portainer, una interfaz web para gestionar +# contenedores. +# +# Funciones principales: +# - Instala Docker y Docker Compose desde los repositorios oficiales. +# - Habilita e inicia los servicios de Docker. +# - Agrega el usuario actual al grupo `docker` para permitir la +# ejecución de comandos de Docker sin `sudo`. +# - Ofrece la opción de instalar Portainer. +# +# =============================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" +# --------------------------------------------------------------- +# install_docker() +# --------------------------------------------------------------- +# Orquesta la instalación y configuración de Docker y Portainer. +# --------------------------------------------------------------- install_docker() { log_step "Configuración de Docker y Portainer" - # Instalar Docker + # --- 1. Instalación de Docker --- log_info "Instalando Docker y Docker Compose..." - sudo pacman -S --noconfirm --needed \ - docker docker-compose || { - log_error "Error al instalar Docker" + if ! sudo pacman -S --noconfirm --needed docker docker-compose; then + log_error "No se pudo instalar Docker. Abortando." return 1 - } - - # Habilitar y iniciar Docker - log_info "Habilitando servicio de Docker..." - sudo systemctl enable docker.service - sudo systemctl enable containerd.service - sudo systemctl start docker.service - - # Agregar usuario al grupo docker (si no está ya) - if ! groups "$USER" | grep -q docker; then - log_info "Agregando usuario al grupo docker..." - sudo usermod -aG docker "$USER" - log_warning "Necesitarás cerrar sesión y volver a iniciar para usar Docker sin sudo" fi + # --- 2. Configuración del Servicio de Docker --- + log_info "Habilitando e iniciando los servicios de Docker..." + # Habilita los servicios para que se inicien automáticamente con el sistema. + sudo systemctl enable docker.service + sudo systemctl enable containerd.service + # Inicia los servicios en la sesión actual. + sudo systemctl start docker.service + + # --- 3. Configuración de Permisos de Usuario --- + # Agrega el usuario actual al grupo `docker` para evitar tener que usar `sudo`. + if ! groups "$USER" | grep -q docker; then + log_info "Agregando al usuario '$USER' al grupo 'docker'..." + if ! sudo usermod -aG docker "$USER"; then + log_error "No se pudo agregar el usuario al grupo 'docker'." + # No es un error fatal, así que solo se muestra una advertencia. + else + log_warning "Para que los cambios de grupo surtan efecto, debes cerrar sesión y volver a iniciarla." + fi + fi + + # --- 4. Instalación Opcional de Portainer --- echo "" read -p "¿Deseas instalar Portainer (interfaz web para Docker)? [S/n]: " confirm_portainer if [[ ! "${confirm_portainer}" =~ ^[Nn]$ ]]; then - log_info "Configurando Portainer..." + log_info "Instalando Portainer..." - # Verificar si Portainer ya está corriendo + # Comprueba si el contenedor de Portainer ya existe para evitar errores. if sudo docker ps -a --format '{{.Names}}' | grep -q "^portainer$"; then - log_info "Portainer ya existe. Reiniciando contenedor..." - sudo docker stop portainer 2>/dev/null || true - sudo docker rm portainer 2>/dev/null || true + log_info "El contenedor de Portainer ya existe. Se detendrá y eliminará para volver a crearlo." + sudo docker stop portainer >/dev/null 2>&1 || true + sudo docker rm portainer >/dev/null 2>&1 || true fi - # Crear volumen y contenedor de Portainer - sudo docker volume create portainer_data 2>/dev/null || true + # Crea un volumen de Docker para persistir los datos de Portainer. + sudo docker volume create portainer_data >/dev/null 2>&1 || true + # Ejecuta el contenedor de Portainer. if sudo docker run -d -p 8000:8000 -p 9443:9443 \ --name portainer \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ portainer/portainer-ce:latest; then - log_success "Portainer instalado y ejecutándose" - log_info "Accede a Portainer en: https://localhost:9443" + log_success "Portainer se ha instalado y está corriendo." + log_info "Puedes acceder a la interfaz web en: https://localhost:9443" else - log_error "Error al instalar Portainer" - # No retornamos error, Docker ya está instalado. + log_error "No se pudo instalar Portainer." + # No se devuelve un error aquí porque la instalación de Docker fue exitosa. fi else log_info "Se omitió la instalación de Portainer." fi - log_success "Configuración de Docker completada." + log_success "La configuración de Docker ha finalizado." return 0 } -# Ejecutar si se llama directamente +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then install_docker "$@" fi diff --git a/modules/hyprland-config.sh b/modules/hyprland-config.sh index d90caa7..c84df9b 100755 --- a/modules/hyprland-config.sh +++ b/modules/hyprland-config.sh @@ -2,55 +2,69 @@ # =============================================================== # hyprland-config.sh - Instala la configuración personalizada de Hyprland # =============================================================== +# +# Este módulo se encarga de instalar una configuración personalizada +# para el gestor de ventanas Hyprland. +# +# Funciones principales: +# - Realiza una copia de seguridad de la configuración existente de +# Hyprland en ~/.config/hypr. +# - Copia la nueva configuración desde la carpeta `hypr_config` +# del repositorio a ~/.config/hypr. +# - Establece un tema de iconos por defecto, utilizando para ello +# funciones del módulo `icon_manager.sh`. +# +# =============================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" -# Cargar el gestor de iconos para usar sus funciones +# Se carga el módulo `icon_manager.sh` para poder utilizar su +# función `set_default_icon_theme`. source "${SCRIPT_DIR}/icon_manager.sh" run_module_main() { - log_step "Instalación de Configuración de Hyprland" + log_step "Instalación de la Configuración de Hyprland" - # --- 1. Copiar archivos de configuración --- - # La configuración de Hyprland debe estar en una carpeta 'hypr_config' en la raíz del repo + # --- 1. Copia de Archivos de Configuración --- + # La configuración que se va a instalar debe estar en una carpeta + # llamada `hypr_config` en la raíz del repositorio. local source_dir="${SCRIPT_DIR}/../hypr_config" local dest_dir="$HOME/.config/hypr" if [[ ! -d "$source_dir" ]]; then - log_error "No se encontró el directorio de configuración 'hypr_config' en la raíz del repositorio." - log_info "Asegúrate de que la carpeta con tu configuración se llame 'hypr_config'." + log_error "No se encontró el directorio de configuración 'hypr_config'." + log_info "Asegúrate de que la carpeta con tu configuración de Hyprland exista en la raíz del repositorio." return 1 fi - # Crear copia de seguridad si ya existe una configuración - if [[ -d "$dest_dir" ]]; then - local backup_dir="${dest_dir}.bak_$(date +%F_%T)" - log_warning "Configuración de Hyprland existente encontrada." - log_info "Creando copia de seguridad en: ${backup_dir}" - if mv "$dest_dir" "$backup_dir"; then - log_success "Copia de seguridad creada." - else - log_error "No se pudo crear la copia de seguridad. Abortando." - return 1 - fi + # Se crea una copia de seguridad de la configuración existente antes de sobrescribirla. + # Se utiliza la función `backup_file` definida en `common.sh`. + if ! backup_file "$dest_dir"; then + return 1 fi log_info "Copiando la configuración de Hyprland a ${dest_dir}..." - # Usamos rsync para una copia eficiente - rsync -a --info=progress2 "$source_dir/" "$dest_dir/" + # Se usa `rsync` para una copia eficiente que muestra el progreso. + if ! rsync -a --info=progress2 "$source_dir/" "$dest_dir/"; then + log_error "No se pudo copiar la configuración de Hyprland." + return 1 + fi - # --- 2. Establecer el tema de iconos por defecto --- + # --- 2. Establecimiento del Tema de Iconos --- log_info "Estableciendo el tema de iconos por defecto (Tela Nord)..." - # Llamamos a la función específica de icon_manager.sh - set_default_icon_theme + # Llama a una función del módulo `icon_manager.sh`. + if ! set_default_icon_theme; then + log_warning "No se pudo establecer el tema de iconos por defecto." + # No es un error fatal, la configuración principal ya se copió. + fi - log_success "Configuración de Hyprland instalada correctamente." - log_warning "Por favor, cierra sesión y vuelve a iniciarla para aplicar los cambios." + log_success "La configuración de Hyprland se ha instalado correctamente." + log_warning "Para que los cambios se apliquen, por favor, cierra sesión y vuelve a iniciarla." return 0 } -# Ejecutar si se llama directamente +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then run_module_main "$@" -fi \ No newline at end of file +fi diff --git a/modules/icon_manager.sh b/modules/icon_manager.sh index 01bcdba..84cf93f 100755 --- a/modules/icon_manager.sh +++ b/modules/icon_manager.sh @@ -1,31 +1,62 @@ #!/usr/bin/env bash -# icon_manager.sh (v2) +# =============================================================== +# icon_manager.sh - Gestor de Temas de Iconos para Hyprland +# =============================================================== # -# Un script de gestión para instalar y cambiar entre diferentes temas de iconos -# en un entorno Hyprland/Omarchy. Incluye temas base y personalizaciones. +# Este módulo proporciona una interfaz interactiva para instalar y +# cambiar entre diferentes temas de iconos. Está diseñado para +# integrarse con Hyprland, modificando su fichero de autostart +# para asegurar que la configuración del tema de iconos sea persistente +# entre sesiones. # +# Dependencias: git, gsettings (parte de glib2). +# +# =============================================================== set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" # --- Variables Globales --- +# Ruta al fichero de autostart de Hyprland donde se guardará la configuración. AUTOSTART_FILE="$HOME/.config/hypr/autostart.conf" +# Directorio estándar para iconos instalados por el usuario. ICON_DIR_USER="$HOME/.local/share/icons" # --- Funciones de Utilidad --- -# Función para verificar dependencias +# --------------------------------------------------------------- +# check_deps() +# --------------------------------------------------------------- +# Verifica que las dependencias necesarias (git y gsettings) +# estén instaladas en el sistema. +# --------------------------------------------------------------- check_deps() { if ! command_exists git; then - log_error "git no está instalado. Por favor, instálalo para continuar (ej. sudo pacman -S git)." + log_error "El comando 'git' no está instalado. Por favor, instálalo para continuar (ej. sudo pacman -S git)." + return 1 + fi + if ! command_exists gsettings; then + log_error "El comando 'gsettings' no está instalado. Es parte de 'glib2' y es esencial." return 1 fi return 0 } -# Función para aplicar la configuración de forma persistente -# Argumento 1: Nombre del tema de iconos (ej. 'Tela-nord-dark') +# --------------------------------------------------------------- +# apply_theme(theme_name) +# --------------------------------------------------------------- +# Aplica un tema de iconos y lo hace persistente. +# +# Esta función realiza dos acciones: +# 1. Modifica el fichero de autostart de Hyprland (`autostart.conf`) +# para que el tema se cargue automáticamente en cada inicio de sesión. +# 2. Aplica el tema en la sesión actual usando `gsettings` para +# que el cambio sea visible de inmediato. +# +# Parámetros: +# $1 - Nombre exacto del tema de iconos a aplicar. +# --------------------------------------------------------------- apply_theme() { local theme_name="$1" log_info "Aplicando el tema de iconos '$theme_name'..." @@ -33,10 +64,10 @@ apply_theme() { mkdir -p "$(dirname "$AUTOSTART_FILE")" touch "$AUTOSTART_FILE" - # Eliminar cualquier configuración de icon-theme anterior para evitar conflictos + # Elimina configuraciones anteriores del tema de iconos para evitar duplicados. sed -i '/exec-once = gsettings set org.gnome.desktop.interface icon-theme/d' "$AUTOSTART_FILE" - # Añadir el bloque de configuración si no existe + # Añade un bloque de configuración si no existe. if ! grep -Fq "CONFIGURACIÓN DE TEMA DE ICONOS" "$AUTOSTART_FILE"; then echo -e "\n# -----------------------------------------------------" >> "$AUTOSTART_FILE" echo "# CONFIGURACIÓN DE TEMA DE ICONOS" >> "$AUTOSTART_FILE" @@ -45,18 +76,18 @@ apply_theme() { echo "exec-once = sleep 1" >> "$AUTOSTART_FILE" fi - # Añadir el comando gsettings para el tema seleccionado + # Añade el comando para establecer el tema seleccionado. echo "exec-once = gsettings set org.gnome.desktop.interface icon-theme '$theme_name'" >> "$AUTOSTART_FILE" - # Aplicar el tema en la sesión actual para un efecto inmediato + # Aplica el tema en la sesión actual. gsettings set org.gnome.desktop.interface icon-theme "$theme_name" - log_success "¡Tema configurado! Se aplicó en la sesión actual y se guardó en $AUTOSTART_FILE" + log_success "¡Tema configurado! Se aplicó en la sesión actual y se guardó en $AUTOSTART_FILE." } # --- Funciones de Instalación de Temas --- -# Función auxiliar para asegurar que el tema base Papirus esté instalado +# Asegura que el tema base de Papirus esté instalado, ya que otros temas lo usan como base. ensure_papirus_installed() { local temp_dir="$1" if [[ ! -d "$ICON_DIR_USER/Papirus-Dark" ]]; then @@ -68,19 +99,16 @@ ensure_papirus_installed() { fi } -# Función para instalar y aplicar el tema Tela Nord (usado como default) -# Argumento 1 (opcional): Directorio temporal a utilizar. +# Instala el tema 'Tela-nord-dark', que se usa como predeterminado en la configuración de Hyprland. set_default_icon_theme() { local theme_name="Tela-nord-dark" - local temp_dir_param="${1:-}" # Aceptar directorio temporal como parámetro - log_info "Gestionando el tema de iconos por defecto '$theme_name'..." + local temp_dir_param="${1:-}" + log_step "Gestionando el tema de iconos por defecto '$theme_name'" if [[ -d "$ICON_DIR_USER/$theme_name" ]]; then log_info "El tema '$theme_name' ya está instalado." else log_info "Instalando el tema '$theme_name'..." - # Si no se pasa un directorio, crear uno propio y limpiarlo. - # Si se pasa, usarlo sin limpiarlo (la función llamadora se encarga). local temp_dir="${temp_dir_param}" [[ -z "$temp_dir" ]] && temp_dir=$(mktemp -d) @@ -92,22 +120,23 @@ set_default_icon_theme() { apply_theme "$theme_name" } +# Instala la versión estándar del tema Papirus. install_papirus_standard() { local theme_name="Papirus-Dark" local temp_dir="$1" - echo "--- Gestionando Papirus Icons (Estándar) ---" + log_step "Gestionando Papirus Icons (Estándar)" ensure_papirus_installed "$temp_dir" - # Si el usuario quiere el Papirus estándar, restauramos los colores por si acaso if command_exists papirus-folders; then papirus-folders --default --theme "$theme_name" fi apply_theme "$theme_name" } +# Instala el tema Candy. install_candy() { local theme_name="Candy" local temp_dir="$1" - echo "--- Gestionando Candy Icons ---" + log_step "Gestionando Candy Icons" if [[ -d "$ICON_DIR_USER/$theme_name" ]]; then log_info "El tema ya está instalado." else @@ -118,24 +147,23 @@ install_candy() { apply_theme "$theme_name" } +# Instala el tema Papirus con colores de la paleta Catppuccin. install_papirus_catppuccin() { local theme_name="Papirus-Dark" local catppuccin_flavor="mocha" local temp_dir="$1" - echo "--- Gestionando Papirus Icons con colores Catppuccin ($catppuccin_flavor) ---" + log_step "Gestionando Papirus Icons con colores Catppuccin ($catppuccin_flavor)" ensure_papirus_installed "$temp_dir" - # 2. Descargar y ejecutar el script de personalización log_info "Descargando y aplicando el colorizador Catppuccin..." git clone --depth 1 https://github.com/catppuccin/papirus-folders.git "$temp_dir/papirus-folders-catppuccin" chmod +x "$temp_dir/papirus-folders-catppuccin/papirus-folders" - # Ejecutar el script para cambiar el color de las carpetas + # Ejecuta el script para cambiar el color de las carpetas. "$temp_dir/papirus-folders-catppuccin/papirus-folders" -C "catppuccin-${catppuccin_flavor}" --theme "$theme_name" - # 3. Aplicar el tema (el nombre sigue siendo Papirus-Dark, pero los iconos han cambiado) apply_theme "$theme_name" } @@ -167,7 +195,6 @@ run_module_main() { echo read -p "Tu elección: " choice - # Limpiar el directorio temporal para la nueva operación rm -rf -- "$temp_dir"/* case $choice in @@ -189,6 +216,7 @@ run_module_main() { return 0 } +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then run_module_main "$@" -fi \ No newline at end of file +fi diff --git a/modules/mouse_cursor.sh b/modules/mouse_cursor.sh index 976cf3f..d8769a5 100755 --- a/modules/mouse_cursor.sh +++ b/modules/mouse_cursor.sh @@ -2,75 +2,123 @@ # =============================================================== # mouse_cursor.sh - Instala y configura el tema de cursor Bibata # =============================================================== +# +# Este módulo automatiza la descarga, instalación y configuración +# del tema de cursor "Bibata-Modern-Ice". +# +# Funciones principales: +# - Descarga el tema de cursor desde su repositorio de GitHub. +# - Lo instala en el directorio ~/.icons del usuario. +# - Configura el cursor para Hyprland, modificando el fichero +# `~/.config/hypr/envs.conf`. +# - Configura el cursor para aplicaciones GTK a través de `gsettings`. +# +# Dependencias: curl, tar, gsettings (parte de glib2). +# +# =============================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" +# --------------------------------------------------------------- +# check_cursor_deps() +# --------------------------------------------------------------- +# Verifica que las dependencias necesarias para este módulo estén +# instaladas. +# --------------------------------------------------------------- +check_cursor_deps() { + local missing_deps=0 + for cmd in curl tar gsettings; do + if ! command_exists "$cmd"; then + log_error "El comando '$cmd' es necesario pero no está instalado." + ((missing_deps++)) + fi + done + return $missing_deps +} + +# --------------------------------------------------------------- +# install_mouse_cursor() +# --------------------------------------------------------------- +# Orquesta todo el proceso de instalación y configuración del cursor. +# --------------------------------------------------------------- install_mouse_cursor() { log_step "Instalación del Tema de Cursor (Bibata-Modern-Ice)" - # --- Variables --- + if ! check_cursor_deps; then + return 1 + fi + + # --- Variables de Configuración --- local CURSOR_THEME='Bibata-Modern-Ice' local CURSOR_SIZE=24 - local ENVS_FILE="$HOME/.config/hypr/envs.conf" - local AUTOSTART_FILE="$HOME/.config/hypr/autostart.conf" + local HYPR_CONFIG_DIR="$HOME/.config/hypr" + local ENVS_FILE="${HYPR_CONFIG_DIR}/envs.conf" local DOWNLOAD_URL="https://github.com/ful1e5/Bibata_Cursor/releases/download/v2.0.7/Bibata-Modern-Ice.tar.xz" local ARCHIVE_NAME="Bibata-Modern-Ice.tar.xz" - # --- Paso 1 y 2: Descargar, Extraer e Instalar --- + # --- 1. Descarga e Instalación --- log_info "Descargando e instalando el tema de cursor..." local TEMP_DIR TEMP_DIR=$(mktemp -d -p "/tmp" cursor_setup_XXXXXX) trap 'rm -rf "${TEMP_DIR}"' EXIT # Limpieza automática al salir - if curl -sL "$DOWNLOAD_URL" -o "${TEMP_DIR}/${ARCHIVE_NAME}"; then - tar -xJf "${TEMP_DIR}/${ARCHIVE_NAME}" -C "${TEMP_DIR}" - mkdir -p "$HOME/.icons" - # Asegurar una instalación limpia eliminando la versión anterior si existe - if [ -d "${TEMP_DIR}/${CURSOR_THEME}" ]; then - rm -rf "$HOME/.icons/${CURSOR_THEME}" # Eliminar destino para evitar conflictos - if mv "${TEMP_DIR}/${CURSOR_THEME}" "$HOME/.icons/"; then - log_success "Tema de cursor instalado en ~/.icons/" - else - log_error "No se pudo mover el tema del cursor a ~/.icons/" - return 1 - fi - else - log_error "El directorio del tema '${CURSOR_THEME}' no se encontró en el archivo." - return 1 - fi - else + if ! curl -sL "$DOWNLOAD_URL" -o "${TEMP_DIR}/${ARCHIVE_NAME}"; then log_error "No se pudo descargar el tema de cursor desde $DOWNLOAD_URL" return 1 fi - # --- Paso 3: Configurar variables de entorno para Hyprland --- - if [ -f "$ENVS_FILE" ]; then - log_info "Configurando variables de entorno en $ENVS_FILE..." - if ! grep -q "HYPRCURSOR_THEME,${CURSOR_THEME}" "$ENVS_FILE"; then - echo -e "\n# Custom Cursor Theme" >> "$ENVS_FILE" - echo "env = HYPRCURSOR_THEME,$CURSOR_THEME" >> "$ENVS_FILE" - echo "env = HYPRCURSOR_SIZE,$CURSOR_SIZE" >> "$ENVS_FILE" - echo "env = XCURSOR_THEME,$CURSOR_THEME" >> "$ENVS_FILE" - echo "env = XCURSOR_SIZE,$CURSOR_SIZE" >> "$ENVS_FILE" - log_success "Variables de cursor añadidas a Hyprland." - else - log_info "Las variables de cursor para Hyprland ya parecen estar configuradas." + tar -xJf "${TEMP_DIR}/${ARCHIVE_NAME}" -C "${TEMP_DIR}" + mkdir -p "$HOME/.icons" + + # Asegura una instalación limpia eliminando la versión anterior si existe. + if [[ -d "${TEMP_DIR}/${CURSOR_THEME}" ]]; then + rm -rf "$HOME/.icons/${CURSOR_THEME}" + if ! mv "${TEMP_DIR}/${CURSOR_THEME}" "$HOME/.icons/"; then + log_error "No se pudo mover el tema del cursor a ~/.icons/" + return 1 fi + log_success "Tema de cursor instalado en ~/.icons/" + else + log_error "El directorio del tema '${CURSOR_THEME}' no se encontró en el archivo descargado." + return 1 fi - # --- Paso 4: Configurar GTK --- - log_info "Configurando el cursor para aplicaciones GTK..." - gsettings set org.gnome.desktop.interface cursor-theme "$CURSOR_THEME" - gsettings set org.gnome.desktop.interface cursor-size "$CURSOR_SIZE" - log_success "Configuración de GSettings aplicada." + # --- 2. Configuración para Hyprland --- + log_info "Configurando el cursor para Hyprland..." + mkdir -p "$HYPR_CONFIG_DIR" + touch "$ENVS_FILE" - log_success "¡Configuración del cursor completada!" - log_warning "Por favor, cierra sesión y vuelve a iniciarla para aplicar los cambios." + # Elimina configuraciones de cursor anteriores para evitar duplicados. + sed -i '/^env = HYPRCURSOR_THEME/d' "$ENVS_FILE" + sed -i '/^env = HYPRCURSOR_SIZE/d' "$ENVS_FILE" + sed -i '/^env = XCURSOR_THEME/d' "$ENVS_FILE" + sed -i '/^env = XCURSOR_SIZE/d' "$ENVS_FILE" + + # Añade las nuevas variables de entorno. + echo -e "\n# Configuración del Tema de Cursor (gestionado por Omarchy Setup)" >> "$ENVS_FILE" + echo "env = HYPRCURSOR_THEME,$CURSOR_THEME" >> "$ENVS_FILE" + echo "env = HYPRCURSOR_SIZE,$CURSOR_SIZE" >> "$ENVS_FILE" + echo "env = XCURSOR_THEME,$CURSOR_THEME" >> "$ENVS_FILE" + echo "env = XCURSOR_SIZE,$CURSOR_SIZE" >> "$ENVS_FILE" + log_success "Variables de entorno para el cursor añadidas a $ENVS_FILE." + + # --- 3. Configuración para Aplicaciones GTK --- + log_info "Configurando el cursor para aplicaciones GTK..." + if gsettings set org.gnome.desktop.interface cursor-theme "$CURSOR_THEME" && \ + gsettings set org.gnome.desktop.interface cursor-size "$CURSOR_SIZE"; then + log_success "Configuración de GSettings para GTK aplicada correctamente." + else + log_error "No se pudo aplicar la configuración de GSettings para GTK." + return 1 + fi + + log_success "La configuración del cursor ha finalizado." + log_warning "Para que todos los cambios surtan efecto, por favor, cierra sesión y vuelve a iniciarla." return 0 } -# Ejecutar si se llama directamente +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then install_mouse_cursor "$@" -fi \ No newline at end of file +fi diff --git a/modules/printer.sh b/modules/printer.sh index 97fd24d..519eff2 100755 --- a/modules/printer.sh +++ b/modules/printer.sh @@ -2,6 +2,19 @@ # =============================================================== # printer.sh - Configuración de impresoras (CUPS) # =============================================================== +# +# Este módulo instala y configura el sistema de impresión CUPS +# (Common Unix Printing System) en Arch Linux. +# +# Funciones principales: +# - Instala CUPS, filtros de impresión y drivers genéricos. +# - Instala Avahi para la detección automática de impresoras en red. +# - Instala drivers específicos para impresoras Epson desde AUR. +# - Habilita y arranca los servicios de CUPS y Avahi. +# - Añade al usuario al grupo `lp` para permitir la administración +# de impresoras. +# +# =============================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" @@ -11,65 +24,65 @@ install_printer() { local target_user="${SUDO_USER:-$USER}" - log_info "Instalando CUPS y paquetes base..." + # --- 1. Instalación de Paquetes Base --- + log_info "Instalando CUPS y paquetes base de impresión..." + # Paquetes: + # - cups, cups-pdf, cups-filters: El núcleo de CUPS. + # - ghostscript, gsfonts: Para interpretar PostScript. + # - gutenprint, foomatic-*: Drivers de impresión genéricos. + # - system-config-printer: Herramienta gráfica de configuración. + # - avahi, nss-mdns: Para descubrir impresoras en la red. local base_pkgs=( - cups cups-pdf cups-filters - ghostscript gsfonts - gutenprint + cups cups-pdf cups-filters ghostscript gsfonts gutenprint foomatic-db-engine foomatic-db foomatic-db-ppds foomatic-db-nonfree foomatic-db-nonfree-ppds - system-config-printer - avahi nss-mdns + system-config-printer avahi nss-mdns ) - local pkg_failed=false - for pkg in "${base_pkgs[@]}"; do - if ! check_and_install_pkg "$pkg"; then - pkg_failed=true - fi - done - if [[ "$pkg_failed" == true ]]; then - log_warning "Algunos paquetes base no pudieron instalarse. Revisa los mensajes anteriores." + + if ! sudo pacman -S --noconfirm --needed "${base_pkgs[@]}"; then + log_warning "Algunos paquetes base de impresión no pudieron instalarse. El servicio podría no funcionar." fi - log_info "Instalando drivers para Epson (ESC/P-R)..." + # --- 2. Instalación de Drivers de AUR --- + log_info "Instalando drivers para impresoras Epson (desde AUR)..." + # Drivers específicos para modelos de inyección de tinta de Epson. local aur_drivers=("epson-inkjet-printer-escpr" "epson-inkjet-printer-escpr2" "epson-printer-utility") if ! aur_install_packages "${aur_drivers[@]}"; then - log_warning "No se pudieron instalar todos los drivers de Epson de forma automática. Revisa 'epson-inkjet-printer-escpr2' y 'epson-printer-utility' manualmente." + log_warning "No se pudieron instalar todos los drivers de Epson desde AUR. Revisa los mensajes de error." fi - log_info "Verificando servicios de impresión..." + # --- 3. Habilitación de Servicios --- + log_info "Habilitando y arrancando los servicios de impresión..." local services=("cups.service" "avahi-daemon.service") for svc in "${services[@]}"; do - if sudo systemctl is-enabled "$svc" &>/dev/null; then - log_info "${svc} ya está habilitado." - else + if ! sudo systemctl is-enabled "$svc" &>/dev/null; then sudo systemctl enable "$svc" - log_success "${svc} habilitado." + log_success "Servicio ${svc} habilitado." fi - - if sudo systemctl is-active "$svc" &>/dev/null; then - log_info "${svc} ya está en ejecución." - else + if ! sudo systemctl is-active "$svc" &>/dev/null; then sudo systemctl start "$svc" - log_success "${svc} iniciado." + log_success "Servicio ${svc} iniciado." fi done + # --- 4. Configuración de Permisos de Usuario --- + # El usuario debe pertenecer al grupo `lp` para administrar impresoras. if ! id -nG "$target_user" | grep -qw lp; then - log_info "Agregando usuario ${target_user} al grupo lp..." + log_info "Agregando al usuario '${target_user}' al grupo 'lp' para administrar impresoras..." sudo usermod -aG lp "$target_user" + log_warning "Para que este cambio de grupo tenga efecto, es necesario cerrar sesión y volver a iniciarla." else - log_info "El usuario ${target_user} ya pertenece al grupo lp." + log_info "El usuario '${target_user}' ya pertenece al grupo 'lp'." fi - log_success "Dependencias de impresión instaladas." - log_info "Añade tu impresora Epson L4150 desde http://localhost:631 o con 'system-config-printer'." - log_info "El módulo no configura impresoras automáticamente; solo deja listas las dependencias." + log_success "La configuración de CUPS ha finalizado." + log_info "Puedes añadir y gestionar tus impresoras desde la interfaz web de CUPS en http://localhost:631" + log_info "o utilizando la herramienta gráfica 'system-config-printer'." return 0 } -# Ejecutar si se llama directamente +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then install_printer "$@" fi diff --git a/modules/ssh-keyring.sh b/modules/ssh-keyring.sh index 063c5c4..04b72eb 100755 --- a/modules/ssh-keyring.sh +++ b/modules/ssh-keyring.sh @@ -2,10 +2,37 @@ # =============================================================== # ssh-keyring.sh - Sincronizar claves SSH con GNOME Keyring # =============================================================== +# +# Este módulo se encarga de encontrar todas las claves SSH privadas +# en el directorio ~/.ssh del usuario y añadirlas al agente de +# GNOME Keyring. Esto permite que las claves estén disponibles +# para autenticación sin necesidad de introducir la passphrase +# cada vez, ya que el keyring las gestiona de forma segura. +# +# Funciones principales: +# - Inicia el daemon de GNOME Keyring con los componentes de +# SSH y secretos. +# - Configura la variable de entorno SSH_AUTH_SOCK para que +# apunten al socket del keyring. +# - Detecta claves ya cargadas para evitar añadirlas de nuevo. +# +# Dependencias: gnome-keyring, openssh. +# +# =============================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" +# --------------------------------------------------------------- +# _derive_fingerprint(key_path) +# --------------------------------------------------------------- +# Obtiene el "fingerprint" (huella digital) de una clave SSH. +# Esto se usa para identificar de forma única cada clave y así +# evitar añadir al agente claves que ya han sido cargadas. +# +# Parámetros: +# $1 - Ruta a la clave SSH privada. +# --------------------------------------------------------------- _derive_fingerprint() { local key_path="$1" local pub_path="${key_path}.pub" @@ -19,73 +46,72 @@ _derive_fingerprint() { echo "$fingerprint" } +# --------------------------------------------------------------- +# sync_ssh_keyring() +# --------------------------------------------------------------- +# Función principal que orquesta la sincronización de claves. +# --------------------------------------------------------------- sync_ssh_keyring() { log_step "Sincronizar claves SSH con GNOME Keyring" + # --- 1. Verificación de Dependencias --- if ! command_exists gnome-keyring-daemon; then - log_error "gnome-keyring-daemon no está instalado. Ejecuta primero el módulo de aplicaciones." + log_error "El comando 'gnome-keyring-daemon' no está instalado. Ejecuta primero el módulo de aplicaciones." return 1 fi - if ! command_exists ssh-add; then - log_error "ssh-add no está disponible (openssh). Instala el módulo de aplicaciones antes." + log_error "El comando 'ssh-add' (de openssh) no está disponible. Instala primero el módulo de aplicaciones." return 1 fi + # --- 2. Configuración del Entorno de GNOME Keyring --- + # Asegura que la variable SSH_AUTH_SOCK apunte al socket correcto. mkdir -p "${HOME}/.config/environment.d" cat <<'EOF' > "${HOME}/.config/environment.d/10-gnome-keyring.conf" SSH_AUTH_SOCK=/run/user/$UID/keyring/ssh EOF + # Inicia el daemon de GNOME Keyring si no está ya en ejecución. local keyring_eval="" if keyring_eval="$(gnome-keyring-daemon --start --components=ssh,secrets 2>/dev/null)"; then eval "$keyring_eval" - log_success "GNOME Keyring iniciado." + log_success "El daemon de GNOME Keyring se ha iniciado." else - log_info "GNOME Keyring ya estaba en ejecución." + log_info "El daemon de GNOME Keyring ya estaba en ejecución." fi + # Exporta la variable SSH_AUTH_SOCK para la sesión actual. local keyring_socket="${SSH_AUTH_SOCK:-/run/user/$UID/keyring/ssh}" if [[ ! -S "$keyring_socket" ]]; then - log_warning "No se encontró el socket de GNOME Keyring en ${keyring_socket}." - if [[ -S "/run/user/$UID/keyring/ssh" ]]; then - keyring_socket="/run/user/$UID/keyring/ssh" - else - log_error "GNOME Keyring no expone el componente SSH. Revisa tu sesión." - return 1 - fi + log_error "No se encontró el socket de GNOME Keyring. El componente SSH podría no estar activo." + return 1 fi export SSH_AUTH_SOCK="$keyring_socket" + # --- 3. Búsqueda y Filtrado de Claves SSH --- local ssh_dir="${HOME}/.ssh" if [[ ! -d "$ssh_dir" ]]; then - log_warning "No existe el directorio ${ssh_dir}. No hay claves para agregar." + log_warning "El directorio ${ssh_dir} no existe. No hay claves para agregar." return 0 fi + # Encuentra todas las claves privadas en ~/.ssh, excluyendo ficheros públicos y de configuración. mapfile -t ssh_private_keys < <( find "$ssh_dir" -maxdepth 1 -type f -perm -u=r \ - ! -name "*.pub" \ - ! -name "*-cert.pub" \ - ! -name "known_hosts" \ - ! -name "known_hosts.*" \ - ! -name "authorized_keys" \ - ! -name "config" \ - ! -name "*.old" \ - ! -name "agent" \ - ! -name "*.bak" \ - 2>/dev/null | sort + ! -name "*.pub" ! -name "*-cert.pub" ! -name "known_hosts" \ + ! -name "known_hosts.*" ! -name "authorized_keys" ! -name "config" \ + ! -name "*.old" ! -name "agent" ! -name "*.bak" 2>/dev/null | sort ) if [[ ${#ssh_private_keys[@]} -eq 0 ]]; then - log_warning "No se encontraron claves privadas SSH en ${ssh_dir}." + log_info "No se encontraron claves privadas en ${ssh_dir}." return 0 fi + # --- 4. Sincronización de Claves --- + # Obtiene los fingerprints de las claves que ya están cargadas en el agente. local existing_fingerprints="" if output=$(SSH_AUTH_SOCK="$SSH_AUTH_SOCK" ssh-add -l 2>/dev/null); then existing_fingerprints="$(awk '{print $2}' <<<"$output")" - else - existing_fingerprints="" fi local added=0 @@ -93,37 +119,40 @@ EOF local fingerprint fingerprint="$(_derive_fingerprint "$key_path")" if [[ -z "$fingerprint" ]] && ! ssh-keygen -y -f "$key_path" >/dev/null 2>&1; then - log_warning "El archivo $(basename "$key_path") no parece una clave privada válida. Se omite." + log_warning "El archivo $(basename "$key_path") no parece una clave privada válida y será omitido." continue fi + # Si la clave ya está en el agente, la omite. if [[ -n "$fingerprint" ]] && grep -Fq "$fingerprint" <<<"$existing_fingerprints"; then - log_info "Clave $(basename "$key_path") ya está registrada en el keyring." + log_info "La clave $(basename "$key_path") ya está registrada en el keyring." continue fi - log_info "Añadiendo clave $(basename "$key_path") al keyring..." + # Intenta añadir la clave. Se pedirá la passphrase si está protegida. + log_info "Añadiendo la clave $(basename "$key_path") al keyring..." if SSH_AUTH_SOCK="$SSH_AUTH_SOCK" ssh-add "$key_path"; then - log_success "Clave $(basename "$key_path") añadida correctamente." + log_success "La clave $(basename "$key_path") se ha añadido correctamente." added=$((added + 1)) if [[ -n "$fingerprint" ]]; then existing_fingerprints+=$'\n'"$fingerprint" fi else - log_warning "No se pudo añadir la clave $(basename "$key_path")." + log_warning "No se pudo añadir la clave $(basename "$key_path"). Es posible que la passphrase sea incorrecta." fi done if [[ $added -gt 0 ]]; then - log_success "Claves SSH sincronizadas con GNOME Keyring." + log_success "Se han sincronizado ${added} claves SSH con GNOME Keyring." else - log_info "No se añadieron nuevas claves SSH." + log_info "Todas las claves SSH ya estaban sincronizadas. No se añadieron nuevas claves." fi - log_info "Para verificar, ejecuta: ssh-add -l" + log_info "Para verificar las claves cargadas, puedes ejecutar: ssh-add -l" return 0 } +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then sync_ssh_keyring "$@" fi diff --git a/modules/zerotier.sh b/modules/zerotier.sh index fa4c8ee..c1b8a0b 100755 --- a/modules/zerotier.sh +++ b/modules/zerotier.sh @@ -2,6 +2,18 @@ # =============================================================== # zerotier.sh - Configuración de ZeroTier # =============================================================== +# +# Este módulo se encarga de la instalación y configuración de +# ZeroTier One, un servicio de red virtual que permite conectar +# dispositivos de forma segura a través de internet. +# +# Funciones principales: +# - Instala el paquete `zerotier-one` desde los repositorios. +# - Habilita e inicia el servicio de ZeroTier. +# - Ofrece una opción interactiva para que el usuario pueda unirse +# a una red de ZeroTier inmediatamente después de la instalación. +# +# =============================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" @@ -9,46 +21,51 @@ source "${SCRIPT_DIR}/common.sh" install_zerotier() { log_step "Configuración de ZeroTier" - # Instalar ZeroTier - log_info "Instalando ZeroTier..." - sudo pacman -S --noconfirm --needed zerotier-one || { - log_error "Error al instalar ZeroTier" + # --- 1. Instalación de ZeroTier --- + log_info "Instalando ZeroTier One..." + if ! aur_install_packages "zerotier-one"; then + log_error "No se pudo instalar ZeroTier One. Abortando." return 1 - } + fi - # Habilitar y iniciar servicio - log_info "Habilitando servicio de ZeroTier..." - sudo systemctl enable zerotier-one.service - sudo systemctl start zerotier-one.service + # --- 2. Habilitación del Servicio --- + log_info "Habilitando e iniciando el servicio de ZeroTier..." + # `enable --now` habilita el servicio para que arranque con el sistema + # y lo inicia inmediatamente en la sesión actual. + if ! sudo systemctl enable --now zerotier-one.service; then + log_error "No se pudo iniciar el servicio de ZeroTier." + return 1 + fi - log_success "ZeroTier instalado y servicio iniciado." - log_info "Tu ID de ZeroTier es: $(sudo zerotier-cli info | awk '{print $3}')" + log_success "ZeroTier se ha instalado y el servicio está en ejecución." + log_info "Tu ID de nodo de ZeroTier es: $(sudo zerotier-cli info | awk '{print $3}')" echo "" + # --- 3. Unirse a una Red (Opcional) --- read -p "¿Deseas unirte a una red de ZeroTier ahora? [s/N]: " confirm if [[ "${confirm}" =~ ^[SsYy]$ ]]; then read -p "Introduce el ID de la red de ZeroTier: " network_id if [[ -n "$network_id" ]]; then - log_info "Uniéndote a la red ${network_id}..." + log_info "Enviando solicitud para unirse a la red ${network_id}..." if sudo zerotier-cli join "$network_id"; then - log_success "Solicitud enviada para unirse a la red ${network_id}." - log_warning "Recuerda autorizar este dispositivo en el panel de control de ZeroTier." + log_success "Solicitud enviada correctamente." + log_warning "Recuerda que debes autorizar este dispositivo en el panel de control de tu red ZeroTier." else - log_error "No se pudo unir a la red ${network_id}." + log_error "No se pudo enviar la solicitud para unirse a la red ${network_id}." fi else log_warning "No se introdujo ningún ID de red. Operación cancelada." fi else - log_info "Operación omitida." - log_info "Para unirte a una red más tarde, ejecuta:" + log_info "Se omitió la unión a una red." + log_info "Para unirte a una red más tarde, puedes ejecutar el comando:" log_info "sudo zerotier-cli join " fi return 0 } -# Ejecutar si se llama directamente +# Ejecutar si se llama directamente al script. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then install_zerotier "$@" fi diff --git a/modules/zsh-config.sh b/modules/zsh-config.sh index 0f787ee..148fd81 100755 --- a/modules/zsh-config.sh +++ b/modules/zsh-config.sh @@ -1,9 +1,20 @@ #!/usr/bin/env bash +# =============================================================== +# zsh-config.sh - Configuración completa de Zsh +# =============================================================== # -# Módulo para configurar Zsh, Oh My Zsh, Oh My Posh y dependencias. +# Este módulo se encarga de transformar la experiencia de la terminal +# mediante la instalación y configuración de Zsh, Oh My Zsh y Oh My Posh. # +# Funciones principales: +# - Instala Zsh y un conjunto de herramientas de terminal útiles. +# - Instala y configura Oh My Posh, incluyendo un tema personalizado. +# - Instala Oh My Zsh y gestiona sus plugins. +# - Descarga y aplica un fichero .zshrc preconfigurado. +# - Cambia el shell por defecto del usuario a Zsh. +# +# =============================================================== -# Asegurarse de que las funciones comunes están cargadas SCRIPT_DIR_MODULE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR_ROOT="$(cd "${SCRIPT_DIR_MODULE}/.." && pwd)" if [[ -f "${SCRIPT_DIR_MODULE}/common.sh" ]]; then @@ -13,215 +24,185 @@ else exit 1 fi +# Opciones para `curl` que añaden timeouts y reintentos para robustez. +ZSH_CURL_TIMEOUT_OPTS=(--fail --location --silent --show-error --connect-timeout 10 --max-time 60 --retry 2 --retry-delay 2) + +# --------------------------------------------------------------- +# zsh_download_with_timeout(url, destination) +# --------------------------------------------------------------- +# Descarga un fichero desde una URL a un destino local usando `curl` +# con las opciones de timeout y reintentos definidas globalmente. +# +# Parámetros: +# $1 - URL del fichero a descargar. +# $2 - Ruta de destino donde se guardará el fichero. +# --------------------------------------------------------------- +zsh_download_with_timeout() { + local url="$1" + local dest="$2" + if curl "${ZSH_CURL_TIMEOUT_OPTS[@]}" -o "$dest" "$url"; then + return 0 + fi + return 1 +} + +# --------------------------------------------------------------- +# install_zsh() +# --------------------------------------------------------------- +# Función principal que orquesta toda la configuración de Zsh. +# --------------------------------------------------------------- install_zsh() { log_step "Configuración Completa de Zsh" + # Determina el usuario y el directorio home de destino, manejando el caso de `sudo`. local target_user="${SUDO_USER:-$USER}" - local target_home="$HOME" + local target_home if [[ -n "${SUDO_USER:-}" ]]; then target_home="$(getent passwd "$target_user" 2>/dev/null | cut -d: -f6)" - if [[ -z "$target_home" ]]; then - target_home="$(eval echo "~${target_user}")" - fi fi target_home="${target_home:-$HOME}" - # --- 1. Instalar paquetes necesarios desde Pacman --- - log_info "Instalando Zsh y herramientas esenciales..." + # --- 1. Instalación de Paquetes --- + log_info "Instalando Zsh y herramientas de terminal..." + # Paquetes: + # - zsh y plugins: El shell y sus complementos básicos. + # - zoxide, fastfetch, yt-dlp: Herramientas que mejoran la productividad + # y están integradas en el .zshrc personalizado. local pkgs=( - git - zsh - zsh-completions - zsh-syntax-highlighting - zsh-autosuggestions - zoxide # Navegación inteligente - fastfetch # Información del sistema - yt-dlp # Descarga de videos/audio - unrar p7zip lsof # Dependencias para funciones en .zshrc + git zsh zsh-completions zsh-syntax-highlighting zsh-autosuggestions + zoxide fastfetch yt-dlp unrar p7zip lsof ) - for pkg in "${pkgs[@]}"; do - check_and_install_pkg "$pkg" - done + if ! sudo pacman -S --noconfirm --needed "${pkgs[@]}"; then + log_warning "Algunos paquetes de Zsh no pudieron instalarse." + fi - # Instalar Oh My Posh con fallback a AUR si es necesario + # Instala Oh My Posh, con fallback a AUR y luego al script oficial si es necesario. if ! command_exists oh-my-posh; then log_info "Instalando Oh My Posh..." - if command_exists pacman && sudo pacman -S --noconfirm --needed oh-my-posh 2>/dev/null; then - log_success "Oh My Posh instalado desde pacman." + if sudo pacman -S --noconfirm --needed oh-my-posh 2>/dev/null; then + log_success "Oh My Posh instalado desde los repositorios oficiales." + elif aur_install_packages "oh-my-posh-bin"; then + log_success "Oh My Posh instalado desde AUR." else - log_warning "Pacman no pudo instalar oh-my-posh. Intentando con un helper AUR..." - if aur_install_packages "oh-my-posh-bin"; then - log_success "Oh My Posh instalado usando helper AUR (${AUR_HELPER_CMD})." - else - log_warning "No se pudo instalar Oh My Posh mediante pacman ni AUR." - log_info "Descargando instalador oficial de Oh My Posh..." - if curl -fsSL https://ohmyposh.dev/install.sh | sudo bash -s -- -d /usr/local/bin; then - log_success "Oh My Posh instalado usando el script oficial." + log_warning "No se pudo instalar Oh My Posh desde pacman ni AUR. Intentando con el script oficial..." + local omp_installer; omp_installer="$(mktemp)" + if zsh_download_with_timeout "https://ohmyposh.dev/install.sh" "$omp_installer"; then + if sudo bash "$omp_installer" -d /usr/local/bin; then + log_success "Oh My Posh instalado con el script oficial." else - log_error "Fallo la instalación de Oh My Posh usando el script oficial." - return 1 - fi + log_error "Falló la instalación de Oh My Posh con el script oficial."; rm -f "$omp_installer"; return 1 + fi; rm -f "$omp_installer" + else + log_error "No se pudo descargar el instalador de Oh My Posh."; rm -f "${omp_installer:-}"; return 1 fi fi else log_info "Oh My Posh ya está instalado." fi - # --- 2. Instalar Oh My Zsh (si no existe) --- + # --- 2. Instalación de Oh My Zsh --- local target_ohmyzsh_dir="${target_home}/.oh-my-zsh" if [[ ! -d "$target_ohmyzsh_dir" ]]; then log_info "Instalando Oh My Zsh..." - # Usar RUNZSH=no para evitar que inicie un nuevo shell y CHSH=no para no cambiar el shell aún - if ! env HOME="$target_home" RUNZSH=no CHSH=no \ - sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended --keep-zshrc; then - log_error "Falló la instalación de Oh My Zsh." - return 1 + local omz_installer; omz_installer="$(mktemp)" + if zsh_download_with_timeout "https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh" "$omz_installer"; then + # Se ejecuta de forma no interactiva, sin cambiar el shell aún. + if ! env HOME="$target_home" RUNZSH=no CHSH=no sh "$omz_installer" --unattended --keep-zshrc; then + log_error "Falló la instalación de Oh My Zsh."; rm -f "$omz_installer"; return 1 + fi; rm -f "$omz_installer" + else + log_error "No se pudo descargar el instalador de Oh My Zsh."; rm -f "${omz_installer:-}"; return 1 fi else log_info "Oh My Zsh ya está instalado." fi - # Asegurar plugins personalizados de Oh My Zsh (zsh-autosuggestions, zsh-syntax-highlighting) - local zsh_custom="${target_ohmyzsh_dir}/custom" - local zsh_custom_plugins="${zsh_custom}/plugins" - mkdir -p "$zsh_custom_plugins" - + # --- 3. Gestión de Plugins de Oh My Zsh --- + # Asegura que los plugins de autocompletado y resaltado de sintaxis estén clonados. ensure_omz_plugin() { - local name="$1" - local repo="$2" - local plugin_path="${zsh_custom_plugins}/${name}" - + local name="$1" repo="$2" + local plugin_path="${target_home}/.oh-my-zsh/custom/plugins/${name}" if [[ -d "${plugin_path}/.git" ]]; then - log_info "Actualizando plugin ${name}..." + log_info "Actualizando el plugin de Oh My Zsh: ${name}..." git -C "$plugin_path" pull --ff-only >/dev/null 2>&1 || true - elif [[ -d "$plugin_path" ]]; then - log_info "Plugin ${name} ya existe." - else - log_info "Clonando plugin ${name}..." - if git clone --depth 1 "$repo" "$plugin_path" >/dev/null 2>&1; then - log_success "Plugin ${name} instalado." - else - log_warning "No se pudo clonar ${name}. Se usará la versión de los paquetes del sistema." - fi + elif [[ ! -d "$plugin_path" ]]; then + log_info "Clonando el plugin de Oh My Zsh: ${name}..." + git clone --depth 1 "$repo" "$plugin_path" >/dev/null 2>&1 fi } - ensure_omz_plugin "zsh-autosuggestions" "https://github.com/zsh-users/zsh-autosuggestions.git" ensure_omz_plugin "zsh-syntax-highlighting" "https://github.com/zsh-users/zsh-syntax-highlighting.git" - # --- 3. Descargar y configurar el .zshrc personalizado --- - log_info "Actualizando configuración .zshrc..." - local repo_zshrc_path="${SCRIPT_DIR_ROOT}/.zshrc" + # --- 4. Configuración del .zshrc --- + log_info "Configurando el fichero .zshrc..." local tmp_download="${target_home}/.zshrc.omarchy-tmp" local source_file="" - - if curl -fsSL "${REPO_BASE}/.zshrc" -o "$tmp_download" && [[ -s "$tmp_download" ]]; then + # Intenta descargar el .zshrc desde el repositorio remoto. + if zsh_download_with_timeout "${REPO_BASE}/.zshrc" "$tmp_download"; then source_file="$tmp_download" - log_success "Configuración .zshrc descargada desde el repositorio remoto." + # Si falla, usa la copia local que viene con el script. + elif [[ -f "${SCRIPT_DIR_ROOT}/.zshrc" ]]; then + log_warning "No se pudo descargar .zshrc. Se usará la copia local." + source_file="${SCRIPT_DIR_ROOT}/.zshrc" else - rm -f "$tmp_download" - if [[ -f "$repo_zshrc_path" ]]; then - log_warning "No se pudo descargar .zshrc. Usando la copia local del repositorio." - source_file="$repo_zshrc_path" - else - log_error "No se pudo obtener la configuración .zshrc (sin red y sin copia local)." - return 1 - fi + log_error "No se pudo obtener el fichero .zshrc."; return 1 fi - - # Crear copia de seguridad antes de sobrescribir + # Crea una copia de seguridad y reemplaza el .zshrc existente. backup_file "${target_home}/.zshrc" || { rm -f "$tmp_download"; return 1; } - - if [[ "$source_file" == "$tmp_download" ]]; then - if mv "$tmp_download" "${target_home}/.zshrc"; then - log_success "Archivo .zshrc actualizado." - else - rm -f "$tmp_download" - log_error "No se pudo mover el archivo .zshrc descargado." - return 1 - fi - else - if cp "$source_file" "${target_home}/.zshrc"; then - log_success "Archivo .zshrc actualizado desde la copia local." - else - log_error "No se pudo copiar la configuración .zshrc local." - return 1 - fi + if ! cp "$source_file" "${target_home}/.zshrc"; then + log_error "No se pudo actualizar el fichero .zshrc."; rm -f "$tmp_download"; return 1 fi + rm -f "$tmp_download" + log_success ".zshrc actualizado correctamente." - # --- 4. Descargar el tema de Oh My Posh --- - log_info "Configurando tema de Oh My Posh (Catppuccin Frappe)..." + # --- 5. Configuración del Tema de Oh My Posh --- + log_info "Configurando el tema de Oh My Posh (Catppuccin Frappe)..." local posh_themes_dir="${target_home}/.poshthemes" local theme_file="$posh_themes_dir/catppuccin_frappe.omp.json" - local posh_theme_local="${SCRIPT_DIR_ROOT}/themes/catppuccin_frappe.omp.json" mkdir -p "$posh_themes_dir" - - if curl -fsSL "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/catppuccin_frappe.omp.json" -o "$theme_file"; then - chmod 644 "$theme_file" 2>/dev/null || true - log_success "Tema Catppuccin Frappe descargado en $theme_file" - else - rm -f "$theme_file" - if [[ -f "$posh_theme_local" ]]; then - if cp "$posh_theme_local" "$theme_file"; then - chmod 644 "$theme_file" 2>/dev/null || true - log_warning "No se pudo descargar el tema remoto. Se utilizó la copia incluida en el repositorio." - else - log_error "No se pudo copiar la versión local del tema Catppuccin." - fi + # Descarga el tema y, si falla, usa la copia local. + if ! zsh_download_with_timeout "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/catppuccin_frappe.omp.json" "$theme_file"; then + if [[ -f "${SCRIPT_DIR_ROOT}/themes/catppuccin_frappe.omp.json" ]]; then + cp "${SCRIPT_DIR_ROOT}/themes/catppuccin_frappe.omp.json" "$theme_file" + log_warning "No se pudo descargar el tema. Se usó la copia local." else - log_error "No se pudo descargar el tema de Oh My Posh y no hay copia local disponible." - # No retornamos error, el .zshrc tiene un fallback + log_error "No se pudo obtener el tema de Oh My Posh." fi fi - + # Genera el fichero de autocompletado para Zsh. if command_exists oh-my-posh; then local omp_completion_dir="${target_home}/.local/share/zsh/site-functions" mkdir -p "$omp_completion_dir" - if oh-my-posh completion zsh > "${omp_completion_dir}/_oh-my-posh" 2>/dev/null; then - log_success "Autocompletado de Oh My Posh actualizado." - fi + oh-my-posh completion zsh > "${omp_completion_dir}/_oh-my-posh" 2>/dev/null || true fi + log_success "Tema de Oh My Posh configurado." - # --- 5. Cambiar el shell por defecto a Zsh para el usuario actual --- - local current_shell - current_shell="$(getent passwd "$target_user" 2>/dev/null | cut -d: -f7)" - current_shell="${current_shell:-$SHELL}" + # --- 6. Cambio de Shell por Defecto --- + local current_shell; current_shell="$(getent passwd "$target_user" 2>/dev/null | cut -d: -f7)" if [[ "$(basename "$current_shell")" != "zsh" ]]; then - log_info "Cambiando el shell por defecto a Zsh..." - local zsh_path - zsh_path="$(command -v zsh)" - if [[ -z "$zsh_path" ]]; then - log_error "No se encontró la ruta de Zsh. Aborta el cambio de shell." - elif sudo -n chsh -s "$zsh_path" "$target_user"; then - log_success "Shell cambiado a Zsh. El cambio será efectivo en el próximo inicio de sesión." + log_info "Cambiando el shell por defecto a Zsh para el usuario '$target_user'..." + if ! sudo chsh -s "$(command -v zsh)" "$target_user"; then + log_error "No se pudo cambiar el shell automáticamente." else - log_error "No se pudo cambiar el shell automáticamente. Ejecuta 'sudo chsh -s \"$zsh_path\" $target_user' manualmente." + log_success "Shell cambiado a Zsh. El cambio será efectivo en el próximo inicio de sesión." fi - else - log_info "Zsh ya es el shell por defecto." fi - # --- 6. Configurar .bashrc para lanzar Zsh (para sesiones no interactivas) --- - local bashrc_zsh_loader=' -# Launch Zsh -if [ -t 1 ]; then - exec zsh -fi' + # --- 7. Configuración de .bashrc --- + # Añade una línea a .bashrc para que las terminales que se abran con Bash + # ejecuten Zsh automáticamente. + local bashrc_zsh_loader='if [ -t 1 ]; then exec zsh; fi' if [[ -f "${target_home}/.bashrc" ]] && ! grep -q "exec zsh" "${target_home}/.bashrc"; then - log_info "Configurando .bashrc para iniciar Zsh automáticamente..." - echo "$bashrc_zsh_loader" >> "${target_home}/.bashrc" - else - log_info ".bashrc ya está configurado para lanzar Zsh." + echo -e "\n# Iniciar Zsh automáticamente\n$bashrc_zsh_loader" >> "${target_home}/.bashrc" fi - # --- 7. Mensaje final --- + # --- 8. Mensaje Final --- echo "" - log_warning "¡IMPORTANTE! Para que los iconos se vean bien, debes configurar tu terminal:" - log_info "1. Abre las Preferencias de tu terminal." - log_info "2. Ve a la sección de Perfil -> Apariencia/Texto." - log_info "3. Cambia la fuente a una 'Nerd Font' (ej: FiraCode Nerd Font, MesloLGS NF)." - log_info "4. Cierra y vuelve a abrir la terminal para ver todos los cambios." - log_warning "Recuerda instalar manualmente una Nerd Font; el script no instala fuentes." + log_warning "¡ACCIÓN REQUERIDA! Para que los iconos del prompt se vean bien:" + log_info "1. Instala una 'Nerd Font'. La recomendada es Meslo." + log_info " Puedes hacerlo con el comando: oh-my-posh font install meslo" + log_info "2. Configura tu aplicación de terminal para que use la fuente 'MesloLGS NF'." + log_info "3. Cierra y vuelve a abrir la terminal para aplicar todos los cambios." return 0 } diff --git a/omarchy-setup.sh b/omarchy-setup.sh index 762d26e..725326f 100755 --- a/omarchy-setup.sh +++ b/omarchy-setup.sh @@ -37,10 +37,6 @@ chmod +x "${MODULES_DIR}"/*.sh 2>/dev/null || true SPINNER_ACTIVE=0 SPINNER_MESSAGE= -spinner_clear_line() { - : -} - pause_spinner() { if (( SPINNER_ACTIVE )); then SPINNER_ACTIVE=0 @@ -141,8 +137,23 @@ MODULES=( ["H"]="hyprland-config;run_module_main;🎨 Instalar Configuración de Hyprland;bg" ) +# Módulos a excluir de la opción "Instalar Todo" +EXCLUDED_FROM_ALL=("R") + +# Generar dinámicamente la lista de módulos para "Instalar Todo" +get_install_all_choices() { + local choices=() + for key in $(printf '%s\n' "${!MODULES[@]}" | sort -V); do + # Verificar si la clave no está en el array de exclusión + if ! [[ " ${EXCLUDED_FROM_ALL[*]} " =~ " ${key} " ]]; then + choices+=("$key") + fi + done + echo "${choices[@]}" +} + # Módulos a incluir en la opción "Instalar Todo" -INSTALL_ALL_CHOICES=("1" "2" "K" "3" "4" "5" "6" "7" "F" "H") +INSTALL_ALL_CHOICES=($(get_install_all_choices)) # Función para mostrar el menú show_menu() { @@ -160,7 +171,8 @@ show_menu() { echo -e " ${GREEN}${key})${NC} ${description}" done | sort -V - echo -e " ${GREEN}A)${NC} ✅ Instalar Todo (1, 2, 3, 4, 5, 6, 7, F, H)" + local install_all_keys=$(IFS=,; echo "${INSTALL_ALL_CHOICES[*]}") + echo -e " ${GREEN}A)${NC} ✅ Instalar Todo (${install_all_keys//,/, }) (excluye DaVinci)" echo -e " ${GREEN}0)${NC} 🚪 Salir" echo "" echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" @@ -265,9 +277,6 @@ install_all() { local failed=() for choice in "${INSTALL_ALL_CHOICES[@]}"; do - if [[ "$choice" == "R" ]]; then - continue - fi IFS=';' read -r module_file _ description type <<< "${MODULES[$choice]}" if ! ensure_sudo_session; then @@ -337,7 +346,6 @@ main() { export -f stop_spinner export -f pause_spinner export -f resume_spinner - export -f spinner_clear_line export -f ensure_sudo_session while true; do @@ -385,8 +393,9 @@ main() { read -p "Presiona Enter para continuar..." elif [[ "$choice" == "A" ]]; then - log_warning "La opción 'Instalar Todo' ejecutará los módulos: 1, 2, K, 3, 4, 5, 6, 7, F y H." - log_info "DaVinci Resolve (opción R) no se ejecutará en este lote; instálalo aparte cuando ya tengas el ZIP." + local modules_to_install=$(IFS=,; echo "${INSTALL_ALL_CHOICES[*]}") + log_warning "La opción 'Instalar Todo' ejecutará los módulos: ${modules_to_install//,/, }." + log_info "Los módulos excluidos (como DaVinci Resolve) deben instalarse por separado." echo -ne "${BOLD}¿Confirmas que deseas instalar todas las opciones ahora? [s/N]: ${NC}" read -r confirm if [[ "${confirm}" =~ ^[SsYy]$ ]]; then