Updates scripts share

This commit is contained in:
MacRimi
2026-05-26 17:21:24 +02:00
parent 2dc3a2b93c
commit 3143fedb7a
2 changed files with 454 additions and 118 deletions
+216 -60
View File
@@ -200,7 +200,7 @@ select_nfs_export() {
validate_host_export_exists() {
local server="$1"
local export="$2"
VALIDATION_OUTPUT=$(showmount -e "$server" 2>/dev/null | grep "^$export[[:space:]]")
VALIDATION_OUTPUT=$(showmount -e "$server" 2>/dev/null | grep "^${export}[[:space:]]")
if [[ -n "$VALIDATION_OUTPUT" ]]; then
return 0
else
@@ -551,39 +551,62 @@ mount_nfs_share() {
read -r
}
# ==========================================================
# FSTAB ENTRY DISCOVERY (host mounts NOT registered with pvesm)
# ==========================================================
# Print every NFS entry in /etc/fstab as: server|export|mount_path|opts
# Skips comments and blank lines. Includes both currently-mounted and
# inactive entries (the live state is reported by the caller).
list_nfs_fstab_entries() {
awk '
/^[[:space:]]*#/ { next }
/^[[:space:]]*$/ { next }
$3 == "nfs" || $3 == "nfs4" {
# $1 = server:/export, $2 = mount path, $4 = opts
split($1, srv_exp, ":")
print srv_exp[1] "|" srv_exp[2] "|" $2 "|" $4
}
' /etc/fstab 2>/dev/null
}
# Echo "active" if the given path is currently mounted, "inactive" otherwise.
check_mount_state() {
local path="$1"
if mount | grep -q " on ${path} type "; then
echo "active"
else
echo "inactive"
fi
}
view_nfs_storages() {
show_proxmenux_logo
msg_title "$(translate "NFS Storages in Proxmox")"
msg_title "$(translate "NFS Mounts on Host")"
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
# ---- Proxmox storages (pvesm) ----
local NFS_STORAGES=""
if command -v pvesm >/dev/null 2>&1; then
NFS_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "nfs" {print $1, $3}')
fi
NFS_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "nfs" {print $1, $3}')
if [[ -z "$NFS_STORAGES" ]]; then
msg_warn "$(translate "No NFS storage configured in Proxmox.")"
echo ""
msg_info2 "$(translate "Use option 1 to add an NFS share as Proxmox storage.")"
msg_warn "$(translate "No NFS Proxmox storages configured.")"
else
echo -e "${BOLD}$(translate "NFS Storages:")${CL}"
echo -e "${BOLD}$(translate "NFS Proxmox storages (pvesm):")${CL}"
echo ""
while IFS=" " read -r storage_id storage_status; do
[[ -z "$storage_id" ]] && continue
local storage_info
local storage_info server export_path content
storage_info=$(get_storage_config "$storage_id")
local server export_path content
server=$(echo "$storage_info" | awk '$1 == "server" {print $2}')
export_path=$(echo "$storage_info" | awk '$1 == "export" {print $2}')
content=$(echo "$storage_info" | awk '$1 == "content" {print $2}')
echo -e "${TAB}${BOLD}$storage_id${CL}"
echo -e "${TAB}${BOLD}$storage_id${CL} ${TAB}[pvesm]"
echo -e "${TAB} ${BGN}$(translate "Server:")${CL} ${BL}$server${CL}"
echo -e "${TAB} ${BGN}$(translate "Export:")${CL} ${BL}$export_path${CL}"
echo -e "${TAB} ${BGN}$(translate "Content:")${CL} ${BL}$content${CL}"
@@ -597,62 +620,161 @@ view_nfs_storages() {
done <<< "$NFS_STORAGES"
fi
# ---- Host fstab mounts (NOT pvesm) ----
local FSTAB_ENTRIES
FSTAB_ENTRIES=$(list_nfs_fstab_entries)
if [[ -z "$FSTAB_ENTRIES" ]]; then
echo -e "${BOLD}$(translate "Host fstab NFS mounts:")${CL} $(translate "(none)")"
else
echo -e "${BOLD}$(translate "Host fstab NFS mounts (not registered with pvesm):")${CL}"
echo ""
while IFS="|" read -r server export_path mount_path opts; do
[[ -z "$mount_path" ]] && continue
local mstate
mstate=$(check_mount_state "$mount_path")
echo -e "${TAB}${BOLD}$(basename "$mount_path")${CL} ${TAB}[fstab]"
echo -e "${TAB} ${BGN}$(translate "Server:")${CL} ${BL}$server${CL}"
echo -e "${TAB} ${BGN}$(translate "Export:")${CL} ${BL}$export_path${CL}"
echo -e "${TAB} ${BGN}$(translate "Mount Path:")${CL} ${BL}$mount_path${CL}"
echo -e "${TAB} ${BGN}$(translate "Options:")${CL} ${BL}$opts${CL}"
if [[ "$mstate" == "active" ]]; then
echo -e "${TAB} ${BGN}$(translate "Status:")${CL} ${GN}$(translate "Active")${CL}"
else
echo -e "${TAB} ${BGN}$(translate "Status:")${CL} ${RD}$(translate "Inactive (entry in fstab, not currently mounted)")${CL}"
fi
echo ""
done <<< "$FSTAB_ENTRIES"
fi
echo ""
msg_success "$(translate "Press Enter to continue...")"
read -r
}
remove_nfs_storage() {
if ! command -v pvesm >/dev/null 2>&1; then
dialog --backtitle "ProxMenux" --title "$(translate "Error")" \
--msgbox "\n$(translate "pvesm not found.")" 8 60
# Collect every removable NFS entry: pvesm storages and fstab-only mounts.
local OPTIONS=()
local has_pvesm=0
local has_fstab=0
# pvesm-registered NFS storages
if command -v pvesm >/dev/null 2>&1; then
local NFS_STORAGES
NFS_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "nfs" {print $1}')
if [[ -n "$NFS_STORAGES" ]]; then
has_pvesm=1
while IFS= read -r storage_id; do
[[ -z "$storage_id" ]] && continue
local storage_info server export_path
storage_info=$(get_storage_config "$storage_id")
server=$(echo "$storage_info" | awk '$1 == "server" {print $2}')
export_path=$(echo "$storage_info" | awk '$1 == "export" {print $2}')
# Encode key with a prefix so we know how to handle the selection.
OPTIONS+=("pvesm:$storage_id" "[pvesm] $storage_id ($server:$export_path)")
done <<< "$NFS_STORAGES"
fi
fi
# fstab-only NFS mounts
local FSTAB_ENTRIES
FSTAB_ENTRIES=$(list_nfs_fstab_entries)
if [[ -n "$FSTAB_ENTRIES" ]]; then
has_fstab=1
while IFS="|" read -r server export_path mount_path opts; do
[[ -z "$mount_path" ]] && continue
OPTIONS+=("fstab:$mount_path" "[fstab] $mount_path ($server:$export_path)")
done <<< "$FSTAB_ENTRIES"
fi
if [[ "$has_pvesm" == "0" && "$has_fstab" == "0" ]]; then
dialog --backtitle "ProxMenux" --title "$(translate "Nothing to remove")" \
--msgbox "\n$(translate "No NFS Proxmox storage and no NFS fstab mount found on this host.")" 9 70
return
fi
NFS_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "nfs" {print $1}')
if [[ -z "$NFS_STORAGES" ]]; then
dialog --backtitle "ProxMenux" --title "$(translate "No NFS Storage")" \
--msgbox "\n$(translate "No NFS storage found in Proxmox.")" 8 60
return
fi
OPTIONS=()
while IFS= read -r storage_id; do
[[ -z "$storage_id" ]] && continue
local storage_info server export_path
storage_info=$(get_storage_config "$storage_id")
server=$(echo "$storage_info" | awk '$1 == "server" {print $2}')
export_path=$(echo "$storage_info" | awk '$1 == "export" {print $2}')
OPTIONS+=("$storage_id" "$server:$export_path")
done <<< "$NFS_STORAGES"
SELECTED=$(dialog --backtitle "ProxMenux" --title "$(translate "Remove NFS Storage")" \
--menu "$(translate "Select storage to remove:")" 20 80 10 \
local SELECTED
SELECTED=$(dialog --backtitle "ProxMenux" --title "$(translate "Remove NFS Mount")" \
--menu "$(translate "Select the entry to remove. [pvesm] entries are removed from Proxmox storage; [fstab] entries are unmounted and removed from /etc/fstab.")" \
20 90 12 \
"${OPTIONS[@]}" 3>&1 1>&2 2>&3)
[[ -z "$SELECTED" ]] && return
local storage_info server export_path content
storage_info=$(get_storage_config "$SELECTED")
server=$(echo "$storage_info" | awk '$1 == "server" {print $2}')
export_path=$(echo "$storage_info" | awk '$1 == "export" {print $2}')
content=$(echo "$storage_info" | awk '$1 == "content" {print $2}')
local kind="${SELECTED%%:*}"
local target="${SELECTED#*:}"
if whiptail --yesno "$(translate "Remove Proxmox NFS storage:")\n\n$SELECTED\n\n$(translate "Server:"): $server\n$(translate "Export:"): $export_path\n$(translate "Content:"): $content\n\n$(translate "WARNING: This removes the storage from Proxmox. The NFS server is not affected.")" \
16 80 --title "$(translate "Confirm Remove")"; then
case "$kind" in
pvesm)
local storage_info server export_path content
storage_info=$(get_storage_config "$target")
server=$(echo "$storage_info" | awk '$1 == "server" {print $2}')
export_path=$(echo "$storage_info" | awk '$1 == "export" {print $2}')
content=$(echo "$storage_info" | awk '$1 == "content" {print $2}')
show_proxmenux_logo
msg_title "$(translate "Remove NFS Storage")"
if whiptail --yesno "$(translate "Remove Proxmox NFS storage:")\n\n$target\n\n$(translate "Server:"): $server\n$(translate "Export:"): $export_path\n$(translate "Content:"): $content\n\n$(translate "WARNING: This removes the storage from Proxmox. The NFS server is not affected.")" \
16 80 --title "$(translate "Confirm Remove")"; then
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
show_proxmenux_logo
msg_title "$(translate "Remove NFS Storage")"
echo -e ""
msg_success "$(translate "Press Enter to continue...")"
read -r
fi
if pvesm remove "$target" 2>/dev/null; then
msg_ok "$(translate "Storage") $target $(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
;;
fstab)
local mount_path="$target"
local fstab_line
fstab_line=$(awk -v mp="$mount_path" '$2 == mp && ($3 == "nfs" || $3 == "nfs4") {print; exit}' /etc/fstab)
if whiptail --yesno "$(translate "Remove NFS fstab mount:")\n\n$mount_path\n\n$(translate "fstab line:")\n$fstab_line\n\n$(translate "Steps that will run:")\n 1. $(translate "umount the path if currently mounted")\n 2. $(translate "delete the matching line from /etc/fstab")\n 3. $(translate "remove the (now-empty) directory if possible")\n\n$(translate "WARNING: The NFS server is not affected. The mount directory contents are NOT deleted (data stays on the server).")" \
20 90 --title "$(translate "Confirm Remove")"; then
show_proxmenux_logo
msg_title "$(translate "Remove NFS fstab Mount")"
# Try umount only if currently mounted; never force.
if mount | grep -q " on ${mount_path} type "; then
if umount "$mount_path" 2>/dev/null; then
msg_ok "$(translate "Unmounted:") $mount_path"
else
msg_warn "$(translate "Could not unmount") $mount_path. $(translate "The fstab entry will still be removed; reboot or manual umount needed.")"
fi
else
msg_info2 "$(translate "Not currently mounted — skipping umount.")"
fi
# Delete the matching line(s) from /etc/fstab using awk (exact $2 + $3 match).
cp /etc/fstab /etc/fstab.proxmenux.bak 2>/dev/null
if awk -v mp="$mount_path" '
$2 == mp && ($3 == "nfs" || $3 == "nfs4") { next }
{ print }
' /etc/fstab > /etc/fstab.tmp && mv /etc/fstab.tmp /etc/fstab; then
msg_ok "$(translate "Removed entry from /etc/fstab") ($(translate "backup at /etc/fstab.proxmenux.bak"))"
else
msg_error "$(translate "Failed to edit /etc/fstab — remove the line manually.")"
fi
systemctl daemon-reload 2>/dev/null || true
# Try to remove the directory if empty; keep it otherwise.
if [[ -d "$mount_path" ]] && rmdir "$mount_path" 2>/dev/null; then
msg_ok "$(translate "Removed empty mount directory:") $mount_path"
fi
echo -e ""
msg_success "$(translate "Press Enter to continue...")"
read -r
fi
;;
esac
}
test_nfs_connectivity() {
@@ -687,7 +809,7 @@ test_nfs_connectivity() {
local server
server=$(get_storage_config "$storage_id" | awk '$1 == "server" {print $2}')
echo -n " $storage_id ($server): "
echo -n " [pvesm] $storage_id ($server): "
if ping -c 1 -W 2 "$server" >/dev/null 2>&1; then
echo -ne "${GN}$(translate "Reachable")${CL}"
@@ -715,12 +837,46 @@ test_nfs_connectivity() {
echo ""
done <<< "$NFS_STORAGES"
else
echo " $(translate "No NFS storage configured.")"
echo " $(translate "No NFS Proxmox storage configured.")"
fi
else
msg_warn "$(translate "pvesm not available.")"
fi
# ---- fstab-only NFS mounts ----
local FSTAB_ENTRIES
FSTAB_ENTRIES=$(list_nfs_fstab_entries)
echo ""
echo -e "${BOLD}$(translate "Host fstab NFS Mounts:")${CL}"
if [[ -z "$FSTAB_ENTRIES" ]]; then
echo " $(translate "(none)")"
else
while IFS="|" read -r server export_path mount_path opts; do
[[ -z "$mount_path" ]] && continue
echo -n " [fstab] $mount_path ($server:$export_path): "
if ping -c 1 -W 2 "$server" >/dev/null 2>&1; then
echo -ne "${GN}$(translate "Reachable")${CL}"
if nc -z -w 2 "$server" 2049 2>/dev/null; then
echo -e " | NFS port 2049: ${GN}$(translate "Open")${CL}"
else
echo -e " | NFS port 2049: ${RD}$(translate "Closed")${CL}"
fi
else
echo -e "${RD}$(translate "Unreachable")${CL}"
fi
local mstate
mstate=$(check_mount_state "$mount_path")
if [[ "$mstate" == "active" ]]; then
echo -e " $(translate "Mount status:") ${GN}$(translate "Active")${CL}"
else
echo -e " $(translate "Mount status:") ${RD}$(translate "Not currently mounted")${CL}"
fi
echo ""
done <<< "$FSTAB_ENTRIES"
fi
echo ""
msg_success "$(translate "Press Enter to continue...")"
read -r
@@ -735,8 +891,8 @@ while true; do
--title "$(translate "NFS Host Manager - Proxmox Host")" \
--menu "$(translate "Choose an option:")" 18 70 6 \
"1" "$(translate "Mount NFS Share on Host")" \
"2" "$(translate "View NFS Storages")" \
"3" "$(translate "Remove NFS Storage")" \
"2" "$(translate "View NFS Mounts (pvesm + fstab)")" \
"3" "$(translate "Remove NFS Mount (pvesm or fstab)")" \
"4" "$(translate "Test NFS Connectivity")" \
"5" "$(translate "Exit")" \
3>&1 1>&2 2>&3)
+238 -58
View File
@@ -603,28 +603,52 @@ mount_cifs_share() {
read -r
}
# ==========================================================
# FSTAB ENTRY DISCOVERY (host mounts NOT registered with pvesm)
# ==========================================================
# Print every CIFS entry in /etc/fstab as: server|share|mount_path|opts
# Skips comments and blank lines.
list_cifs_fstab_entries() {
awk '
/^[[:space:]]*#/ { next }
/^[[:space:]]*$/ { next }
$3 == "cifs" {
# $1 = //server/share, $2 = mount path, $4 = opts
sub(/^\/\//, "", $1)
split($1, srv_sh, "/")
print srv_sh[1] "|" srv_sh[2] "|" $2 "|" $4
}
' /etc/fstab 2>/dev/null
}
# Echo "active" if the given path is currently mounted, "inactive" otherwise.
check_mount_state() {
local path="$1"
if mount | grep -q " on ${path} type "; then
echo "active"
else
echo "inactive"
fi
}
view_cifs_storages() {
show_proxmenux_logo
msg_title "$(translate "CIFS Storages in Proxmox")"
msg_title "$(translate "CIFS Mounts on Host")"
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
# ---- Proxmox storages (pvesm) ----
local CIFS_STORAGES=""
if command -v pvesm >/dev/null 2>&1; then
CIFS_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "cifs" {print $1, $3}')
fi
CIFS_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "cifs" {print $1, $3}')
if [[ -z "$CIFS_STORAGES" ]]; then
msg_warn "$(translate "No CIFS storage configured in Proxmox.")"
echo ""
msg_info2 "$(translate "Use option 1 to add a Samba share as Proxmox storage.")"
msg_warn "$(translate "No CIFS Proxmox storages configured.")"
else
echo -e "${BOLD}$(translate "CIFS Storages:")${CL}"
echo -e "${BOLD}$(translate "CIFS Proxmox storages (pvesm):")${CL}"
echo ""
while IFS=" " read -r storage_id storage_status; do
[[ -z "$storage_id" ]] && continue
@@ -635,7 +659,7 @@ view_cifs_storages() {
content=$(echo "$storage_info" | awk '$1 == "content" {print $2}')
username=$(echo "$storage_info" | awk '$1 == "username" {print $2}')
echo -e "${TAB}${BOLD}$storage_id${CL}"
echo -e "${TAB}${BOLD}$storage_id${CL} ${TAB}[pvesm]"
echo -e "${TAB} ${BGN}$(translate "Server:")${CL} ${BL}$server${CL}"
echo -e "${TAB} ${BGN}$(translate "Share:")${CL} ${BL}$share${CL}"
echo -e "${TAB} ${BGN}$(translate "Content:")${CL} ${BL}$content${CL}"
@@ -654,63 +678,183 @@ view_cifs_storages() {
done <<< "$CIFS_STORAGES"
fi
# ---- Host fstab mounts ----
local FSTAB_ENTRIES
FSTAB_ENTRIES=$(list_cifs_fstab_entries)
if [[ -z "$FSTAB_ENTRIES" ]]; then
echo -e "${BOLD}$(translate "Host fstab CIFS mounts:")${CL} $(translate "(none)")"
else
echo -e "${BOLD}$(translate "Host fstab CIFS mounts (not registered with pvesm):")${CL}"
echo ""
while IFS="|" read -r server share mount_path opts; do
[[ -z "$mount_path" ]] && continue
local mstate
mstate=$(check_mount_state "$mount_path")
# Detect credentials/guest from opts
local auth_str="Guest"
if echo "$opts" | grep -q "credentials="; then
local cred_file
cred_file=$(echo "$opts" | grep -oE "credentials=[^,]+" | cut -d= -f2)
auth_str="User ($cred_file)"
fi
echo -e "${TAB}${BOLD}$(basename "$mount_path")${CL} ${TAB}[fstab]"
echo -e "${TAB} ${BGN}$(translate "Server:")${CL} ${BL}$server${CL}"
echo -e "${TAB} ${BGN}$(translate "Share:")${CL} ${BL}$share${CL}"
echo -e "${TAB} ${BGN}$(translate "Mount Path:")${CL} ${BL}$mount_path${CL}"
echo -e "${TAB} ${BGN}$(translate "Auth:")${CL} ${BL}$auth_str${CL}"
echo -e "${TAB} ${BGN}$(translate "Options:")${CL} ${BL}$opts${CL}"
if [[ "$mstate" == "active" ]]; then
echo -e "${TAB} ${BGN}$(translate "Status:")${CL} ${GN}$(translate "Active")${CL}"
else
echo -e "${TAB} ${BGN}$(translate "Status:")${CL} ${RD}$(translate "Inactive (entry in fstab, not currently mounted)")${CL}"
fi
echo ""
done <<< "$FSTAB_ENTRIES"
fi
echo ""
msg_success "$(translate "Press Enter to continue...")"
read -r
}
remove_cifs_storage() {
if ! command -v pvesm >/dev/null 2>&1; then
dialog --backtitle "ProxMenux" --title "$(translate "Error")" \
--msgbox "\n$(translate "pvesm not found.")" 8 60
local OPTIONS=()
local has_pvesm=0
local has_fstab=0
# pvesm-registered CIFS storages
if command -v pvesm >/dev/null 2>&1; then
local CIFS_STORAGES
CIFS_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "cifs" {print $1}')
if [[ -n "$CIFS_STORAGES" ]]; then
has_pvesm=1
while IFS= read -r storage_id; do
[[ -z "$storage_id" ]] && continue
local storage_info server share
storage_info=$(get_storage_config "$storage_id")
server=$(echo "$storage_info" | awk '$1 == "server" {print $2}')
share=$(echo "$storage_info" | awk '$1 == "share" {print $2}')
OPTIONS+=("pvesm:$storage_id" "[pvesm] $storage_id ($server/$share)")
done <<< "$CIFS_STORAGES"
fi
fi
# fstab-only CIFS mounts
local FSTAB_ENTRIES
FSTAB_ENTRIES=$(list_cifs_fstab_entries)
if [[ -n "$FSTAB_ENTRIES" ]]; then
has_fstab=1
while IFS="|" read -r server share mount_path opts; do
[[ -z "$mount_path" ]] && continue
OPTIONS+=("fstab:$mount_path" "[fstab] $mount_path ($server/$share)")
done <<< "$FSTAB_ENTRIES"
fi
if [[ "$has_pvesm" == "0" && "$has_fstab" == "0" ]]; then
dialog --backtitle "ProxMenux" --title "$(translate "Nothing to remove")" \
--msgbox "\n$(translate "No CIFS Proxmox storage and no CIFS fstab mount found on this host.")" 9 70
return
fi
CIFS_STORAGES=$(pvesm status 2>/dev/null | awk '$2 == "cifs" {print $1}')
if [[ -z "$CIFS_STORAGES" ]]; then
dialog --backtitle "ProxMenux" --title "$(translate "No CIFS Storage")" \
--msgbox "\n$(translate "No CIFS storage found in Proxmox.")" 8 60
return
fi
OPTIONS=()
while IFS= read -r storage_id; do
[[ -z "$storage_id" ]] && continue
local storage_info server share
storage_info=$(get_storage_config "$storage_id")
server=$(echo "$storage_info" | awk '$1 == "server" {print $2}')
share=$(echo "$storage_info" | awk '$1 == "share" {print $2}')
OPTIONS+=("$storage_id" "$server/$share")
done <<< "$CIFS_STORAGES"
SELECTED=$(dialog --backtitle "ProxMenux" --title "$(translate "Remove CIFS Storage")" \
--menu "$(translate "Select storage to remove:")" 20 80 10 \
local SELECTED
SELECTED=$(dialog --backtitle "ProxMenux" --title "$(translate "Remove CIFS Mount")" \
--menu "$(translate "Select the entry to remove. [pvesm] entries are removed from Proxmox storage; [fstab] entries are unmounted, removed from /etc/fstab and have their credentials file deleted.")" \
20 90 12 \
"${OPTIONS[@]}" 3>&1 1>&2 2>&3)
[[ -z "$SELECTED" ]] && return
local storage_info server share content username
storage_info=$(get_storage_config "$SELECTED")
server=$(echo "$storage_info" | awk '$1 == "server" {print $2}')
share=$(echo "$storage_info" | awk '$1 == "share" {print $2}')
content=$(echo "$storage_info" | awk '$1 == "content" {print $2}')
username=$(echo "$storage_info" | awk '$1 == "username" {print $2}')
local kind="${SELECTED%%:*}"
local target="${SELECTED#*:}"
if whiptail --yesno "$(translate "Remove Proxmox CIFS storage:")\n\n$SELECTED\n\n$(translate "Server:"): $server\n$(translate "Share:"): $share\n$(translate "Content:"): $content\n\n$(translate "WARNING: This removes the storage from Proxmox. The Samba server is not affected.")" \
16 80 --title "$(translate "Confirm Remove")"; then
case "$kind" in
pvesm)
local storage_info server share content username
storage_info=$(get_storage_config "$target")
server=$(echo "$storage_info" | awk '$1 == "server" {print $2}')
share=$(echo "$storage_info" | awk '$1 == "share" {print $2}')
content=$(echo "$storage_info" | awk '$1 == "content" {print $2}')
username=$(echo "$storage_info" | awk '$1 == "username" {print $2}')
show_proxmenux_logo
msg_title "$(translate "Remove CIFS Storage")"
if whiptail --yesno "$(translate "Remove Proxmox CIFS storage:")\n\n$target\n\n$(translate "Server:"): $server\n$(translate "Share:"): $share\n$(translate "Content:"): $content\n\n$(translate "WARNING: This removes the storage from Proxmox. The Samba server is not affected.")" \
16 80 --title "$(translate "Confirm Remove")"; then
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
show_proxmenux_logo
msg_title "$(translate "Remove CIFS Storage")"
echo -e ""
msg_success "$(translate "Press Enter to continue...")"
read -r
fi
if pvesm remove "$target" 2>/dev/null; then
msg_ok "$(translate "Storage") $target $(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
;;
fstab)
local mount_path="$target"
local fstab_line
fstab_line=$(awk -v mp="$mount_path" '$2 == mp && $3 == "cifs" {print; exit}' /etc/fstab)
# Detect credentials= file for cleanup
local cred_file=""
if [[ "$fstab_line" =~ credentials=([^,[:space:]]+) ]]; then
cred_file="${BASH_REMATCH[1]}"
fi
local cred_msg
cred_msg="$(translate "(no credentials file — guest mode)")"
[[ -n "$cred_file" ]] && cred_msg="$(translate "Credentials file:") $cred_file"
if whiptail --yesno "$(translate "Remove CIFS fstab mount:")\n\n$mount_path\n\n$(translate "fstab line:")\n$fstab_line\n\n$cred_msg\n\n$(translate "Steps that will run:")\n 1. $(translate "umount the path if currently mounted")\n 2. $(translate "delete the matching line from /etc/fstab")\n 3. $(translate "delete the credentials file (if any)")\n 4. $(translate "remove the (now-empty) directory if possible")\n\n$(translate "WARNING: The Samba server is not affected. The mount directory contents are NOT deleted.")" \
22 90 --title "$(translate "Confirm Remove")"; then
show_proxmenux_logo
msg_title "$(translate "Remove CIFS fstab Mount")"
if mount | grep -q " on ${mount_path} type "; then
if umount "$mount_path" 2>/dev/null; then
msg_ok "$(translate "Unmounted:") $mount_path"
else
msg_warn "$(translate "Could not unmount") $mount_path. $(translate "The fstab entry will still be removed; reboot or manual umount needed.")"
fi
else
msg_info2 "$(translate "Not currently mounted — skipping umount.")"
fi
# Delete the matching line(s) from /etc/fstab using awk (exact $2 + $3 match).
cp /etc/fstab /etc/fstab.proxmenux.bak 2>/dev/null
if awk -v mp="$mount_path" '
$2 == mp && $3 == "cifs" { next }
{ print }
' /etc/fstab > /etc/fstab.tmp && mv /etc/fstab.tmp /etc/fstab; then
msg_ok "$(translate "Removed entry from /etc/fstab") ($(translate "backup at /etc/fstab.proxmenux.bak"))"
else
msg_error "$(translate "Failed to edit /etc/fstab — remove the line manually.")"
fi
systemctl daemon-reload 2>/dev/null || true
# Remove credentials file if it's under the standard ProxMenux dir
if [[ -n "$cred_file" && -f "$cred_file" && "$cred_file" == /etc/samba/credentials/* ]]; then
rm -f "$cred_file"
msg_ok "$(translate "Removed credentials file:") $cred_file"
fi
if [[ -d "$mount_path" ]] && rmdir "$mount_path" 2>/dev/null; then
msg_ok "$(translate "Removed empty mount directory:") $mount_path"
fi
echo -e ""
msg_success "$(translate "Press Enter to continue...")"
read -r
fi
;;
esac
}
test_samba_connectivity() {
@@ -741,7 +885,7 @@ test_samba_connectivity() {
local server
server=$(get_storage_config "$storage_id" | awk '$1 == "server" {print $2}')
echo -n " $storage_id ($server): "
echo -n " [pvesm] $storage_id ($server): "
if ping -c 1 -W 2 "$server" >/dev/null 2>&1; then
echo -ne "${GN}$(translate "Reachable")${CL}"
@@ -772,12 +916,48 @@ test_samba_connectivity() {
echo ""
done <<< "$CIFS_STORAGES"
else
echo " $(translate "No CIFS storage configured.")"
echo " $(translate "No CIFS Proxmox storage configured.")"
fi
else
msg_warn "$(translate "pvesm not available.")"
fi
# ---- fstab-only CIFS mounts ----
local FSTAB_ENTRIES
FSTAB_ENTRIES=$(list_cifs_fstab_entries)
echo ""
echo -e "${BOLD}$(translate "Host fstab CIFS Mounts:")${CL}"
if [[ -z "$FSTAB_ENTRIES" ]]; then
echo " $(translate "(none)")"
else
while IFS="|" read -r server share mount_path opts; do
[[ -z "$mount_path" ]] && continue
echo -n " [fstab] $mount_path ($server/$share): "
if ping -c 1 -W 2 "$server" >/dev/null 2>&1; then
echo -ne "${GN}$(translate "Reachable")${CL}"
if nc -z -w 2 "$server" 445 2>/dev/null; then
echo -e " | SMB 445: ${GN}$(translate "Open")${CL}"
elif nc -z -w 2 "$server" 139 2>/dev/null; then
echo -e " | NetBIOS 139: ${GN}$(translate "Open")${CL}"
else
echo -e " | SMB ports: ${RD}$(translate "Closed")${CL}"
fi
else
echo -e "${RD}$(translate "Unreachable")${CL}"
fi
local mstate
mstate=$(check_mount_state "$mount_path")
if [[ "$mstate" == "active" ]]; then
echo -e " $(translate "Mount status:") ${GN}$(translate "Active")${CL}"
else
echo -e " $(translate "Mount status:") ${RD}$(translate "Not currently mounted")${CL}"
fi
echo ""
done <<< "$FSTAB_ENTRIES"
fi
echo ""
msg_success "$(translate "Press Enter to continue...")"
read -r
@@ -792,8 +972,8 @@ while true; do
--title "$(translate "Samba Host Manager - Proxmox Host")" \
--menu "$(translate "Choose an option:")" 18 70 6 \
"1" "$(translate "Mount Samba Share on Host")" \
"2" "$(translate "View CIFS Storages")" \
"3" "$(translate "Remove CIFS Storage")" \
"2" "$(translate "View CIFS Mounts (pvesm + fstab)")" \
"3" "$(translate "Remove CIFS Mount (pvesm or fstab)")" \
"4" "$(translate "Test Samba Connectivity")" \
"5" "$(translate "Exit")" \
3>&1 1>&2 2>&3)