mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2025-10-02 16:16:19 +00:00
Compare commits
107 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d987d639ab | ||
|
e7e180e468 | ||
|
76770f82cd | ||
|
4079d4fd7c | ||
|
ac48178369 | ||
|
c2e9f038ee | ||
|
70220d9829 | ||
|
b9a1f378ec | ||
|
f6bc090a98 | ||
|
be519f3932 | ||
|
0a46f77555 | ||
|
0e6cc0c7e5 | ||
|
11cd425162 | ||
|
aa269688d6 | ||
|
4c9e94768e | ||
|
581157fa82 | ||
|
e748e479cc | ||
|
5c9e4eea1e | ||
|
0c1189b233 | ||
|
5ec9b82b4a | ||
|
c84ec533da | ||
|
fb80c6ad7a | ||
|
2e3bfff6a4 | ||
|
e96ce30891 | ||
|
10de5b2e5f | ||
|
1966081239 | ||
|
b48d806d53 | ||
|
97784d74e7 | ||
|
c42e92b07d | ||
|
2c52943b54 | ||
|
4ccb1902cb | ||
|
349b0572cd | ||
|
87fae8a9eb | ||
|
a77a097f47 | ||
|
a84d81143e | ||
|
d9cee50ef3 | ||
|
0fc414e5e9 | ||
|
e18f20ce4c | ||
|
c12af4060c | ||
|
9992ea0dee | ||
|
b8310f1c5d | ||
|
78f66af702 | ||
|
4d7564094e | ||
|
370f4694d1 | ||
|
fc7c740691 | ||
|
8e1f955519 | ||
|
aa3d16d981 | ||
|
5447f0e4df | ||
|
97294df208 | ||
|
c6f53629da | ||
|
fcba907658 | ||
|
f481df7b8d | ||
|
81079a35d9 | ||
|
bda344c382 | ||
|
c4ebc396af | ||
|
4cdbf1231b | ||
|
92db58a9f6 | ||
|
5f07f47308 | ||
|
2132ae79a6 | ||
|
bda7834a4f | ||
|
7693f313c4 | ||
|
d2200a64e0 | ||
|
a5c46ab837 | ||
|
a389282e23 | ||
|
1f90b5b739 | ||
|
2c59500046 | ||
|
a59a056e12 | ||
|
235364013b | ||
|
1049ac6eac | ||
|
04dc7af25c | ||
|
f62ea3ad04 | ||
|
14c75f2cd9 | ||
|
9ae68b9653 | ||
|
b7ab4c4568 | ||
|
7d0b3a0c87 | ||
|
0d38f7f290 | ||
|
12e5ef4231 | ||
|
f3aa1f7414 | ||
|
f2eaec6e02 | ||
|
0654a3ed55 | ||
|
9a27138d96 | ||
|
b3c9f71c02 | ||
|
e9c9b957db | ||
|
29cdf6fa48 | ||
|
8466a8e21e | ||
|
1523b6b8a8 | ||
|
33205e1008 | ||
|
537af385f8 | ||
|
7259b0a850 | ||
|
11fbfda6bf | ||
|
4f0353d0fb | ||
|
a605d68d73 | ||
|
237b7fbf1b | ||
|
4a7e21f6b4 | ||
|
b7017573b8 | ||
|
a98b087c5d | ||
|
161c840136 | ||
|
4dd2abc202 | ||
|
cc0e9f61a7 | ||
|
21a658f1f4 | ||
|
b99f391c2a | ||
|
9abe25b91a | ||
|
2531fc6dac | ||
|
e5551cb179 | ||
|
4728b7a8b7 | ||
|
2863921e15 | ||
|
b93668edfe |
48
CHANGELOG.md
48
CHANGELOG.md
@@ -1,3 +1,51 @@
|
||||
## 2025-08-20
|
||||
|
||||
### New version v1.1.5
|
||||
|
||||
### Added
|
||||
|
||||
- **New Script: Upgrade PVE 8 to PVE 9**
|
||||
Added a full upgrade tool located under `Utilities and Tools`. It provides:
|
||||
1. **Automatic upgrade** from PVE 8 to 9
|
||||
2. **Interactive upgrade** with step-by-step confirmations
|
||||
3. **Check-only mode** using `check-pve8to9`
|
||||
4. **Manual instructions** shown in order for users who prefer to upgrade manually
|
||||
|
||||
- **New Tools in System Utilities**
|
||||
- [`s-tui`](https://github.com/amanusk/s-tui): Terminal-based CPU monitoring with graphs
|
||||
- [`intel-gpu-tools`](https://gitlab.freedesktop.org/drm/igt-gpu-tools): Useful for Intel GPU diagnostics
|
||||
|
||||
---
|
||||
|
||||
### Improved
|
||||
|
||||
- **APT Upgrade Handling**
|
||||
The PVE upgrade function now blocks the process if any package prompts for manual confirmation. This avoids partial upgrades and ensures consistency.
|
||||
|
||||
- **Network Optimization (sysctl)**
|
||||
- Obsolete kernel parameters removed (e.g., `tcp_tw_recycle`, `nf_conntrack_helper`) to prevent warnings in **Proxmox 9 / kernel 6.14**
|
||||
- Now generates only valid, up-to-date sysctl parameters
|
||||
|
||||
- **AMD CPU Patch Handling**
|
||||
- Now applies correct `idle=nomwait` and KVM options (`ignore_msrs=1`, `report_ignored_msrs=0`)
|
||||
- Expected warning is now documented and safely handled for stability with Ryzen/EPYC
|
||||
|
||||
- **Timezone & NTP Fixes**
|
||||
- Automatically detects timezone using public IP geolocation
|
||||
- Falls back to UTC if detection fails
|
||||
- Restarts Postfix after timezone set → resolves `/var/spool/postfix/etc/localtime` mismatch warning
|
||||
|
||||
- **Repository & Package Installer Logic**
|
||||
- Now verifies that working repositories exist before installing any package
|
||||
- If none are available, adds a fallback **Debian stable** repository
|
||||
- Replaces deprecated `mlocate` with `plocate` (compatible with Debian 13 and Proxmox 9)
|
||||
|
||||
- **Improved Logs and User Feedback**
|
||||
- Actions that fail now provide precise messages (instead of falsely marking as success)
|
||||
- Helps users clearly understand what's been applied or skipped
|
||||
|
||||
|
||||
|
||||
## 2025-08-06
|
||||
|
||||
### New version v1.1.4
|
||||
|
@@ -59,7 +59,7 @@ Then, follow the on-screen options to manage your Proxmox server efficiently.
|
||||
|
||||
## 📌 System Requirements
|
||||
🖥 **Compatible with:**
|
||||
- Proxmox VE 8.x**
|
||||
- Proxmox VE 8.x and 9.x
|
||||
|
||||
📦 **Dependencies:**
|
||||
- `bash`, `curl`, `wget`, `jq`, `whiptail`, `python3-venv` (These dependencies are installed automatically during setup.)
|
||||
|
@@ -526,6 +526,7 @@ show_installation_options() {
|
||||
"1" "Normal Version (English only)" 3>&1 1>&2 2>&3)
|
||||
|
||||
if [ -z "$INSTALL_TYPE" ]; then
|
||||
show_proxmenux_logo
|
||||
msg_warn "Installation cancelled."
|
||||
exit 1
|
||||
fi
|
||||
@@ -535,6 +536,7 @@ show_installation_options() {
|
||||
"2" "Translation Version (Multi-language support)" 3>&1 1>&2 2>&3)
|
||||
|
||||
if [ -z "$INSTALL_TYPE" ]; then
|
||||
show_proxmenux_logo
|
||||
msg_warn "Installation cancelled."
|
||||
exit 1
|
||||
fi
|
||||
@@ -543,6 +545,7 @@ show_installation_options() {
|
||||
|
||||
|
||||
if [ -z "$INSTALL_TYPE" ]; then
|
||||
show_proxmenux_logo
|
||||
msg_warn "Installation cancelled."
|
||||
exit 1
|
||||
fi
|
||||
@@ -550,12 +553,14 @@ show_installation_options() {
|
||||
# For new installations, show confirmation with details
|
||||
if [ "$current_install_type" = "none" ]; then
|
||||
if ! show_installation_confirmation "$INSTALL_TYPE"; then
|
||||
show_proxmenux_logo
|
||||
msg_warn "Installation cancelled."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! handle_installation_change "$current_install_type" "$INSTALL_TYPE"; then
|
||||
show_proxmenux_logo
|
||||
msg_warn "Installation cancelled."
|
||||
exit 1
|
||||
fi
|
||||
|
435
json/cache.json
435
json/cache.json
@@ -2132,6 +2132,439 @@
|
||||
"de": "Zum Beenden von iptraf-ng, x drücken",
|
||||
"it": "Per uscire da iptraf-ng, premi x",
|
||||
"pt": "Para sair do iptraf-ng, pressione x"
|
||||
},
|
||||
"Proxmox VE 8 to 9 Manual Upgrade Guide": {
|
||||
"es": "Guía de actualización manual de Proxmox VE 8 a 9",
|
||||
"fr": "Guide de mise à niveau manuelle de Proxmox VE 8 vers 9",
|
||||
"de": "Manuelles Upgrade-Handbuch: Proxmox VE 8 auf 9",
|
||||
"it": "Guida all'aggiornamento manuale da Proxmox VE 8 a 9",
|
||||
"pt": "Guia de atualização manual do Proxmox VE 8 para 9"
|
||||
},
|
||||
"Source:": {
|
||||
"es": "Fuente:",
|
||||
"fr": "Source :",
|
||||
"de": "Quelle:",
|
||||
"it": "Fonte:",
|
||||
"pt": "Fonte:"
|
||||
},
|
||||
"IMPORTANT PREREQUISITES:": {
|
||||
"es": "REQUISITOS PREVIOS IMPORTANTES:",
|
||||
"fr": "PRÉREQUIS IMPORTANTS :",
|
||||
"de": "WICHTIGE VORAUSSETZUNGEN:",
|
||||
"it": "PREREQUISITI IMPORTANTI:",
|
||||
"pt": "PRÉ-REQUISITOS IMPORTANTES:"
|
||||
},
|
||||
"System must be updated to latest PVE 8.4+ before starting": {
|
||||
"es": "El sistema debe estar actualizado a la versión PVE 8.4+ antes de comenzar",
|
||||
"fr": "Le système doit être mis à jour vers PVE 8.4+ avant de commencer",
|
||||
"de": "Das System muss vor dem Start auf PVE 8.4+ aktualisiert sein",
|
||||
"it": "Il sistema deve essere aggiornato a PVE 8.4+ prima di iniziare",
|
||||
"pt": "O sistema deve estar atualizado para PVE 8.4+ antes de começar"
|
||||
},
|
||||
"Use SSH or terminal access (SSH recommended)": {
|
||||
"es": "Use acceso por SSH o terminal (se recomienda SSH)",
|
||||
"fr": "Utilisez un accès SSH ou terminal (SSH recommandé)",
|
||||
"de": "SSH- oder Terminalzugang verwenden (SSH empfohlen)",
|
||||
"it": "Usa accesso SSH o terminale (consigliato SSH)",
|
||||
"pt": "Use acesso por SSH ou terminal (SSH recomendado)"
|
||||
},
|
||||
"Use tmux or screen to avoid interruptions": {
|
||||
"es": "Use tmux o screen para evitar interrupciones",
|
||||
"fr": "Utilisez tmux ou screen pour éviter les interruptions",
|
||||
"de": "Verwenden Sie tmux oder screen, um Unterbrechungen zu vermeiden",
|
||||
"it": "Usa tmux o screen per evitare interruzioni",
|
||||
"pt": "Use tmux ou screen para evitar interrupções"
|
||||
},
|
||||
"Have valid backups of all VMs and containers": {
|
||||
"es": "Tenga copias de seguridad válidas de todas las VMs y contenedores",
|
||||
"fr": "Ayez des sauvegardes valides de toutes les VM et conteneurs",
|
||||
"de": "Halten Sie gültige Backups aller VMs und Container bereit",
|
||||
"it": "Avere backup validi di tutte le VM e i container",
|
||||
"pt": "Tenha backups válidos de todas as VMs e contêineres"
|
||||
},
|
||||
"At least 5GB free space on root filesystem": {
|
||||
"es": "Al menos 5 GB de espacio libre en el sistema de archivos raíz",
|
||||
"fr": "Au moins 5 Go d’espace libre sur le système de fichiers racine",
|
||||
"de": "Mindestens 5 GB freier Speicherplatz auf dem Root-Dateisystem",
|
||||
"it": "Almeno 5 GB di spazio libero sul filesystem root",
|
||||
"pt": "Pelo menos 5 GB de espaço livre no sistema de arquivos raiz"
|
||||
},
|
||||
"Do not run the upgrade from the Web UI virtual console (it will disconnect)": {
|
||||
"es": "No ejecute la actualización desde la consola virtual de la interfaz web (se desconectará)",
|
||||
"fr": "N’exécutez pas la mise à niveau depuis la console virtuelle de l’interface Web (elle se déconnectera)",
|
||||
"de": "Führen Sie das Upgrade nicht über die virtuelle Konsole der Web-UI aus (die Verbindung wird getrennt)",
|
||||
"it": "Non eseguire l’aggiornamento dalla console virtuale dell’interfaccia Web (si disconnetterà)",
|
||||
"pt": "Não execute a atualização pelo console virtual da interface Web (a conexão será interrompida)"
|
||||
},
|
||||
"Update system to latest PVE 8.4+ (if not done already):": {
|
||||
"es": "Actualizar el sistema a PVE 8.4+ (si aún no se ha hecho):",
|
||||
"fr": "Mettre à jour le système vers PVE 8.4+ (si ce n’est pas déjà fait) :",
|
||||
"de": "System auf PVE 8.4+ aktualisieren (falls noch nicht geschehen):",
|
||||
"it": "Aggiornare il sistema a PVE 8.4+ (se non già fatto):",
|
||||
"pt": "Atualizar o sistema para PVE 8.4+ (se ainda não foi feito):"
|
||||
},
|
||||
"Or use ProxMenux update function": {
|
||||
"es": "O use la función de actualización de ProxMenux",
|
||||
"fr": "Ou utilisez la fonction de mise à jour de ProxMenux",
|
||||
"de": "Oder verwenden Sie die Aktualisierungsfunktion von ProxMenux",
|
||||
"it": "Oppure usa la funzione di aggiornamento di ProxMenux",
|
||||
"pt": "Ou use a função de atualização do ProxMenux"
|
||||
},
|
||||
"Verify PVE version (must be 8.4.1 or newer):": {
|
||||
"es": "Verificar la versión de PVE (debe ser 8.4.1 o superior):",
|
||||
"fr": "Vérifier la version de PVE (doit être 8.4.1 ou plus récente) :",
|
||||
"de": "PVE-Version prüfen (muss 8.4.1 oder neuer sein):",
|
||||
"it": "Verificare la versione di PVE (deve essere 8.4.1 o successiva):",
|
||||
"pt": "Verificar a versão do PVE (deve ser 8.4.1 ou superior):"
|
||||
},
|
||||
"If this node runs hyper-converged Ceph: ensure Ceph is 19.x (Squid) BEFORE upgrading PVE.": {
|
||||
"es": "Si este nodo ejecuta Ceph hiperconvergente: asegúrese de que Ceph sea 19.x (Squid) ANTES de actualizar PVE.",
|
||||
"fr": "Si ce nœud exécute un Ceph hyperconvergé : assurez-vous que Ceph est en 19.x (Squid) AVANT de mettre à niveau PVE.",
|
||||
"de": "Wenn dieser Knoten hyperkonvergentes Ceph betreibt: Stellen Sie sicher, dass Ceph 19.x (Squid) ist, BEVOR Sie PVE aktualisieren.",
|
||||
"it": "Se questo nodo esegue Ceph iperconvergente: assicurarsi che Ceph sia 19.x (Squid) PRIMA di aggiornare PVE.",
|
||||
"pt": "Se este nó executa Ceph hiperconvergente: certifique-se de que o Ceph esteja em 19.x (Squid) ANTES de atualizar o PVE."
|
||||
},
|
||||
"If not 19.x, upgrade Ceph (Reef→Squid) first per the official guide:": {
|
||||
"es": "Si no es 19.x, actualice primero Ceph (Reef→Squid) según la guía oficial:",
|
||||
"fr": "Si ce n’est pas 19.x, mettez d’abord à niveau Ceph (Reef→Squid) selon le guide officiel :",
|
||||
"de": "Wenn nicht 19.x, aktualisieren Sie Ceph zuerst (Reef→Squid) gemäß der offiziellen Anleitung:",
|
||||
"it": "Se non è 19.x, aggiornare prima Ceph (Reef→Squid) secondo la guida ufficiale:",
|
||||
"pt": "Se não for 19.x, atualize primeiro o Ceph (Reef→Squid) conforme o guia oficial:"
|
||||
},
|
||||
"Run upgrade checklist script:": {
|
||||
"es": "Ejecutar el script de la lista de verificación de actualización:",
|
||||
"fr": "Exécuter le script de liste de vérification de mise à niveau :",
|
||||
"de": "Upgrade-Checklisten-Skript ausführen:",
|
||||
"it": "Eseguire lo script della checklist di aggiornamento:",
|
||||
"pt": "Executar o script da lista de verificação de atualização:"
|
||||
},
|
||||
"If it warns about 'systemd-boot' meta-package, remove it:": {
|
||||
"es": "Si advierte sobre el metapaquete 'systemd-boot', elimínelo:",
|
||||
"fr": "S’il signale le méta-paquet « systemd-boot », supprimez-le :",
|
||||
"de": "Wenn vor dem Metapaket „systemd-boot“ gewarnt wird, entfernen Sie es:",
|
||||
"it": "Se avvisa del metapacchetto 'systemd-boot', rimuoverlo:",
|
||||
"pt": "Se alertar sobre o metapacote 'systemd-boot', remova-o:"
|
||||
},
|
||||
"Start terminal multiplexer (recommended):": {
|
||||
"es": "Iniciar un multiplexor de terminal (recomendado):",
|
||||
"fr": "Démarrer un multiplexeur de terminal (recommandé) :",
|
||||
"de": "Terminal-Multiplexer starten (empfohlen):",
|
||||
"it": "Avviare un multiplexer di terminale (consigliato):",
|
||||
"pt": "Iniciar um multiplexador de terminal (recomendado):"
|
||||
},
|
||||
"# Recommended: avoids disconnection during upgrade": {
|
||||
"es": "# Recomendado: evita desconexiones durante la actualización",
|
||||
"fr": "# Recommandé : évite les déconnexions pendant la mise à niveau",
|
||||
"de": "# Empfohlen: vermeidet Verbindungsabbrüche während des Upgrades",
|
||||
"it": "# Consigliato: evita disconnessioni durante l’aggiornamento",
|
||||
"pt": "# Recomendado: evita desconexões durante a atualização"
|
||||
},
|
||||
"# Alternative if you prefer screen": {
|
||||
"es": "# Alternativa si prefiere screen",
|
||||
"fr": "# Alternative si vous préférez screen",
|
||||
"de": "# Alternative, wenn Sie screen bevorzugen",
|
||||
"it": "# Alternativa se preferisci screen",
|
||||
"pt": "# Alternativa se preferir screen"
|
||||
},
|
||||
"Update Debian repositories to Trixie:": {
|
||||
"es": "Actualizar los repositorios de Debian a Trixie:",
|
||||
"fr": "Mettre à jour les dépôts Debian vers Trixie :",
|
||||
"de": "Debian-Repositories auf Trixie aktualisieren:",
|
||||
"it": "Aggiornare i repository Debian a Trixie:",
|
||||
"pt": "Atualizar os repositórios Debian para Trixie:"
|
||||
},
|
||||
"Update PVE enterprise repository (Only if using enterprise):": {
|
||||
"es": "Actualizar el repositorio empresarial de PVE (solo si usa enterprise):",
|
||||
"fr": "Mettre à jour le dépôt entreprise de PVE (uniquement si vous utilisez enterprise) :",
|
||||
"de": "PVE-Enterprise-Repository aktualisieren (nur bei Verwendung von Enterprise):",
|
||||
"it": "Aggiornare il repository enterprise di PVE (solo se si usa enterprise):",
|
||||
"pt": "Atualizar o repositório enterprise do PVE (apenas se usar enterprise):"
|
||||
},
|
||||
"Skip this step if using no-subscription repository": {
|
||||
"es": "Omita este paso si usa el repositorio sin suscripción",
|
||||
"fr": "Ignorez cette étape si vous utilisez le dépôt sans abonnement",
|
||||
"de": "Überspringen Sie diesen Schritt, wenn Sie das No-Subscription-Repository verwenden",
|
||||
"it": "Saltare questo passaggio se si usa il repository senza sottoscrizione",
|
||||
"pt": "Pule esta etapa se usar o repositório sem assinatura"
|
||||
},
|
||||
"Add new PVE 9 enterprise repository (deb822 format) (Only if using enterprise):": {
|
||||
"es": "Agregar el nuevo repositorio empresarial de PVE 9 (formato deb822) (solo si usa enterprise):",
|
||||
"fr": "Ajouter le nouveau dépôt entreprise de PVE 9 (format deb822) (uniquement si vous utilisez enterprise) :",
|
||||
"de": "Neues PVE-9-Enterprise-Repository (deb822-Format) hinzufügen (nur bei Enterprise):",
|
||||
"it": "Aggiungere il nuovo repository enterprise di PVE 9 (formato deb822) (solo se si usa enterprise):",
|
||||
"pt": "Adicionar o novo repositório enterprise do PVE 9 (formato deb822) (apenas se usar enterprise):"
|
||||
},
|
||||
"Only if using enterprise subscription": {
|
||||
"es": "Solo si utiliza suscripción empresarial",
|
||||
"fr": "Uniquement si vous avez un abonnement entreprise",
|
||||
"de": "Nur bei vorhandener Enterprise-Abonnement",
|
||||
"it": "Solo se si dispone di una sottoscrizione enterprise",
|
||||
"pt": "Apenas se você tiver assinatura enterprise"
|
||||
},
|
||||
"OR add new PVE 9 no-subscription repository:": {
|
||||
"es": "O agregar el nuevo repositorio de PVE 9 sin suscripción:",
|
||||
"fr": "OU ajouter le nouveau dépôt PVE 9 sans abonnement :",
|
||||
"de": "ODER das neue PVE-9-No-Subscription-Repository hinzufügen:",
|
||||
"it": "OPPURE aggiungere il nuovo repository PVE 9 senza sottoscrizione:",
|
||||
"pt": "OU adicionar o novo repositório PVE 9 sem assinatura:"
|
||||
},
|
||||
"Only if using no-subscription repository": {
|
||||
"es": "Solo si usa el repositorio sin suscripción",
|
||||
"fr": "Uniquement si vous utilisez le dépôt sans abonnement",
|
||||
"de": "Nur bei Verwendung des No-Subscription-Repository",
|
||||
"it": "Solo se si usa il repository senza sottoscrizione",
|
||||
"pt": "Apenas se usar o repositório sem assinatura"
|
||||
},
|
||||
"Refresh APT index and verify repositories:": {
|
||||
"es": "Actualizar el índice de APT y verificar los repositorios:",
|
||||
"fr": "Actualiser l’index APT et vérifier les dépôts :",
|
||||
"de": "APT-Index aktualisieren und Repositories prüfen:",
|
||||
"it": "Aggiornare l’indice APT e verificare i repository:",
|
||||
"pt": "Atualizar o índice do APT e verificar os repositórios:"
|
||||
},
|
||||
"Ensure there are no errors and that proxmox-ve candidate shows 9.x": {
|
||||
"es": "Asegúrese de que no haya errores y de que el candidato de proxmox-ve sea 9.x",
|
||||
"fr": "Assurez-vous qu’il n’y a aucune erreur et que le candidat proxmox-ve indique 9.x",
|
||||
"de": "Stellen Sie sicher, dass keine Fehler auftreten und der proxmox-ve-Kandidat 9.x anzeigt",
|
||||
"it": "Assicurarsi che non vi siano errori e che il candidato di proxmox-ve sia 9.x",
|
||||
"pt": "Certifique-se de que não há erros e que o candidato proxmox-ve mostre 9.x"
|
||||
},
|
||||
"Update Ceph repository (Only if using Ceph):": {
|
||||
"es": "Actualizar el repositorio de Ceph (solo si usa Ceph):",
|
||||
"fr": "Mettre à jour le dépôt Ceph (uniquement si vous utilisez Ceph) :",
|
||||
"de": "Ceph-Repository aktualisieren (nur bei Verwendung von Ceph):",
|
||||
"it": "Aggiornare il repository di Ceph (solo se si usa Ceph):",
|
||||
"pt": "Atualizar o repositório do Ceph (apenas se usar Ceph):"
|
||||
},
|
||||
"Use enterprise URL if you have subscription.": {
|
||||
"es": "Use la URL enterprise si dispone de suscripción.",
|
||||
"fr": "Utilisez l’URL enterprise si vous avez un abonnement.",
|
||||
"de": "Verwenden Sie die Enterprise-URL, wenn Sie ein Abonnement haben.",
|
||||
"it": "Usa l’URL enterprise se hai una sottoscrizione.",
|
||||
"pt": "Use a URL enterprise se tiver assinatura."
|
||||
},
|
||||
"Remove old repository files:": {
|
||||
"es": "Eliminar los archivos de repositorio antiguos:",
|
||||
"fr": "Supprimer les anciens fichiers de dépôt :",
|
||||
"de": "Alte Repository-Dateien entfernen:",
|
||||
"it": "Rimuovere i vecchi file di repository:",
|
||||
"pt": "Remover arquivos antigos de repositório:"
|
||||
},
|
||||
"Also comment any remaining 'bookworm' entries in *.list if present.": {
|
||||
"es": "Comente también cualquier entrada restante de ‘bookworm’ en *.list si existe.",
|
||||
"fr": "Commentez également toute entrée ‘bookworm’ restante dans *.list si présente.",
|
||||
"de": "Kommentieren Sie außerdem verbleibende ‚bookworm‘-Einträge in *.list, falls vorhanden.",
|
||||
"it": "Commentare anche eventuali voci ‘bookworm’ rimanenti in *.list se presenti.",
|
||||
"pt": "Comente também quaisquer entradas ‘bookworm’ restantes em *.list, se houver."
|
||||
},
|
||||
"Update package index:": {
|
||||
"es": "Actualizar el índice de paquetes:",
|
||||
"fr": "Mettre à jour l’index des paquets :",
|
||||
"de": "Paketindex aktualisieren:",
|
||||
"it": "Aggiornare l’indice dei pacchetti:",
|
||||
"pt": "Atualizar o índice de pacotes:"
|
||||
},
|
||||
"Disable kernel audit messages (optional but recommended):": {
|
||||
"es": "Desactivar los mensajes de auditoría del kernel (opcional pero recomendado):",
|
||||
"fr": "Désactiver les messages d’audit du noyau (optionnel mais recommandé) :",
|
||||
"de": "Kernel-Audit-Meldungen deaktivieren (optional, aber empfohlen):",
|
||||
"it": "Disabilitare i messaggi di audit del kernel (opzionale ma consigliato):",
|
||||
"pt": "Desativar as mensagens de auditoria do kernel (opcional, mas recomendado):"
|
||||
},
|
||||
"Start the main system upgrade:": {
|
||||
"es": "Iniciar la actualización principal del sistema:",
|
||||
"fr": "Démarrer la mise à niveau principale du système :",
|
||||
"de": "Hauptsystem-Upgrade starten:",
|
||||
"it": "Avviare l’aggiornamento principale del sistema:",
|
||||
"pt": "Iniciar a atualização principal do sistema:"
|
||||
},
|
||||
"This will take time. Answer prompts carefully - see notes below.": {
|
||||
"es": "Esto llevará tiempo. Responda a las indicaciones con cuidado (vea las notas a continuación).",
|
||||
"fr": "Cela prendra du temps. Répondez aux invites avec attention (voir les notes ci-dessous).",
|
||||
"de": "Dies wird einige Zeit dauern. Beantworten Sie Rückfragen sorgfältig (siehe Hinweise unten).",
|
||||
"it": "Questo richiederà tempo. Rispondi con attenzione alle richieste (vedi note sotto).",
|
||||
"pt": "Isso levará tempo. Responda às solicitações com atenção (veja as notas abaixo)."
|
||||
},
|
||||
"UPGRADE PROMPTS - RECOMMENDED ANSWERS:": {
|
||||
"es": "INDICACIONES DE ACTUALIZACIÓN - RESPUESTAS RECOMENDADAS:",
|
||||
"fr": "INVITES DE MISE À NIVEAU - RÉPONSES RECOMMANDÉES :",
|
||||
"de": "UPGRADE-AUFFORDERUNGEN – EMPFOHLENE ANTWORTEN:",
|
||||
"it": "PROMPT DI AGGIORNAMENTO - RISPOSTE CONSIGLIATE:",
|
||||
"pt": "PROMPTS DE ATUALIZAÇÃO - RESPOSTAS RECOMENDADAS:"
|
||||
},
|
||||
"Keep current version (N)": {
|
||||
"es": "Mantener la versión actual (N)",
|
||||
"fr": "Conserver la version actuelle (N)",
|
||||
"de": "Aktuelle Version beibehalten (N)",
|
||||
"it": "Mantieni la versione corrente (N)",
|
||||
"pt": "Manter a versão atual (N)"
|
||||
},
|
||||
"Install maintainer's version (Y)": {
|
||||
"es": "Instalar la versión del mantenedor del paquete (Y)",
|
||||
"fr": "Installer la version du mainteneur du paquet (Y)",
|
||||
"de": "Version des Paketbetreuers installieren (Y)",
|
||||
"it": "Installare la versione del maintainer del pacchetto (Y)",
|
||||
"pt": "Instalar a versão do mantenedor do pacote (Y)"
|
||||
},
|
||||
"Keep current version (N) if modified": {
|
||||
"es": "Mantener la versión actual (N) si está modificada",
|
||||
"fr": "Conserver la version actuelle (N) si elle a été modifiée",
|
||||
"de": "Aktuelle Version beibehalten (N), falls angepasst",
|
||||
"it": "Mantieni la versione corrente (N) se modificata",
|
||||
"pt": "Manter a versão atual (N) se estiver modificada"
|
||||
},
|
||||
"Service restarts:": {
|
||||
"es": "Reinicios de servicios:",
|
||||
"fr": "Redémarrages de services :",
|
||||
"de": "Neustarts von Diensten:",
|
||||
"it": "Riavvii dei servizi:",
|
||||
"pt": "Reinicializações de serviços:"
|
||||
},
|
||||
"Use default (Yes)": {
|
||||
"es": "Usar la opción predeterminada (Sí)",
|
||||
"fr": "Utiliser l’option par défaut (Oui)",
|
||||
"de": "Standardoption verwenden (Ja)",
|
||||
"it": "Usare l’opzione predefinita (Sì)",
|
||||
"pt": "Usar a opção padrão (Sim)"
|
||||
},
|
||||
"Press 'q' to exit": {
|
||||
"es": "Presione «q» para salir",
|
||||
"fr": "Appuyez sur « q » pour quitter",
|
||||
"de": "Drücken Sie „q“, um zu beenden",
|
||||
"it": "Premi «q» per uscire",
|
||||
"pt": "Pressione «q» para sair"
|
||||
},
|
||||
"If booting in EFI mode with root on LVM: install GRUB for EFI": {
|
||||
"es": "Si inicia en modo EFI con root en LVM: instale GRUB para EFI",
|
||||
"fr": "Si vous démarrez en mode EFI avec root sur LVM : installez GRUB pour EFI",
|
||||
"de": "Wenn Sie im EFI-Modus mit Root auf LVM booten: GRUB für EFI installieren",
|
||||
"it": "Se l’avvio è in modalità EFI con root su LVM: installare GRUB per EFI",
|
||||
"pt": "Se iniciar em modo EFI com root no LVM: instale o GRUB para EFI"
|
||||
},
|
||||
"Per official known issues; ensures proper boot after upgrade": {
|
||||
"es": "Según las incidencias conocidas oficiales, garantiza un arranque correcto tras la actualización",
|
||||
"fr": "Selon les problèmes connus officiels, cela garantit un démarrage correct après la mise à niveau",
|
||||
"de": "Laut den offiziellen Known Issues sorgt dies für einen ordnungsgemäßen Start nach dem Upgrade",
|
||||
"it": "Secondo le note ufficiali dei problemi noti, garantisce un avvio corretto dopo l’aggiornamento",
|
||||
"pt": "De acordo com os problemas conhecidos oficiais, garante uma inicialização correta após a atualização"
|
||||
},
|
||||
"Run checklist again to verify upgrade:": {
|
||||
"es": "Ejecutar de nuevo la lista de verificación para comprobar la actualización:",
|
||||
"fr": "Relancer la liste de vérification pour valider la mise à niveau :",
|
||||
"de": "Checkliste erneut ausführen, um das Upgrade zu verifizieren:",
|
||||
"it": "Eseguire nuovamente la checklist per verificare l’aggiornamento:",
|
||||
"pt": "Executar novamente a lista de verificação para validar a atualização:"
|
||||
},
|
||||
"Should show fewer or no issues": {
|
||||
"es": "Debería mostrar menos problemas o ninguno",
|
||||
"fr": "Devrait afficher moins de problèmes, voire aucun",
|
||||
"de": "Sollte weniger oder keine Probleme anzeigen",
|
||||
"it": "Dovrebbe mostrare meno problemi o nessuno",
|
||||
"pt": "Deve mostrar menos problemas ou nenhum"
|
||||
},
|
||||
"Reboot the system:": {
|
||||
"es": "Reiniciar el sistema:",
|
||||
"fr": "Redémarrer le système :",
|
||||
"de": "System neu starten:",
|
||||
"it": "Riavviare il sistema:",
|
||||
"pt": "Reiniciar o sistema:"
|
||||
},
|
||||
"After reboot, verify PVE version:": {
|
||||
"es": "Después del reinicio, verificar la versión de PVE:",
|
||||
"fr": "Après le redémarrage, vérifier la version de PVE :",
|
||||
"de": "Nach dem Neustart die PVE-Version prüfen:",
|
||||
"it": "Dopo il riavvio, verificare la versione di PVE:",
|
||||
"pt": "Após reiniciar, verificar a versão do PVE:"
|
||||
},
|
||||
"Should show pve-manager/9.x.x": {
|
||||
"es": "Debería mostrar pve-manager/9.x.x",
|
||||
"fr": "Devrait afficher pve-manager/9.x.x",
|
||||
"de": "Sollte pve-manager/9.x.x anzeigen",
|
||||
"it": "Dovrebbe mostrare pve-manager/9.x.x",
|
||||
"pt": "Deve mostrar pve-manager/9.x.x"
|
||||
},
|
||||
"Optional: Modernize repository sources:": {
|
||||
"es": "Opcional: Modernizar las fuentes de repositorio:",
|
||||
"fr": "Optionnel : Moderniser les sources des dépôts :",
|
||||
"de": "Optional: Repository-Quellen modernisieren:",
|
||||
"it": "Opzionale: Modernizzare le fonti del repository:",
|
||||
"pt": "Opcional: Modernizar as fontes de repositório:"
|
||||
},
|
||||
"Converts to deb822; keeps .list backups as .bak": {
|
||||
"es": "Convierte a deb822; mantiene copias .list como .bak",
|
||||
"fr": "Convertit en deb822 ; conserve les sauvegardes .list en .bak",
|
||||
"de": "Konvertiert zu deb822; behält .list-Backups als .bak bei",
|
||||
"it": "Converte in deb822; mantiene i backup .list come .bak",
|
||||
"pt": "Converte para deb822; mantém backups .list como .bak"
|
||||
},
|
||||
"CLUSTER UPGRADE NOTES:": {
|
||||
"es": "NOTAS DE ACTUALIZACIÓN DEL CLÚSTER:",
|
||||
"fr": "NOTES DE MISE À NIVEAU DU CLUSTER :",
|
||||
"de": "HINWEISE ZUM CLUSTER-UPGRADE:",
|
||||
"it": "NOTE DI AGGIORNAMENTO DEL CLUSTER:",
|
||||
"pt": "NOTAS DE ATUALIZAÇÃO DO CLUSTER:"
|
||||
},
|
||||
"Upgrade one node at a time": {
|
||||
"es": "Actualizar un nodo a la vez",
|
||||
"fr": "Mettre à niveau un nœud à la fois",
|
||||
"de": "Jeweils nur einen Knoten aktualisieren",
|
||||
"it": "Aggiornare un nodo alla volta",
|
||||
"pt": "Atualizar um nó por vez"
|
||||
},
|
||||
"Migrate VMs away from node being upgraded": {
|
||||
"es": "Migrar las VMs fuera del nodo que se está actualizando",
|
||||
"fr": "Migrer les VM hors du nœud en cours de mise à niveau",
|
||||
"de": "VMs vom zu aktualisierenden Knoten weg migrieren",
|
||||
"it": "Migrare le VM dal nodo in aggiornamento",
|
||||
"pt": "Migrar as VMs para fora do nó em atualização"
|
||||
},
|
||||
"Wait for each node to complete before starting next": {
|
||||
"es": "Esperar a que cada nodo termine antes de empezar con el siguiente",
|
||||
"fr": "Attendre que chaque nœud soit terminé avant de commencer le suivant",
|
||||
"de": "Warten, bis jeder Knoten abgeschlossen ist, bevor der nächste beginnt",
|
||||
"it": "Attendere che ogni nodo termini prima di iniziare il successivo",
|
||||
"pt": "Aguardar cada nó concluir antes de iniciar o próximo"
|
||||
},
|
||||
"HA groups will be migrated to HA rules automatically": {
|
||||
"es": "Los grupos de HA se migrarán automáticamente a reglas de HA",
|
||||
"fr": "Les groupes HA seront migrés automatiquement vers des règles HA",
|
||||
"de": "HA-Gruppen werden automatisch in HA-Regeln migriert",
|
||||
"it": "I gruppi HA verranno migrati automaticamente a regole HA",
|
||||
"pt": "Grupos de HA serão migrados automaticamente para regras de HA"
|
||||
},
|
||||
"TROUBLESHOOTING:": {
|
||||
"es": "SOLUCIÓN DE PROBLEMAS:",
|
||||
"fr": "DÉPANNAGE :",
|
||||
"de": "FEHLERBEHEBUNG:",
|
||||
"it": "RISOLUZIONE DEI PROBLEMI:",
|
||||
"pt": "SOLUÇÃO DE PROBLEMAS:"
|
||||
},
|
||||
"If upgrade fails:": {
|
||||
"es": "Si la actualización falla:",
|
||||
"fr": "Si la mise à niveau échoue :",
|
||||
"de": "Wenn das Upgrade fehlschlägt:",
|
||||
"it": "Se l’aggiornamento fallisce:",
|
||||
"pt": "Se a atualização falhar:"
|
||||
},
|
||||
"If repositories error:": {
|
||||
"es": "Si hay errores de repositorios:",
|
||||
"fr": "En cas d’erreurs de dépôts :",
|
||||
"de": "Bei Repository-Fehlern:",
|
||||
"it": "In caso di errori dei repository:",
|
||||
"pt": "Se houver erros nos repositórios:"
|
||||
},
|
||||
"If 'proxmox-ve' removal warning:": {
|
||||
"es": "Si aparece advertencia de eliminación de ‘proxmox-ve’:",
|
||||
"fr": "Si un avertissement de suppression de ‘proxmox-ve’ apparaît :",
|
||||
"de": "Bei Warnung zur Entfernung von ‚proxmox-ve‘:",
|
||||
"it": "Se compare un avviso di rimozione di ‘proxmox-ve’:",
|
||||
"pt": "Se aparecer um aviso de remoção de ‘proxmox-ve’:"
|
||||
},
|
||||
"Emergency recovery:": {
|
||||
"es": "Recuperación de emergencia:",
|
||||
"fr": "Récupération d’urgence :",
|
||||
"de": "Notfallwiederherstellung:",
|
||||
"it": "Ripristino di emergenza:",
|
||||
"pt": "Recuperação de emergência:"
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -773,6 +773,20 @@
|
||||
],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "Copyparty",
|
||||
"slug": "copyparty",
|
||||
"desc": "Copyparty is a lightweight, portable HTTP file server with a browser-based interface. It supports drag-and-drop uploads, downloads, deduplication, media playback, and advanced search, making it ideal for quickly sharing and managing files.",
|
||||
"script": "tools/addon/copyparty.sh",
|
||||
"script_url": "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/copyparty.sh",
|
||||
"categories": [
|
||||
11
|
||||
],
|
||||
"notes": [
|
||||
"Execute within the Proxmox shell or in LXC"
|
||||
],
|
||||
"type": "addon"
|
||||
},
|
||||
{
|
||||
"name": "Cosmos",
|
||||
"slug": "cosmos",
|
||||
@@ -899,6 +913,22 @@
|
||||
"notes": [],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "Debian 13",
|
||||
"slug": "debian-13-vm",
|
||||
"desc": "Debian 13 (Trixie) Linux is a distribution that emphasizes free software. It supports many hardware platforms",
|
||||
"script": "vm/debian-13-vm.sh",
|
||||
"script_url": "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/vm/debian-13-vm.sh",
|
||||
"categories": [
|
||||
2
|
||||
],
|
||||
"notes": [
|
||||
"VM has no root password set. To login type in user `root` and just press enter",
|
||||
"After installation, checkout: \u00b4https://github.com/community-scripts/ProxmoxVE/discussions/836\u00b4 for useful Debian commands",
|
||||
"If you use Cloud-init, checkout after installation: \u00b4https://github.com/community-scripts/ProxmoxVE/discussions/272\u00b4"
|
||||
],
|
||||
"type": "vm"
|
||||
},
|
||||
{
|
||||
"name": "Debian 12",
|
||||
"slug": "debian-vm",
|
||||
@@ -1008,7 +1038,7 @@
|
||||
{
|
||||
"name": "Docmost",
|
||||
"slug": "docmost",
|
||||
"desc": "Open-source collaborative wiki and documentation software Create, collaborate, and share knowledge seamlessly with Docmost. Ideal for managing your wiki, knowledge-base, documentation and a lot more.",
|
||||
"desc": "Open-source collaborative wiki and documentation software. Create, collaborate, and share knowledge seamlessly with Docmost. Ideal for managing your wiki, knowledge-base, documentation and a lot more.",
|
||||
"script": "ct/docmost.sh",
|
||||
"script_url": "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/docmost.sh",
|
||||
"categories": [
|
||||
@@ -1461,8 +1491,7 @@
|
||||
9
|
||||
],
|
||||
"notes": [
|
||||
"Execute within an existing LXC Console",
|
||||
"WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing."
|
||||
"Execute within an existing LXC Console (Debian / Ubuntu / Alpine supported)"
|
||||
],
|
||||
"type": "addon"
|
||||
},
|
||||
@@ -1696,23 +1725,6 @@
|
||||
"notes": [],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "Home Assistant Core",
|
||||
"slug": "homeassistant-core",
|
||||
"desc": "A standalone installation of Home Assistant Core refers to a setup where the Home Assistant Core software is installed directly on a device or operating system, without the use of Docker containers. This provides a simpler, but less flexible and scalable solution, as the software is tightly coupled with the underlying system.",
|
||||
"script": "ct/homeassistant-core.sh",
|
||||
"script_url": "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/homeassistant-core.sh",
|
||||
"categories": [
|
||||
16
|
||||
],
|
||||
"notes": [
|
||||
"If the LXC is created Privileged, the script will automatically set up USB passthrough.",
|
||||
"Requires PVE 8.2.2 with kernel 6.8.4-3-pve or newer",
|
||||
"Deprecation-Warning: This Core-based setup will be deprecated by August 2025. Use Home Assistant OS is strongly recommended to ensure long-term stability and updates.",
|
||||
"config path: `/root/.homeassistant`"
|
||||
],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "Home Assistant Container",
|
||||
"slug": "homeassistant",
|
||||
@@ -1787,6 +1799,20 @@
|
||||
],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "HortusFox",
|
||||
"slug": "hortusfox",
|
||||
"desc": "HortusFox is a collaborative plant management system for plant enthusiasts. Manage, document and track your entire plant collection \u2013 self-hosted and privacy-friendly.",
|
||||
"script": "ct/hortusfox.sh",
|
||||
"script_url": "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/hortusfox.sh",
|
||||
"categories": [
|
||||
24
|
||||
],
|
||||
"notes": [
|
||||
"Login Credentials : `cat ~/hortusfox.creds`"
|
||||
],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "Proxmox VE Host Backup",
|
||||
"slug": "host-backup",
|
||||
@@ -2010,7 +2036,7 @@
|
||||
"script": "ct/jenkins.sh",
|
||||
"script_url": "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/jenkins.sh",
|
||||
"categories": [
|
||||
22
|
||||
20
|
||||
],
|
||||
"notes": [],
|
||||
"type": "ct"
|
||||
@@ -3207,7 +3233,9 @@
|
||||
4,
|
||||
2
|
||||
],
|
||||
"notes": [],
|
||||
"notes": [
|
||||
"If you use VLANs (default LAN is set to VLAN 999), make sure the Proxmox Linux Bridge is configured as VLAN-aware, otherwise the VM may fail to start."
|
||||
],
|
||||
"type": "vm"
|
||||
},
|
||||
{
|
||||
@@ -3326,6 +3354,22 @@
|
||||
"notes": [],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "Palmr",
|
||||
"slug": "palmr",
|
||||
"desc": "Palmr is a fast and secure platform for sharing files, built with performance and privacy in mind.",
|
||||
"script": "ct/palmr.sh",
|
||||
"script_url": "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/palmr.sh",
|
||||
"categories": [
|
||||
11
|
||||
],
|
||||
"notes": [
|
||||
"This LXC is very memory-hungry when updating; it requires at least 6GB RAM, but RAM may be reduced to as low as 2GB when running normally",
|
||||
"To use a bind mount for storage, create symlinks to your mount for both `uploads` and `temp-uploads` in `/opt/palmr_data`",
|
||||
"To use Palmr with a reverse proxy, uncomment `SECURE_SITE` in `/opt/palmr/apps/server/.env`"
|
||||
],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "PaperlessAI",
|
||||
"slug": "paperless-ai",
|
||||
@@ -3362,10 +3406,14 @@
|
||||
12
|
||||
],
|
||||
"notes": [
|
||||
"Show Login Credentials, type `update` in the LXC console",
|
||||
"Show Login Credentials, type `cat ~/paperless.creds` in the LXC console",
|
||||
"Script installs English as default OCR language. To install additional languages, use `apt-get install tesseract-ocr-[lang]`, where [lang] is the language code (e.g. `apt-get install tesseract-ocr-deu`)."
|
||||
],
|
||||
"type": "ct"
|
||||
"type": "ct",
|
||||
"default_credentials": {
|
||||
"username": "admin",
|
||||
"password": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Part-DB",
|
||||
@@ -3917,7 +3965,8 @@
|
||||
],
|
||||
"notes": [
|
||||
"Create Proxmox-API-Token first: `https://github.com/rcourtman/Pulse?tab=readme-ov-file#creating-api-token`",
|
||||
"After installation, access the web interface to configure your Proxmox connection details through the built-in setup wizard"
|
||||
"After installation, access the web interface to configure your Proxmox connection details through the built-in setup wizard",
|
||||
"Configure authentication in the Web UI => Settings => Security"
|
||||
],
|
||||
"type": "ct"
|
||||
},
|
||||
@@ -3963,7 +4012,11 @@
|
||||
18
|
||||
],
|
||||
"notes": [],
|
||||
"type": "ct"
|
||||
"type": "ct",
|
||||
"default_credentials": {
|
||||
"username": "proxmox",
|
||||
"password": "proxmox"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Radarr",
|
||||
@@ -4356,6 +4409,23 @@
|
||||
],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "Swizzin",
|
||||
"slug": "swizzin",
|
||||
"desc": "Swizzin is a light-weight, modular, and user-friendly seedbox solution for Debian-based servers. It allows for the easy installation and management of a wide variety of applications commonly used for torrenting and media management, such as rTorrent, Sonarr, Radarr, and Plex, all accessible through a command-line utility or a web-based dashboard.",
|
||||
"script": "ct/swizzin.sh",
|
||||
"script_url": "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/swizzin.sh",
|
||||
"categories": [
|
||||
15
|
||||
],
|
||||
"notes": [
|
||||
"Installation might take a long time if choosing to install many apps. Be patient.",
|
||||
"Swizzin is a management suite, not a single application. Use the 'box' command inside the container to install/manage individual apps like rTorrent, Sonarr, etc. A full list can be found in documentation.",
|
||||
"It is very recommended to install at least the 'panel' for web access, and 'nginx' for easy access to other apps.",
|
||||
"WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing."
|
||||
],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "Syncthing",
|
||||
"slug": "syncthing",
|
||||
@@ -4454,9 +4524,7 @@
|
||||
"categories": [
|
||||
5
|
||||
],
|
||||
"notes": [
|
||||
"WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing."
|
||||
],
|
||||
"notes": [],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
@@ -4596,6 +4664,21 @@
|
||||
],
|
||||
"type": "turnkey"
|
||||
},
|
||||
{
|
||||
"name": "twingate-connector",
|
||||
"slug": "twingate-connector",
|
||||
"desc": "Twingate Connectors are lightweight software components that establish secure, least-privileged access between private network resources and authorized users without exposing the network to the internet. They act as outbound-only bridges between your protected resources and the Twingate infrastructure, ensuring zero-trust access without the need for a VPN.",
|
||||
"script": "ct/twingate-connector.sh",
|
||||
"script_url": "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/twingate-connector.sh",
|
||||
"categories": [
|
||||
4
|
||||
],
|
||||
"notes": [
|
||||
"You can get your Twingate access or refresh tokens from the Twingate Admin Console. `https://auth.twingate.com/signup-v2`",
|
||||
"If you need to update your access or refresh tokens, they can be found in /etc/twingate/connector.conf"
|
||||
],
|
||||
"type": "ct"
|
||||
},
|
||||
{
|
||||
"name": "TypeSense",
|
||||
"slug": "typesense",
|
||||
@@ -5010,7 +5093,8 @@
|
||||
4
|
||||
],
|
||||
"notes": [
|
||||
"Wireguard and WGDashboard are not the same. More info: `https://docs.wgdashboard.dev/what-is-wireguard-what-is-wgdashboard.html`"
|
||||
"Wireguard and WGDashboard are not the same. More info: `https://docs.wgdashboard.dev/what-is-wireguard-what-is-wgdashboard.html`",
|
||||
"WGDashboard installation is optional.`"
|
||||
],
|
||||
"type": "ct",
|
||||
"default_credentials": {
|
||||
|
@@ -6,8 +6,8 @@
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : MIT (https://raw.githubusercontent.com/MacRimi/ProxMenux/main/LICENSE)
|
||||
# Version : 1.0
|
||||
# Last Updated: 28/01/2025
|
||||
# Version : 1.1
|
||||
# Last Updated: 17/08/2025
|
||||
# ==========================================================
|
||||
# Description:
|
||||
# This script automates the process of enabling and configuring Intel Integrated GPU (iGPU) support in Proxmox VE LXC containers.
|
||||
@@ -32,7 +32,7 @@ initialize_cache
|
||||
|
||||
|
||||
|
||||
# Select LXC container
|
||||
|
||||
select_container() {
|
||||
|
||||
CONTAINERS=$(pct list | awk 'NR>1 {print $1, $3}' | xargs -n2)
|
||||
@@ -59,14 +59,14 @@ select_container() {
|
||||
|
||||
|
||||
|
||||
# Validate that the selected container is valid
|
||||
|
||||
validate_container_id() {
|
||||
if [ -z "$CONTAINER_ID" ]; then
|
||||
msg_error "$(translate 'Container ID not defined. Make sure to select a container first.')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the container is running and stop it before configuration
|
||||
|
||||
if pct status "$CONTAINER_ID" | grep -q "running"; then
|
||||
msg_info "$(translate 'Stopping the container before applying configuration...')"
|
||||
pct stop "$CONTAINER_ID"
|
||||
@@ -76,77 +76,103 @@ validate_container_id() {
|
||||
|
||||
|
||||
|
||||
# Configure LXC for Coral TPU and iGPU
|
||||
configure_lxc_for_igpu() {
|
||||
validate_container_id
|
||||
|
||||
CONFIG_FILE="/etc/pve/lxc/${CONTAINER_ID}.conf"
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
msg_error "$(translate 'Configuration file for container') $CONTAINER_ID $(translate 'not found.')"
|
||||
exit 1
|
||||
[[ -f "$CONFIG_FILE" ]] || { msg_error "$(translate 'Configuration file for container') $CONTAINER_ID $(translate 'not found.')"; exit 1; }
|
||||
|
||||
|
||||
if [[ ! -d /dev/dri ]]; then
|
||||
modprobe i915 2>/dev/null || true
|
||||
for _ in {1..5}; do
|
||||
[[ -d /dev/dri ]] && break
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
if grep -q "^unprivileged: 1" "$CONFIG_FILE"; then
|
||||
msg_info "$(translate 'The container is unprivileged. Changing to privileged...')"
|
||||
sed -i "s/^unprivileged: 1/unprivileged: 0/" "$CONFIG_FILE"
|
||||
STORAGE_TYPE=$(pct config "$CONTAINER_ID" | grep "^rootfs:" | awk -F, '{print $2}' | cut -d'=' -f2)
|
||||
if [[ "$STORAGE_TYPE" == "dir" ]]; then
|
||||
STORAGE_PATH=$(pct config "$CONTAINER_ID" | grep "^rootfs:" | awk '{print $2}' | cut -d',' -f1)
|
||||
chown -R root:root "$STORAGE_PATH"
|
||||
fi
|
||||
msg_ok "$(translate 'Container changed to privileged.')"
|
||||
CT_TYPE=$(pct config "$CONTAINER_ID" | awk '/^unprivileged:/ {print $2}')
|
||||
[[ -z "$CT_TYPE" ]] && CT_TYPE="0"
|
||||
|
||||
msg_info "$(translate 'Configuring Intel iGPU passthrough for container...')"
|
||||
|
||||
for rn in /dev/dri/renderD*; do
|
||||
[[ -e "$rn" ]] || continue
|
||||
chmod 660 "$rn" 2>/dev/null || true
|
||||
chgrp render "$rn" 2>/dev/null || true
|
||||
done
|
||||
|
||||
mapfile -t RENDER_NODES < <(find /dev/dri -maxdepth 1 -type c -name 'renderD*' 2>/dev/null || true)
|
||||
mapfile -t CARD_NODES < <(find /dev/dri -maxdepth 1 -type c -name 'card*' 2>/dev/null || true)
|
||||
FB_NODE=""
|
||||
[[ -e /dev/fb0 ]] && FB_NODE="/dev/fb0"
|
||||
|
||||
if [[ ${#RENDER_NODES[@]} -eq 0 && ${#CARD_NODES[@]} -eq 0 && -z "$FB_NODE" ]]; then
|
||||
msg_warn "$(translate 'No VA-API devices found on host (/dev/dri*, /dev/fb0). Is i915 loaded?')"
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
||||
if grep -q "^lxc.apparmor.profile" "$CONFIG_FILE"; then
|
||||
msg_info "$(translate 'Disabling AppArmor profile to avoid conflicts...')"
|
||||
sed -i "/^lxc.apparmor.profile/d" "$CONFIG_FILE"
|
||||
msg_ok "$(translate 'AppArmor profile removed.')"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Configure iGPU
|
||||
if ! grep -q "features: nesting=1" "$CONFIG_FILE"; then
|
||||
if grep -q '^features:' "$CONFIG_FILE"; then
|
||||
grep -Eq '^features:.*(^|,)\s*nesting=1(\s|,|$)' "$CONFIG_FILE" || sed -i 's/^features:\s*/&nesting=1, /' "$CONFIG_FILE"
|
||||
else
|
||||
echo "features: nesting=1" >> "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
if ! grep -q "c 226:0 rwm" "$CONFIG_FILE"; then
|
||||
echo "lxc.cgroup2.devices.allow: c 226:0 rwm # iGPU" >> "$CONFIG_FILE"
|
||||
echo "lxc.cgroup2.devices.allow: c 226:128 rwm # iGPU" >> "$CONFIG_FILE"
|
||||
|
||||
|
||||
if [[ "$CT_TYPE" == "0" ]]; then
|
||||
|
||||
sed -i '/^lxc\.cgroup2\.devices\.allow:\s*c\s*226:/d' "$CONFIG_FILE"
|
||||
sed -i '\|^lxc\.mount\.entry:\s*/dev/dri|d' "$CONFIG_FILE"
|
||||
sed -i '\|^lxc\.mount\.entry:\s*/dev/fb0|d' "$CONFIG_FILE"
|
||||
|
||||
echo "lxc.cgroup2.devices.allow: c 226:* rwm" >> "$CONFIG_FILE"
|
||||
echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >> "$CONFIG_FILE"
|
||||
echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >> "$CONFIG_FILE"
|
||||
[[ -n "$FB_NODE" ]] && echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >> "$CONFIG_FILE"
|
||||
|
||||
|
||||
else
|
||||
sed -i '/^dev[0-9]\+:/d' "$CONFIG_FILE"
|
||||
|
||||
idx=0
|
||||
for c in "${CARD_NODES[@]}"; do
|
||||
echo "dev${idx}: $c,gid=44" >> "$CONFIG_FILE"
|
||||
idx=$((idx+1))
|
||||
done
|
||||
for r in "${RENDER_NODES[@]}"; do
|
||||
echo "dev${idx}: $r,gid=104" >> "$CONFIG_FILE"
|
||||
idx=$((idx+1))
|
||||
done
|
||||
|
||||
fi
|
||||
msg_ok "$(translate 'iGPU configuration added to container') $CONTAINER_ID."
|
||||
|
||||
if ! grep -q "c 29:0 rwm # Framebuffer" "$CONFIG_FILE"; then
|
||||
echo "lxc.cgroup2.devices.allow: c 29:0 rwm # Framebuffer" >> "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
if ! grep -q "lxc.mount.entry: /dev/fb0" "$CONFIG_FILE"; then
|
||||
echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >> "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
|
||||
msg_ok "$(translate 'Coral TPU and iGPU configuration added to container') $CONTAINER_ID."
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Install iGPU drivers in the container
|
||||
|
||||
|
||||
install_igpu_in_container() {
|
||||
|
||||
msg_info2 "$(translate 'Installing iGPU drivers inside the container...')"
|
||||
tput sc
|
||||
LOG_FILE=$(mktemp)
|
||||
|
||||
msg_info "$(translate 'Installing iGPU drivers...')"
|
||||
|
||||
pct start "$CONTAINER_ID" >/dev/null 2>&1
|
||||
|
||||
script -q -c "pct exec \"$CONTAINER_ID\" -- bash -c '
|
||||
set -e
|
||||
getent group video >/dev/null || groupadd -g 44 video
|
||||
getent group render >/dev/null || groupadd -g 104 render
|
||||
usermod -aG video,render root || true
|
||||
|
||||
apt-get update >/dev/null 2>&1
|
||||
apt-get install -y va-driver-all ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools
|
||||
chgrp video /dev/dri && chmod 755 /dev/dri
|
||||
adduser root video && adduser root render
|
||||
|
||||
chgrp video /dev/dri 2>/dev/null || true
|
||||
chmod 755 /dev/dri 2>/dev/null || true
|
||||
'" "$LOG_FILE"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
@@ -167,6 +193,7 @@ install_igpu_in_container() {
|
||||
|
||||
select_container
|
||||
show_proxmenux_logo
|
||||
msg_title "$(translate "Add HW iGPU acceleration to an LXC")"
|
||||
configure_lxc_for_igpu
|
||||
install_igpu_in_container
|
||||
|
||||
|
@@ -187,7 +187,12 @@ is_disk_in_use() {
|
||||
|
||||
FREE_DISKS=()
|
||||
|
||||
LVM_DEVICES=$(pvs --noheadings -o pv_name 2> >(grep -v 'File descriptor .* leaked') | xargs -n1 readlink -f | sort -u)
|
||||
LVM_DEVICES=$(pvs --noheadings -o pv_name 2> >(grep -v 'File descriptor .* leaked') | xargs -r -n1 readlink -f | sort -u)
|
||||
|
||||
if [[ -n "$LVM_DEVICES" ]] && echo "$LVM_DEVICES" | grep -qFx "$REAL_PATH"; then
|
||||
IS_MOUNTED=true
|
||||
fi
|
||||
|
||||
RAID_ACTIVE=$(grep -Po 'md\d+\s*:\s*active\s+raid[0-9]+' /proc/mdstat | awk '{print $1}' | sort -u)
|
||||
|
||||
while read -r DISK; do
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
# ==========================================================
|
||||
# Remove Subscription Banner - Proxmox VE 9.x ONLY
|
||||
# Remove Subscription Banner - Proxmox VE 9.x
|
||||
# ==========================================================
|
||||
REPO_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main"
|
||||
BASE_DIR="/usr/local/share/proxmenux"
|
||||
@@ -15,7 +15,7 @@ fi
|
||||
load_language
|
||||
initialize_cache
|
||||
|
||||
# Tool registration system
|
||||
|
||||
ensure_tools_json() {
|
||||
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
|
||||
}
|
||||
@@ -33,7 +33,7 @@ remove_subscription_banner_pve9() {
|
||||
local GZ_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz"
|
||||
local APT_HOOK="/etc/apt/apt.conf.d/no-nag-script"
|
||||
|
||||
# Verify PVE 9.x
|
||||
|
||||
local pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+\.[0-9]+' | head -1)
|
||||
local pve_major=$(echo "$pve_version" | cut -d. -f1)
|
||||
|
||||
@@ -44,45 +44,49 @@ remove_subscription_banner_pve9() {
|
||||
|
||||
msg_info "Detected Proxmox VE $pve_version - Applying PVE 9.x patches"
|
||||
|
||||
# Verify that the file exists
|
||||
|
||||
if [ ! -f "$JS_FILE" ]; then
|
||||
msg_error "JavaScript file not found: $JS_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# Create backup of original file
|
||||
|
||||
|
||||
local backup_file="${JS_FILE}.backup.pve9.$(date +%Y%m%d_%H%M%S)"
|
||||
cp "$JS_FILE" "$backup_file"
|
||||
|
||||
# Clean any existing problematic APT hooks
|
||||
|
||||
for f in /etc/apt/apt.conf.d/*nag*; do
|
||||
[[ -e "$f" ]] && rm -f "$f"
|
||||
done
|
||||
|
||||
[[ -f "$GZ_FILE" ]] && rm -f "$GZ_FILE"
|
||||
[[ -f "$MIN_JS_FILE" ]] && rm -f "$MIN_JS_FILE"
|
||||
|
||||
find /var/cache/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
|
||||
find /var/lib/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
|
||||
find /var/cache/nginx/ -type f -delete 2>/dev/null || true
|
||||
|
||||
|
||||
# Main subscription check patches for PVE 9
|
||||
sed -i "s/res\.data\.status\.toLowerCase() !== 'active'/false/g" "$JS_FILE"
|
||||
sed -i "s/subscriptionActive: ''/subscriptionActive: true/g" "$JS_FILE"
|
||||
sed -i "s/title: gettext('No valid subscription')/title: gettext('Community Edition')/g" "$JS_FILE"
|
||||
|
||||
# Additional UX improvements for PVE 9
|
||||
|
||||
sed -i "s/You do not have a valid subscription for this server/Community Edition - No subscription required/g" "$JS_FILE"
|
||||
sed -i "s/Enterprise repository needs valid subscription/Enterprise repository configured/g" "$JS_FILE"
|
||||
sed -i "s/icon: Ext\.Msg\.WARNING/icon: Ext.Msg.INFO/g" "$JS_FILE"
|
||||
|
||||
# Additional subscription patterns that may exist in PVE 9
|
||||
|
||||
sed -i "s/subscription = !(/subscription = false \&\& (/g" "$JS_FILE"
|
||||
|
||||
# Remove compressed/minified files to force regeneration
|
||||
[[ -f "$GZ_FILE" ]] && rm -f "$GZ_FILE"
|
||||
[[ -f "$MIN_JS_FILE" ]] && rm -f "$MIN_JS_FILE"
|
||||
if grep -q "res\.data\.status\.toLowerCase() !== 'active'" "$JS_FILE"; then
|
||||
msg_warn "Some patches may not have applied correctly, retrying..."
|
||||
sed -i "s/res\.data\.status\.toLowerCase() !== 'active'/false/g" "$JS_FILE"
|
||||
fi
|
||||
|
||||
# Clear various caches
|
||||
find /var/cache/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
|
||||
find /var/lib/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
|
||||
|
||||
# Create PVE 9.x specific APT hook
|
||||
[[ -f "$APT_HOOK" ]] && rm -f "$APT_HOOK"
|
||||
cat > "$APT_HOOK" << 'EOF'
|
||||
DPkg::Post-Invoke {
|
||||
@@ -96,7 +100,7 @@ EOF
|
||||
|
||||
chmod 644 "$APT_HOOK"
|
||||
|
||||
# Verify APT hook syntax
|
||||
|
||||
if ! apt-config dump >/dev/null 2>&1; then
|
||||
msg_warn "APT hook has syntax issues, removing..."
|
||||
rm -f "$APT_HOOK"
|
||||
@@ -105,15 +109,16 @@ EOF
|
||||
fi
|
||||
|
||||
|
||||
msg_ok "Subscription banner removed successfully for Proxmox VE $pve_version"
|
||||
msg_ok "Banner removal process completed"
|
||||
|
||||
systemctl reload nginx 2>/dev/null || true
|
||||
|
||||
msg_ok "Subscription banner removed successfully for Proxmox VE $pve_version"
|
||||
msg_ok "Banner removal process completed - refresh your browser to see changes"
|
||||
|
||||
register_tool "subscription_banner" true
|
||||
}
|
||||
|
||||
|
||||
# Execute function if called directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
remove_subscription_banner_pve9
|
||||
fi
|
||||
|
119
scripts/global/remove-banner-pve9_.sh
Normal file
119
scripts/global/remove-banner-pve9_.sh
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/bin/bash
|
||||
# ==========================================================
|
||||
# Remove Subscription Banner - Proxmox VE 9.x ONLY
|
||||
# ==========================================================
|
||||
REPO_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main"
|
||||
BASE_DIR="/usr/local/share/proxmenux"
|
||||
UTILS_FILE="$BASE_DIR/utils.sh"
|
||||
VENV_PATH="/opt/googletrans-env"
|
||||
TOOLS_JSON="/usr/local/share/proxmenux/installed_tools.json"
|
||||
|
||||
if [[ -f "$UTILS_FILE" ]]; then
|
||||
source "$UTILS_FILE"
|
||||
fi
|
||||
|
||||
load_language
|
||||
initialize_cache
|
||||
|
||||
# Tool registration system
|
||||
ensure_tools_json() {
|
||||
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
|
||||
}
|
||||
|
||||
register_tool() {
|
||||
local tool="$1"
|
||||
local state="$2"
|
||||
ensure_tools_json
|
||||
jq --arg t "$tool" --argjson v "$state" '.[$t]=$v' "$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
|
||||
}
|
||||
|
||||
remove_subscription_banner_pve9() {
|
||||
local JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js"
|
||||
local MIN_JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js"
|
||||
local GZ_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz"
|
||||
local APT_HOOK="/etc/apt/apt.conf.d/no-nag-script"
|
||||
|
||||
# Verify PVE 9.x
|
||||
local pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+\.[0-9]+' | head -1)
|
||||
local pve_major=$(echo "$pve_version" | cut -d. -f1)
|
||||
|
||||
if [ "$pve_major" -lt 9 ] 2>/dev/null; then
|
||||
msg_error "This script is for PVE 9.x only. Detected PVE $pve_version"
|
||||
return 1
|
||||
fi
|
||||
|
||||
msg_info "Detected Proxmox VE $pve_version - Applying PVE 9.x patches"
|
||||
|
||||
# Verify that the file exists
|
||||
if [ ! -f "$JS_FILE" ]; then
|
||||
msg_error "JavaScript file not found: $JS_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# Create backup of original file
|
||||
local backup_file="${JS_FILE}.backup.pve9.$(date +%Y%m%d_%H%M%S)"
|
||||
cp "$JS_FILE" "$backup_file"
|
||||
|
||||
# Clean any existing problematic APT hooks
|
||||
for f in /etc/apt/apt.conf.d/*nag*; do
|
||||
[[ -e "$f" ]] && rm -f "$f"
|
||||
done
|
||||
|
||||
|
||||
# Main subscription check patches for PVE 9
|
||||
sed -i "s/res\.data\.status\.toLowerCase() !== 'active'/false/g" "$JS_FILE"
|
||||
sed -i "s/subscriptionActive: ''/subscriptionActive: true/g" "$JS_FILE"
|
||||
sed -i "s/title: gettext('No valid subscription')/title: gettext('Community Edition')/g" "$JS_FILE"
|
||||
|
||||
# Additional UX improvements for PVE 9
|
||||
sed -i "s/You do not have a valid subscription for this server/Community Edition - No subscription required/g" "$JS_FILE"
|
||||
sed -i "s/Enterprise repository needs valid subscription/Enterprise repository configured/g" "$JS_FILE"
|
||||
sed -i "s/icon: Ext\.Msg\.WARNING/icon: Ext.Msg.INFO/g" "$JS_FILE"
|
||||
|
||||
# Additional subscription patterns that may exist in PVE 9
|
||||
sed -i "s/subscription = !(/subscription = false \&\& (/g" "$JS_FILE"
|
||||
|
||||
# Remove compressed/minified files to force regeneration
|
||||
[[ -f "$GZ_FILE" ]] && rm -f "$GZ_FILE"
|
||||
[[ -f "$MIN_JS_FILE" ]] && rm -f "$MIN_JS_FILE"
|
||||
|
||||
# Clear various caches
|
||||
find /var/cache/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
|
||||
find /var/lib/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
|
||||
|
||||
# Create PVE 9.x specific APT hook
|
||||
[[ -f "$APT_HOOK" ]] && rm -f "$APT_HOOK"
|
||||
cat > "$APT_HOOK" << 'EOF'
|
||||
DPkg::Post-Invoke {
|
||||
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/res\\.data\\.status\\.toLowerCase() !== '\''active'\''/false/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
|
||||
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/subscriptionActive: '\'\'\''/subscriptionActive: true/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
|
||||
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/title: gettext('\''No valid subscription'\'')/title: gettext('\''Community Edition'\'')/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
|
||||
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/subscription = !(/subscription = false \\&\\& (/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
|
||||
"rm -f /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz || true";
|
||||
};
|
||||
EOF
|
||||
|
||||
chmod 644 "$APT_HOOK"
|
||||
|
||||
# Verify APT hook syntax
|
||||
if ! apt-config dump >/dev/null 2>&1; then
|
||||
msg_warn "APT hook has syntax issues, removing..."
|
||||
rm -f "$APT_HOOK"
|
||||
else
|
||||
msg_ok "APT hook created successfully"
|
||||
fi
|
||||
|
||||
|
||||
msg_ok "Subscription banner removed successfully for Proxmox VE $pve_version"
|
||||
msg_ok "Banner removal process completed"
|
||||
|
||||
|
||||
register_tool "subscription_banner" true
|
||||
}
|
||||
|
||||
|
||||
# Execute function if called directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
remove_subscription_banner_pve9
|
||||
fi
|
@@ -179,9 +179,11 @@ EOF
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export APT_LISTCHANGES_FRONTEND=none
|
||||
export NEEDRESTART_MODE=a
|
||||
export UCF_FORCE_CONFOLD=1
|
||||
export DPKG_OPTIONS="--force-confdef --force-confold"
|
||||
|
||||
msg_info "$(translate "Performing packages upgrade...")"
|
||||
apt-get install pv -y > /dev/null 2>&1
|
||||
@@ -195,22 +197,24 @@ EOF
|
||||
tput civis
|
||||
tput sc
|
||||
|
||||
|
||||
(
|
||||
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' dist-upgrade 2>&1 | \
|
||||
/usr/bin/env \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
APT_LISTCHANGES_FRONTEND=none \
|
||||
NEEDRESTART_MODE=a \
|
||||
UCF_FORCE_CONFOLD=1 \
|
||||
apt-get -y \
|
||||
-o Dpkg::Options::="--force-confdef" \
|
||||
-o Dpkg::Options::="--force-confold" \
|
||||
dist-upgrade 2>&1 | \
|
||||
while IFS= read -r line; do
|
||||
if [[ "$line" =~ ^(Setting up|Unpacking|Preparing to unpack|Processing triggers for) ]]; then
|
||||
|
||||
if [[ "$line" =~ ^(Setting\ up|Unpacking|Preparing\ to\ unpack|Processing\ triggers\ for) ]]; then
|
||||
package_name=$(echo "$line" | sed -E 's/.*(Setting up|Unpacking|Preparing to unpack|Processing triggers for) ([^ ]+).*/\2/')
|
||||
|
||||
|
||||
[ -z "$package_name" ] && package_name="$(translate "Unknown")"
|
||||
|
||||
|
||||
tput rc
|
||||
tput ed
|
||||
|
||||
|
||||
row=$(( $(tput lines) - 6 ))
|
||||
tput cup $row 0; echo "$(translate "Installing packages...")"
|
||||
tput cup $((row + 1)) 0; echo "──────────────────────────────────────────────"
|
||||
@@ -218,12 +222,10 @@ EOF
|
||||
tput cup $((row + 3)) 0; echo "Progress: [ ] 0%"
|
||||
tput cup $((row + 4)) 0; echo "──────────────────────────────────────────────"
|
||||
|
||||
|
||||
for i in $(seq 1 10); do
|
||||
progress=$((i * 10))
|
||||
tput cup $((row + 3)) 9
|
||||
printf "[%-50s] %3d%%" "$(printf "#%.0s" $(seq 1 $((progress/2))))" "$progress"
|
||||
|
||||
done
|
||||
fi
|
||||
done
|
||||
@@ -232,6 +234,7 @@ EOF
|
||||
if [ $? -eq 0 ]; then
|
||||
tput rc
|
||||
tput ed
|
||||
tput cnorm
|
||||
msg_ok "$(translate "System upgrade completed")"
|
||||
fi
|
||||
|
||||
|
267
scripts/lcx/lxc-privileged-to-unprivileged.sh
Normal file
267
scripts/lcx/lxc-privileged-to-unprivileged.sh
Normal file
@@ -0,0 +1,267 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==========================================================
|
||||
# ProxMenu - LXC Privileged to Unprivileged Converter
|
||||
# ==========================================================
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : MIT (https://raw.githubusercontent.com/MacRimi/ProxMenux/main/LICENSE)
|
||||
# Version : 1.1
|
||||
# Last Updated: 19/08/2025
|
||||
# ==========================================================
|
||||
# Description:
|
||||
# This script converts a privileged LXC container to an unprivileged one
|
||||
# using the direct conversion method (mount and chown).
|
||||
# ==========================================================
|
||||
|
||||
# Configuration ============================================
|
||||
REPO_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main"
|
||||
BASE_DIR="/usr/local/share/proxmenux"
|
||||
UTILS_FILE="$BASE_DIR/utils.sh"
|
||||
VENV_PATH="/opt/googletrans-env"
|
||||
|
||||
if [[ -f "$UTILS_FILE" ]]; then
|
||||
source "$UTILS_FILE"
|
||||
fi
|
||||
|
||||
load_language
|
||||
initialize_cache
|
||||
|
||||
# ==========================================================
|
||||
|
||||
select_privileged_container() {
|
||||
|
||||
CONTAINERS=$(pct list | awk 'NR>1 {print $1, $3}' | while read id name; do
|
||||
if pct config "$id" | grep -q "^unprivileged: 0" || ! pct config "$id" | grep -q "^unprivileged:"; then
|
||||
echo "$id" "$name"
|
||||
fi
|
||||
done | xargs -n2)
|
||||
|
||||
if [ -z "$CONTAINERS" ]; then
|
||||
msg_error "$(translate 'No privileged containers available in Proxmox.')"
|
||||
exit 1
|
||||
fi
|
||||
cleanup
|
||||
CONTAINER_ID=$(whiptail --title "$(translate 'Select Privileged Container')" \
|
||||
--menu "$(translate 'Select the privileged LXC container to convert:')" 20 70 10 $CONTAINERS 3>&1 1>&2 2>&3)
|
||||
|
||||
if [ -z "$CONTAINER_ID" ]; then
|
||||
msg_error "$(translate 'No container selected. Exiting.')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
msg_ok "$(translate 'Privileged container selected:') $CONTAINER_ID"
|
||||
}
|
||||
|
||||
validate_container_id() {
|
||||
if [ -z "$CONTAINER_ID" ]; then
|
||||
msg_error "$(translate 'Container ID not defined. Make sure to select a container first.')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if pct config "$CONTAINER_ID" | grep -q "^unprivileged: 1"; then
|
||||
msg_error "$(translate 'Container') $CONTAINER_ID $(translate 'is already unprivileged.')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if pct status "$CONTAINER_ID" | grep -q "running"; then
|
||||
msg_info "$(translate 'Stopping the container before conversion...')"
|
||||
pct stop "$CONTAINER_ID"
|
||||
msg_ok "$(translate 'Container stopped.')"
|
||||
fi
|
||||
}
|
||||
|
||||
show_backup_warning() {
|
||||
local message="$(translate 'It is strongly recommended to create a backup of your container before proceeding with the conversion.')"
|
||||
message="$message\n\n$(translate 'Do you want to continue with the conversion now, or exit to create a backup first?')"
|
||||
message="$message\n\n$(translate 'Continue: Proceed with conversion')"
|
||||
message="$message\n$(translate 'Exit: Stop to create backup manually')"
|
||||
|
||||
if whiptail --title "$(translate 'Backup Recommendation')" \
|
||||
--yes-button "$(translate 'Continue')" \
|
||||
--no-button "$(translate 'Exit')" \
|
||||
--yesno "$message" 18 80; then
|
||||
return 0
|
||||
else
|
||||
msg_info2 "$(translate 'User chose to exit for manual backup creation.')"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
convert_direct_method() {
|
||||
msg_info2 "$(translate 'Starting direct conversion of container') $CONTAINER_ID..."
|
||||
|
||||
TEMP_DIR="/tmp/lxc_convert_$CONTAINER_ID"
|
||||
mkdir -p "$TEMP_DIR"
|
||||
|
||||
|
||||
ROOTFS_CONFIG=$(pct config "$CONTAINER_ID" | grep "^rootfs:")
|
||||
if [ -z "$ROOTFS_CONFIG" ]; then
|
||||
msg_error "$(translate 'Could not find rootfs configuration for container.')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
STORAGE_DISK=$(echo "$ROOTFS_CONFIG" | awk '{print $2}' | cut -d, -f1)
|
||||
|
||||
msg_ok "$(translate 'Storage disk identifier:') $STORAGE_DISK"
|
||||
|
||||
|
||||
DISK_PATH=$(pvesm path "$STORAGE_DISK" 2>/dev/null)
|
||||
|
||||
if [ -n "$DISK_PATH" ] && [ -e "$DISK_PATH" ]; then
|
||||
msg_ok "$(translate 'Disk path resolved via pvesm:') $DISK_PATH"
|
||||
else
|
||||
|
||||
STORAGE_NAME=$(echo "$STORAGE_DISK" | cut -d: -f1)
|
||||
DISK_NAME=$(echo "$STORAGE_DISK" | cut -d: -f2)
|
||||
|
||||
msg_info2 "$(translate 'pvesm path failed, trying manual detection...')"
|
||||
msg_info2 "$(translate 'Storage:') $STORAGE_NAME, $(translate 'Disk:') $DISK_NAME"
|
||||
|
||||
|
||||
for vg in pve $(vgs --noheadings -o vg_name 2>/dev/null | tr -d ' '); do
|
||||
if [ -e "/dev/$vg/$DISK_NAME" ]; then
|
||||
DISK_PATH="/dev/$vg/$DISK_NAME"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
if [ -z "$DISK_PATH" ] || [ ! -e "$DISK_PATH" ]; then
|
||||
ZFS_PATH="/dev/zvol/$STORAGE_NAME/$DISK_NAME"
|
||||
if [ -e "$ZFS_PATH" ]; then
|
||||
DISK_PATH="$ZFS_PATH"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ -z "$DISK_PATH" ] || [ ! -e "$DISK_PATH" ]; then
|
||||
msg_error "$(translate 'Could not determine disk path for:') $STORAGE_DISK"
|
||||
msg_error "$(translate 'Tried pvesm path and manual detection methods')"
|
||||
msg_info2 "$(translate 'Available storage information:')"
|
||||
pvesm status 2>/dev/null || msg_error "$(translate 'pvesm status failed')"
|
||||
rmdir "$TEMP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
msg_ok "$(translate 'Mounting container filesystem')"
|
||||
if ! mount "$DISK_PATH" "$TEMP_DIR" 2>/dev/null; then
|
||||
|
||||
if ! mount -o loop "$DISK_PATH" "$TEMP_DIR" 2>/dev/null; then
|
||||
msg_error "$(translate 'Failed to mount container filesystem.')"
|
||||
msg_error "$(translate 'Disk path:') $DISK_PATH"
|
||||
msg_success "$(translate "Press Enter to return")"
|
||||
read -r
|
||||
rmdir "$TEMP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
msg_info "$(translate 'Converting file ownership (this may take several minutes)...')"
|
||||
|
||||
|
||||
find "$TEMP_DIR" -type f -print0 | while IFS= read -r -d '' S; do
|
||||
|
||||
if [ ! -e "$S" ] || [ ! -r "$S" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
if STAT_OUTPUT=$(stat -c "%u %g" "$S" 2>/dev/null); then
|
||||
U=$(echo "$STAT_OUTPUT" | awk '{print $1}')
|
||||
G=$(echo "$STAT_OUTPUT" | awk '{print $2}')
|
||||
F=100000
|
||||
|
||||
|
||||
NEW_UID=$((F + U))
|
||||
NEW_GID=$((F + G))
|
||||
|
||||
|
||||
if ! chown "$NEW_UID:$NEW_GID" "$S" 2>/dev/null; then
|
||||
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
find "$TEMP_DIR" -type d -print0 | while IFS= read -r -d '' S; do
|
||||
|
||||
if [ ! -e "$S" ] || [ ! -r "$S" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
if STAT_OUTPUT=$(stat -c "%u %g" "$S" 2>/dev/null); then
|
||||
U=$(echo "$STAT_OUTPUT" | awk '{print $1}')
|
||||
G=$(echo "$STAT_OUTPUT" | awk '{print $2}')
|
||||
F=100000
|
||||
|
||||
|
||||
NEW_UID=$((F + U))
|
||||
NEW_GID=$((F + G))
|
||||
|
||||
|
||||
if ! chown "$NEW_UID:$NEW_GID" "$S" 2>/dev/null; then
|
||||
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
[ -e "$TEMP_DIR/var/spool/postfix/dev/-random" ] && rm -f "$TEMP_DIR/var/spool/postfix/dev/-random"
|
||||
[ -e "$TEMP_DIR/var/spool/postfix/dev/-urandom" ] && rm -f "$TEMP_DIR/var/spool/postfix/dev/-urandom"
|
||||
|
||||
|
||||
[ -e "$TEMP_DIR/usr/bin/sudo" ] && chmod u+s "$TEMP_DIR/usr/bin/sudo"
|
||||
|
||||
umount "$TEMP_DIR"
|
||||
rmdir "$TEMP_DIR"
|
||||
|
||||
|
||||
CONFIG_FILE="/etc/pve/lxc/$CONTAINER_ID.conf"
|
||||
if ! grep -q "^unprivileged:" "$CONFIG_FILE"; then
|
||||
echo "unprivileged: 1" >> "$CONFIG_FILE"
|
||||
else
|
||||
sed -i 's/^unprivileged:.*/unprivileged: 1/' "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
msg_ok "$(translate 'Direct conversion completed for container') $CONTAINER_ID"
|
||||
}
|
||||
|
||||
cleanup_and_finalize() {
|
||||
|
||||
if whiptail --yesno "$(translate 'Do you want to start the converted unprivileged container') $CONTAINER_ID $(translate 'now?')" 10 60; then
|
||||
msg_info2 "$(translate 'Starting unprivileged container...')"
|
||||
pct start "$CONTAINER_ID"
|
||||
msg_ok "$(translate 'Unprivileged container') $CONTAINER_ID $(translate 'started successfully.')"
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
show_proxmenux_logo
|
||||
msg_title "$(translate "LXC Privileged to Unprivileged conversion")"
|
||||
msg_info "$(translate 'Starting LXC Privileged to Unprivileged conversion process...')"
|
||||
|
||||
select_privileged_container
|
||||
validate_container_id
|
||||
show_backup_warning
|
||||
|
||||
convert_direct_method
|
||||
cleanup_and_finalize
|
||||
|
||||
msg_ok "$(translate 'Converted container ID:') $CONTAINER_ID"
|
||||
msg_ok "$(translate 'LXC conversion from privileged to unprivileged completed successfully!')"
|
||||
echo -e
|
||||
msg_success "$(translate "Press Enter to continue")"
|
||||
read -r
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
main
|
103
scripts/menus/lxc_menu.sh
Normal file
103
scripts/menus/lxc_menu.sh
Normal file
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==========================================================
|
||||
# ProxMenu - LXC Conversion Management Menu
|
||||
# ==========================================================
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : MIT (https://raw.githubusercontent.com/MacRimi/ProxMenux/main/LICENSE)
|
||||
# Version : 1.0
|
||||
# Last Updated: 19/08/2025
|
||||
# ==========================================================
|
||||
# Description:
|
||||
# This script provides a menu interface for LXC container privilege conversions.
|
||||
# Allows converting between privileged and unprivileged containers safely.
|
||||
# ==========================================================
|
||||
|
||||
# Configuration ============================================
|
||||
REPO_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main"
|
||||
BASE_DIR="/usr/local/share/proxmenux"
|
||||
UTILS_FILE="$BASE_DIR/utils.sh"
|
||||
VENV_PATH="/opt/googletrans-env"
|
||||
|
||||
if [[ -f "$UTILS_FILE" ]]; then
|
||||
source "$UTILS_FILE"
|
||||
fi
|
||||
|
||||
load_language
|
||||
initialize_cache
|
||||
|
||||
# ==========================================================
|
||||
|
||||
show_main_menu() {
|
||||
CHOICE=$(dialog --backtitle "ProxMenux" --title "$(translate 'LXC Management')" \
|
||||
--menu "$(translate 'Select conversion option:')" 20 70 10 \
|
||||
"1" "$(translate 'Convert Privileged to Unprivileged')" \
|
||||
"2" "$(translate 'Convert Unprivileged to Privileged')" \
|
||||
"3" "$(translate 'Show Container Privilege Status')" \
|
||||
"4" "$(translate 'Exit')" 3>&1 1>&2 2>&3)
|
||||
|
||||
case $CHOICE in
|
||||
1)
|
||||
bash <(curl -fsSL "$REPO_URL/scripts/lcx/lxc-privileged-to-unprivileged.sh")
|
||||
;;
|
||||
2)
|
||||
convert_unprivileged_to_privileged
|
||||
;;
|
||||
3)
|
||||
show_container_status
|
||||
;;
|
||||
4)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
|
||||
convert_unprivileged_to_privileged() {
|
||||
|
||||
bash <(curl -fsSL "$REPO_URL/scripts/lcx/lxc-privileged-to-unprivileged.sh")
|
||||
|
||||
}
|
||||
|
||||
show_container_status() {
|
||||
show_proxmenux_logo
|
||||
msg_info "$(translate 'Gathering container privilege information...')"
|
||||
|
||||
|
||||
TEMP_FILE=$(mktemp)
|
||||
|
||||
echo "$(translate 'LXC Container Privilege Status')" > "$TEMP_FILE"
|
||||
echo "=================================" >> "$TEMP_FILE"
|
||||
echo "" >> "$TEMP_FILE"
|
||||
|
||||
pct list | awk 'NR>1 {print $1, $3}' | while read id name; do
|
||||
if pct config "$id" | grep -q "^unprivileged: 1"; then
|
||||
status="$(translate 'Unprivileged')"
|
||||
else
|
||||
status="$(translate 'Privileged')"
|
||||
fi
|
||||
|
||||
running_status=$(pct status "$id" | grep -q "running" && echo "$(translate 'Running')" || echo "$(translate 'Stopped')")
|
||||
|
||||
printf "ID: %-4s | %-20s | %-12s | %s\n" "$id" "$name" "$status" "$running_status" >> "$TEMP_FILE"
|
||||
done
|
||||
|
||||
|
||||
cleanup
|
||||
dialog --backtitle "ProxMenux" --title "$(translate 'Container Status')" --textbox "$TEMP_FILE" 25 80
|
||||
|
||||
|
||||
rm -f "$TEMP_FILE"
|
||||
show_main_menu
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
show_main_menu
|
@@ -16,27 +16,87 @@ BASE_DIR="/usr/local/share/proxmenux"
|
||||
UTILS_FILE="$BASE_DIR/utils.sh"
|
||||
VENV_PATH="/opt/googletrans-env"
|
||||
|
||||
if [[ -f "$UTILS_FILE" ]]; then
|
||||
source "$UTILS_FILE"
|
||||
fi
|
||||
|
||||
load_language
|
||||
initialize_cache
|
||||
# ==========================================================
|
||||
|
||||
if ! command -v dialog &>/dev/null; then
|
||||
apt update -qq >/dev/null 2>&1
|
||||
apt install -y dialog >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
|
||||
check_pve9_translation_compatibility() {
|
||||
local pve_version
|
||||
|
||||
if command -v pveversion &>/dev/null; then
|
||||
pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+' | head -1)
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ -n "$pve_version" ]] && [[ "$pve_version" -ge 9 ]] && [[ -d "$VENV_PATH" ]]; then
|
||||
|
||||
local has_googletrans=false
|
||||
local has_cache=false
|
||||
|
||||
if [[ -f "$VENV_PATH/bin/pip" ]]; then
|
||||
if "$VENV_PATH/bin/pip" list 2>/dev/null | grep -q "googletrans"; then
|
||||
has_googletrans=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -f "$BASE_DIR/cache.json" ]]; then
|
||||
has_cache=true
|
||||
fi
|
||||
|
||||
if [[ "$has_googletrans" = true ]] || [[ "$has_cache" = true ]]; then
|
||||
|
||||
dialog --clear \
|
||||
--backtitle "ProxMenux - Compatibility Required" \
|
||||
--title "Translation Environment Incompatible with PVE $pve_version" \
|
||||
--msgbox "NOTICE: You are running Proxmox VE $pve_version with translation components installed.\n\nTranslations are NOT supported in PVE 9+. This causes:\n• Menu loading errors\n• Translation failures\n• System instability\n\nREQUIRED ACTION:\nProxMenux will now automatically reinstall the Normal Version.\n\nThis process will:\n• Remove incompatible translation components\n• Install PVE 9+ compatible version\n• Preserve all your settings and preferences\n\nPress OK to continue with automatic reinstallation..." 20 75
|
||||
|
||||
bash <(curl -sSL "$REPO_URL/install_proxmenux.sh")
|
||||
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
check_pve9_translation_compatibility
|
||||
|
||||
# ==========================================================
|
||||
|
||||
if [[ -f "$UTILS_FILE" ]]; then
|
||||
source "$UTILS_FILE"
|
||||
fi
|
||||
|
||||
|
||||
if [[ "$PROXMENUX_PVE9_WARNING_SHOWN" = "1" ]]; then
|
||||
|
||||
if ! load_language 2>/dev/null; then
|
||||
LANGUAGE="en"
|
||||
fi
|
||||
|
||||
else
|
||||
load_language
|
||||
initialize_cache
|
||||
fi
|
||||
|
||||
# ==========================================================
|
||||
|
||||
show_menu() {
|
||||
local TEMP_FILE
|
||||
TEMP_FILE=$(mktemp)
|
||||
|
||||
while true; do
|
||||
|
||||
local menu_title="Main ProxMenux"
|
||||
if [[ -n "$PROXMENUX_PVE9_WARNING_SHOWN" ]]; then
|
||||
menu_title="Main ProxMenux"
|
||||
fi
|
||||
|
||||
dialog --clear \
|
||||
--backtitle "ProxMenux" \
|
||||
--title "$(translate "Main ProxMenux")" \
|
||||
--title "$(translate "$menu_title")" \
|
||||
--menu "$(translate "Select an option:")" 20 70 10 \
|
||||
1 "$(translate "Settings post-install Proxmox")" \
|
||||
2 "$(translate "Help and Info Commands")" \
|
||||
@@ -52,7 +112,6 @@ show_menu() {
|
||||
local EXIT_STATUS=$?
|
||||
|
||||
if [[ $EXIT_STATUS -ne 0 ]]; then
|
||||
# ESC pressed or Cancel
|
||||
clear
|
||||
msg_ok "$(translate "Thank you for using ProxMenux. Goodbye!")"
|
||||
rm -f "$TEMP_FILE"
|
||||
@@ -63,7 +122,7 @@ show_menu() {
|
||||
|
||||
case $OPTION in
|
||||
1) exec bash <(curl -s "$REPO_URL/scripts/menus/menu_post_install.sh") ;;
|
||||
2) bash <(curl -s "$REPO_URL/scripts/help_info_menu.sh") ;;
|
||||
2) exec bash <(curl -s "$REPO_URL/scripts/help_info_menu.sh") ;;
|
||||
3) exec bash <(curl -s "$REPO_URL/scripts/menus/hw_grafics_menu.sh") ;;
|
||||
4) exec bash <(curl -s "$REPO_URL/scripts/menus/create_vm_menu.sh") ;;
|
||||
5) exec bash <(curl -s "$REPO_URL/scripts/menus/storage_menu.sh") ;;
|
||||
@@ -77,6 +136,4 @@ show_menu() {
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
show_menu
|
||||
|
82
scripts/menus/main_menu_.sh
Normal file
82
scripts/menus/main_menu_.sh
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==========================================================
|
||||
# ProxMenu - A menu-driven script for Proxmox VE management
|
||||
# ==========================================================
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : MIT (https://raw.githubusercontent.com/MacRimi/ProxMenux/main/LICENSE)
|
||||
# Version : 2.0
|
||||
# Last Updated: 04/04/2025
|
||||
# ==========================================================
|
||||
|
||||
# Configuration ============================================
|
||||
REPO_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main"
|
||||
BASE_DIR="/usr/local/share/proxmenux"
|
||||
UTILS_FILE="$BASE_DIR/utils.sh"
|
||||
VENV_PATH="/opt/googletrans-env"
|
||||
|
||||
if [[ -f "$UTILS_FILE" ]]; then
|
||||
source "$UTILS_FILE"
|
||||
fi
|
||||
|
||||
load_language
|
||||
initialize_cache
|
||||
# ==========================================================
|
||||
|
||||
if ! command -v dialog &>/dev/null; then
|
||||
apt update -qq >/dev/null 2>&1
|
||||
apt install -y dialog >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
show_menu() {
|
||||
local TEMP_FILE
|
||||
TEMP_FILE=$(mktemp)
|
||||
|
||||
while true; do
|
||||
dialog --clear \
|
||||
--backtitle "ProxMenux" \
|
||||
--title "$(translate "Main ProxMenux")" \
|
||||
--menu "$(translate "Select an option:")" 20 70 10 \
|
||||
1 "$(translate "Settings post-install Proxmox")" \
|
||||
2 "$(translate "Help and Info Commands")" \
|
||||
3 "$(translate "Hardware: GPUs and Coral-TPU")" \
|
||||
4 "$(translate "Create VM from template or script")" \
|
||||
5 "$(translate "Disk and Storage Manager")" \
|
||||
6 "$(translate "Proxmox VE Helper Scripts")" \
|
||||
7 "$(translate "Network Management")" \
|
||||
8 "$(translate "Utilities and Tools")" \
|
||||
9 "$(translate "Settings")" \
|
||||
0 "$(translate "Exit")" 2>"$TEMP_FILE"
|
||||
|
||||
local EXIT_STATUS=$?
|
||||
|
||||
if [[ $EXIT_STATUS -ne 0 ]]; then
|
||||
# ESC pressed or Cancel
|
||||
clear
|
||||
msg_ok "$(translate "Thank you for using ProxMenux. Goodbye!")"
|
||||
rm -f "$TEMP_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
OPTION=$(<"$TEMP_FILE")
|
||||
|
||||
case $OPTION in
|
||||
1) exec bash <(curl -s "$REPO_URL/scripts/menus/menu_post_install.sh") ;;
|
||||
2) bash <(curl -s "$REPO_URL/scripts/help_info_menu.sh") ;;
|
||||
3) exec bash <(curl -s "$REPO_URL/scripts/menus/hw_grafics_menu.sh") ;;
|
||||
4) exec bash <(curl -s "$REPO_URL/scripts/menus/create_vm_menu.sh") ;;
|
||||
5) exec bash <(curl -s "$REPO_URL/scripts/menus/storage_menu.sh") ;;
|
||||
6) exec bash <(curl -s "$REPO_URL/scripts/menus/menu_Helper_Scripts.sh") ;;
|
||||
7) exec bash <(curl -s "$REPO_URL/scripts/menus/network_menu.sh") ;;
|
||||
8) exec bash <(curl -s "$REPO_URL/scripts/menus/utilities_menu.sh") ;;
|
||||
9) exec bash <(curl -s "$REPO_URL/scripts/menus/config_menu.sh") ;;
|
||||
0) clear; msg_ok "$(translate "Thank you for using ProxMenu. Goodbye!")"; rm -f "$TEMP_FILE"; exit 0 ;;
|
||||
*) msg_warn "$(translate "Invalid option")"; sleep 2 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
show_menu
|
@@ -26,11 +26,12 @@ initialize_cache
|
||||
|
||||
while true; do
|
||||
OPTION=$(dialog --clear --backtitle "ProxMenux" --title "$(translate "Utilities Menu")" \
|
||||
--menu "\n$(translate "Select an option:")" 20 70 8 \
|
||||
--menu "$(translate "Select an option:")" 20 70 8 \
|
||||
"1" "$(translate "UUp Dump ISO creator Custom")" \
|
||||
"2" "$(translate "System Utilities Installer")" \
|
||||
"3" "$(translate "Proxmox System Update")" \
|
||||
"4" "$(translate "Return to Main Menu")" \
|
||||
"4" "$(translate "Upgrade PVE 8 to PVE 9")" \
|
||||
"5" "$(translate "Return to Main Menu")" \
|
||||
2>&1 >/dev/tty)
|
||||
|
||||
case $OPTION in
|
||||
@@ -69,7 +70,13 @@ initialize_cache
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
4) exec bash <(curl -s "$REPO_URL/scripts/menus/main_menu.sh") ;;
|
||||
4)
|
||||
bash <(curl -s "$REPO_URL/scripts/utilities/upgrade_pve8_to_pve9.sh")
|
||||
if [ $? -ne 0 ]; then
|
||||
return
|
||||
fi
|
||||
;;
|
||||
5) exec bash <(curl -s "$REPO_URL/scripts/menus/main_menu.sh") ;;
|
||||
*) exec bash <(curl -s "$REPO_URL/scripts/menus/main_menu.sh") ;;
|
||||
esac
|
||||
done
|
@@ -164,15 +164,17 @@ remove_subscription_banner() {
|
||||
# ==========================================================
|
||||
|
||||
|
||||
configure_time_sync() {
|
||||
msg_info "$(translate "Configuring system time settings...")"
|
||||
configure_time_sync_() {
|
||||
msg_info2 "$(translate "Configuring system time settings...")"
|
||||
|
||||
|
||||
# Get public IP address
|
||||
this_ip=$(dig +short myip.opendns.com @resolver1.opendns.com)
|
||||
if [ -z "$this_ip" ]; then
|
||||
msg_warn "$(translate "Failed to obtain public IP address")"
|
||||
timezone="UTC"
|
||||
else
|
||||
|
||||
# Get timezone based on IP
|
||||
timezone=$(curl -s "https://ipapi.co/${this_ip}/timezone")
|
||||
if [ -z "$timezone" ]; then
|
||||
msg_warn "$(translate "Failed to determine timezone from IP address")"
|
||||
@@ -182,16 +184,64 @@ configure_time_sync() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Set the timezone
|
||||
if timedatectl set-timezone "$timezone"; then
|
||||
msg_ok "$(translate "Timezone set to $timezone")"
|
||||
else
|
||||
msg_error "$(translate "Failed to set timezone to $timezone")"
|
||||
fi
|
||||
|
||||
# Configure time synchronization
|
||||
msg_info "$(translate "Enabling automatic time synchronization...")"
|
||||
if timedatectl set-ntp true; then
|
||||
msg_ok "$(translate "Time settings configured - Timezone:") $timezone"
|
||||
systemctl restart postfix 2>/dev/null || true
|
||||
msg_ok "$(translate "Automatic time synchronization enabled")"
|
||||
register_tool "time_sync" true
|
||||
else
|
||||
msg_error "$(translate "Failed to enable automatic time synchronization")"
|
||||
fi
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
configure_time_sync() {
|
||||
msg_info2 "$(translate "Configuring system time settings...")"
|
||||
|
||||
this_ip=$(dig +short myip.opendns.com @resolver1.opendns.com 2>/dev/null)
|
||||
if [ -z "$this_ip" ]; then
|
||||
msg_warn "$(translate "Failed to obtain public IP address - keeping current timezone settings")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
timezone=$(curl -s --connect-timeout 10 "https://ipapi.co/${this_ip}/timezone" 2>/dev/null)
|
||||
if [ -z "$timezone" ] || [ "$timezone" = "undefined" ]; then
|
||||
msg_warn "$(translate "Failed to determine timezone from IP address - keeping current timezone settings")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Found timezone $timezone for IP $this_ip")"
|
||||
|
||||
if timedatectl set-timezone "$timezone"; then
|
||||
msg_ok "$(translate "Timezone set to $timezone")"
|
||||
|
||||
if timedatectl set-ntp true; then
|
||||
msg_ok "$(translate "Time settings configured - Timezone:") $timezone"
|
||||
register_tool "time_sync" true
|
||||
|
||||
systemctl restart postfix 2>/dev/null || true
|
||||
else
|
||||
msg_warn "$(translate "Failed to enable automatic time synchronization")"
|
||||
fi
|
||||
else
|
||||
msg_warn "$(translate "Failed to set timezone - keeping current settings")"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# ==========================================================
|
||||
skip_apt_languages() {
|
||||
msg_info "$(translate "Configuring APT to skip downloading additional languages...")"
|
||||
@@ -228,11 +278,10 @@ optimize_journald() {
|
||||
[Journal]
|
||||
Storage=persistent
|
||||
SplitMode=none
|
||||
RateLimitInterval=0
|
||||
RateLimitIntervalSec=0
|
||||
RateLimitBurst=0
|
||||
RateLimitIntervalSec=30s
|
||||
RateLimitBurst=1000
|
||||
ForwardToSyslog=no
|
||||
ForwardToWall=yes
|
||||
ForwardToWall=no
|
||||
Seal=no
|
||||
Compress=yes
|
||||
SystemMaxUse=64M
|
||||
@@ -418,59 +467,68 @@ force_apt_ipv4() {
|
||||
}
|
||||
|
||||
# ==========================================================
|
||||
|
||||
apply_network_optimizations() {
|
||||
msg_info "$(translate "Optimizing network settings...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
cat <<EOF > /etc/sysctl.d/99-network.conf
|
||||
net.core.netdev_max_backlog=8192
|
||||
net.core.optmem_max=8192
|
||||
net.core.rmem_max=16777216
|
||||
net.core.somaxconn=8151
|
||||
net.core.wmem_max=16777216
|
||||
cat <<'EOF' > /etc/sysctl.d/99-network.conf
|
||||
# ==========================================================
|
||||
# ProxMenux - Network tuning (PVE 9 compatible)
|
||||
# ==========================================================
|
||||
|
||||
# Core buffers & queues
|
||||
net.core.netdev_max_backlog = 8192
|
||||
net.core.optmem_max = 8192
|
||||
net.core.rmem_max = 16777216
|
||||
net.core.wmem_max = 16777216
|
||||
net.core.somaxconn = 8151
|
||||
|
||||
# IPv4 security hardening
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv4.conf.all.log_martians = 0
|
||||
net.ipv4.conf.all.rp_filter = 1
|
||||
net.ipv4.conf.all.secure_redirects = 0
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_source_route = 0
|
||||
net.ipv4.conf.default.log_martians = 0
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
net.ipv4.conf.default.secure_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
|
||||
# ICMP handling
|
||||
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||
net.ipv4.ip_local_port_range=1024 65535
|
||||
|
||||
# TCP/IP tuning
|
||||
net.ipv4.ip_local_port_range = 1024 65535
|
||||
net.ipv4.tcp_base_mss = 1024
|
||||
net.ipv4.tcp_challenge_ack_limit = 999999999
|
||||
net.ipv4.tcp_fin_timeout=10
|
||||
net.ipv4.tcp_keepalive_intvl=30
|
||||
net.ipv4.tcp_keepalive_probes=3
|
||||
net.ipv4.tcp_keepalive_time=240
|
||||
net.ipv4.tcp_limit_output_bytes=65536
|
||||
net.ipv4.tcp_max_syn_backlog=8192
|
||||
net.ipv4.tcp_max_tw_buckets = 1440000
|
||||
net.ipv4.tcp_fin_timeout = 10
|
||||
net.ipv4.tcp_keepalive_intvl = 30
|
||||
net.ipv4.tcp_keepalive_probes= 3
|
||||
net.ipv4.tcp_keepalive_time = 240
|
||||
net.ipv4.tcp_limit_output_bytes = 65536
|
||||
net.ipv4.tcp_max_syn_backlog = 8192
|
||||
net.ipv4.tcp_mtu_probing = 1
|
||||
net.ipv4.tcp_rfc1337=1
|
||||
net.ipv4.tcp_rmem=8192 87380 16777216
|
||||
net.ipv4.tcp_sack=1
|
||||
net.ipv4.tcp_slow_start_after_idle=0
|
||||
net.ipv4.tcp_syn_retries=3
|
||||
net.ipv4.tcp_rfc1337 = 1
|
||||
net.ipv4.tcp_rmem = 8192 87380 16777216
|
||||
net.ipv4.tcp_sack = 1
|
||||
net.ipv4.tcp_slow_start_after_idle = 0
|
||||
net.ipv4.tcp_syn_retries = 3
|
||||
net.ipv4.tcp_synack_retries = 2
|
||||
net.ipv4.tcp_tw_recycle = 0
|
||||
net.ipv4.tcp_tw_reuse = 0
|
||||
net.ipv4.tcp_wmem=8192 65536 16777216
|
||||
net.netfilter.nf_conntrack_generic_timeout = 60
|
||||
net.netfilter.nf_conntrack_helper=0
|
||||
net.netfilter.nf_conntrack_max = 524288
|
||||
net.netfilter.nf_conntrack_tcp_timeout_established = 28800
|
||||
net.ipv4.tcp_wmem = 8192 65536 16777216
|
||||
|
||||
# Unix sockets
|
||||
net.unix.max_dgram_qlen = 4096
|
||||
EOF
|
||||
|
||||
|
||||
sysctl --system > /dev/null 2>&1
|
||||
|
||||
|
||||
local interfaces_file="/etc/network/interfaces"
|
||||
if ! grep -q 'source /etc/network/interfaces.d/*' "$interfaces_file"; then
|
||||
echo "source /etc/network/interfaces.d/*" >> "$interfaces_file"
|
||||
@@ -480,6 +538,7 @@ EOF
|
||||
register_tool "network_optimization" true
|
||||
}
|
||||
|
||||
|
||||
# ==========================================================
|
||||
disable_rpc() {
|
||||
msg_info "$(translate "Disabling portmapper/rpcbind for security...")"
|
||||
@@ -686,11 +745,18 @@ install_log2ram_auto() {
|
||||
|
||||
|
||||
sed -i "s/^SIZE=.*/SIZE=$LOG2RAM_SIZE/" /etc/log2ram.conf
|
||||
|
||||
|
||||
LOG2RAM_BIN="$(command -v log2ram || echo /usr/local/bin/log2ram)"
|
||||
rm -f /etc/cron.daily/log2ram /etc/cron.weekly/log2ram /etc/cron.monthly/log2ram 2>/dev/null || true
|
||||
rm -f /etc/cron.hourly/log2ram
|
||||
echo "0 */$CRON_HOURS * * * root /usr/sbin/log2ram write" > /etc/cron.d/log2ram
|
||||
msg_ok "$(translate "log2ram write scheduled every") $CRON_HOURS $(translate "hour(s)")"
|
||||
|
||||
{
|
||||
echo 'MAILTO=""'
|
||||
echo "0 */$CRON_HOURS * * * root $LOG2RAM_BIN write >/dev/null 2>&1"
|
||||
} > /etc/cron.d/log2ram
|
||||
|
||||
chmod 0644 /etc/cron.d/log2ram
|
||||
chown root:root /etc/cron.d/log2ram
|
||||
msg_ok "$(translate "Log2RAM write scheduled every") $CRON_HOURS $(translate "hour(s)")"
|
||||
|
||||
|
||||
cat << 'EOF' > /usr/local/bin/log2ram-check.sh
|
||||
@@ -706,7 +772,12 @@ fi
|
||||
EOF
|
||||
|
||||
chmod +x /usr/local/bin/log2ram-check.sh
|
||||
echo "*/5 * * * * root /usr/local/bin/log2ram-check.sh" > /etc/cron.d/log2ram-auto-sync
|
||||
{
|
||||
echo 'MAILTO=""'
|
||||
echo "*/5 * * * * root /usr/local/bin/log2ram-check.sh >/dev/null 2>&1"
|
||||
} > /etc/cron.d/log2ram-auto-sync
|
||||
chmod 0644 /etc/cron.d/log2ram-auto-sync
|
||||
chown root:root /etc/cron.d/log2ram-auto-sync
|
||||
msg_ok "$(translate "Auto-sync enabled when /var/log exceeds 90% of") $LOG2RAM_SIZE"
|
||||
|
||||
register_tool "log2ram" true
|
||||
@@ -776,7 +847,7 @@ run_complete_optimization() {
|
||||
|
||||
apt_upgrade
|
||||
remove_subscription_banner
|
||||
configure_time_sync
|
||||
#configure_time_sync
|
||||
skip_apt_languages
|
||||
optimize_journald
|
||||
optimize_logrotate
|
||||
|
@@ -228,14 +228,13 @@ optimize_journald() {
|
||||
Storage=persistent
|
||||
# Don't split Journald logs by user
|
||||
SplitMode=none
|
||||
# Disable rate limits
|
||||
RateLimitInterval=0
|
||||
RateLimitIntervalSec=0
|
||||
RateLimitBurst=0
|
||||
# Reasonable rate limits (evita spam en kernel/auditd)
|
||||
RateLimitIntervalSec=30s
|
||||
RateLimitBurst=1000
|
||||
# Disable Journald forwarding to syslog
|
||||
ForwardToSyslog=no
|
||||
# Journald forwarding to wall /var/log/kern.log
|
||||
ForwardToWall=yes
|
||||
# Don't forward to wall (para evitar mensajes en terminales)
|
||||
ForwardToWall=no
|
||||
# Disable signing of the logs, save cpu resources
|
||||
Seal=no
|
||||
Compress=yes
|
||||
@@ -515,11 +514,9 @@ skip_apt_languages() {
|
||||
|
||||
|
||||
|
||||
configure_time_sync() {
|
||||
configure_time_sync_() {
|
||||
msg_info2 "$(translate "Configuring system time settings...")"
|
||||
|
||||
# Set timezone
|
||||
# msg_info "$(translate "Attempting to set timezone automatically based on IP address...")"
|
||||
|
||||
# Get public IP address
|
||||
this_ip=$(dig +short myip.opendns.com @resolver1.opendns.com)
|
||||
@@ -547,12 +544,51 @@ configure_time_sync() {
|
||||
# Configure time synchronization
|
||||
msg_info "$(translate "Enabling automatic time synchronization...")"
|
||||
if timedatectl set-ntp true; then
|
||||
systemctl restart postfix 2>/dev/null || true
|
||||
msg_ok "$(translate "Automatic time synchronization enabled")"
|
||||
register_tool "time_sync" true
|
||||
msg_success "$(translate "Time settings configuration completed")"
|
||||
else
|
||||
msg_error "$(translate "Failed to enable automatic time synchronization")"
|
||||
fi
|
||||
|
||||
msg_success "$(translate "Time settings configuration completed")"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
configure_time_sync() {
|
||||
msg_info2 "$(translate "Configuring system time settings...")"
|
||||
|
||||
this_ip=$(dig +short myip.opendns.com @resolver1.opendns.com 2>/dev/null)
|
||||
if [ -z "$this_ip" ]; then
|
||||
msg_warn "$(translate "Failed to obtain public IP address - keeping current timezone settings")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
timezone=$(curl -s --connect-timeout 10 "https://ipapi.co/${this_ip}/timezone" 2>/dev/null)
|
||||
if [ -z "$timezone" ] || [ "$timezone" = "undefined" ]; then
|
||||
msg_warn "$(translate "Failed to determine timezone from IP address - keeping current timezone settings")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Found timezone $timezone for IP $this_ip")"
|
||||
|
||||
if timedatectl set-timezone "$timezone"; then
|
||||
msg_ok "$(translate "Timezone set to $timezone")"
|
||||
|
||||
if timedatectl set-ntp true; then
|
||||
msg_ok "$(translate "Time settings configured - Timezone:") $timezone"
|
||||
register_tool "time_sync" true
|
||||
|
||||
systemctl restart postfix 2>/dev/null || true
|
||||
else
|
||||
msg_warn "$(translate "Failed to enable automatic time synchronization")"
|
||||
fi
|
||||
else
|
||||
msg_warn "$(translate "Failed to set timezone - keeping current settings")"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -564,7 +600,7 @@ configure_time_sync() {
|
||||
|
||||
|
||||
|
||||
install_system_utils() {
|
||||
install_system_utils_() {
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
@@ -639,7 +675,7 @@ EOF
|
||||
"btop" "$(translate "Modern resource monitor")" "OFF"
|
||||
"iftop" "$(translate "Real-time network usage")" "OFF"
|
||||
"iotop" "$(translate "Monitor disk I/O usage")" "OFF"
|
||||
"iperf3" "$(translate "Network performance testing")" "OFF"
|
||||
#"iperf3" "$(translate "Network performance testing")" "OFF"
|
||||
"ipset" "$(translate "Manage IP sets")" "OFF"
|
||||
"iptraf-ng" "$(translate "Network monitoring tool")" "OFF"
|
||||
"mlocate" "$(translate "Locate files quickly")" "OFF"
|
||||
@@ -649,6 +685,7 @@ EOF
|
||||
"tmux" "$(translate "Terminal multiplexer")" "OFF"
|
||||
"unzip" "$(translate "Extract ZIP files")" "OFF"
|
||||
"zip" "$(translate "Create ZIP files")" "OFF"
|
||||
"s-tui" "$(translate "Stress-Terminal UI")" "OFF"
|
||||
"libguestfs-tools" "$(translate "VM disk utilities")" "OFF"
|
||||
"aria2" "$(translate "Multi-source downloader")" "OFF"
|
||||
"cabextract" "$(translate "Extract CAB files")" "OFF"
|
||||
@@ -746,6 +783,191 @@ EOF
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
install_system_utils() {
|
||||
command_exists() { command -v "$1" >/dev/null 2>&1; }
|
||||
|
||||
ensure_repositories() {
|
||||
local sources_file="/etc/apt/sources.list"
|
||||
local need_update=false
|
||||
|
||||
if [[ ! -f "$sources_file" ]]; then
|
||||
msg_warn "$(translate "sources.list not found, creating default Debian repository...")"
|
||||
cat > "$sources_file" << EOF
|
||||
# Default Debian ${OS_CODENAME} repository
|
||||
deb http://deb.debian.org/debian ${OS_CODENAME} main contrib non-free non-free-firmware
|
||||
EOF
|
||||
need_update=true
|
||||
else
|
||||
if ! grep -q "deb.*${OS_CODENAME}.*main" "$sources_file"; then
|
||||
echo "deb http://deb.debian.org/debian ${OS_CODENAME} main contrib non-free non-free-firmware" >> "$sources_file"
|
||||
need_update=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$need_update" == true ]] || ! apt list --installed >/dev/null 2>&1; then
|
||||
msg_info "$(translate "Updating APT package lists...")"
|
||||
apt-get update -o Acquire::AllowInsecureRepositories=true >/dev/null 2>&1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
install_single_package() {
|
||||
local package="$1"
|
||||
local command_name="${2:-$package}"
|
||||
local description="$3"
|
||||
|
||||
msg_info "$(translate "Installing") $package ($description)..."
|
||||
local install_success=false
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y "$package" >/dev/null 2>&1 && install_success=true
|
||||
cleanup
|
||||
|
||||
if [[ "$install_success" == true ]]; then
|
||||
hash -r 2>/dev/null
|
||||
sleep 1
|
||||
if command_exists "$command_name"; then
|
||||
msg_ok "$package $(translate "installed correctly and available")"
|
||||
return 0
|
||||
else
|
||||
msg_warn "$package $(translate "installed but command not immediately available")"
|
||||
msg_info2 "$(translate "May need to restart terminal")"
|
||||
return 2
|
||||
fi
|
||||
else
|
||||
msg_error "$(translate "Error installing") $package"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
show_utilities_selection() {
|
||||
local utilities=(
|
||||
"axel" "$(translate "Download accelerator")" "OFF"
|
||||
"dos2unix" "$(translate "Convert DOS/Unix text files")" "OFF"
|
||||
"grc" "$(translate "Generic log/command colorizer")" "OFF"
|
||||
"htop" "$(translate "Interactive process viewer")" "OFF"
|
||||
"btop" "$(translate "Modern resource monitor")" "OFF"
|
||||
"iftop" "$(translate "Real-time network usage")" "OFF"
|
||||
"iotop" "$(translate "Monitor disk I/O usage")" "OFF"
|
||||
# "iperf3" "$(translate "Network performance testing")" "OFF"
|
||||
"intel-gpu-tools" "$(translate "tools for the Intel graphics driver")" "OFF"
|
||||
"ipset" "$(translate "Manage IP sets")" "OFF"
|
||||
"iptraf-ng" "$(translate "Network monitoring tool")" "OFF"
|
||||
"s-tui" "$(translate "Stress-Terminal UI")" "OFF"
|
||||
"plocate" "$(translate "Locate files quickly")" "OFF"
|
||||
"msr-tools" "$(translate "Access CPU MSRs")" "OFF"
|
||||
"net-tools" "$(translate "Legacy networking tools")" "OFF"
|
||||
"sshpass" "$(translate "Non-interactive SSH login")" "OFF"
|
||||
"tmux" "$(translate "Terminal multiplexer")" "OFF"
|
||||
"unzip" "$(translate "Extract ZIP files")" "OFF"
|
||||
"zip" "$(translate "Create ZIP files")" "OFF"
|
||||
"libguestfs-tools" "$(translate "VM disk utilities")" "OFF"
|
||||
"aria2" "$(translate "Multi-source downloader")" "OFF"
|
||||
"cabextract" "$(translate "Extract CAB files")" "OFF"
|
||||
"wimtools" "$(translate "Manage WIM images")" "OFF"
|
||||
"genisoimage" "$(translate "Create ISO images")" "OFF"
|
||||
"chntpw" "$(translate "Edit Windows registry/passwords")" "OFF"
|
||||
)
|
||||
|
||||
local selected
|
||||
selected=$(
|
||||
dialog --clear --backtitle "ProxMenu - $(translate "System Utilities")" \
|
||||
--title "$(translate "Select utilities to install")" \
|
||||
--checklist "$(translate "Use SPACE to select/deselect, ENTER to confirm")" \
|
||||
20 70 12 "${utilities[@]}" 3>&1 1>&2 2>&3
|
||||
)
|
||||
local status=$?
|
||||
|
||||
|
||||
echo "$selected"
|
||||
return "$status"
|
||||
}
|
||||
|
||||
install_selected_utilities() {
|
||||
local selected="$1"
|
||||
|
||||
|
||||
if [[ -z "$selected" ]]; then
|
||||
dialog --clear --backtitle "ProxMenu" \
|
||||
--title "$(translate "No Selection")" \
|
||||
--msgbox "$(translate "No utilities were selected")" 8 40
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
||||
show_proxmenux_logo
|
||||
msg_title "$SCRIPT_TITLE"
|
||||
msg_info2 "$(translate "Installing selected utilities")"
|
||||
|
||||
if ! ensure_repositories; then
|
||||
msg_error "$(translate "Failed to configure repositories. Installation aborted.")"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local failed=0 success=0 warning=0
|
||||
local selected_array
|
||||
IFS=' ' read -ra selected_array <<< "$selected"
|
||||
|
||||
declare -A package_to_command=(
|
||||
["plocate"]="locate"
|
||||
["msr-tools"]="rdmsr"
|
||||
["net-tools"]="netstat"
|
||||
["libguestfs-tools"]="virt-filesystems"
|
||||
["aria2"]="aria2c"
|
||||
["wimtools"]="wimlib-imagex"
|
||||
)
|
||||
|
||||
for util in "${selected_array[@]}"; do
|
||||
util="${util%\"}"; util="${util#\"}"
|
||||
local verify_command="${package_to_command[$util]:-$util}"
|
||||
install_single_package "$util" "$verify_command" "$util"
|
||||
case $? in
|
||||
0) success=$((success+1)) ;;
|
||||
1) failed=$((failed+1)) ;;
|
||||
2) warning=$((warning+1)) ;;
|
||||
esac
|
||||
sleep 1
|
||||
done
|
||||
|
||||
[[ -f ~/.bashrc ]] && source ~/.bashrc >/dev/null 2>&1
|
||||
hash -r 2>/dev/null
|
||||
|
||||
echo
|
||||
msg_info2 "$(translate "Installation summary"):"
|
||||
msg_ok "$(translate "Successful"): $success"
|
||||
(( warning > 0 )) && msg_warn "$(translate "Warnings"): $warning"
|
||||
(( failed > 0 )) && msg_error "$(translate "Failed"): $failed"
|
||||
msg_success "$(translate "Common system utilities installation completed")"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
local selected_utilities
|
||||
selected_utilities=$(show_utilities_selection)
|
||||
local dlg_status=$?
|
||||
|
||||
if [[ $dlg_status -ne 0 ]]; then
|
||||
dialog --clear --backtitle "ProxMenu" \
|
||||
--title "$(translate "Canceled")" \
|
||||
--msgbox "$(translate "Action canceled by user")" 8 40
|
||||
|
||||
show_proxmenux_logo
|
||||
return 0
|
||||
fi
|
||||
|
||||
install_selected_utilities "$selected_utilities"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ==========================================================
|
||||
|
||||
|
||||
@@ -785,7 +1007,7 @@ EOF
|
||||
|
||||
|
||||
|
||||
apply_amd_fixes() {
|
||||
apply_amd_fixes_() {
|
||||
msg_info2 "$(translate "Detecting AMD CPU and applying fixes if necessary...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -858,6 +1080,107 @@ apply_amd_fixes() {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
apply_amd_fixes() {
|
||||
msg_info2 "$(translate "Detecting AMD CPU and applying fixes if necessary...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
local cpu_model
|
||||
cpu_model=$(grep -i -m 1 "model name" /proc/cpuinfo || true)
|
||||
|
||||
if echo "$cpu_model" | grep -qiE "EPYC|Ryzen"; then
|
||||
msg_ok "$(translate "AMD CPU detected")"
|
||||
else
|
||||
msg_ok "$(translate "No AMD CPU detected. Skipping AMD fixes.")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
msg_info "$(translate "Applying AMD-specific fixes...")"
|
||||
|
||||
|
||||
local cmdline_file="/etc/kernel/cmdline"
|
||||
local grub_file="/etc/default/grub"
|
||||
local added_param="idle=nomwait"
|
||||
local uses_zfs=false
|
||||
|
||||
if grep -q "root=ZFS=" "$cmdline_file" 2>/dev/null; then
|
||||
uses_zfs=true
|
||||
fi
|
||||
|
||||
if $uses_zfs && [[ -f "$cmdline_file" ]]; then
|
||||
# ZFS/systemd-boot
|
||||
if ! grep -qw "$added_param" "$cmdline_file"; then
|
||||
cp "$cmdline_file" "${cmdline_file}.bak"
|
||||
|
||||
sed -i "s|\s*$| $added_param|" "$cmdline_file"
|
||||
msg_ok "$(translate "Added '$added_param' to /etc/kernel/cmdline")"
|
||||
else
|
||||
msg_ok "$(translate "'$added_param' already present in /etc/kernel/cmdline")"
|
||||
fi
|
||||
|
||||
if command -v proxmox-boot-tool >/dev/null 2>&1; then
|
||||
proxmox-boot-tool refresh >/dev/null 2>&1 && \
|
||||
msg_ok "$(translate "proxmox-boot-tool refreshed")" || \
|
||||
msg_warn "$(translate "Failed to refresh proxmox-boot-tool")"
|
||||
fi
|
||||
else
|
||||
# GRUB (no ZFS)
|
||||
if [[ -f "$grub_file" ]]; then
|
||||
|
||||
grep -q '^GRUB_CMDLINE_LINUX_DEFAULT="' "$grub_file" || echo 'GRUB_CMDLINE_LINUX_DEFAULT=""' >> "$grub_file"
|
||||
|
||||
if ! grep -q 'GRUB_CMDLINE_LINUX_DEFAULT=' "$grub_file"; then
|
||||
msg_warn "$(translate "GRUB_CMDLINE_LINUX_DEFAULT not found in GRUB config")"
|
||||
else
|
||||
if ! grep -q "GRUB_CMDLINE_LINUX_DEFAULT=.*\b$added_param\b" "$grub_file"; then
|
||||
cp "$grub_file" "${grub_file}.bak"
|
||||
sed -i "s/^\(GRUB_CMDLINE_LINUX_DEFAULT=\"[^\"]*\)\"/\1 $added_param\"/" "$grub_file"
|
||||
msg_ok "$(translate "Added '$added_param' to GRUB_CMDLINE_LINUX_DEFAULT")"
|
||||
else
|
||||
msg_ok "$(translate "'$added_param' already present in GRUB_CMDLINE_LINUX_DEFAULT")"
|
||||
fi
|
||||
update-grub >/dev/null 2>&1 && \
|
||||
msg_ok "$(translate "GRUB configuration updated")" || \
|
||||
msg_warn "$(translate "Failed to update GRUB")"
|
||||
fi
|
||||
else
|
||||
msg_warn "$(translate "GRUB config file not found; skipping GRUB changes")"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
local kvm_conf="/etc/modprobe.d/kvm.conf"
|
||||
touch "$kvm_conf"
|
||||
|
||||
if ! grep -q "^options kvm " "$kvm_conf"; then
|
||||
echo "options kvm ignore_msrs=Y report_ignored_msrs=N" >> "$kvm_conf"
|
||||
msg_ok "$(translate "KVM MSR options added to /etc/modprobe.d/kvm.conf")"
|
||||
else
|
||||
|
||||
if ! grep -q "ignore_msrs=" "$kvm_conf"; then
|
||||
sed -i 's/^options kvm /options kvm ignore_msrs=Y /' "$kvm_conf"
|
||||
else
|
||||
sed -i 's/ignore_msrs=[YNyn]/ignore_msrs=Y/' "$kvm_conf"
|
||||
fi
|
||||
if ! grep -q "report_ignored_msrs=" "$kvm_conf"; then
|
||||
sed -i 's/^options kvm .*/& report_ignored_msrs=N/' "$kvm_conf"
|
||||
else
|
||||
sed -i 's/report_ignored_msrs=[YNyn]/report_ignored_msrs=N/' "$kvm_conf"
|
||||
fi
|
||||
msg_ok "$(translate "KVM MSR options ensured in /etc/modprobe.d/kvm.conf")"
|
||||
fi
|
||||
|
||||
msg_success "$(translate "AMD CPU fixes applied successfully")"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ==========================================================
|
||||
|
||||
|
||||
@@ -892,77 +1215,80 @@ force_apt_ipv4() {
|
||||
|
||||
|
||||
apply_network_optimizations() {
|
||||
msg_info2 "$(translate "Optimizing network settings...")"
|
||||
msg_info "$(translate "Optimizing network settings...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
local sysctl_conf="/etc/sysctl.d/99-network.conf"
|
||||
local interfaces_file="/etc/network/interfaces"
|
||||
cat <<'EOF' > /etc/sysctl.d/99-network.conf
|
||||
# ==========================================================
|
||||
# ProxMenux - Network tuning (PVE 9 compatible)
|
||||
# ==========================================================
|
||||
|
||||
msg_info "$(translate "Applying network optimizations...")"
|
||||
# Core buffers & queues
|
||||
net.core.netdev_max_backlog = 8192
|
||||
net.core.optmem_max = 8192
|
||||
net.core.rmem_max = 16777216
|
||||
net.core.wmem_max = 16777216
|
||||
net.core.somaxconn = 8151
|
||||
|
||||
# Update sysctl configuration
|
||||
cat <<EOF > "$sysctl_conf"
|
||||
net.core.netdev_max_backlog=8192
|
||||
net.core.optmem_max=8192
|
||||
net.core.rmem_max=16777216
|
||||
net.core.somaxconn=8151
|
||||
net.core.wmem_max=16777216
|
||||
# IPv4 security hardening
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv4.conf.all.log_martians = 0
|
||||
net.ipv4.conf.all.rp_filter = 1
|
||||
net.ipv4.conf.all.secure_redirects = 0
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_source_route = 0
|
||||
net.ipv4.conf.default.log_martians = 0
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
net.ipv4.conf.default.secure_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
|
||||
# ICMP handling
|
||||
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||
net.ipv4.ip_local_port_range=1024 65535
|
||||
|
||||
# TCP/IP tuning
|
||||
net.ipv4.ip_local_port_range = 1024 65535
|
||||
net.ipv4.tcp_base_mss = 1024
|
||||
net.ipv4.tcp_challenge_ack_limit = 999999999
|
||||
net.ipv4.tcp_fin_timeout=10
|
||||
net.ipv4.tcp_keepalive_intvl=30
|
||||
net.ipv4.tcp_keepalive_probes=3
|
||||
net.ipv4.tcp_keepalive_time=240
|
||||
net.ipv4.tcp_limit_output_bytes=65536
|
||||
net.ipv4.tcp_max_syn_backlog=8192
|
||||
net.ipv4.tcp_max_tw_buckets = 1440000
|
||||
net.ipv4.tcp_fin_timeout = 10
|
||||
net.ipv4.tcp_keepalive_intvl = 30
|
||||
net.ipv4.tcp_keepalive_probes= 3
|
||||
net.ipv4.tcp_keepalive_time = 240
|
||||
net.ipv4.tcp_limit_output_bytes = 65536
|
||||
net.ipv4.tcp_max_syn_backlog = 8192
|
||||
net.ipv4.tcp_mtu_probing = 1
|
||||
net.ipv4.tcp_rfc1337=1
|
||||
net.ipv4.tcp_rmem=8192 87380 16777216
|
||||
net.ipv4.tcp_sack=1
|
||||
net.ipv4.tcp_slow_start_after_idle=0
|
||||
net.ipv4.tcp_syn_retries=3
|
||||
net.ipv4.tcp_rfc1337 = 1
|
||||
net.ipv4.tcp_rmem = 8192 87380 16777216
|
||||
net.ipv4.tcp_sack = 1
|
||||
net.ipv4.tcp_slow_start_after_idle = 0
|
||||
net.ipv4.tcp_syn_retries = 3
|
||||
net.ipv4.tcp_synack_retries = 2
|
||||
net.ipv4.tcp_tw_recycle = 0
|
||||
net.ipv4.tcp_tw_reuse = 0
|
||||
net.ipv4.tcp_wmem=8192 65536 16777216
|
||||
net.netfilter.nf_conntrack_generic_timeout = 60
|
||||
net.netfilter.nf_conntrack_helper=0
|
||||
net.netfilter.nf_conntrack_max = 524288
|
||||
net.netfilter.nf_conntrack_tcp_timeout_established = 28800
|
||||
net.ipv4.tcp_wmem = 8192 65536 16777216
|
||||
|
||||
# Unix sockets
|
||||
net.unix.max_dgram_qlen = 4096
|
||||
EOF
|
||||
|
||||
|
||||
sysctl --system > /dev/null 2>&1
|
||||
|
||||
# Ensure /etc/network/interfaces includes the interfaces.d directory
|
||||
|
||||
local interfaces_file="/etc/network/interfaces"
|
||||
if ! grep -q 'source /etc/network/interfaces.d/*' "$interfaces_file"; then
|
||||
echo "source /etc/network/interfaces.d/*" >> "$interfaces_file"
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Network optimizations applied")"
|
||||
msg_success "$(translate "Network optimization completed")"
|
||||
msg_ok "$(translate "Network optimization completed")"
|
||||
register_tool "network_optimization" true
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ==========================================================
|
||||
|
||||
|
||||
@@ -3002,18 +3328,18 @@ configure_log2ram() {
|
||||
"12" "$(translate "Every 12 hours")" OFF \
|
||||
3>&1 1>&2 2>&3) || return 0
|
||||
|
||||
# Activar auto-sync si se pasa del 90%
|
||||
|
||||
if whiptail --title "Log2RAM" --yesno "$(translate "Enable auto-sync if /var/log exceeds 90% of its size?")" 10 60; then
|
||||
ENABLE_AUTOSYNC=true
|
||||
else
|
||||
ENABLE_AUTOSYNC=false
|
||||
fi
|
||||
|
||||
# Instalación
|
||||
|
||||
msg_info "$(translate "Installing Log2RAM from GitHub...")"
|
||||
rm -rf /tmp/log2ram
|
||||
|
||||
# Ensure git is available
|
||||
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
msg_info "$(translate "Installing required package: git")"
|
||||
apt-get update -qq >/dev/null 2>&1
|
||||
@@ -3031,13 +3357,22 @@ configure_log2ram() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Aplicar configuración
|
||||
|
||||
sed -i "s/^SIZE=.*/SIZE=$LOG2RAM_SIZE/" /etc/log2ram.conf
|
||||
LOG2RAM_BIN="$(command -v log2ram || echo /usr/local/bin/log2ram)"
|
||||
rm -f /etc/cron.daily/log2ram /etc/cron.weekly/log2ram /etc/cron.monthly/log2ram 2>/dev/null || true
|
||||
rm -f /etc/cron.hourly/log2ram
|
||||
echo "0 */$CRON_HOURS * * * root /usr/sbin/log2ram write" > /etc/cron.d/log2ram
|
||||
|
||||
{
|
||||
echo 'MAILTO=""'
|
||||
echo "0 */$CRON_HOURS * * * root $LOG2RAM_BIN write >/dev/null 2>&1"
|
||||
} > /etc/cron.d/log2ram
|
||||
|
||||
chmod 0644 /etc/cron.d/log2ram
|
||||
chown root:root /etc/cron.d/log2ram
|
||||
msg_ok "$(translate "Log2RAM write scheduled every") $CRON_HOURS $(translate "hour(s)")"
|
||||
|
||||
# Auto-sync
|
||||
|
||||
if [[ "$ENABLE_AUTOSYNC" == true ]]; then
|
||||
cat << 'EOF' > /usr/local/bin/log2ram-check.sh
|
||||
#!/bin/bash
|
||||
@@ -3050,7 +3385,14 @@ if (( USED_KB > THRESHOLD )); then
|
||||
fi
|
||||
EOF
|
||||
chmod +x /usr/local/bin/log2ram-check.sh
|
||||
echo "*/5 * * * * root /usr/local/bin/log2ram-check.sh" > /etc/cron.d/log2ram-auto-sync
|
||||
|
||||
{
|
||||
echo 'MAILTO=""'
|
||||
echo "*/5 * * * * root /usr/local/bin/log2ram-check.sh >/dev/null 2>&1"
|
||||
} > /etc/cron.d/log2ram-auto-sync
|
||||
chmod 0644 /etc/cron.d/log2ram-auto-sync
|
||||
chown root:root /etc/cron.d/log2ram-auto-sync
|
||||
|
||||
msg_ok "$(translate "Auto-sync enabled when /var/log exceeds 90% of") $LOG2RAM_SIZE"
|
||||
else
|
||||
rm -f /usr/local/bin/log2ram-check.sh /etc/cron.d/log2ram-auto-sync
|
||||
|
@@ -489,6 +489,93 @@ uninstall_persistent_network() {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uninstall_amd_fixes() {
|
||||
msg_info2 "$(translate "Reverting AMD (Ryzen/EPYC) fixes...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
|
||||
if grep -q "root=ZFS=" /proc/cmdline 2>/dev/null; then
|
||||
|
||||
cmdline_file="/etc/kernel/cmdline"
|
||||
if [[ -f "$cmdline_file" ]] && grep -q "idle=nomwait" "$cmdline_file"; then
|
||||
cp "$cmdline_file" "${cmdline_file}.bak.$(date +%Y%m%d_%H%M%S)" || {
|
||||
msg_error "$(translate "Failed to backup $cmdline_file")"
|
||||
return 1
|
||||
}
|
||||
|
||||
sed -i 's/\bidle=nomwait\b//g; s/[[:space:]]\+/ /g; s/^ //; s/ $//' "$cmdline_file"
|
||||
|
||||
if command -v proxmox-boot-tool >/dev/null 2>&1; then
|
||||
proxmox-boot-tool refresh >/dev/null 2>&1 || {
|
||||
msg_error "$(translate "Failed to refresh boot configuration")"
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
msg_ok "$(translate "Removed idle=nomwait from /etc/kernel/cmdline (ZFS)")"
|
||||
fi
|
||||
else
|
||||
|
||||
grub_file="/etc/default/grub"
|
||||
if [[ -f "$grub_file" ]] && grep -q 'GRUB_CMDLINE_LINUX_DEFAULT=' "$grub_file"; then
|
||||
if grep -q "idle=nomwait" "$grub_file"; then
|
||||
cp "$grub_file" "${grub_file}.bak.$(date +%Y%m%d_%H%M%S)" || {
|
||||
msg_error "$(translate "Failed to backup $grub_file")"
|
||||
return 1
|
||||
}
|
||||
|
||||
sed -i -E 's/(GRUB_CMDLINE_LINUX_DEFAULT=")/\1/; s/\bidle=nomwait\b//g' "$grub_file"
|
||||
|
||||
awk -F\" '
|
||||
$1=="GRUB_CMDLINE_LINUX_DEFAULT=" {
|
||||
gsub(/[[:space:]]+/," ",$2); sub(/^ /,"",$2); sub(/ $/,"",$2)
|
||||
}1
|
||||
' OFS="\"" "$grub_file" > "${grub_file}.tmp" && mv "${grub_file}.tmp" "$grub_file"
|
||||
|
||||
update-grub >/dev/null 2>&1 || {
|
||||
msg_error "$(translate "Failed to update GRUB configuration")"
|
||||
return 1
|
||||
}
|
||||
msg_ok "$(translate "Removed idle=nomwait from GRUB configuration")"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
kvm_conf="/etc/modprobe.d/kvm.conf"
|
||||
if [[ -f "$kvm_conf" ]]; then
|
||||
if grep -Eq '(ignore_msrs|report_ignored_msrs)' "$kvm_conf"; then
|
||||
cp "$kvm_conf" "${kvm_conf}.bak.$(date +%Y%m%d_%H%M%S)" || {
|
||||
msg_error "$(translate "Failed to backup $kvm_conf")"
|
||||
return 1
|
||||
}
|
||||
sed -i -E '/ignore_msrs|report_ignored_msrs/d' "$kvm_conf"
|
||||
|
||||
if [[ ! -s "$kvm_conf" ]]; then
|
||||
rm -f "$kvm_conf"
|
||||
msg_ok "$(translate "Removed empty KVM configuration file")"
|
||||
else
|
||||
msg_ok "$(translate "Removed KVM MSR options from configuration")"
|
||||
fi
|
||||
|
||||
update-initramfs -u -k all >/dev/null 2>&1 || true
|
||||
else
|
||||
msg_ok "$(translate "KVM MSR options not present, nothing to revert")"
|
||||
fi
|
||||
fi
|
||||
|
||||
msg_success "$(translate "AMD fixes have been successfully reverted")"
|
||||
register_tool "amd_fixes" false
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################
|
||||
|
||||
migrate_installed_tools() {
|
||||
@@ -604,6 +691,7 @@ show_uninstall_menu() {
|
||||
figurine) desc="Figurine";;
|
||||
fastfetch) desc="Fastfetch";;
|
||||
log2ram) desc="Log2ram (SSD Protection)";;
|
||||
amd_fixes) desc="AMD CPU (Ryzen/EPYC) fixes";;
|
||||
persistent_network) desc="Setting persistent network interfaces";;
|
||||
*) desc="$tool";;
|
||||
esac
|
||||
|
@@ -223,7 +223,12 @@ is_disk_in_use() {
|
||||
}
|
||||
|
||||
FREE_DISKS=()
|
||||
LVM_DEVICES=$(pvs --noheadings -o pv_name 2> >(grep -v 'File descriptor .* leaked') | xargs -n1 readlink -f | sort -u)
|
||||
LVM_DEVICES=$(pvs --noheadings -o pv_name 2> >(grep -v 'File descriptor .* leaked') | xargs -r -n1 readlink -f | sort -u)
|
||||
|
||||
if [[ -n "$LVM_DEVICES" ]] && echo "$LVM_DEVICES" | grep -qFx "$REAL_PATH"; then
|
||||
IS_MOUNTED=true
|
||||
fi
|
||||
|
||||
RAID_ACTIVE=$(grep -Po 'md\d+\s*:\s*active\s+raid[0-9]+' /proc/mdstat | awk '{print $1}' | sort -u)
|
||||
|
||||
while read -r DISK; do
|
||||
|
275
scripts/utilities/proxmox-upgrade-pve8-to-pve9-manual-guide.sh
Normal file
275
scripts/utilities/proxmox-upgrade-pve8-to-pve9-manual-guide.sh
Normal file
@@ -0,0 +1,275 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==========================================================
|
||||
# ProxMenux - Manual Proxmox VE 8 to 9 Upgrade Guide
|
||||
# ==========================================================
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : MIT (https://raw.githubusercontent.com/MacRimi/ProxMenux/main/LICENSE)
|
||||
# Version : 1.0
|
||||
# Last Updated: 13/08/2025
|
||||
# ==========================================================
|
||||
|
||||
# Configuration ============================================
|
||||
REPO_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main"
|
||||
BASE_DIR="/usr/local/share/proxmenux"
|
||||
UTILS_FILE="$BASE_DIR/utils.sh"
|
||||
VENV_PATH="/opt/googletrans-env"
|
||||
|
||||
if [[ -f "$UTILS_FILE" ]]; then
|
||||
source "$UTILS_FILE"
|
||||
fi
|
||||
load_language
|
||||
initialize_cache
|
||||
# ==========================================================
|
||||
|
||||
show_command() {
|
||||
local step="$1"
|
||||
local description="$2"
|
||||
local command="$3"
|
||||
local note="$4"
|
||||
local command_extra="$5"
|
||||
|
||||
echo -e "${BGN}${step}.${CL} ${BL}${description}${CL}"
|
||||
echo ""
|
||||
echo -e "${TAB}${command}"
|
||||
echo -e
|
||||
[[ -n "$note" ]] && echo -e "${TAB}${DARK_GRAY}${note}${CL}"
|
||||
[[ -n "$command_extra" ]] && echo -e "${TAB}${YW}${command_extra}${CL}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
show_proxmox_upgrade_manual_guide() {
|
||||
clear
|
||||
show_proxmenux_logo
|
||||
msg_title "$(translate "Proxmox VE 8 to 9 Manual Upgrade Guide")"
|
||||
|
||||
echo -e "${TAB}${BL}------------------------------------------------------------------------${CL}"
|
||||
echo -e
|
||||
echo -e "${TAB}${BGN}$(translate "Source:")${CL} ${BL}https://pve.proxmox.com/wiki/Upgrade_from_8_to_9${CL}"
|
||||
echo -e
|
||||
echo -e
|
||||
echo -e "${TAB}${BOLD}$(translate "IMPORTANT PREREQUISITES:")${CL}"
|
||||
echo -e
|
||||
echo -e "${TAB}${BGN}• $(translate "System must be updated to latest PVE 8.4+ before starting")${CL}"
|
||||
echo -e "${TAB}${BGN}• $(translate "Use SSH or terminal access (SSH recommended)")${CL}"
|
||||
echo -e "${TAB}${BGN}• $(translate "Use tmux or screen to avoid interruptions")${CL}"
|
||||
echo -e "${TAB}${BGN}• $(translate "Have valid backups of all VMs and containers")${CL}"
|
||||
echo -e "${TAB}${BGN}• $(translate "At least 5GB free space on root filesystem")${CL}"
|
||||
echo -e "${TAB}${BGN}• $(translate "Do not run the upgrade from the Web UI virtual console (it will disconnect)")${CL}"
|
||||
echo -e
|
||||
echo -e "${TAB}${BL}------------------------------------------------------------------------${CL}"
|
||||
echo -e
|
||||
|
||||
|
||||
show_command "1" \
|
||||
"$(translate "Update system to latest PVE 8.4+ (if not done already):")\n\n" \
|
||||
"apt update && apt dist-upgrade -y" \
|
||||
"$(translate "Or use ProxMenux update function")" \
|
||||
"\n\n"
|
||||
|
||||
|
||||
show_command "2" \
|
||||
"$(translate "Verify PVE version (must be 8.4.1 or newer):")\n\n" \
|
||||
"pveversion" \
|
||||
"" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "2.1" \
|
||||
"${YW}$(translate "If this node runs hyper-converged Ceph: ensure Ceph is 19.x (Squid) BEFORE upgrading PVE.")${CL}\n\n" \
|
||||
"ceph --version" \
|
||||
"$(translate "If not 19.x, upgrade Ceph (Reef→Squid) first per the official guide:") ${BL}https://pve.proxmox.com/wiki/Ceph_Squid${CL}" \
|
||||
"\n"
|
||||
|
||||
|
||||
|
||||
show_command "3" \
|
||||
"$(translate "Run upgrade checklist script:")\n\n" \
|
||||
"pve8to9 --full" \
|
||||
"${YW}$(translate "If it warns about 'systemd-boot' meta-package, remove it:")${CL} apt remove systemd-boot" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "4" \
|
||||
"$(translate "Start terminal multiplexer (recommended):")\n\n" \
|
||||
"tmux new-session -s upgrade ${DARK_GRAY}$(translate "# Recommended: avoids disconnection during upgrade")${CL}\n\n screen -S upgrade ${DARK_GRAY}$(translate "# Alternative if you prefer screen")${CL}" \
|
||||
"" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "5" \
|
||||
"$(translate "Update Debian repositories to Trixie:")\n\n" \
|
||||
"sed -i 's/bookworm/trixie/g' /etc/apt/sources.list" \
|
||||
"" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "6" \
|
||||
"${YW}$(translate "Update PVE enterprise repository (Only if using enterprise):")${CL}\n\n" \
|
||||
"${CUS}sed -i 's/bookworm/trixie/g' /etc/apt/sources.list.d/pve-enterprise.list${CL}" \
|
||||
"$(translate "Skip this step if using no-subscription repository")" \
|
||||
"\n\n"
|
||||
|
||||
|
||||
show_command "7" \
|
||||
"${YW}$(translate "Add new PVE 9 enterprise repository (deb822 format) (Only if using enterprise):")${CL}\n\n" \
|
||||
"${CUS}cat > /etc/apt/sources.list.d/pve-enterprise.sources << EOF
|
||||
Types: deb
|
||||
URIs: https://enterprise.proxmox.com/debian/pve
|
||||
Suites: trixie
|
||||
Components: pve-enterprise
|
||||
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
|
||||
EOF${CL}" \
|
||||
"$(translate "Only if using enterprise subscription")" \
|
||||
"\n\n"
|
||||
|
||||
|
||||
show_command "8" \
|
||||
"$(translate "OR add new PVE 9 no-subscription repository:")\n\n" \
|
||||
"cat > /etc/apt/sources.list.d/proxmox.sources << EOF
|
||||
Types: deb
|
||||
URIs: http://download.proxmox.com/debian/pve
|
||||
Suites: trixie
|
||||
Components: pve-no-subscription
|
||||
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
|
||||
EOF" \
|
||||
"$(translate "Only if using no-subscription repository")" \
|
||||
"\n\n"
|
||||
|
||||
|
||||
show_command "8.1" \
|
||||
"$(translate "Refresh APT index and verify repositories:")\n\n" \
|
||||
"apt update && apt policy | sed -n '1,120p'" \
|
||||
"$(translate "Ensure there are no errors and that proxmox-ve candidate shows 9.x")" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "9" \
|
||||
"${YW}$(translate "Update Ceph repository (Only if using Ceph):")${CL}\n\n" \
|
||||
"${CUS}cat > /etc/apt/sources.list.d/ceph.sources << EOF
|
||||
Types: deb
|
||||
URIs: http://download.proxmox.com/debian/ceph-squid
|
||||
Suites: trixie
|
||||
Components: no-subscription
|
||||
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
|
||||
EOF${CL}" \
|
||||
"$(translate "Use enterprise URL if you have subscription.")" \
|
||||
"\n\n"
|
||||
|
||||
|
||||
show_command "10" \
|
||||
"$(translate "Remove old repository files:")\n\n" \
|
||||
"rm -f /etc/apt/sources.list.d/pve-enterprise.list /etc/apt/sources.list.d/ceph.list" \
|
||||
"$(translate "Also comment any remaining 'bookworm' entries in *.list if present.")" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "11" \
|
||||
"$(translate "Update package index:")\n\n" \
|
||||
"apt update" \
|
||||
"" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "12" \
|
||||
"$(translate "Disable kernel audit messages (optional but recommended):")\n\n" \
|
||||
"systemctl disable --now systemd-journald-audit.socket" \
|
||||
"" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "13" \
|
||||
"$(translate "Start the main system upgrade:")\n\n" \
|
||||
"apt dist-upgrade" \
|
||||
"$(translate "This will take time. Answer prompts carefully - see notes below.")\n" \
|
||||
"\n"
|
||||
|
||||
|
||||
echo -e "${TAB}${BOLD}$(translate "UPGRADE PROMPTS - RECOMMENDED ANSWERS:")${CL}"
|
||||
echo -e
|
||||
echo -e "${TAB}${BGN}/etc/issue:${CL} ${YW}$(translate "Keep current version (N)")${CL}"
|
||||
echo -e "${TAB}${BGN}/etc/lvm/lvm.conf:${CL} ${YW}$(translate "Install maintainer's version (Y)")${CL}"
|
||||
echo -e "${TAB}${BGN}/etc/ssh/sshd_config:${CL} ${YW}$(translate "Install maintainer's version (Y)")${CL}"
|
||||
echo -e "${TAB}${BGN}/etc/default/grub:${CL} ${YW}$(translate "Keep current version (N) if modified")${CL}"
|
||||
echo -e "${TAB}${BGN}/etc/chrony/chrony.conf:${CL} ${YW}$(translate "Install maintainer's version (Y)")${CL}"
|
||||
echo -e "${TAB}${BGN}$(translate "Service restarts:")${CL} ${YW}$(translate "Use default (Yes)")${CL}"
|
||||
echo -e "${TAB}${BGN}apt-listchanges:${CL} ${YW}$(translate "Press 'q' to exit")${CL}"
|
||||
echo -e
|
||||
echo -e
|
||||
echo -e
|
||||
|
||||
|
||||
show_command "13.1" \
|
||||
"${YW}$(translate "If booting in EFI mode with root on LVM: install GRUB for EFI")${CL}\n\n" \
|
||||
"[ -d /sys/firmware/efi ] && apt install grub-efi-amd64" \
|
||||
"$(translate "Per official known issues; ensures proper boot after upgrade")" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "14" \
|
||||
"$(translate "Run checklist again to verify upgrade:")\n\n" \
|
||||
"pve8to9 --full" \
|
||||
"$(translate "Should show fewer or no issues")" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "15" \
|
||||
"$(translate "Reboot the system:")\n\n" \
|
||||
"reboot" \
|
||||
"" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "16" \
|
||||
"$(translate "After reboot, verify PVE version:")\n\n" \
|
||||
"pveversion" \
|
||||
"$(translate "Should show pve-manager/9.x.x")" \
|
||||
"\n"
|
||||
|
||||
|
||||
show_command "17" \
|
||||
"$(translate "Optional: Modernize repository sources:")\n\n" \
|
||||
"apt modernize-sources" \
|
||||
"$(translate "Converts to deb822; keeps .list backups as .bak")" \
|
||||
"\n"
|
||||
|
||||
echo -e "${TAB}${BL}------------------------------------------------------------------------${CL}"
|
||||
echo -e
|
||||
echo -e
|
||||
echo -e "${TAB}${BOLD}$(translate "CLUSTER UPGRADE NOTES:")${CL}"
|
||||
echo -e
|
||||
echo -e "${TAB}${BGN}• $(translate "Upgrade one node at a time")${CL}"
|
||||
echo -e "${TAB}${BGN}• $(translate "Migrate VMs away from node being upgraded")${CL}"
|
||||
echo -e "${TAB}${BGN}• $(translate "Wait for each node to complete before starting next")${CL}"
|
||||
echo -e "${TAB}${BGN}• $(translate "HA groups will be migrated to HA rules automatically")${CL}"
|
||||
echo -e
|
||||
echo -e
|
||||
|
||||
echo -e
|
||||
echo -e "${TAB}${BOLD}$(translate "TROUBLESHOOTING:")${CL}"
|
||||
echo -e
|
||||
echo -e "${TAB}${BGN}$(translate "If GUI does not load:")${CL} ${YW}Check with 'systemctl status pveproxy' and restart with 'systemctl restart pveproxy'${CL}"
|
||||
echo -e "${TAB}${BGN}$(translate "If ZFS errors occur:")${CL} ${YW}Ensure the 'zfsutils-linux' package is up to date${CL}"
|
||||
echo -e "${TAB}${BGN}$(translate "If network does not work:")${CL} ${YW}Check /etc/network/interfaces and ensure 'ifupdown2' is installed${CL}"
|
||||
echo -e "${TAB}${BGN}$(translate "If upgrade fails:")${CL} ${YW}apt -f install${CL}"
|
||||
echo -e "${TAB}${BGN}$(translate "If repositories error:")${CL} ${YW}Check /etc/apt/sources.list*${CL}"
|
||||
echo -e "${TAB}${BGN}$(translate "If 'proxmox-ve' removal warning:")${CL} ${YW}Fix repository configuration (ensure PVE 9 repo active)${CL}"
|
||||
echo -e "${TAB}${BGN}$(translate "Emergency recovery:")${CL} ${YW}Boot from rescue system${CL}"
|
||||
echo -e
|
||||
echo -e
|
||||
|
||||
|
||||
echo -e
|
||||
msg_success "$(translate "Press Enter to return to menu...")"
|
||||
echo -e
|
||||
read -r
|
||||
clear
|
||||
exit 0
|
||||
#bash <(curl -fsSL "$REPO_URL/scripts/utilities/upgrade_pve8_to_pve9.sh")
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Main execution
|
||||
show_proxmox_upgrade_manual_guide
|
180
scripts/utilities/pve8to9_check.sh
Normal file
180
scripts/utilities/pve8to9_check.sh
Normal file
@@ -0,0 +1,180 @@
|
||||
#!/bin/bash
|
||||
# ==========================================================
|
||||
# ProxMenuX - Upgrade PVE 8 → 9 (Simplified, per official guide)
|
||||
# ==========================================================
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : MIT (https://raw.githubusercontent.com/MacRimi/ProxMenux/main/LICENSE)
|
||||
# Version : 1.0
|
||||
# Last Updated: 14/08/2025
|
||||
# ==========================================================
|
||||
|
||||
REPO_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main"
|
||||
BASE_DIR="/usr/local/share/proxmenux"
|
||||
UTILS_FILE="$BASE_DIR/utils.sh"
|
||||
|
||||
|
||||
if [[ -f "$UTILS_FILE" ]]; then
|
||||
source "$UTILS_FILE"
|
||||
fi
|
||||
|
||||
load_language
|
||||
initialize_cache
|
||||
|
||||
|
||||
# ==========================================================
|
||||
|
||||
LOG="/var/log/pve8-a-pve9-$(date +%Y%m%d-%H%M%S).log"
|
||||
: > "$LOG"
|
||||
|
||||
disable_translation_post_upgrade() {
|
||||
translate() { echo "$1"; }
|
||||
}
|
||||
disable_translation_post_upgrade
|
||||
|
||||
if [[ "$pve_version" -ge 9 ]]; then
|
||||
disable_translation_post_upgrade
|
||||
fi
|
||||
|
||||
|
||||
|
||||
run_pve8to9_check2() {
|
||||
local tmp
|
||||
tmp="$(mktemp)"
|
||||
echo -e
|
||||
set -o pipefail
|
||||
pve8to9 --full 2>&1 | tee -a "$LOG" | tee "$tmp"
|
||||
local rc=${PIPESTATUS[0]}
|
||||
|
||||
local fails warns
|
||||
fails=$(grep -c 'FAIL:' "$tmp" || true)
|
||||
warns=$(grep -c 'WARN:' "$tmp" || true)
|
||||
|
||||
|
||||
if (( fails > 0 )); then
|
||||
echo -e
|
||||
echo -e "${BFR}${RD}[ERROR] $(translate "Pre-check found") $fails $(translate "blocking issue(s).")\n$(translate "Please resolve the problem(s) as described above, then re-run the upgrade script.")${CL}"
|
||||
echo -e
|
||||
|
||||
local repair_commands=()
|
||||
local repair_descriptions=()
|
||||
|
||||
# Error 1: systemd-boot meta-package
|
||||
if grep -q 'systemd-boot meta-package installed' "$tmp"; then
|
||||
repair_commands+=("apt install systemd-boot-efi systemd-boot-tools -y && apt remove systemd-boot -y")
|
||||
repair_descriptions+=("$(translate "Fix systemd-boot meta-package conflict")")
|
||||
echo -e "${YW}$(translate "Fix systemd-boot:") ${CL}apt install systemd-boot-efi systemd-boot-tools -y && apt remove systemd-boot -y"
|
||||
fi
|
||||
|
||||
|
||||
# Error 2: Ceph version incompatible
|
||||
if grep -q -E '(ceph.*version|ceph.*incompatible)' "$tmp"; then
|
||||
repair_commands+=("ceph versions && pveceph upgrade")
|
||||
repair_descriptions+=("$(translate "Upgrade Ceph to compatible version")")
|
||||
echo -e "${YW}$(translate "Fix Ceph version:") ${CL}ceph versions && pveceph upgrade"
|
||||
fi
|
||||
|
||||
# Error 3: Repository configuration issues
|
||||
if grep -q -E '(repository.*issue|repo.*problem|sources.*error)' "$tmp"; then
|
||||
repair_commands+=("cleanup_duplicate_repos && configure_repositories")
|
||||
repair_descriptions+=("$(translate "Fix repository configuration")")
|
||||
echo -e "${YW}$(translate "Fix repositories:") ${CL}cleanup_duplicate_repos && configure_repositories"
|
||||
fi
|
||||
|
||||
# Error 4: Package conflicts
|
||||
if grep -q -E '(package.*conflict|dependency.*problem)' "$tmp"; then
|
||||
repair_commands+=("apt update && apt autoremove -y && apt autoclean")
|
||||
repair_descriptions+=("$(translate "Resolve package conflicts")")
|
||||
echo -e "${YW}$(translate "Fix package conflicts:") ${CL}apt update && apt autoremove -y && apt autoclean"
|
||||
fi
|
||||
|
||||
# Error 5: Disk space issues
|
||||
if grep -q -E '(disk.*space|storage.*full|no.*space)' "$tmp"; then
|
||||
repair_commands+=("apt clean && apt autoremove -y && journalctl --vacuum-time=7d")
|
||||
repair_descriptions+=("$(translate "Free up disk space")")
|
||||
echo -e "${YW}$(translate "Fix disk space:") ${CL}apt clean && apt autoremove -y && journalctl --vacuum-time=7d"
|
||||
fi
|
||||
|
||||
# Error 6: Network/DNS issues
|
||||
if grep -q -E '(network.*error|dns.*problem|connection.*failed)' "$tmp"; then
|
||||
repair_commands+=("systemctl restart networking && systemctl restart systemd-resolved")
|
||||
repair_descriptions+=("$(translate "Fix network connectivity")")
|
||||
echo -e "${YW}$(translate "Fix network:") ${CL}systemctl restart networking && systemctl restart systemd-resolved"
|
||||
fi
|
||||
|
||||
echo -e
|
||||
|
||||
|
||||
if [[ ${#repair_commands[@]} -gt 0 ]]; then
|
||||
echo -e "${BFR}${CY}$(translate "Repair Options:")${CL}"
|
||||
echo -e "${TAB}${GN}1.${CL} $(translate "Try automatic repair of detected issues")"
|
||||
echo -e "${TAB}${GN}2.${CL} $(translate "Show manual repair commands")"
|
||||
echo -e
|
||||
echo -n "$(translate "Select option [1-2] (default: 2): ")"
|
||||
read -r repair_choice
|
||||
|
||||
case "$repair_choice" in
|
||||
1)
|
||||
echo -e
|
||||
msg_info2 "$(translate "Attempting automatic repair...")"
|
||||
local repair_success=0
|
||||
for i in "${!repair_commands[@]}"; do
|
||||
echo -e "${TAB}${YW}$(translate "Executing:") ${repair_descriptions[$i]}${CL}"
|
||||
if eval "${repair_commands[$i]}"; then
|
||||
msg_ok "${repair_descriptions[$i]} - $(translate "Success")"
|
||||
else
|
||||
msg_error "${repair_descriptions[$i]} - $(translate "Failed")"
|
||||
repair_success=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $repair_success -eq 0 ]]; then
|
||||
echo -e
|
||||
msg_info2 "$(translate "Re-running pre-check after repairs...")"
|
||||
sleep 2
|
||||
run_pve8to9_check
|
||||
return $?
|
||||
else
|
||||
echo -e
|
||||
msg_error "$(translate "Some repairs failed. Please fix manually and re-run the script.")"
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
echo -e
|
||||
echo -e "$(translate "${BFR}${CY}Manual Repair Commands:${CL}")"
|
||||
for i in "${!repair_commands[@]}"; do
|
||||
echo -e "${TAB}${BL}# ${repair_descriptions[$i]}${CL}"
|
||||
echo -e
|
||||
echo -e "${TAB}${repair_commands[$i]}"
|
||||
echo -e
|
||||
done
|
||||
echo -e
|
||||
msg_info2 "$(translate "Once finished, re-run the script 'PVE 8 to 9 check' to verify that all issues.")"
|
||||
echo -e
|
||||
msg_success "$(translate "Press Enter to exit the script after reading instructions...")"
|
||||
read -r
|
||||
rm -f "$tmp"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
msg_success "$(translate "Press Enter to continue")"
|
||||
read -r
|
||||
fi
|
||||
|
||||
echo -e
|
||||
msg_ok "$(translate "Checklist post-upgrade finished. Warnings:") $warns"
|
||||
echo -e
|
||||
msg_success "$(translate "Press Enter to continue")"
|
||||
read -r
|
||||
rm -f "$tmp"
|
||||
return $rc
|
||||
|
||||
}
|
||||
|
||||
show_proxmenux_logo
|
||||
msg_title "$(translate "Run PVE 8 to 9 check")"
|
||||
run_pve8to9_check2
|
||||
|
||||
|
@@ -143,10 +143,12 @@ EOF
|
||||
"btop" "$(translate "Modern resource monitor")" "OFF"
|
||||
"iftop" "$(translate "Real-time network usage")" "OFF"
|
||||
"iotop" "$(translate "Monitor disk I/O usage")" "OFF"
|
||||
"iperf3" "$(translate "Network performance testing")" "OFF"
|
||||
#"iperf3" "$(translate "Network performance testing")" "OFF"
|
||||
"intel-gpu-tools" "$(translate "tools for the Intel graphics driver")" "OFF"
|
||||
"s-tui" "$(translate "Stress-Terminal UI")" "OFF"
|
||||
"ipset" "$(translate "Manage IP sets")" "OFF"
|
||||
"iptraf-ng" "$(translate "Network monitoring tool")" "OFF"
|
||||
"mlocate" "$(translate "Locate files quickly")" "OFF"
|
||||
"plocate" "$(translate "Locate files quickly")" "OFF"
|
||||
"msr-tools" "$(translate "Access CPU MSRs")" "OFF"
|
||||
"net-tools" "$(translate "Legacy networking tools")" "OFF"
|
||||
"sshpass" "$(translate "Non-interactive SSH login")" "OFF"
|
||||
@@ -190,7 +192,7 @@ EOF
|
||||
local warning=0
|
||||
|
||||
declare -A package_to_command=(
|
||||
["mlocate"]="locate"
|
||||
["plocate"]="locate"
|
||||
["msr-tools"]="rdmsr"
|
||||
["net-tools"]="netstat"
|
||||
["libguestfs-tools"]="virt-filesystems"
|
||||
@@ -302,10 +304,12 @@ EOF
|
||||
"btop:Modern resource monitor"
|
||||
"iftop:Real-time network usage"
|
||||
"iotop:Monitor disk I/O usage"
|
||||
"iperf3:Network performance testing"
|
||||
#"iperf3:Network performance testing"
|
||||
"intel-gpu-tools:tools for the Intel graphics driver"
|
||||
"s-tui:Stress-Terminal UI"
|
||||
"ipset:Manage IP sets"
|
||||
"iptraf-ng:Network monitoring tool"
|
||||
"locate:Locate files quickly"
|
||||
"plocate:Locate files quickly"
|
||||
"rdmsr:Access CPU MSRs"
|
||||
"netstat:Legacy networking tools"
|
||||
"sshpass:Non-interactive SSH login"
|
||||
@@ -361,10 +365,12 @@ EOF
|
||||
"btop:btop:Modern resource monitor"
|
||||
"iftop:iftop:Real-time network usage"
|
||||
"iotop:iotop:Monitor disk I/O usage"
|
||||
"iperf3:iperf3:Network performance testing"
|
||||
#"iperf3:iperf3:Network performance testing"
|
||||
"intel-gpu-tools:tools for the Intel graphics driver"
|
||||
"s-tui:Stress-Terminal UI"
|
||||
"ipset:ipset:Manage IP sets"
|
||||
"iptraf-ng:iptraf-ng:Network monitoring tool"
|
||||
"mlocate:locate:Locate files quickly"
|
||||
"plocate:locate:Locate files quickly"
|
||||
"msr-tools:rdmsr:Access CPU MSRs"
|
||||
"net-tools:netstat:Legacy networking tools"
|
||||
"sshpass:sshpass:Non-interactive SSH login"
|
||||
|
1137
scripts/utilities/upgrade_pve8_to_pve9.sh
Normal file
1137
scripts/utilities/upgrade_pve8_to_pve9.sh
Normal file
File diff suppressed because it is too large
Load Diff
@@ -52,8 +52,7 @@ NEON_PURPLE_BLUE="\033[38;5;99m"
|
||||
WHITE="\033[38;5;15m"
|
||||
RESET="\033[0m"
|
||||
DARK_GRAY="\033[38;5;244m"
|
||||
DARK_GRAY="\033[38;5;244m"
|
||||
DARK_GRAY="\033[38;5;244m"
|
||||
ORANGE="\033[38;5;208m"
|
||||
YW="\033[33m"
|
||||
YWB="\033[1;33m"
|
||||
GN="\033[1;92m"
|
||||
@@ -137,6 +136,12 @@ msg_info2() {
|
||||
echo -e "${TAB}${BOLD}${YW}${HOLD}${msg}${CL}"
|
||||
}
|
||||
|
||||
# Display info message with spinner
|
||||
msg_info3() {
|
||||
local msg="$1"
|
||||
echo -ne "${TAB}${YW}${HOLD}${msg}${CL}"
|
||||
}
|
||||
|
||||
# Display success message
|
||||
msg_success() {
|
||||
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then
|
||||
@@ -165,7 +170,7 @@ msg_warn() {
|
||||
fi
|
||||
printf "\e[?25h"
|
||||
local msg="$1"
|
||||
echo -e "${BFR}${TAB}${NV}${CL} ${YWB}${msg}${CL}"
|
||||
echo -e "${BFR}${TAB}${CL} ${YWB}${msg}${CL}"
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +184,12 @@ msg_ok() {
|
||||
echo -e "${BFR}${TAB}${CM}${GN}${msg}${CL}"
|
||||
}
|
||||
|
||||
msg_ok2() {
|
||||
printf "\e[?25h"
|
||||
local msg="$1"
|
||||
echo -e "${BFR}${TAB}${CM}${GN}${msg}${CL}"
|
||||
}
|
||||
|
||||
|
||||
# Display error message
|
||||
msg_error() {
|
||||
|
@@ -1 +1 @@
|
||||
1.1.4
|
||||
1.1.5
|
Reference in New Issue
Block a user