fix(i18n): natural Spanish for the menus and the OCI catalogue.

This commit is contained in:
MacRimi
2026-10-05 18:10:17 +02:00
parent 7a4a6e114d
commit 6b50763e54
12 changed files with 1783 additions and 1565 deletions
@@ -0,0 +1,99 @@
"""The menus that install drivers inside a container leave out the ones
created from an OCI image: those are changed from OCI manager Apps."""
from pathlib import Path
import re
import subprocess
import tempfile
from unittest import TestCase
ROOT = Path(__file__).resolve().parents[3]
MENUS = ('scripts/gpu_tpu/add_gpu_lxc.sh', 'scripts/gpu_tpu/install_coral_lxc.sh')
ORDINARY = "arch: amd64\ncores: 2\nhostname: debian\nostype: debian\nrootfs: local-lvm:vm-111-disk-0,size=8G\n"
OCI = ORDINARY + "entrypoint: /init\nlxc.signal.halt: SIGTERM\n"
def function(path, name):
source = (ROOT / path).read_text()
return re.search(rf'^{name}\(\) \{{\n.*?^\}}\n', source, re.MULTILINE | re.DOTALL)[0]
class GpuMenusHideOci(TestCase):
def is_oci(self, config):
with tempfile.TemporaryDirectory() as folder:
(Path(folder) / '111.conf').write_text(config)
helper = function('scripts/utils.sh', 'pmx_lxc_is_oci').replace('/etc/pve/lxc', folder)
return subprocess.run(['bash', '-c', helper + 'pmx_lxc_is_oci 111'], capture_output=True).returncode == 0
def test_a_container_from_an_oci_image_is_told_apart_by_its_configuration(self):
self.assertTrue(self.is_oci(OCI))
self.assertTrue(self.is_oci(ORDINARY + "cmd: nginx -g 'daemon off;'\n"))
self.assertFalse(self.is_oci(ORDINARY))
# A setting that only mentions the word is not an entrypoint.
self.assertFalse(self.is_oci(ORDINARY + "description: entrypoint: none\n"))
def test_a_container_without_configuration_is_not_one(self):
with tempfile.TemporaryDirectory() as folder:
helper = function('scripts/utils.sh', 'pmx_lxc_is_oci').replace('/etc/pve/lxc', folder)
self.assertNotEqual(subprocess.run(['bash', '-c', helper + 'pmx_lxc_is_oci 999'],
capture_output=True).returncode, 0)
def test_both_menus_skip_them_and_say_so(self):
for menu in MENUS:
body = function(menu, 'select_container')
self.assertLess(body.index('pmx_lxc_is_oci "$ctid"'), body.index('menu_items+=('), menu)
self.assertIn('Containers created from an OCI image are not listed:', body, menu)
self.assertEqual(body.count('${oci_note}'), 2, menu)
SWITCHES = (('scripts/gpu_tpu/switch_gpu_mode.sh', 'apply_lxc_action_for_vm_mode', 'prompt_lxc_action_for_vm_mode'),
('scripts/gpu_tpu/switch_gpu_mode_direct.sh', 'apply_lxc_action_for_vm_mode', 'prompt_lxc_action_for_vm_mode'),
('scripts/gpu_tpu/add_gpu_vm.sh', 'cleanup_lxc_configs', None))
class GpuToVmKeepsOciConfiguration(TestCase):
"""A GPU that moves to a VM stops the containers that use it. One created
from an OCI image keeps its configuration, which OCI manager Apps records."""
def test_an_oci_container_is_never_edited(self):
for script, apply, _ in SWITCHES:
body = function(script, apply)
guard = body.index('pmx_lxc_is_oci "$ctid"')
self.assertLess(guard, body.index('action="keep_gpu_disable_onboot"'), script)
removal = body.index('"$action" == "remove_gpu_keep_onboot"')
self.assertLess(guard, removal, script)
# The only edit of a configuration hangs from the per-container action.
self.assertEqual(len(re.findall(r'_from_lxc_conf "\$', body)), 1, script)
edit = body.index('_from_lxc_conf "$')
condition = body.rindex('if [[', 0, edit)
self.assertIn('"$action" == "remove_gpu_keep_onboot"', body[condition:edit], script)
def test_the_list_names_them_and_nothing_is_asked_when_all_are_oci(self):
for script, _, prompt in SWITCHES:
source = (ROOT / script).read_text() if prompt is None else function(script, prompt)
self.assertIn('", OCI"', source, script)
self.assertIn('OCI containers keep their configuration', source, script)
self.assertIn('"$oci_count" -eq ${#LXC_AFFECTED_CTIDS[@]}', source, script)
class DiskAndSharePickersHideOci(TestCase):
"""Adding a disk or a mount, and the NFS and Samba set-ups, change the
container they are given. A container from an OCI image is not offered."""
def test_every_picker_filters_before_it_lists(self):
pickers = ((function('scripts/global/share-common.func', 'select_lxc_container'), 'options+=('),
(function('scripts/global/share-common.func', 'select_privileged_lxc'), 'ct_list+='),
(function('scripts/share/lxc-mount-manager_minimal.sh', 'select_lxc_container'), 'options+=('))
for body, listing in pickers:
self.assertLess(body.index('pmx_lxc_is_oci "$id"'), body.index(listing))
self.assertIn('Containers created from an OCI image are not listed', body)
disk = (ROOT / 'scripts/storage/disk-passthrough_ct.sh').read_text()
picker = disk[disk.index('CT_LIST=""'):disk.index('if [ -z "$CTID" ]')]
self.assertLess(picker.index('pmx_lxc_is_oci "$ct_id"'), picker.index('CT_LIST+='))
self.assertIn('${OCI_NOTE}" $UI_MENU_H $UI_MENU_W $CT_LIST_H', picker)
def test_a_disk_in_use_is_still_looked_for_in_every_container(self):
for script in ('scripts/storage/disk-passthrough_ct.sh', 'scripts/storage/disk-passthrough.sh'):
source = (ROOT / script).read_text()
check = source[source.index('disk_referenced_in_config "$CT_CONFIG_RAW" "$DISK"'):]
scan = check[:check.index("done < <(pct list | awk 'NR>1 {print $1, $3}')")]
self.assertNotIn('pmx_lxc_is_oci', scan, script)
+1531 -1526
View File
File diff suppressed because it is too large Load Diff
+25 -5
View File
@@ -449,15 +449,26 @@ select_lxc_container() {
return 1
fi
local options=()
local options=() oci_note="" list_h=15
while read -r id name status; do
if [[ -n "$id" ]]; then
if pmx_lxc_is_oci "$id"; then
list_h=12
oci_note="\n\n$(translate "Containers created from an OCI image are not listed: their paths are changed in OCI manager Apps (Recreate).")"
continue
fi
options+=("$id" "$name ($status)")
fi
done <<< "$ct_list"
if [[ ${#options[@]} -eq 0 ]]; then
dialog --title "$(translate "Error")" \
--msgbox "$(translate "No LXC containers available")${oci_note}" 12 66
return 1
fi
ctid=$(dialog --title "$(translate "Select LXC Container")" \
--menu "\n$(translate "Select container:")" 25 80 15 \
--menu "\n$(translate "Select container:")${oci_note}" 25 80 "$list_h" \
"${options[@]}" 3>&1 1>&2 2>&3)
if [[ -z "$ctid" ]]; then
@@ -600,15 +611,24 @@ select_privileged_lxc() {
# === Select CT ===
local ct_list ctid ct_status conf unpriv
ct_list=$(pct list | awk 'NR>1 {print $1, $3}')
local oci_note="" list_h=12 id name
while read -r id name; do
[[ -n "$id" ]] || continue
if pmx_lxc_is_oci "$id"; then
list_h=8
oci_note="\n\n$(translate "Containers created from an OCI image are not listed.")"
continue
fi
ct_list+="${ct_list:+ }$id ${name:-CT-$id}"
done < <(pct list | awk 'NR>1 {print $1, $3}')
if [[ -z "$ct_list" ]]; then
dialog --backtitle "ProxMenux" --title "$(translate "Error")" \
--msgbox "$(translate "No CTs available in the system.")" 8 50
--msgbox "$(translate "No CTs available in the system.")${oci_note}" 10 60
return 1
fi
ctid=$(dialog --backtitle "ProxMenux" --title "$(translate "Select CT")" \
--menu "$(translate "Select the CT to manage NFS/Samba client:")" 20 70 12 \
--menu "$(translate "Select the CT to manage NFS/Samba client:")${oci_note}" 20 70 "$list_h" \
$ct_list 3>&1 1>&2 2>&3)
if [[ -z "$ctid" ]]; then
+10 -3
View File
@@ -251,7 +251,7 @@ detect_host_gpus() {
# Container selection
# ============================================================
select_container() {
local menu_items=()
local menu_items=() oci_hidden=0
while IFS= read -r line; do
[[ "$line" =~ ^VMID ]] && continue
local ctid status name
@@ -259,19 +259,26 @@ select_container() {
status=$(echo "$line" | awk '{print $2}')
name=$(echo "$line" | awk '{print $3}')
[[ -z "$ctid" ]] && continue
if pmx_lxc_is_oci "$ctid"; then
oci_hidden=$((oci_hidden + 1))
continue
fi
menu_items+=("$ctid" "${name:-CT-${ctid}} (${status})")
done < <(pct list 2>/dev/null)
local oci_note="" list_h=12
[[ $oci_hidden -gt 0 ]] && list_h=7 && oci_note="\n\n$(translate 'Containers created from an OCI image are not listed: their devices are changed in OCI manager Apps (Recreate).')"
if [[ ${#menu_items[@]} -eq 0 ]]; then
dialog --backtitle "ProxMenux" \
--title "$(translate 'Add GPU to LXC')" \
--msgbox "\n$(translate 'No LXC containers found on this system.')" 8 60
--msgbox "\n$(translate 'No LXC containers found on this system.')${oci_note}" 12 66
exit 0
fi
CONTAINER_ID=$(dialog --backtitle "ProxMenux" \
--title "$(translate 'Add GPU to LXC')" \
--menu "\n$(translate 'Select the LXC container:')" 20 72 12 \
--menu "\n$(translate 'Select the LXC container:')${oci_note}" 20 72 "$list_h" \
"${menu_items[@]}" \
2>&1 >/dev/tty) || exit 0
}
+31 -13
View File
@@ -1402,7 +1402,7 @@ check_switch_mode() {
SWITCH_FROM_LXC=true
SWITCH_LXC_LIST=$(IFS=', '; echo "${lxc_affected[*]}")
local msg action_choice
local msg action_choice oci_count=0
msg="\n$(translate 'The selected GPU is currently used by the following LXC container(s):')\n\n"
local i
for i in "${!LXC_AFFECTED_CTIDS[@]}"; do
@@ -1411,8 +1411,13 @@ check_switch_mode() {
onboot_txt="onboot=0"
[[ "${LXC_AFFECTED_RUNNING[$i]}" == "1" ]] && status_txt="$(translate 'running')"
[[ "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]] && onboot_txt="onboot=1"
if pmx_lxc_is_oci "${LXC_AFFECTED_CTIDS[$i]}"; then
onboot_txt+=", OCI"
oci_count=$((oci_count + 1))
fi
msg+=" • CT ${LXC_AFFECTED_CTIDS[$i]} (${LXC_AFFECTED_NAMES[$i]}) [${status_txt}, ${onboot_txt}]\n"
done
[[ "$oci_count" -gt 0 ]] && msg+="\n$(translate 'OCI containers keep their configuration: they are stopped and their Start on boot is disabled. Their GPU is removed from OCI manager Apps, with Recreate.')\n"
msg+="\n$(translate 'VM passthrough requires exclusive VFIO binding of the GPU.')\n"
msg+="$(translate 'Choose how to handle affected LXC containers before switching to VM mode.')\n\n"
[[ "$running_count" -gt 0 ]] && \
@@ -1421,17 +1426,22 @@ check_switch_mode() {
msg+="\Z1\Zb$(translate 'Start on boot enabled (onboot=1)'): ${onboot_count}\Zn\n"
msg+="\n\Z1$(translate 'After this LXC → VM switch, reboot the host so the new binding state is applied cleanly.')\Zn"
action_choice=$(_pmx_menu --default-item "2" \
"$(translate 'GPU Used in LXC Containers')" \
"$msg" 25 96 8 \
"1" "$(translate 'Keep GPU in LXC config (disable Start on boot)')" \
"2" "$(translate 'Remove GPU from LXC config (keep Start on boot)')") || exit 0
if [[ "$oci_count" -eq ${#LXC_AFFECTED_CTIDS[@]} ]]; then
LXC_SWITCH_ACTION="keep_gpu_disable_onboot"
_pmx_msgbox "$(translate 'GPU Used in LXC Containers')" "$msg" 25 96
else
action_choice=$(_pmx_menu --default-item "2" \
"$(translate 'GPU Used in LXC Containers')" \
"$msg" 25 96 8 \
"1" "$(translate 'Keep GPU in LXC config (disable Start on boot)')" \
"2" "$(translate 'Remove GPU from LXC config (keep Start on boot)')") || exit 0
case "$action_choice" in
1) LXC_SWITCH_ACTION="keep_gpu_disable_onboot" ;;
2) LXC_SWITCH_ACTION="remove_gpu_keep_onboot" ;;
*) exit 0 ;;
esac
case "$action_choice" in
1) LXC_SWITCH_ACTION="keep_gpu_disable_onboot" ;;
2) LXC_SWITCH_ACTION="remove_gpu_keep_onboot" ;;
*) exit 0 ;;
esac
fi
else
SWITCH_FROM_LXC=false
fi
@@ -1942,7 +1952,15 @@ cleanup_lxc_configs() {
msg_ok "$(translate 'LXC already stopped') ${ctid}" | tee -a "$screen_capture"
fi
if [[ "$LXC_SWITCH_ACTION" == "keep_gpu_disable_onboot" ]]; then
# OCI manager Apps keeps the record of what an OCI container has: its
# configuration is not edited from here.
local action="$LXC_SWITCH_ACTION"
if pmx_lxc_is_oci "$ctid"; then
action="keep_gpu_disable_onboot"
msg_warn "$(translate 'OCI container, configuration kept. Remove its GPU from OCI manager Apps, with Recreate: CT') ${ctid}" | tee -a "$screen_capture"
fi
if [[ "$action" == "keep_gpu_disable_onboot" ]]; then
if [[ "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]]; then
if pct set "$ctid" -onboot 0 >>"$LOG_FILE" 2>&1; then
msg_warn "$(translate 'Start on boot disabled for LXC') ${ctid}" | tee -a "$screen_capture"
@@ -1952,7 +1970,7 @@ cleanup_lxc_configs() {
fi
fi
if [[ "$LXC_SWITCH_ACTION" == "remove_gpu_keep_onboot" && -f "$conf" ]]; then
if [[ "$action" == "remove_gpu_keep_onboot" && -f "$conf" ]]; then
_remove_selected_gpu_from_lxc_conf "$conf"
msg_ok "$(translate 'GPU access removed from LXC') ${ctid}" | tee -a "$screen_capture"
fi
+10 -3
View File
@@ -63,7 +63,7 @@ initialize_cache
# ==========================================================
select_container() {
local menu_items=()
local menu_items=() oci_hidden=0
while IFS= read -r line; do
[[ "$line" =~ ^VMID ]] && continue
local ctid status name
@@ -71,19 +71,26 @@ select_container() {
status=$(echo "$line" | awk '{print $2}')
name=$(echo "$line" | awk '{print $3}')
[[ -z "$ctid" ]] && continue
if pmx_lxc_is_oci "$ctid"; then
oci_hidden=$((oci_hidden + 1))
continue
fi
menu_items+=("$ctid" "${name:-CT-${ctid}} (${status})")
done < <(pct list 2>/dev/null)
local oci_note="" list_h=12
[[ $oci_hidden -gt 0 ]] && list_h=7 && oci_note="\n\n$(translate 'Containers created from an OCI image are not listed: their devices are changed in OCI manager Apps (Recreate).')"
if [[ ${#menu_items[@]} -eq 0 ]]; then
dialog --backtitle "ProxMenux" \
--title "$(translate 'Install Coral TPU in LXC')" \
--msgbox "\n$(translate 'No LXC containers found on this system.')" 8 60
--msgbox "\n$(translate 'No LXC containers found on this system.')${oci_note}" 12 66
exit 0
fi
CONTAINER_ID=$(dialog --backtitle "ProxMenux" \
--title "$(translate 'Install Coral TPU in LXC')" \
--menu "\n$(translate 'Select the LXC container:')" 20 72 12 \
--menu "\n$(translate 'Select the LXC container:')${oci_note}" 20 72 "$list_h" \
"${menu_items[@]}" \
2>&1 >/dev/tty) || exit 0
+23 -3
View File
@@ -770,7 +770,7 @@ detect_affected_lxc_for_selected() {
prompt_lxc_action_for_vm_mode() {
[[ ${#LXC_AFFECTED_CTIDS[@]} -eq 0 ]] && return 0
local running_count=0 onboot_count=0 i
local running_count=0 onboot_count=0 oci_count=0 i
for i in "${!LXC_AFFECTED_CTIDS[@]}"; do
[[ "${LXC_AFFECTED_RUNNING[$i]}" == "1" ]] && running_count=$((running_count + 1))
[[ "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]] && onboot_count=$((onboot_count + 1))
@@ -783,11 +783,23 @@ prompt_lxc_action_for_vm_mode() {
st="$(translate 'stopped')"; ob="onboot=0"
[[ "${LXC_AFFECTED_RUNNING[$i]}" == "1" ]] && st="$(translate 'running')"
[[ "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]] && ob="onboot=1"
if pmx_lxc_is_oci "${LXC_AFFECTED_CTIDS[$i]}"; then
ob+=", OCI"
oci_count=$((oci_count + 1))
fi
msg+=" • CT ${LXC_AFFECTED_CTIDS[$i]} (${LXC_AFFECTED_NAMES[$i]}) [${st}, ${ob}]\n"
done
[[ "$oci_count" -gt 0 ]] && msg+="\n$(translate 'OCI containers keep their configuration: they are stopped and their Start on boot is disabled. Their GPU is removed from OCI manager Apps, with Recreate.')\n"
msg+="\n$(translate 'Switching to GPU -> VM mode requires exclusive VFIO binding.')\n"
[[ "$running_count" -gt 0 ]] && msg+="\Z1$(translate 'Running containers detected'): ${running_count}\Zn\n"
[[ "$onboot_count" -gt 0 ]] && msg+="\Z1\Zb$(translate 'Start on boot enabled'): ${onboot_count}\Zn\n"
if [[ "$oci_count" -eq ${#LXC_AFFECTED_CTIDS[@]} ]]; then
LXC_ACTION="keep_gpu_disable_onboot"
dialog --backtitle "ProxMenux" --colors \
--title "$(translate 'LXC Conflict Policy')" \
--msgbox "$msg" 22 80
return 0
fi
msg+="\n$(translate 'Choose conflict policy:')"
choice=$(dialog --backtitle "ProxMenux" --colors \
@@ -849,13 +861,21 @@ apply_lxc_action_for_vm_mode() {
fi
fi
if [[ "$LXC_ACTION" == "keep_gpu_disable_onboot" && "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]]; then
# OCI manager Apps keeps the record of what an OCI container has: its
# configuration is not edited from here.
local action="$LXC_ACTION"
if pmx_lxc_is_oci "$ctid"; then
action="keep_gpu_disable_onboot"
msg_warn "$(translate 'OCI container, configuration kept. Remove its GPU from OCI manager Apps, with Recreate: CT') ${ctid}" | tee -a "$screen_capture"
fi
if [[ "$action" == "keep_gpu_disable_onboot" && "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]]; then
if pct set "$ctid" -onboot 0 >>"$LOG_FILE" 2>&1; then
msg_warn "$(translate 'Start on boot disabled for LXC') ${ctid}" | tee -a "$screen_capture"
fi
fi
if [[ "$LXC_ACTION" == "remove_gpu_keep_onboot" && -f "$conf" ]]; then
if [[ "$action" == "remove_gpu_keep_onboot" && -f "$conf" ]]; then
local t
for t in "${types[@]}"; do
_remove_type_from_lxc_conf "$conf" "$t"
+21 -3
View File
@@ -596,7 +596,7 @@ detect_affected_lxc_for_selected() {
prompt_lxc_action_for_vm_mode() {
[[ ${#LXC_AFFECTED_CTIDS[@]} -eq 0 ]] && return 0
local running_count=0 onboot_count=0 i
local running_count=0 onboot_count=0 oci_count=0 i
for i in "${!LXC_AFFECTED_CTIDS[@]}"; do
[[ "${LXC_AFFECTED_RUNNING[$i]}" == "1" ]] && running_count=$((running_count + 1))
[[ "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]] && onboot_count=$((onboot_count + 1))
@@ -609,11 +609,21 @@ prompt_lxc_action_for_vm_mode() {
st="$(translate 'stopped')"; ob="onboot=0"
[[ "${LXC_AFFECTED_RUNNING[$i]}" == "1" ]] && st="$(translate 'running')"
[[ "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]] && ob="onboot=1"
if pmx_lxc_is_oci "${LXC_AFFECTED_CTIDS[$i]}"; then
ob+=", OCI"
oci_count=$((oci_count + 1))
fi
msg+=" - CT ${LXC_AFFECTED_CTIDS[$i]} (${LXC_AFFECTED_NAMES[$i]}) [${st}, ${ob}]\n"
done
[[ "$oci_count" -gt 0 ]] && msg+="\n$(translate 'OCI containers keep their configuration: they are stopped and their Start on boot is disabled. Their GPU is removed from OCI manager Apps, with Recreate.')\n"
msg+="\n$(translate 'Switching to GPU -> VM mode requires exclusive VFIO binding.')\n"
[[ "$running_count" -gt 0 ]] && msg+="$(translate 'Running containers detected'): ${running_count}\n"
[[ "$onboot_count" -gt 0 ]] && msg+="$(translate 'Start on boot enabled'): ${onboot_count}\n"
if [[ "$oci_count" -eq ${#LXC_AFFECTED_CTIDS[@]} ]]; then
LXC_ACTION="keep_gpu_disable_onboot"
hybrid_msgbox "$(translate 'LXC Conflict Policy')" "$msg" 22 80
return 0
fi
msg+="\n$(translate 'Choose conflict policy'):"
local choice
@@ -675,13 +685,21 @@ apply_lxc_action_for_vm_mode() {
fi
fi
if [[ "$LXC_ACTION" == "keep_gpu_disable_onboot" && "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]]; then
# OCI manager Apps keeps the record of what an OCI container has: its
# configuration is not edited from here.
local action="$LXC_ACTION"
if pmx_lxc_is_oci "$ctid"; then
action="keep_gpu_disable_onboot"
msg_warn "$(translate 'OCI container, configuration kept. Remove its GPU from OCI manager Apps, with Recreate: CT') ${ctid}" | tee -a "$screen_capture"
fi
if [[ "$action" == "keep_gpu_disable_onboot" && "${LXC_AFFECTED_ONBOOT[$i]}" == "1" ]]; then
if pct set "$ctid" -onboot 0 >>"$LOG_FILE" 2>&1; then
msg_warn "$(translate 'Start on boot disabled for LXC') ${ctid}" | tee -a "$screen_capture"
fi
fi
if [[ "$LXC_ACTION" == "remove_gpu_keep_onboot" && -f "$conf" ]]; then
if [[ "$action" == "remove_gpu_keep_onboot" && -f "$conf" ]]; then
local t
for t in "${types[@]}"; do
_remove_type_from_lxc_conf "$conf" "$t"
+2 -2
View File
@@ -34,14 +34,14 @@ while true; do
OPTION=$(dialog --colors --backtitle "ProxMenux" \
--title "$(translate "Storage & Share Manager")" \
--menu "\n$(translate "Select an option:")" 28 78 17 \
"" "\Zb\Z4 HOST\Zn" \
"" "\Z4──────────────────────────── HOST ─────────────────────────────\Zn" \
"1" "$(translate "Add NFS share as Proxmox Storage")" \
"2" "$(translate "Add Samba share as Proxmox Storage")" \
"3" "$(translate "Add iSCSI Target as Proxmox Storage")" \
"4" "$(translate "Add Local Disk as Proxmox Storage")" \
"5" "$(translate "Create Shared Directory on Host")" \
"" "" \
"" "\Zb\Z4 LXC\Zn" \
"" "\Z4───────────────────────────── LXC ─────────────────────────────\Zn" \
"6" "$(translate "Configure LXC Mount Points (Host ↔ Container)")" \
"" "" \
"7" "$(translate "Configure NFS Client in LXC (only privileged)")" \
+10 -4
View File
@@ -266,19 +266,25 @@ select_lxc_container() {
return 1
fi
local options=()
local options=() oci_note="" list_h=15
while read -r id name status; do
[[ -n "$id" && "$id" =~ ^[0-9]+$ ]] && options+=("$id" "${name:-unnamed} ($status)")
[[ -n "$id" && "$id" =~ ^[0-9]+$ ]] || continue
if pmx_lxc_is_oci "$id"; then
list_h=12
oci_note="\n\n$(translate "Containers created from an OCI image are not listed: their paths are changed in OCI manager Apps (Recreate).")"
continue
fi
options+=("$id" "${name:-unnamed} ($status)")
done <<< "$ct_list"
if [[ ${#options[@]} -eq 0 ]]; then
dialog --title "Error" --msgbox "$(translate "No valid containers found")" 8 50
dialog --title "Error" --msgbox "$(translate "No valid containers found")${oci_note}" 12 66
return 1
fi
local ctid
ctid=$(dialog --title "$(translate "Select LXC Container")" \
--menu "$(translate "Select container:")" 25 85 15 \
--menu "$(translate "Select container:")${oci_note}" 25 85 "$list_h" \
"${options[@]}" 3>&1 1>&2 2>&3)
[[ $? -ne 0 || -z "$ctid" ]] && return 1
+14 -3
View File
@@ -196,18 +196,29 @@ disk_referenced_in_config() {
CT_LIST=$(pct list | awk 'NR>1 {print $1, $3}')
CT_LIST=""
OCI_NOTE=""
CT_LIST_H=$UI_MENU_LIST_H
while read -r ct_id ct_name; do
[[ -n "$ct_id" ]] || continue
if pmx_lxc_is_oci "$ct_id"; then
CT_LIST_H=$((UI_MENU_LIST_H - 2))
OCI_NOTE="\n\n$(translate "Containers created from an OCI image are not listed: their paths are changed in OCI manager Apps (Recreate).")"
continue
fi
CT_LIST+="${CT_LIST:+ }$ct_id ${ct_name:-CT-$ct_id}"
done < <(pct list | awk 'NR>1 {print $1, $3}')
if [ -z "$CT_LIST" ]; then
dialog --backtitle "$BACKTITLE" \
--title "$(translate "Error")" \
--msgbox "$(translate "No CTs available in the system.")" $UI_MSG_H $UI_MSG_W
--msgbox "$(translate "No CTs available in the system.")${OCI_NOTE}" 12 $UI_MSG_W
exit 1
fi
# shellcheck disable=SC2086 # CT_LIST is intentionally word-split into dialog menu pairs
CTID=$(dialog --backtitle "$BACKTITLE" \
--title "$(translate "Select CT for destination disk")" \
--menu "$(translate "Select the CT to which you want to add disks:")" $UI_MENU_H $UI_MENU_W $UI_MENU_LIST_H \
--menu "$(translate "Select the CT to which you want to add disks:")${OCI_NOTE}" $UI_MENU_H $UI_MENU_W $CT_LIST_H \
$CT_LIST \
2>&1 >/dev/tty)
+7
View File
@@ -419,6 +419,13 @@ update_component_status() {
# Hybrid Dialog Functions (Web/Terminal)
# ============================================
# A container created from an OCI image declares its entrypoint (or cmd) in
# its configuration. It has no package manager to install drivers with, and
# OCI manager Apps is what changes its devices.
pmx_lxc_is_oci() {
grep -qaE '^(entrypoint|cmd):' "/etc/pve/lxc/${1}.conf" 2>/dev/null
}
# Detect if running in web mode
is_web_mode() {
[[ "$EXECUTION_MODE" == "web" ]]