¡Hola a todos!
Antes de nada, quiero felicitar a @jonatan por este excelente proyecto de foro comunitario y agradecerle por darnos este espacio.
Dicho esto, quiero compartir con la comunidad una invitación para colaborar en ProxMenux.
He preparado una guía de contribución para que cualquiera que se anime a participar sepa cómo crear scripts que sigan la línea visual y funcional del proyecto. El objetivo es que la experiencia de usuario sea coherente y predecible, sin importar quién escriba el script.
A continuación, os dejo la guía completa. ¡No os asustéis por la longitud! Está muy detallada para resolver cualquier duda. Esta invitación también estará disponible en el GitHub y en la nueva página web del proyecto.
Cómo contribuir a ProxMenux
¡Gracias por tu interés en contribuir a ProxMenux! Esta guía explica cómo funciona el proyecto por dentro y cómo puedes aportar tus propias ideas, ya sean nuevos scripts, correcciones o mejoras.
El objetivo es que ProxMenux sea fácil de usar y también fácil de extender. Por eso, se han definido unas pautas para que todos los scripts tengan un aspecto y un comportamiento coherentes.
Tabla de Contenidos
- [Cabecera del Script](#cabecera-del-script)
- [Estructura del Proyecto](#estructura-del-proyecto)
- [Filosofía de Diseño: La UI en Dos Fases](#filosofía-de-diseño-la-ui-en-dos-fases)
- [`dialog` vs `whiptail`: Cuándo usar cada uno](#dialog-vs-whiptail-cuándo-usar-cada-uno)
- Funciones de Mensajería
- Convenciones para los Diálogos
- Guía de Traducción
- Buenas y Malas Prácticas
- Cómo Enviar tu Contribución (El Flujo de Trabajo en GitHub)
1. Cabecera del Script
Para mantener la consistencia, cada script en ProxMenux comienza con dos bloques de comentarios. Ambos son obligatorios.
* Bloque superior — metadatos. Aquí es donde se da crédito al autor. Incluye tu nombre y, si quieres, enlaces a tu perfil de GitHub y a una página de patrocinio (Ko-fi, GitHub Sponsors, etc.). ¡Tu tiempo y desarrollo merecen ser reconocidos!
* Bloque inferior — descripción. Un párrafo sencillo que explique qué hace el script. Es lo primero que leerá un usuario para decidir si le interesa ejecutarlo.
Sobre la licencia (GPL-3.0)
ProxMenux usa la licencia GPL-3.0 para asegurar que sea siempre un proyecto libre y abierto. Al contribuir, aceptas que tu código se distribuya bajo esta misma licencia.
# ==========================================================
ProxMenux - A menu-driven script for Proxmox VE management
==========================================================
Author : Tu Nombre
GitHub : github.com/tu-usuario
Sponsor : ko-fi.com/tu-usuario
Maintainer : MacRimi
Copyright : (c) 2026 MacRimi & contributors
License : (GPL-3.0) (< ProxMenux/LICENSE at main · MacRimi/ProxMenux · GitHub )>
Version : 1.0
Last Updated: DD/MM/YYYY
==========================================================
Description:
Párrafo corto explicando qué hace el script.
Menciona las acciones principales (ej. “crea un pool ZFS”,
“configura IOMMU y reinicia”), los recursos que modifica,
y cualquier prerrequisito que el usuario deba conocer.
==========================================================
2. Estructura del Proyecto
Esta es la organización de las carpetas del proyecto. Sirve de guía para saber dónde colocar un nuevo script o dónde encontrar el código existente.
plaintext
scripts/
├── menus/ # Scripts de menú de nivel superior (puntos de entrada)
├── storage/ # Scripts de discos, almacenamiento y passthrough
├── share/ # Scripts para NFS, Samba y recursos compartidos locales
├── vm/ # Scripts de creación y configuración de VMs
├── gpu_tpu/ # Scripts de passthrough para GPU/TPU
├── post_install/ # Scripts de automatización post-instalación
├── backup_restore/ # Scripts de copia de seguridad y restauración
├── utilities/ # Scripts de utilidades del sistema
├── global/ # Librerías de ayuda compartidas (usadas por otros scripts)
├── utils.sh # Funciones de utilidad compartidas y ayudantes de mensajería
└── help_info_menu.sh # Ayuda interactiva y referencia de comandos
3. Filosofía de Diseño: La UI en Dos Fases
Esta es la convención más importante del proyecto. Para asegurar una experiencia de usuario consistente y predecible, todos los scripts siguen un diseño en dos fases:
| Fase | Propósito | Estado de la Pantalla |
|---|---|---|
| Fase 1 — Selección | Recopilar todas las decisiones del usuario y hacer comprobaciones previas. | Superposiciones de dialog. Si algo tarda, se muestra un spinner que luego desaparece. |
| Fase 2 — Ejecución | Ejecutar todas las operaciones y mostrar un log de progreso que se va acumulando. | Mensajes de msg_info / msg_ok; nunca dialog. |
El principio es: recopila todo primero, luego ejecuta todo. Así, el usuario interactúa con menús limpios (Fase 1) y luego ve un resultado claro de lo que ha pasado (Fase 2), sin mezclar ambas cosas.
Fase 1 — Patrón Típico
bash
Show full code block
# Trabajo preparatorio silencioso entre diálogos
msg_info "$(translate "Checking disk assignments...")"
ASSIGNED_TO=$(check_assignments "$DISK")
stop_spinner # <-- La línea se limpia en silencio, el resultado se guarda en la variable
# El siguiente diálogo puede usar la información obtenida
if [ -n "$ASSIGNED_TO" ]; then
dialog --yesno "$(translate "Disk already assigned. Continue?")" $UI_YESNO_H $UI_YESNO_W
fi
Fase 2 — Patrón Típico
bash
Show full code block
# --- FASE 2 — EJECUCIÓN ---
show_proxmenux_logo
msg_title "$(translate "My Script Title")"
# Se resume lo que el usuario decidió o lo que se detectó en la Fase 1
msg_ok "$(translate "CT $CTID selected.")"
msg_ok "$(translate "Disks to process: ${#DISK_LIST[@]}")"
# Ahora, se ejecutan las operaciones
for i in "${!DISK_LIST[@]}"; do
msg_info "$(translate "Formatting disk...")"
mkfs."$FORMAT" "$DISK" >/dev/null 2>&1
msg_ok "$(translate "Formatted.")"
done
msg_success "$(translate "Press Enter to return to menu...")"
read -r
Pautas para la Fase 2: La fase siempre empieza con show_proxmenux_logo + msg_title, resume inmediatamente los resultados de la Fase 1 con msg_ok, y nunca vuelve a llamar a show_proxmenux_logo ni a dialog.
4. dialog vs whiptail: Cuándo usar cada uno
Ambas herramientas crean interfaces en la terminal, pero se usan para propósitos muy distintos.
| Herramienta | Cuándo se usa | Efecto en pantalla |
|---|---|---|
dialog |
Siempre en la Fase 1. Es la herramienta por defecto para cualquier menú interactivo. | Limpia la pantalla y toma el control total. Al cerrar, restaura lo que había antes. |
whiptail |
Solo en la Fase 2, y solo si es inevitable. El caso típico es un aviso de reinicio al final. | Dibuja una ventana más ligera que no borra el historial de la terminal. El log de msg_ok sigue visible detrás. |
¿Por qué esta distinción? Si se usa
dialogen la Fase 2, se borraría todo el progreso que el usuario ha estado viendo. Conwhiptail, se mantiene ese contexto visual.
5. Funciones de Mensajería
Existe una serie de funciones en utils.sh para estandarizar todos los mensajes. Su uso es clave para mantener la coherencia visual en todo el proyecto.
| Función | Propósito |
|---|---|
msg_info "texto" |
Indicar una operación en curso (muestra un spinner). |
stop_spinner |
Detener el spinner en la Fase 1 sin dejar rastro. |
msg_ok "texto" |
Confirmar que una operación ha terminado con éxito. |
msg_warn "texto" |
Mostrar una advertencia importante. |
msg_error "texto" |
Informar de un error que detiene el script. |
msg_info2 "texto" |
Dar información adicional no crítica (en color cian). |
msg_success "texto" |
Para el mensaje final de “Pulsa Enter para volver”. |
msg_title "texto" |
Para el título principal al inicio de la Fase 2. |
show_proxmenux_logo |
Para limpiar la pantalla y mostrar el logo (solo una vez al inicio de la Fase 2). |
6. Convenciones para los Diálogos
Al usar dialog, se siguen estas convenciones para que todos los menús se vean y comporten igual:
-
Pasar siempre
--backtitle "$BACKTITLE". La variable ya está definida como “ProxMenux”. -
Envolver todos los textos visibles en
$(translate "..."). -
Redirigir la salida con
2>&1 >/dev/ttypara capturar la selección. -
Usar las variables de tamaño predefinidas (
$UI_MENU_H,$UI_MSG_W, etc.). -
Comprobar siempre si el usuario ha pulsado “Cancelar” (la variable de salida estará vacía) y, en ese caso, salir del script sin hacer nada.
bash
Show full code block
VMID=$(dialog --backtitle "$BACKTITLE" --title "$(translate "Select VM")" ... 2>&1 >/dev/tty)
# Si el usuario pulsa Cancelar o Esc, la variable VMID estará vacía.
if [ -z "$VMID" ]; then
exit 0# Salir silenciosamente.
fi
7. Guía de Traducción
Todas las cadenas de texto visibles para el usuario deben estar envueltas en la función translate:
bash
msg_ok "$(translate "Operation completed successfully.")"
msg_error "$(translate "Failed to start container") $CTID."
dialog --title "$(translate "Select Storage")" ...
Reglas:
-
Escribe las cadenas en inglés; la traducción se gestiona automáticamente.
-
Sé conciso. Evita incrustar variables en frases largas si es posible.
-
No traduzcas nombres de variables, rutas o identificadores técnicos.
8. Buenas y Malas Prácticas
Qué Hacer
-
Separar claramente la Fase 1 (recopilación con
dialog) de la Fase 2 (ejecución conmsg_ok). -
Resumir al inicio de la Fase 2 lo que se decidió en la Fase 1.
-
Usar
whiptailsi se necesita un diálogo de confirmación al final de la Fase 2. -
Redirigir la salida de los comandos (
>/dev/null 2>&1) en la Fase 2 para mantener el log limpio.
Qué Evitar
-
Usar
dialogen la Fase 2 (rompe el flujo visual). -
Llamar a
show_proxmenux_logomás de una vez en la Fase 2 (borra el progreso). -
Usar
clearen lugar deshow_proxmenux_logo. -
Usar
msg_warnpara algo que ha funcionado (ej: “IOMMU activado, requiere reinicio” es unmsg_ok).
9. Cómo Enviar tu Contribución (El Flujo de Trabajo en GitHub)
Para enviar código al proyecto se utiliza un flujo de trabajo basado en ramas, muy común en el desarrollo de software.
Modelo de Ramas
El proyecto usa un modelo de tres niveles:
| Rama | Propósito |
|---|---|
main |
Es la versión estable, la que usan los usuarios finales. Aquí solo llega código probado. |
develop |
Es la rama de desarrollo. Todas las nuevas funcionalidades se integran aquí primero. Es el canal “beta”. |
feature/* |
Son ramas temporales para cada nueva funcionalidad. Nacen de develop y vuelven a develop una vez revisadas. |
Flujo de Trabajo en 5 Pasos
-
Crea tu propia rama a partir de
develop:bash
Show full code block
# Clona el repositorio (si no lo has hecho ya)
git clone <https://github.com/MacRimi/ProxMenux.git>
cd ProxMenux# Sincroniza y muévete a la rama de desarrollo
git checkout develop
git pull origin develop# Crea tu rama para la nueva funcionalidad
git checkout -b feature/añadir-script-tailscale -
Desarrolla y haz commit de tus cambios:
bash
# ...escribes tu código y lo pruebas...
git add scripts/utilities/mi-nuevo-script.sh
git commit -m "Añade un script para instalar Tailscale" -
Sube tu rama a GitHub:
bash
git push -u origin feature/añadir-script-tailscale -
Abre una Pull Request (PR) hacia
develop: En GitHub, verás un botón para crear una “Pull Request”. Asegúrate de que la rama base seadevelop(NOmain). En la descripción, explica qué hace tu script y dónde lo has probado. -
Revisión y fusión: El código será revisado para asegurar que sigue las pautas. Si todo está bien, se fusionará en
develop. ¡Tu contribución ya formará parte de la próxima versión!
Si tienes cualquier duda, puedes abrir una “Discusión” en GitHub o en este foro.
¡Gracias de nuevo por tu tiempo y tu interés en hacer de ProxMenux un proyecto mejor!