From 0d9fc317ca1457dfac73ae522eb17e5ad5e52773 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Tue, 10 Dec 2024 09:06:11 +0100 Subject: [PATCH 1/5] NFSD: show connected clients --- tools/json/config.system.json | 82 +++++++++++++------ .../functions/set_runtime_variables.sh | 4 +- tools/modules/runtime/config.runtime.sh | 1 + .../{network => system}/module_nfsd.sh | 59 ++++++++++++- 4 files changed, 118 insertions(+), 28 deletions(-) rename tools/modules/{network => system}/module_nfsd.sh (62%) diff --git a/tools/json/config.system.json b/tools/json/config.system.json index 13428890..b4d19331 100644 --- a/tools/json/config.system.json +++ b/tools/json/config.system.json @@ -130,33 +130,65 @@ }, { "id": "NFS01", - "description": "Install network filesystem (NFS) daemon", - "command": [ - "module_nfsd install" - ], - "status": "Stable", - "author": "@igorpecovnik", - "condition": "! module_nfsd status" - }, - { - "id": "NFS02", - "description": "Configure network filesystem (NFS) daemon", - "command": [ - "module_nfsd manage" - ], - "status": "Stable", - "author": "@igorpecovnik", - "condition": "module_nfsd status" + "description": "Network filesystem (NFS) Server", + "sub": [ + { + "id": "NFS02", + "description": "Enable network filesystem (NFS) daemon", + "command": [ + "module_nfsd install" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "! module_nfsd status" + }, + { + "id": "NFS03", + "description": "Configure network filesystem (NFS) daemon", + "command": [ + "module_nfsd manage" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_nfsd status" + }, + { + "id": "NFS04", + "description": "Remove network filesystem (NFS) daemon", + "command": [ + "module_nfsd remove" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_nfsd status" + }, + { + "id": "NFS05", + "description": "Show network filesystem (NFS) daemon clients", + "command": [ + "module_nfsd clients" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_nfsd status && [[ ${NFS_CLIENTS_NUMBER} -gt 0 ]]" + } + ] }, { - "id": "NFS03", - "description": "Remove network filesystem (NFS) daemon", - "command": [ - "module_nfsd uninstall" - ], - "status": "Stable", - "author": "@igorpecovnik", - "condition": "module_nfsd status" + "id": "NFS11", + "description": "Network filesystem (NFS) Client", + "sub": [ + { + "id": "NFS06", + "description": "Show network filesystem (NFS) servers in subnet", + "command": [ + "module_nfsd servers" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "" + } + ] } ] }, diff --git a/tools/modules/functions/set_runtime_variables.sh b/tools/modules/functions/set_runtime_variables.sh index 87ca3d26..f2bf6620 100644 --- a/tools/modules/functions/set_runtime_variables.sh +++ b/tools/modules/functions/set_runtime_variables.sh @@ -67,7 +67,9 @@ function set_runtime_variables() { # zfs subsystem - determine if our kernel is not too recent ZFS_DKMS_VERSION=$(LC_ALL=C apt-cache policy zfs-dkms | grep Candidate | xargs | cut -d" " -f2 | cut -c-5) ZFS_KERNEL_MAX=$(wget -qO- https://github.com/openzfs/zfs/raw/refs/tags/zfs-${ZFS_DKMS_VERSION}/META | grep Maximum | cut -d" " -f2) - + # count NFS clients that are connected to the system + NFS_CLIENTS_CONNECTED=($(ss | grep :nfs | awk '{print $NF}' | cut -d":" -f1)) + NFS_CLIENTS_NUMBER="${#NFS_CLIENTS_CONNECTED[@]}" # detect desktop check_desktop diff --git a/tools/modules/runtime/config.runtime.sh b/tools/modules/runtime/config.runtime.sh index abb41396..3edb035a 100644 --- a/tools/modules/runtime/config.runtime.sh +++ b/tools/modules/runtime/config.runtime.sh @@ -96,6 +96,7 @@ fi update_sub_submenu_data "System" "Storage" "SY220" "$(module_zfs zfs_version)" update_sub_submenu_data "System" "Storage" "SY221" "$(module_zfs zfs_installed_version)" +update_sub_submenu_data "System" "Storage" "NFS04" "$NFS_CLIENTS_NUMBER" update_sub_submenu_data "Software" "Database" "DAT002" "Server: $LOCALIPADD" update_sub_submenu_data "Software" "Database" "DAT006" "http://$LOCALIPADD:${module_options["module_phpmyadmin,port"]}" update_sub_submenu_data "Software" "Media" "MED006" "http://$LOCALIPADD:${module_options["module_stirling,port"]}" diff --git a/tools/modules/network/module_nfsd.sh b/tools/modules/system/module_nfsd.sh similarity index 62% rename from tools/modules/network/module_nfsd.sh rename to tools/modules/system/module_nfsd.sh index e18d80b9..78e8fb60 100644 --- a/tools/modules/network/module_nfsd.sh +++ b/tools/modules/system/module_nfsd.sh @@ -2,7 +2,7 @@ module_options+=( ["module_nfsd,author"]="@igorpecovnik" ["module_nfsd,feature"]="module_nfsd" ["module_nfsd,desc"]="Install nfsd server" - ["module_nfsd,example"]="install remove manage add status help" + ["module_nfsd,example"]="install remove manage add status clients servers help" ["module_nfsd,port"]="" ["module_nfsd,status"]="Active" ["module_nfsd,arch"]="" @@ -103,6 +103,61 @@ function module_nfsd () { fi ;; "${commands[5]}") + show_message <<< $(printf '%s\n' "${NFS_CLIENTS_CONNECTED[@]}") + ;; + "${commands[6]}") + LIST=($(nmap -oG - -p2049 ${LOCALSUBNET} | grep '/open/' | cut -d' ' -f2)) + LIST_LENGTH=$((${#LIST[@]})) + if nfs_server=$(dialog --no-items \ + --title "Network filesystem (NFS) servers in subnet" \ + --menu "" \ + $((${LIST_LENGTH} + 6)) \ + 80 \ + $((${LIST_LENGTH})) \ + ${LIST[@]} 3>&1 1>&2 2>&3); then + # verify if we can connect there + LIST=($(showmount -e "${nfs_server}" | tail -n +2 | cut -d" " -f1 | sort)) + VERIFIED_LIST=() + local tempfolder=$(mktemp -d) + local alreadymounted=$(df | grep $nfs_server | cut -d" " -f1 | xargs) + for i in "${LIST[@]}"; do + mount -n -t nfs $nfs_server:$i ${tempfolder} 2>/dev/null + if [[ $? -eq 0 ]]; then + if echo "${alreadymounted}" | grep -vq $i; then + VERIFIED_LIST+=($i) + fi + umount ${tempfolder} + fi + done + VERIFIED_LIST_LENGTH=$((${#VERIFIED_LIST[@]})) + if shares=$(dialog --no-items \ + --title "Network filesystem (NFS) shares on ${nfs_server}" \ + --menu "" \ + $((${VERIFIED_LIST_LENGTH} + 6)) \ + 80 \ + $((${VERIFIED_LIST_LENGTH})) \ + ${VERIFIED_LIST[@]} 3>&1 1>&2 2>&3) + then + if mount_folder=$(dialog --title \ + "Where do you want to mount $shares ?" \ + --inputbox "" \ + 6 80 "/armbian" 3>&1 1>&2 2>&3); then + if mount_options=$(dialog --title \ + "Which mount options do you want to use?" \ + --inputbox "" \ + 6 80 "auto,noatime 0 0" 3>&1 1>&2 2>&3); then + mkdir -p ${mount_folder} + read + sed -i '\?^'$nfs_server:$shares'?d' /etc/fstab + echo "${nfs_server}:${shares} ${mount_folder} nfs ${mount_options}" >> /etc/fstab + systemctl daemon-reload + mount ${mount_options} + fi + fi + fi + fi + ;; + "${commands[7]}") echo -e "\nUsage: ${module_options["module_nfsd,feature"]} " echo -e "Commands: ${module_options["module_nfsd,example"]}" echo "Available commands:" @@ -114,7 +169,7 @@ function module_nfsd () { echo ;; *) - ${module_options["module_nfsd,feature"]} ${commands[5]} + ${module_options["module_nfsd,feature"]} ${commands[7]} ;; esac } From d806ebab31b1258824cae367af67df769422837a Mon Sep 17 00:00:00 2001 From: Dimitry Ishenko Date: Tue, 10 Dec 2024 21:41:08 -0500 Subject: [PATCH 2/5] Add container-aware service wrapper --- tools/modules/functions/service.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tools/modules/functions/service.sh diff --git a/tools/modules/functions/service.sh b/tools/modules/functions/service.sh new file mode 100644 index 00000000..942ba60c --- /dev/null +++ b/tools/modules/functions/service.sh @@ -0,0 +1,17 @@ +# service.sh + +declare -A module_options +module_options+=( + ["service,author"]="@dimitry-ishenko" + ["service,desc"]="Wrapper for service manipulation" + ["service,example"]="service install some.service" + ["service,feature"]="service" + ["service,status"]="active" +) + +function service() +{ + # ignore these commands, if running inside container + [[ "$1" =~ ^(reload|restart|start|status|stop)$ ]] && systemd-detect-virt -qc && return 0 + systemctl "$@" +} From a96be0a9fa3bd54f3f2e306a1227e3ea301ba964 Mon Sep 17 00:00:00 2001 From: Dimitry Ishenko Date: Tue, 10 Dec 2024 21:43:17 -0500 Subject: [PATCH 3/5] nfsd: work inside container --- tools/modules/system/module_nfsd.sh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tools/modules/system/module_nfsd.sh b/tools/modules/system/module_nfsd.sh index 78e8fb60..7bd700df 100644 --- a/tools/modules/system/module_nfsd.sh +++ b/tools/modules/system/module_nfsd.sh @@ -14,6 +14,9 @@ function module_nfsd () { local title="nfsd" local condition=$(which "$title" 2>/dev/null)? + local package_name=nfs-kernel-server + local service_name=nfs-server.service + # we will store our config in subfolder mkdir -p /etc/exports.d/ @@ -24,13 +27,13 @@ function module_nfsd () { case "$1" in "${commands[0]}") - apt_install_wrapper apt-get -y install nfs-common nfs-kernel-server + apt_install_wrapper apt-get -y install $package_name # add some exports ${module_options["module_nfsd,feature"]} ${commands[2]} - systemctl restart nfs-server.service + service restart $service_name ;; "${commands[1]}") - apt_install_wrapper apt-get -y autopurge nfs-kernel-server + apt_install_wrapper apt-get -y autopurge $package_name ;; "${commands[2]}") while true; do @@ -65,7 +68,7 @@ function module_nfsd () { break fi done - systemctl restart nfs-server.service + service restart $service_name ;; "${commands[3]}") # choose between most common options @@ -96,11 +99,7 @@ function module_nfsd () { fi ;; "${commands[4]}") - if systemctl is-active --quiet nfs-server.service; then - return 0 - else - return 1 - fi + check_if_installed $package_name ;; "${commands[5]}") show_message <<< $(printf '%s\n' "${NFS_CLIENTS_CONNECTED[@]}") @@ -169,7 +168,7 @@ function module_nfsd () { echo ;; *) - ${module_options["module_nfsd,feature"]} ${commands[7]} + ${module_options["module_nfsd,feature"]} ${commands[7]} ;; esac } From 000c8edbc1ad4de42c72b4afa66015eef6e93f0d Mon Sep 17 00:00:00 2001 From: Dimitry Ishenko Date: Wed, 11 Dec 2024 00:29:24 -0500 Subject: [PATCH 4/5] nfsd: fix uninstall command --- tools/json/config.system.json | 44 +++++++++--- tools/modules/functions/service.sh | 1 + tools/modules/system/module_nfs.sh | 101 ++++++++++++++++++++++++++++ tools/modules/system/module_nfsd.sh | 7 +- 4 files changed, 141 insertions(+), 12 deletions(-) create mode 100644 tools/modules/system/module_nfs.sh diff --git a/tools/json/config.system.json b/tools/json/config.system.json index b4d19331..e22d4df6 100644 --- a/tools/json/config.system.json +++ b/tools/json/config.system.json @@ -130,10 +130,31 @@ }, { "id": "NFS01", - "description": "Network filesystem (NFS) Server", + "description": "Enable Network filesystem (NFS) support", + "command": [ + "module_nfs install" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "! check_if_installed nfs-common" + }, + { + "id": "NFS02", + "description": "Disable Network filesystem (NFS) support", + "command": [ + "module_nfs remove" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "check_if_installed nfs-common" + }, + { + "id": "NFS05", + "description": "Manage NFS Server", + "condition": "check_if_installed nfs-common", "sub": [ { - "id": "NFS02", + "id": "NFS06", "description": "Enable network filesystem (NFS) daemon", "command": [ "module_nfsd install" @@ -143,7 +164,7 @@ "condition": "! module_nfsd status" }, { - "id": "NFS03", + "id": "NFS07", "description": "Configure network filesystem (NFS) daemon", "command": [ "module_nfsd manage" @@ -153,7 +174,7 @@ "condition": "module_nfsd status" }, { - "id": "NFS04", + "id": "NFS08", "description": "Remove network filesystem (NFS) daemon", "command": [ "module_nfsd remove" @@ -163,7 +184,7 @@ "condition": "module_nfsd status" }, { - "id": "NFS05", + "id": "NFS09", "description": "Show network filesystem (NFS) daemon clients", "command": [ "module_nfsd clients" @@ -175,18 +196,19 @@ ] }, { - "id": "NFS11", - "description": "Network filesystem (NFS) Client", + "id": "NFS20", + "description": "Manage NFS Client", + "condition": "check_if_installed nfs-common", "sub": [ { - "id": "NFS06", - "description": "Show network filesystem (NFS) servers in subnet", + "id": "NFS21", + "description": "Find NFS servers in subnet and mount shares", "command": [ - "module_nfsd servers" + "module_nfs servers" ], "status": "Stable", "author": "@igorpecovnik", - "condition": "" + "condition": "check_if_installed nfs-common" } ] } diff --git a/tools/modules/functions/service.sh b/tools/modules/functions/service.sh index 942ba60c..30290bbf 100644 --- a/tools/modules/functions/service.sh +++ b/tools/modules/functions/service.sh @@ -13,5 +13,6 @@ function service() { # ignore these commands, if running inside container [[ "$1" =~ ^(reload|restart|start|status|stop)$ ]] && systemd-detect-virt -qc && return 0 + systemctl daemon-reload systemctl "$@" } diff --git a/tools/modules/system/module_nfs.sh b/tools/modules/system/module_nfs.sh new file mode 100644 index 00000000..c9cb113d --- /dev/null +++ b/tools/modules/system/module_nfs.sh @@ -0,0 +1,101 @@ +module_options+=( + ["module_nfs,author"]="@igorpecovnik" + ["module_nfs,feature"]="module_nfs" + ["module_nfs,desc"]="Install nfs client" + ["module_nfs,example"]="install remove servers help" + ["module_nfs,port"]="" + ["module_nfs,status"]="Active" + ["module_nfs,arch"]="" +) +# +# Module nfs client +# +function module_nfs () { + local title="nfs" + local condition=$(which "$title" 2>/dev/null)? + + local package_name=nfs-common + + local commands + IFS=' ' read -r -a commands <<< "${module_options["module_nfs,example"]}" + + nfs_BASE="${SOFTWARE_FOLDER}/nfs" + + case "$1" in + "${commands[0]}") + apt_install_wrapper apt-get -y install $package_name + ;; + "${commands[1]}") + apt_install_wrapper apt-get -y autopurge $package_name + ;; + "${commands[2]}") + + if ! check_if_installed nmap; then + apt_install_wrapper apt-get -y install nmap + fi + + LIST=($(nmap -oG - -p2049 ${LOCALSUBNET} | grep '/open/' | cut -d' ' -f2 | grep -v "${LOCALIPADD}")) + LIST_LENGTH=$((${#LIST[@]})) + if nfs_server=$(dialog --no-items \ + --title "Network filesystem (NFS) servers in subnet" \ + --menu "" \ + $((${LIST_LENGTH} + 6)) \ + 80 \ + $((${LIST_LENGTH})) \ + ${LIST[@]} 3>&1 1>&2 2>&3); then + # verify if we can connect there + LIST=($(showmount -e "${nfs_server}" | tail -n +2 | cut -d" " -f1 | sort)) + VERIFIED_LIST=() + local tempfolder=$(mktemp -d) + local alreadymounted=$(df | grep $nfs_server | cut -d" " -f1 | xargs) + for i in "${LIST[@]}"; do + mount -n -t nfs $nfs_server:$i ${tempfolder} 2>/dev/null + if [[ $? -eq 0 ]]; then + if echo "${alreadymounted}" | grep -vq $i; then + VERIFIED_LIST+=($i) + fi + umount ${tempfolder} + fi + done + VERIFIED_LIST_LENGTH=$((${#VERIFIED_LIST[@]})) + if shares=$(dialog --no-items \ + --title "Network filesystem (NFS) shares on ${nfs_server}" \ + --menu "" \ + $((${VERIFIED_LIST_LENGTH} + 6)) \ + 80 \ + $((${VERIFIED_LIST_LENGTH})) \ + ${VERIFIED_LIST[@]} 3>&1 1>&2 2>&3) + then + if mount_folder=$(dialog --title \ + "Where do you want to mount $shares ?" \ + --inputbox "" \ + 6 80 "/armbian" 3>&1 1>&2 2>&3); then + if mount_options=$(dialog --title \ + "Which mount options do you want to use?" \ + --inputbox "" \ + 6 80 "auto,noatime 0 0" 3>&1 1>&2 2>&3); then + mkdir -p ${mount_folder} + sed -i '\?^'$nfs_server:$shares'?d' /etc/fstab + echo "${nfs_server}:${shares} ${mount_folder} nfs ${mount_options}" >> /etc/fstab + systemctl daemon-reload + mount ${mount_folder} + show_message <<< $(mount -t nfs4 | cut -d" " -f1) + fi + fi + fi + fi + ;; + "${commands[3]}") + echo -e "\nUsage: ${module_options["module_nfs,feature"]} " + echo -e "Commands: ${module_options["module_nfs,example"]}" + echo "Available commands:" + echo -e "\tinstall\t- Install $title." + echo -e "\tremove\t- Remove $title." + echo -e "\tservers\t- Find and mount shares $title." + echo + ;; + *) + ${module_options["module_nfs,feature"]} ${commands[3]} + ;; + esac +} diff --git a/tools/modules/system/module_nfsd.sh b/tools/modules/system/module_nfsd.sh index 7bd700df..6d09f904 100644 --- a/tools/modules/system/module_nfsd.sh +++ b/tools/modules/system/module_nfsd.sh @@ -105,7 +105,12 @@ function module_nfsd () { show_message <<< $(printf '%s\n' "${NFS_CLIENTS_CONNECTED[@]}") ;; "${commands[6]}") - LIST=($(nmap -oG - -p2049 ${LOCALSUBNET} | grep '/open/' | cut -d' ' -f2)) + + if ! check_if_installed nmap; then + apt_install_wrapper apt-get -y install nmap + fi + + LIST=($(nmap -oG - -p2049 ${LOCALSUBNET} | grep '/open/' | cut -d' ' -f2 | grep -v "${LOCALIPADD}")) LIST_LENGTH=$((${#LIST[@]})) if nfs_server=$(dialog --no-items \ --title "Network filesystem (NFS) servers in subnet" \ From 3a8d95825e8e403cdf6fb6c8e8610cf47b2dfa1f Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Fri, 20 Dec 2024 11:19:20 +0100 Subject: [PATCH 5/5] Replace check_if_installed --- tools/json/config.system.json | 10 +++++----- tools/modules/system/module_nfs.sh | 10 ++++------ tools/modules/system/module_nfsd.sh | 6 +++--- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/tools/json/config.system.json b/tools/json/config.system.json index 930a6958..41e13e31 100644 --- a/tools/json/config.system.json +++ b/tools/json/config.system.json @@ -136,7 +136,7 @@ ], "status": "Stable", "author": "@igorpecovnik", - "condition": "! check_if_installed nfs-common" + "condition": "! pkg_installed nfs-common" }, { "id": "NFS02", @@ -146,12 +146,12 @@ ], "status": "Stable", "author": "@igorpecovnik", - "condition": "check_if_installed nfs-common" + "condition": "pkg_installed nfs-common" }, { "id": "NFS05", "description": "Manage NFS Server", - "condition": "check_if_installed nfs-common", + "condition": "pkg_installed nfs-common", "sub": [ { "id": "NFS06", @@ -198,7 +198,7 @@ { "id": "NFS20", "description": "Manage NFS Client", - "condition": "check_if_installed nfs-common", + "condition": "pkg_installed nfs-common", "sub": [ { "id": "NFS21", @@ -208,7 +208,7 @@ ], "status": "Stable", "author": "@igorpecovnik", - "condition": "check_if_installed nfs-common" + "condition": "pkg_installed nfs-common" } ] } diff --git a/tools/modules/system/module_nfs.sh b/tools/modules/system/module_nfs.sh index c9cb113d..f5cfa13d 100644 --- a/tools/modules/system/module_nfs.sh +++ b/tools/modules/system/module_nfs.sh @@ -14,8 +14,6 @@ function module_nfs () { local title="nfs" local condition=$(which "$title" 2>/dev/null)? - local package_name=nfs-common - local commands IFS=' ' read -r -a commands <<< "${module_options["module_nfs,example"]}" @@ -23,15 +21,15 @@ function module_nfs () { case "$1" in "${commands[0]}") - apt_install_wrapper apt-get -y install $package_name + pkg_install nfs-common ;; "${commands[1]}") - apt_install_wrapper apt-get -y autopurge $package_name + pkg_remove nfs-common ;; "${commands[2]}") - if ! check_if_installed nmap; then - apt_install_wrapper apt-get -y install nmap + if ! pkg_installed nmap; then + pkg_install nmap fi LIST=($(nmap -oG - -p2049 ${LOCALSUBNET} | grep '/open/' | cut -d' ' -f2 | grep -v "${LOCALIPADD}")) diff --git a/tools/modules/system/module_nfsd.sh b/tools/modules/system/module_nfsd.sh index 48ec62b4..9f143b2a 100644 --- a/tools/modules/system/module_nfsd.sh +++ b/tools/modules/system/module_nfsd.sh @@ -98,15 +98,15 @@ function module_nfsd () { fi ;; "${commands[4]}") - check_if_installed nfs-kernel-server + pkg_installed nfs-kernel-server ;; "${commands[5]}") show_message <<< $(printf '%s\n' "${NFS_CLIENTS_CONNECTED[@]}") ;; "${commands[6]}") - if ! check_if_installed nmap; then - apt_install_wrapper apt-get -y install nmap + if ! pkg_installed nmap; then + pkg_install nmap fi LIST=($(nmap -oG - -p2049 ${LOCALSUBNET} | grep '/open/' | cut -d' ' -f2 | grep -v "${LOCALIPADD}"))