mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-09-15 03:06:45 +00:00
The change journal exists so a sysadmin sees what ProxMenux changed on the host — its own configuration, packages and services — not how it uses the host or configures a guest. Several scripts recorded operations that are neither: disk passthrough to a VM, container conversions, VM import/export, mounting a share into an LXC. Those are restored to their original, uninstrumented form. Scripts that operate on the host while also installing a package now record only the package: format-disk keeps its exFAT-tools install, the UUP ISO builder its build dependencies, and the share/host scripts their packages, services and /etc/fstab writes, while the mount and unmount operations they used to log are dropped. The page now reads in three sections: what ProxMenux optimized after install (each function under its menu name), what its other host scripts changed (by script), and what it installed (packages and utilities, each referencing the script that installed it). A file reads as created or modified with its diff, a service shows its state transition, and the undo line appears only when a revert is possible.
541 lines
20 KiB
Bash
541 lines
20 KiB
Bash
#!/bin/bash
|
|
# ==========================================================
|
|
# ProxMenux - iSCSI Host Manager for Proxmox Host
|
|
# ==========================================================
|
|
# Author : MacRimi
|
|
# Copyright : (c) 2024 MacRimi
|
|
# License : GPL-3.0
|
|
# https://github.com/MacRimi/ProxMenux/blob/main/LICENSE
|
|
# Version : 1.0
|
|
# ==========================================================
|
|
# Description:
|
|
# Registers iSCSI targets as Proxmox storage via
|
|
# pvesm add iscsi. Proxmox manages the session natively via
|
|
# open-iscsi; LUNs appear as raw block devices for VM disks.
|
|
#
|
|
# Features:
|
|
# - Auto-installs open-iscsi + enables iscsid service.
|
|
# - sendtargets discovery against a portal (IP:port).
|
|
# - Auto-selects a single target; menu when several.
|
|
# - Storage ID derived from the IQN suffix.
|
|
# - Content type fixed to 'images' (block storage only).
|
|
# - View, remove and connectivity-test for existing storages.
|
|
# ==========================================================
|
|
|
|
LOCAL_SCRIPTS="/usr/local/share/proxmenux/scripts"
|
|
BASE_DIR="/usr/local/share/proxmenux"
|
|
UTILS_FILE="$BASE_DIR/utils.sh"
|
|
|
|
if [[ -f "$UTILS_FILE" ]]; then
|
|
source "$UTILS_FILE"
|
|
fi
|
|
|
|
if [[ -f "$LOCAL_SCRIPTS/global/pmx_journal.sh" ]]; then
|
|
source "$LOCAL_SCRIPTS/global/pmx_journal.sh"
|
|
fi
|
|
|
|
load_language
|
|
initialize_cache
|
|
|
|
if ! command -v pveversion >/dev/null 2>&1; then
|
|
dialog --backtitle "ProxMenux" --title "$(translate "Error")" \
|
|
--msgbox "$(translate "This script must be run on a Proxmox host.")" 8 60
|
|
exit 1
|
|
fi
|
|
|
|
# ==========================================================
|
|
# STORAGE CONFIG READER
|
|
# ==========================================================
|
|
get_storage_config() {
|
|
local storage_id="$1"
|
|
awk -v id="$storage_id" '
|
|
/^[a-z]+: / { found = ($0 ~ ": "id"$"); next }
|
|
found && /^[^ \t]/ { exit }
|
|
found { print }
|
|
' /etc/pve/storage.cfg
|
|
}
|
|
|
|
# ==========================================================
|
|
# TOOLS
|
|
# ==========================================================
|
|
|
|
ensure_iscsi_tools() {
|
|
local FUNC_VERSION="1.0"
|
|
pmx_journal_context "ensure_iscsi_tools" "$FUNC_VERSION"
|
|
|
|
if ! command -v iscsiadm >/dev/null 2>&1; then
|
|
msg_info "$(translate "Installing iSCSI initiator tools...")"
|
|
apt-get update &>/dev/null
|
|
pmx_install_pkg open-iscsi
|
|
pmx_enable_service iscsid 2>/dev/null || true
|
|
msg_ok "$(translate "iSCSI tools installed")"
|
|
fi
|
|
|
|
if ! systemctl is-active --quiet iscsid 2>/dev/null; then
|
|
pmx_apply_setting "iscsid active state" "systemctl is-active iscsid 2>/dev/null || true" \
|
|
systemctl start iscsid || true
|
|
fi
|
|
}
|
|
|
|
# ==========================================================
|
|
# TARGET DISCOVERY
|
|
# ==========================================================
|
|
|
|
select_iscsi_portal() {
|
|
ISCSI_PORTAL=$(dialog --backtitle "ProxMenux" --title "$(translate "iSCSI Portal")" --inputbox \
|
|
"$(translate "Enter iSCSI target portal IP or hostname:")\n\n$(translate "Examples:")\n 192.168.1.100\n 192.168.1.100:3260\n nas.local" \
|
|
14 65 3>&1 1>&2 2>&3)
|
|
[[ $? -ne 0 || -z "$ISCSI_PORTAL" ]] && return 1
|
|
|
|
# Normalise: if no port specified, add default 3260
|
|
if [[ ! "$ISCSI_PORTAL" =~ :[0-9]+$ ]]; then
|
|
ISCSI_PORTAL_DISPLAY="$ISCSI_PORTAL"
|
|
ISCSI_PORTAL_FULL="${ISCSI_PORTAL}:3260"
|
|
else
|
|
ISCSI_PORTAL_DISPLAY="$ISCSI_PORTAL"
|
|
ISCSI_PORTAL_FULL="$ISCSI_PORTAL"
|
|
fi
|
|
|
|
# Extract host for ping
|
|
ISCSI_HOST=$(echo "$ISCSI_PORTAL" | cut -d: -f1)
|
|
return 0
|
|
}
|
|
|
|
discover_iscsi_targets() {
|
|
show_proxmenux_logo
|
|
msg_title "$(translate "Add iSCSI Target as Proxmox Storage")"
|
|
msg_ok "$(translate "Portal:") $ISCSI_PORTAL_DISPLAY"
|
|
msg_info "$(translate "Testing connectivity to portal...")"
|
|
|
|
if ! ping -c 1 -W 3 "$ISCSI_HOST" >/dev/null 2>&1; then
|
|
msg_error "$(translate "Cannot reach portal:") $ISCSI_HOST"
|
|
echo ""
|
|
msg_success "$(translate "Press Enter to continue...")"
|
|
read -r
|
|
return 1
|
|
fi
|
|
msg_ok "$(translate "Portal is reachable")"
|
|
|
|
if ! nc -z -w 3 "$ISCSI_HOST" "${ISCSI_PORTAL_FULL##*:}" 2>/dev/null; then
|
|
msg_warn "$(translate "iSCSI port") ${ISCSI_PORTAL_FULL##*:} $(translate "may be closed — trying discovery anyway...")"
|
|
fi
|
|
|
|
msg_info "$(translate "Discovering iSCSI targets...")"
|
|
DISCOVERY_OUTPUT=$(iscsiadm --mode discovery --type sendtargets \
|
|
--portal "$ISCSI_PORTAL_FULL" 2>&1)
|
|
DISCOVERY_RESULT=$?
|
|
|
|
if [[ $DISCOVERY_RESULT -ne 0 ]]; then
|
|
msg_error "$(translate "iSCSI discovery failed")"
|
|
echo -e "${TAB}$(translate "Error:"): $DISCOVERY_OUTPUT"
|
|
echo ""
|
|
msg_info2 "$(translate "Please check:")"
|
|
echo -e "${TAB}• $(translate "Portal IP and port are correct")"
|
|
echo -e "${TAB}• $(translate "iSCSI service is running on the target")"
|
|
echo -e "${TAB}• $(translate "Firewall allows port") ${ISCSI_PORTAL_FULL##*:}"
|
|
echo -e "${TAB}• $(translate "Initiator IQN is authorised on the target")"
|
|
echo ""
|
|
msg_success "$(translate "Press Enter to continue...")"
|
|
read -r
|
|
return 1
|
|
fi
|
|
|
|
# Parse discovered targets: format is <portal> <iqn>
|
|
TARGETS=$(echo "$DISCOVERY_OUTPUT" | awk '{print $2}' | grep "^iqn\." | sort -u)
|
|
|
|
if [[ -z "$TARGETS" ]]; then
|
|
msg_warn "$(translate "No iSCSI targets found on portal") $ISCSI_PORTAL_DISPLAY"
|
|
echo ""
|
|
msg_success "$(translate "Press Enter to continue...")"
|
|
read -r
|
|
return 1
|
|
fi
|
|
|
|
msg_ok "$(translate "Discovery successful")"
|
|
return 0
|
|
}
|
|
|
|
select_iscsi_target() {
|
|
local target_count
|
|
target_count=$(echo "$TARGETS" | wc -l)
|
|
|
|
if [[ "$target_count" -eq 1 ]]; then
|
|
ISCSI_TARGET=$(echo "$TARGETS" | head -1)
|
|
msg_ok "$(translate "Single target found — selected automatically:") $ISCSI_TARGET"
|
|
return 0
|
|
fi
|
|
|
|
local options=()
|
|
local i=1
|
|
while IFS= read -r iqn; do
|
|
[[ -z "$iqn" ]] && continue
|
|
# Try to get LUN info for display
|
|
local lun_info
|
|
lun_info=$(iscsiadm --mode node --targetname "$iqn" --portal "$ISCSI_PORTAL_FULL" \
|
|
--op show 2>/dev/null | grep "node.conn\[0\].address" | awk -F= '{print $2}' | tr -d ' ' || true)
|
|
options+=("$i" "$iqn")
|
|
i=$((i + 1))
|
|
done <<< "$TARGETS"
|
|
|
|
local choice
|
|
choice=$(dialog --backtitle "ProxMenux" --title "$(translate "Select iSCSI Target")" \
|
|
--menu "\n$(translate "Select target IQN:")" 20 90 10 \
|
|
"${options[@]}" 3>&1 1>&2 2>&3)
|
|
[[ -z "$choice" ]] && return 1
|
|
|
|
ISCSI_TARGET=$(echo "$TARGETS" | sed -n "${choice}p")
|
|
[[ -z "$ISCSI_TARGET" ]] && return 1
|
|
return 0
|
|
}
|
|
|
|
# ==========================================================
|
|
# STORAGE CONFIGURATION
|
|
# ==========================================================
|
|
|
|
configure_iscsi_storage() {
|
|
# Suggest a storage ID derived from target IQN
|
|
local iqn_suffix
|
|
iqn_suffix=$(echo "$ISCSI_TARGET" | awk -F: '{print $NF}' | tr '.' '-' | cut -c1-20)
|
|
local default_id="iscsi-${iqn_suffix}"
|
|
|
|
STORAGE_ID=$(whiptail --inputbox "$(translate "Enter storage ID for Proxmox:")" \
|
|
10 65 "$default_id" \
|
|
--title "$(translate "Storage ID")" 3>&1 1>&2 2>&3)
|
|
[[ $? -ne 0 ]] && return 1
|
|
[[ -z "$STORAGE_ID" ]] && STORAGE_ID="$default_id"
|
|
|
|
if [[ ! "$STORAGE_ID" =~ ^[a-zA-Z0-9][a-zA-Z0-9_-]*$ ]]; then
|
|
whiptail --msgbox "$(translate "Invalid storage ID. Use only letters, numbers, hyphens and underscores.")" 8 70
|
|
return 1
|
|
fi
|
|
|
|
# iSCSI in Proxmox exposes block devices — content is always 'images'
|
|
# (no file-level access like NFS/CIFS)
|
|
MOUNT_CONTENT="images"
|
|
|
|
whiptail --title "$(translate "iSCSI Content Type")" \
|
|
--msgbox "$(translate "iSCSI storage provides raw block devices for VM disk images.")\n\n$(translate "Content type is fixed to:")\n\n images\n\n$(translate "Each LUN will appear as a block device assignable to VMs.")" \
|
|
12 70
|
|
|
|
return 0
|
|
}
|
|
|
|
# ==========================================================
|
|
# PROXMOX INTEGRATION
|
|
# ==========================================================
|
|
|
|
add_proxmox_iscsi_storage() {
|
|
local FUNC_VERSION="1.0"
|
|
pmx_journal_context "add_proxmox_iscsi_storage" "$FUNC_VERSION"
|
|
|
|
local storage_id="$1"
|
|
local portal="$2"
|
|
local target="$3"
|
|
local content="${4:-images}"
|
|
|
|
if ! command -v pvesm >/dev/null 2>&1; then
|
|
msg_error "$(translate "pvesm command not found. This should not happen on Proxmox.")"
|
|
return 1
|
|
fi
|
|
|
|
if pvesm status "$storage_id" >/dev/null 2>&1; then
|
|
msg_warn "$(translate "Storage ID already exists:") $storage_id"
|
|
if ! whiptail --yesno "$(translate "Storage ID already exists. Do you want to remove and recreate it?")" \
|
|
8 60 --title "$(translate "Storage Exists")"; then
|
|
return 0
|
|
fi
|
|
pvesm remove "$storage_id" 2>/dev/null || true
|
|
fi
|
|
|
|
msg_ok "$(translate "Storage ID is available")"
|
|
msg_info "$(translate "Adding iSCSI storage to Proxmox...")"
|
|
|
|
local pvesm_output pvesm_result
|
|
pvesm_output=$(pvesm add iscsi "$storage_id" \
|
|
--portal "$portal" \
|
|
--target "$target" \
|
|
--content "$content" 2>&1)
|
|
pvesm_result=$?
|
|
|
|
if [[ $pvesm_result -eq 0 ]]; then
|
|
msg_ok "$(translate "iSCSI storage added successfully to Proxmox!")"
|
|
echo -e ""
|
|
echo -e "${TAB}${BOLD}$(translate "Storage Added:")${CL}"
|
|
echo -e "${TAB}${BGN}$(translate "Storage ID:")${CL} ${BL}$storage_id${CL}"
|
|
echo -e "${TAB}${BGN}$(translate "Portal:")${CL} ${BL}$portal${CL}"
|
|
echo -e "${TAB}${BGN}$(translate "Target IQN:")${CL} ${BL}$target${CL}"
|
|
echo -e "${TAB}${BGN}$(translate "Content Types:")${CL} ${BL}$content${CL}"
|
|
echo -e ""
|
|
msg_ok "$(translate "Storage is now available in Proxmox web interface under Datacenter > Storage")"
|
|
msg_info2 "$(translate "LUNs appear as block devices assignable to VMs")"
|
|
return 0
|
|
else
|
|
msg_error "$(translate "Failed to add iSCSI storage to Proxmox.")"
|
|
echo -e "${TAB}$(translate "Error details:"): $pvesm_output"
|
|
echo -e ""
|
|
msg_info2 "$(translate "You can add it manually through:")"
|
|
echo -e "${TAB}• $(translate "Proxmox web interface: Datacenter > Storage > Add > iSCSI")"
|
|
echo -e "${TAB}• pvesm add iscsi $storage_id --portal $portal --target $target --content $content"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# ==========================================================
|
|
# MAIN OPERATIONS
|
|
# ==========================================================
|
|
|
|
add_iscsi_to_proxmox() {
|
|
ensure_iscsi_tools
|
|
|
|
# Step 1: Enter portal
|
|
select_iscsi_portal || return
|
|
|
|
# Step 2: Discover targets
|
|
discover_iscsi_targets || return
|
|
|
|
# Step 3: Select target
|
|
select_iscsi_target || return
|
|
|
|
show_proxmenux_logo
|
|
msg_title "$(translate "Add iSCSI Target as Proxmox Storage")"
|
|
msg_ok "$(translate "Portal:") $ISCSI_PORTAL_DISPLAY"
|
|
msg_ok "$(translate "Target:") $ISCSI_TARGET"
|
|
|
|
# Step 4: Configure storage
|
|
configure_iscsi_storage || return
|
|
|
|
# Step 5: Add to Proxmox
|
|
show_proxmenux_logo
|
|
msg_title "$(translate "Add iSCSI Target as Proxmox Storage")"
|
|
msg_ok "$(translate "Portal:") $ISCSI_PORTAL_DISPLAY"
|
|
msg_ok "$(translate "Target:") $ISCSI_TARGET"
|
|
msg_ok "$(translate "Storage ID:") $STORAGE_ID"
|
|
msg_ok "$(translate "Content:") $MOUNT_CONTENT"
|
|
echo -e ""
|
|
|
|
add_proxmox_iscsi_storage "$STORAGE_ID" "$ISCSI_PORTAL_FULL" "$ISCSI_TARGET" "$MOUNT_CONTENT"
|
|
|
|
echo -e ""
|
|
msg_success "$(translate "Press Enter to continue...")"
|
|
read -r
|
|
}
|
|
|
|
view_iscsi_storages() {
|
|
show_proxmenux_logo
|
|
msg_title "$(translate "iSCSI Storages in Proxmox")"
|
|
|
|
echo "=================================================="
|
|
echo ""
|
|
|
|
if ! command -v pvesm >/dev/null 2>&1; then
|
|
msg_error "$(translate "pvesm not found.")"
|
|
echo ""
|
|
msg_success "$(translate "Press Enter to continue...")"
|
|
read -r
|
|
return
|
|
fi
|
|
|
|
ISCSI_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "iscsi" {print $1, $3}')
|
|
if [[ -z "$ISCSI_STORAGES" ]]; then
|
|
msg_warn "$(translate "No iSCSI storage configured in Proxmox.")"
|
|
echo ""
|
|
msg_info2 "$(translate "Use option 1 to add an iSCSI target as Proxmox storage.")"
|
|
else
|
|
echo -e "${BOLD}$(translate "iSCSI Storages:")${CL}"
|
|
echo ""
|
|
while IFS=" " read -r storage_id storage_status; do
|
|
[[ -z "$storage_id" ]] && continue
|
|
local storage_info portal target content
|
|
storage_info=$(get_storage_config "$storage_id")
|
|
portal=$(echo "$storage_info" | awk '$1 == "portal" {print $2}')
|
|
target=$(echo "$storage_info" | awk '$1 == "target" {print $2}')
|
|
content=$(echo "$storage_info" | awk '$1 == "content" {print $2}')
|
|
|
|
echo -e "${TAB}${BOLD}$storage_id${CL}"
|
|
echo -e "${TAB} ${BGN}$(translate "Portal:")${CL} ${BL}$portal${CL}"
|
|
echo -e "${TAB} ${BGN}$(translate "Target IQN:")${CL} ${BL}$target${CL}"
|
|
echo -e "${TAB} ${BGN}$(translate "Content:")${CL} ${BL}$content${CL}"
|
|
if [[ "$storage_status" == "active" ]]; then
|
|
echo -e "${TAB} ${BGN}$(translate "Status:")${CL} ${GN}$(translate "Active")${CL}"
|
|
else
|
|
echo -e "${TAB} ${BGN}$(translate "Status:")${CL} ${RD}$storage_status${CL}"
|
|
fi
|
|
echo ""
|
|
done <<< "$ISCSI_STORAGES"
|
|
fi
|
|
|
|
echo ""
|
|
msg_success "$(translate "Press Enter to continue...")"
|
|
read -r
|
|
}
|
|
|
|
remove_iscsi_storage() {
|
|
local FUNC_VERSION="1.0"
|
|
pmx_journal_context "remove_iscsi_storage" "$FUNC_VERSION"
|
|
|
|
if ! command -v pvesm >/dev/null 2>&1; then
|
|
dialog --backtitle "ProxMenux" --title "$(translate "Error")" \
|
|
--msgbox "\n$(translate "pvesm not found.")" 8 60
|
|
return
|
|
fi
|
|
|
|
ISCSI_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "iscsi" {print $1}')
|
|
if [[ -z "$ISCSI_STORAGES" ]]; then
|
|
dialog --backtitle "ProxMenux" --title "$(translate "No iSCSI Storage")" \
|
|
--msgbox "\n$(translate "No iSCSI storage found in Proxmox.")" 8 60
|
|
return
|
|
fi
|
|
|
|
local options=()
|
|
while IFS= read -r storage_id; do
|
|
[[ -z "$storage_id" ]] && continue
|
|
local storage_info portal target
|
|
storage_info=$(get_storage_config "$storage_id")
|
|
portal=$(echo "$storage_info" | awk '$1 == "portal" {print $2}')
|
|
target=$(echo "$storage_info" | awk '$1 == "target" {print $2}')
|
|
options+=("$storage_id" "$portal — ${target:0:40}")
|
|
done <<< "$ISCSI_STORAGES"
|
|
|
|
local SELECTED
|
|
SELECTED=$(dialog --backtitle "ProxMenux" --title "$(translate "Remove iSCSI Storage")" \
|
|
--menu "$(translate "Select storage to remove:")" 20 90 10 \
|
|
"${options[@]}" 3>&1 1>&2 2>&3)
|
|
[[ -z "$SELECTED" ]] && return
|
|
|
|
local storage_info portal target content
|
|
storage_info=$(get_storage_config "$SELECTED")
|
|
portal=$(echo "$storage_info" | awk '$1 == "portal" {print $2}')
|
|
target=$(echo "$storage_info" | awk '$1 == "target" {print $2}')
|
|
content=$(echo "$storage_info" | awk '$1 == "content" {print $2}')
|
|
|
|
if whiptail --yesno "$(translate "Remove Proxmox iSCSI storage:")\n\n$SELECTED\n\n$(translate "Portal:"): $portal\n$(translate "Target:"): $target\n$(translate "Content:"): $content\n\n$(translate "This removes the storage from Proxmox. The iSCSI target is not affected.")" \
|
|
16 80 --title "$(translate "Confirm Remove")"; then
|
|
|
|
show_proxmenux_logo
|
|
msg_title "$(translate "Remove iSCSI Storage")"
|
|
|
|
if pvesm remove "$SELECTED" 2>/dev/null; then
|
|
msg_ok "$(translate "Storage") $SELECTED $(translate "removed successfully from Proxmox.")"
|
|
else
|
|
msg_error "$(translate "Failed to remove storage.")"
|
|
fi
|
|
|
|
echo -e ""
|
|
msg_success "$(translate "Press Enter to continue...")"
|
|
read -r
|
|
fi
|
|
}
|
|
|
|
test_iscsi_connectivity() {
|
|
show_proxmenux_logo
|
|
msg_title "$(translate "Test iSCSI Connectivity")"
|
|
|
|
echo "=================================================="
|
|
echo ""
|
|
|
|
if command -v iscsiadm >/dev/null 2>&1; then
|
|
msg_ok "$(translate "iSCSI Initiator: AVAILABLE")"
|
|
local initiator_iqn
|
|
initiator_iqn=$(cat /etc/iscsi/initiatorname.iscsi 2>/dev/null | grep "^InitiatorName=" | cut -d= -f2)
|
|
[[ -n "$initiator_iqn" ]] && echo -e " ${BGN}$(translate "Initiator IQN:")${CL} ${BL}$initiator_iqn${CL}"
|
|
|
|
if systemctl is-active --quiet iscsid 2>/dev/null; then
|
|
msg_ok "$(translate "iSCSI Daemon (iscsid): RUNNING")"
|
|
else
|
|
msg_warn "$(translate "iSCSI Daemon (iscsid): STOPPED")"
|
|
fi
|
|
else
|
|
msg_warn "$(translate "iSCSI Initiator: NOT INSTALLED")"
|
|
echo -e " $(translate "Install with: apt-get install open-iscsi")"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
if command -v pvesm >/dev/null 2>&1; then
|
|
echo -e "${BOLD}$(translate "Proxmox iSCSI Storage Status:")${CL}"
|
|
ISCSI_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "iscsi" {print $1, $3}')
|
|
|
|
if [[ -n "$ISCSI_STORAGES" ]]; then
|
|
while IFS=" " read -r storage_id storage_status; do
|
|
[[ -z "$storage_id" ]] && continue
|
|
local portal
|
|
portal=$(get_storage_config "$storage_id" | awk '$1 == "portal" {print $2}')
|
|
local portal_host="${portal%%:*}"
|
|
|
|
echo -n " $storage_id ($portal): "
|
|
|
|
if ping -c 1 -W 2 "$portal_host" >/dev/null 2>&1; then
|
|
echo -ne "${GN}$(translate "Reachable")${CL}"
|
|
local portal_port="${portal##*:}"
|
|
[[ "$portal_port" == "$portal" ]] && portal_port="3260"
|
|
if nc -z -w 2 "$portal_host" "$portal_port" 2>/dev/null; then
|
|
echo -e " | iSCSI port $portal_port: ${GN}$(translate "Open")${CL}"
|
|
else
|
|
echo -e " | iSCSI port $portal_port: ${RD}$(translate "Closed")${CL}"
|
|
fi
|
|
else
|
|
echo -e "${RD}$(translate "Unreachable")${CL}"
|
|
fi
|
|
|
|
if [[ "$storage_status" == "active" ]]; then
|
|
echo -e " $(translate "Proxmox status:") ${GN}$storage_status${CL}"
|
|
else
|
|
echo -e " $(translate "Proxmox status:") ${RD}$storage_status${CL}"
|
|
fi
|
|
|
|
# Show active iSCSI sessions for this target
|
|
local target
|
|
target=$(get_storage_config "$storage_id" | awk '$1 == "target" {print $2}')
|
|
if command -v iscsiadm >/dev/null 2>&1; then
|
|
local session
|
|
session=$(iscsiadm --mode session 2>/dev/null | grep "$target" || true)
|
|
if [[ -n "$session" ]]; then
|
|
echo -e " $(translate "Active session:") ${GN}$(translate "Connected")${CL}"
|
|
else
|
|
echo -e " $(translate "Active session:") ${YW}$(translate "No active session")${CL}"
|
|
fi
|
|
fi
|
|
echo ""
|
|
done <<< "$ISCSI_STORAGES"
|
|
else
|
|
echo " $(translate "No iSCSI storage configured.")"
|
|
fi
|
|
else
|
|
msg_warn "$(translate "pvesm not available.")"
|
|
fi
|
|
|
|
echo ""
|
|
msg_success "$(translate "Press Enter to continue...")"
|
|
read -r
|
|
}
|
|
|
|
# ==========================================================
|
|
# MAIN MENU
|
|
# ==========================================================
|
|
|
|
while true; do
|
|
CHOICE=$(dialog --backtitle "ProxMenux" \
|
|
--title "$(translate "iSCSI Host Manager - Proxmox Host")" \
|
|
--menu "$(translate "Choose an option:")" 18 70 6 \
|
|
"1" "$(translate "Add iSCSI Target as Proxmox Storage")" \
|
|
"2" "$(translate "View iSCSI Storages")" \
|
|
"3" "$(translate "Remove iSCSI Storage")" \
|
|
"4" "$(translate "Test iSCSI Connectivity")" \
|
|
"5" "$(translate "Exit")" \
|
|
3>&1 1>&2 2>&3)
|
|
|
|
RETVAL=$?
|
|
if [[ $RETVAL -ne 0 ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
case $CHOICE in
|
|
1) add_iscsi_to_proxmox ;;
|
|
2) view_iscsi_storages ;;
|
|
3) remove_iscsi_storage ;;
|
|
4) test_iscsi_connectivity ;;
|
|
5) exit 0 ;;
|
|
*) exit 0 ;;
|
|
esac
|
|
done
|