diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index ca6dbea45..9ca4cedcb 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -167,4 +167,4 @@ jobs: echo "# Succesful tests:" >> $GITHUB_STEP_SUMMARY echo "|Release|Command|Description|" >> $GITHUB_STEP_SUMMARY echo "|:---|:---|:---|" >> $GITHUB_STEP_SUMMARY - cat ./*.teststats | sed '$ s/.$//' >> $GITHUB_STEP_SUMMARY + cat ./*.teststats | sed '$ s/.$//' >> $GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/bin/armbian-config b/bin/armbian-config index 30590e663..804ec93d5 100755 --- a/bin/armbian-config +++ b/bin/armbian-config @@ -24,9 +24,6 @@ lib_dir="$script_dir/../lib/armbian-config" doc_dir="$script_dir/../share/doc/armbian-config" json_file="$lib_dir/config.jobs.json" -# -# Load The Bash procedure Objects -json_data=$(<"$json_file") # # Prepare the module options array @@ -37,7 +34,7 @@ declare -A module_options source "$lib_dir/config.functions.sh" set_runtime_variables -check_distro_status +#check_distro_status echo "Loaded Runtime variables..." #| show_infobox ; #set_newt_colors 2 echo "Loaded Dialog..." #| show_infobox ; @@ -52,9 +49,32 @@ echo "Loaded Software helpers..." #| show_infobox ; # # Loads the variables from beta armbian-config for runtime handling -source "$lib_dir/config.runtime.sh" + +# +# Load The Bash procedure Objects +old_json_data=$(<"$json_file") + +# Generate the new JSON data +new_json_data=$(generate_software_json) + +json_data=$(jq -s ' + .[0] as $existing | + .[1] as $new | + { + menu: ($existing.menu + $new.menu) + } +' <(echo "$old_json_data") <(echo "$new_json_data")) + + +#source "$lib_dir/config.runtime.sh" echo "Loaded Runtime conditions..." #| show_infobox ; + + + + + + clear case "$1" in diff --git a/generate_json_data.sh b/generate_json_data.sh new file mode 100644 index 000000000..12f0cc98e --- /dev/null +++ b/generate_json_data.sh @@ -0,0 +1,194 @@ + + + +function set_json_data() { + local i=0 + + features=() + for key in "${!module_options[@]}"; do + if [[ $key == *",feature" ]]; then + features+=("${module_options[$key]}") + fi + done + +{ + echo -e "[" + + for feature in "${features[@]}"; do + feature_prefix=$(echo "${feature:0:3}" | tr '[:lower:]' '[:upper:]') # Extract first 3 letters and convert to uppercase + + i=$((i + 1)) + id=$(printf "%s%03d" "$feature_prefix" "$i") # Combine prefix with padded number + + # Get keys pairs + desc_key="${feature},desc" + example_key="${feature},example" + author_key="${feature},author" + ref_key="${feature},ref_link" + status_key="${feature},status" + doc_key="${feature},doc_link" + helpers_key="${feature},helpers" + group_key="${feature},group" + commands_key="${feature},commands" + port_key="${feature},port" + arch_key="${feature},arch" + + # Get array info + author="${module_options[$author_key]}" + ref_link="${module_options[$ref_key]}" + status="${module_options[$status_key]}" + doc_link="${module_options[$doc_key]}" + desc="${module_options[$desc_key]}" + example="${module_options[$example_key]}" + helpers="${module_options[$helpers_key]}" + group="${module_options[$group_key]}" + commands="${module_options[$commands_key]}" + port="${module_options[$port_key]}" + arch="${module_options[$arch_key]}" + + echo " {" + echo " \"id\": \"$id\"," + echo " \"feature\": \"$feature\"," + echo " \"helpers\": \"$helpers\"," + echo " \"description\": \"$desc ($feature)\"," + echo " \"command\": \"$feature\"," + echo " \"options\": \"$example\"," + echo " \"status\": \"$status\"," + echo " \"condition\": \" \"," + echo " \"reference\": \"$ref_link\"," + echo " \"author\": \"$author\"," + echo " \"group\": \"$group\"," + echo " \"commands\": \"$commands\"," + echo " \"port\": \"$port\"," + echo " \"arch\": \"$arch\"" + + if [ $i -ne ${#features[@]} ]; then + echo " }," + else + echo " }" + fi + done + echo "]" + +} | jq . + +} + + +function generate_module_list() { + set_json_data | jq ' + # Define an array of allowed software groups + def softwareGroups: ["WebHosting", "Netconfig", "Downloaders", "Database", "DNS", "DevTools", "HomeAutomation", "Benchy", "Containers", "Media", "Monitoring", "Management"]; + + { + "menu": [ + { + "id": "Software", + "description": "Run/Install 3rd party applications", + "sub": ( + group_by(.group) + # Skip grouped arrays where the group is null, empty, or not in softwareGroups + | map(select(.[0].group != null and .[0].group != "" and (.[0].group | IN(softwareGroups[])))) + | map({ + "id": .[0].group, + "description": .[0].group, + "sub": ( + map({ + "id": .id, + "description": .description, + "command": [("see_menu " + .feature)], + "options": ("help " + .options + " status"), + "status": .status, + "condition": "", + "author": .author + }) + ) + }) + ) + } + ] + } + ' + } + + +function generate_json_data() { + set_json_data | jq '{ + "menu": [ + { + "id": "tests", + "description": "Run/Install 3rd party applications", + "sub": [ + { + "id": "Modules", + "description": "Various installable modules", + "sub": [ + .[] | + if (.feature | type == "string") and (.feature | startswith("module_")) then + { + "id": .id, + "description": .description, + "command": [("see_menu " + .feature)], + "options": ("help " + .options + " status"), + "status": .status, + "condition": "", + "author": .author + } + else empty + end + ] + } + ] + } + ] + }' + +} + + +# Test Function +interface_json_data_old() { + + # uncomment to set the data to a file + set_json_data | jq --tab --indent 4 '.' > tools/json/config.temp.json + #generate_json_data | jq --indent 4 "." > tools/json/config.temp.json + #json_file="$tools_dir/json/config.temp.json + + json_data=$(generate_json_data) + #generate_top_menu "$json_data" + + generate_menu "Software" "$json_data" +} + + +# Test Function +interface_json_data() { + # Convert the example string to an array + local commands=("raw" "mnu" "top" "sub" "help") + json_data=$(generate_json_data) + case "$1" in + + "${commands[0]}") + echo "Setting JSON data to file..." + set_json_data | jq --tab --indent 4 '.' > tools/json/config.temp.json + ;; + "${commands[1]}") + echo "Generating JSON data..." + generate_json_data | jq --tab --indent 4 '.' > tools/json/config.temp.json + ;; + "${commands[2]}") + generate_top_menu "$json_data" + ;; + "${commands[3]}") + generate_menu "Software" "$json_data" + ;; + "${commands[-1]}") + echo "Usage: interface_json_data " + echo "Available commands:" + echo -e "\traw\t- Set flat JSON data to a file for inspection not used" + echo -e "\tmnu\t- Generate the Menu JSON data to file for inspection not used" + echo -e "\ttop\t- Show the top menu using the JSON data." + echo -e "\tsub\t- Show the Software menu using the JSON data." + ;; + esac +} diff --git a/tests/CON002.conf b/tests/CON002.conf index 57f7cf42e..ad3b1e7cd 100644 --- a/tests/CON002.conf +++ b/tests/CON002.conf @@ -1,3 +1,3 @@ -ENABLED=true +ENABLED=false RELEASE="bookworm:jammy:noble" CONDITION="docker run hello-world" diff --git a/tests/CON005.conf b/tests/CON005.conf index 0493851cb..b017aed30 100644 --- a/tests/CON005.conf +++ b/tests/CON005.conf @@ -1,3 +1,3 @@ -ENABLED=true +ENABLED=false RELEASE="bookworm:jammy:noble" CONDITION="test=\$(docker container ls -a | grep portainer )" diff --git a/tests/HAB001.conf b/tests/HAB001.conf index af065d462..58e61ef31 100644 --- a/tests/HAB001.conf +++ b/tests/HAB001.conf @@ -1,2 +1,2 @@ -ENABLED=true +ENABLED=false CONDITION="[ -f /lib/systemd/system/openhab.service ]" diff --git a/tests/MAN001.conf b/tests/MAN001.conf index 7fb6f613e..c0e79f80f 100644 --- a/tests/MAN001.conf +++ b/tests/MAN001.conf @@ -1,2 +1,2 @@ -ENABLED=true +ENABLED=false CONDITION="[ -f /usr/bin/cockpit-bridge ]" diff --git a/tests/MON001.conf b/tests/MON001.conf index d8a5c0e39..5c4700adc 100644 --- a/tests/MON001.conf +++ b/tests/MON001.conf @@ -1,3 +1,3 @@ -ENABLED=true +ENABLED=false RELEASE="bookworm:jammy:noble" CONDITION="test=\$(docker container ls -a | grep uptime-kuma )" diff --git a/tests/SY008.conf b/tests/SY008.conf index 50d6d2118..c29bc036e 100644 --- a/tests/SY008.conf +++ b/tests/SY008.conf @@ -1,3 +1,3 @@ -ENABLED=true +ENABLED=false PREINSTALL="bash bin/armbian-config --cmd SY009" CONDITION="[ ! -f /usr/bin/zsh ]" diff --git a/tests/SY101.conf b/tests/SY101.conf index 6c6ecbea0..a5d252f7a 100644 --- a/tests/SY101.conf +++ b/tests/SY101.conf @@ -1,2 +1,2 @@ -ENABLED=true +ENABLED=false RELEASE="jammy:bullseye" diff --git a/tests/SY102.conf b/tests/SY102.conf index f1b50ac98..2c70f403b 100644 --- a/tests/SY102.conf +++ b/tests/SY102.conf @@ -1,2 +1,2 @@ -ENABLED=true +ENABLED=false RELEASE="bullseye:bookworm:trixie:jammy:noble" diff --git a/tests/SY202.conf b/tests/SY202.conf index 8bd7d091c..421296f1b 100644 --- a/tests/SY202.conf +++ b/tests/SY202.conf @@ -1 +1 @@ -ENABLED=true +ENABLED=false diff --git a/tests/SY203.conf b/tests/SY203.conf index 8bd7d091c..421296f1b 100644 --- a/tests/SY203.conf +++ b/tests/SY203.conf @@ -1 +1 @@ -ENABLED=true +ENABLED=false diff --git a/tests/SY206.conf b/tests/SY206.conf index 8bd7d091c..421296f1b 100644 --- a/tests/SY206.conf +++ b/tests/SY206.conf @@ -1 +1 @@ -ENABLED=true +ENABLED=false diff --git a/tests/SY207.conf b/tests/SY207.conf index 8bd7d091c..421296f1b 100644 --- a/tests/SY207.conf +++ b/tests/SY207.conf @@ -1 +1 @@ -ENABLED=true +ENABLED=false diff --git a/tools/json/config.help.json b/tools/json/config.help.json deleted file mode 100644 index 3cdb463c3..000000000 --- a/tools/json/config.help.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "menu": [ - { - "id": "Help", - "description": "About this tool", - "sub": [ - { - "id": "HE001", - "description": "Contribute", - "command": [ - "show_message <<< $(about_armbian_configng)" - ], - "status": "Stable", - "author": "@armbian" - }, - { - "id": "HE002", - "description": "List of Config function(WIP)", - "command": [ - "show_message <<< see_use" - ], - "status": "Disabled", - "author": "@armbian" - } - ] - } - ] -} diff --git a/tools/json/config.software.json b/tools/json/config.software.json index 05e0e9587..b1d9d6677 100644 --- a/tools/json/config.software.json +++ b/tools/json/config.software.json @@ -1,7 +1,7 @@ { "menu": [ { - "id": "Software", + "id": "Software00", "description": "Run/Install 3rd party applications", "sub": [ { diff --git a/tools/json/config.temp.json b/tools/json/config.temp.json index 0cfe9d78b..9a856db4b 100644 --- a/tools/json/config.temp.json +++ b/tools/json/config.temp.json @@ -1,48 +1,1431 @@ { "menu": [ { - "id": "Template", - "description": "Description ... ", + "id": "Software00", + "description": "Run/Install 3rd party applications", "sub": [ { - "id": "UID01", - "description": "Description ... ", - "prompt": "", + "id": "WebHosting", + "description": "Web server, LEMP, reverse proxy, Let's Encrypt SSL", + "status": "Stable", "sub": [ { - "id": "SUB02", - "description": "Description ... ", + "id": "SWAG01", + "description": "SWAG reverse proxy install", "command": [ - "show_message <<< \" Message ... \"" + "module_swag install" ], - "status": "", - "author": "Github Username", - "condition": "" + "status": "Stable", + "author": "@armbian", + "condition": "! module_swag status" + }, + { + "id": "SWAG02", + "description": "SWAG reverse proxy .htpasswd set", + "command": [ + "module_swag password" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_swag status" + }, + { + "id": "SWAG03", + "description": "SWAG remove", + "command": [ + "module_swag remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_swag status" + }, + { + "id": "SWAG04", + "description": "SWAG purge with data folder", + "command": [ + "module_swag purge" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_swag status" } ] }, { - "id": "UID03", - "description": "Description ... ", - "command": [ - "show_message <<< \" Message ... \"" - ], - "status": "", - "author": "Github Username", - "condition": "" + "id": "HomeAutomation", + "description": "Home Automation for monitoring and/or control home appliances", + "sub": [ + { + "id": "HAB001", + "description": "openHAB empowering the smart home", + "about": "This operation will install openHAB.", + "command": [ + "module_openhab install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_openhab status" + }, + { + "id": "HAB002", + "description": "openHAB remove", + "about": "This operation will purge openHAB.", + "command": [ + "module_openhab remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_openhab status" + }, + { + "id": "HAB003", + "description": "openHAB purge with data folder", + "about": "This operation will purge openHAB.", + "command": [ + "module_openhab purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_openhab status" + }, + { + "id": "HAS001", + "description": "Home Assistant open source home automation", + "about": "This operation will install Home Assistant.", + "command": [ + "module_haos install" + ], + "status": "Preview", + "author": "@igorpecovnik", + "condition": "! module_haos status && grep -q bookworm /etc/os-release" + }, + { + "id": "HAS002", + "description": "Home Assistant remove", + "about": "This operation will remove Home Assistant.", + "command": [ + "module_haos remove" + ], + "status": "Preview", + "author": "@igorpecovnik", + "condition": "module_haos status" + }, + { + "id": "HAS003", + "description": "Home Assistant purge with data folder", + "about": "This operation will purge Home Assistant.", + "command": [ + "module_haos purge" + ], + "status": "Preview", + "author": "@igorpecovnik", + "condition": "module_haos status" + } + ] + }, + { + "id": "DNS", + "description": "Network-wide ad blockers servers", + "sub": [ + { + "id": "DNS001", + "description": "Pi-hole DNS ad blocker install", + "command": [ + "module_pi_hole install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_pi_hole status" + }, + { + "id": "DNS003", + "description": "Pi-hole remove", + "command": [ + "module_pi_hole remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_pi_hole status" + }, + { + "id": "DNS002", + "description": "Pi-hole change web admin password", + "command": [ + "module_pi_hole password" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_pi_hole status" + }, + { + "id": "DNS004", + "description": "Pi-hole purge", + "command": [ + "module_pi_hole remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_pi_hole status" + } + ] + }, + { + "id": "Desktops", + "description": "Desktop Environments", + "status": "Disabled", + "sub": [ + { + "id": "XFCE", + "description": "XFCE desktop", + "status": "Disabled", + "sub": [ + { + "id": "XFCE01", + "about": "Install XFCE:\nXfce is a lightweight desktop environment for UNIX-like operating systems. It aims to be fast and low on system resources, while still being visually appealing and user friendly.", + "description": "XFCE desktop Install", + "command": [ + "manage_desktops 'xfce' 'install'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ ! -f /usr/share/xsessions/xfce.desktop ]" + }, + { + "id": "XFCE02", + "description": "Uninstall", + "command": [ + "manage_desktops 'xfce' 'uninstall'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/xfce.desktop ]" + }, + { + "id": "XFCE03", + "description": "Enable autologin", + "command": [ + "manage_desktops 'xfce' 'auto'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/xfce.desktop ] && [ ! -f /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf ]" + }, + { + "id": "XFCE04", + "description": "Disable autologin", + "command": [ + "manage_desktops 'xfce' 'manual'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/xfce.desktop ] && [ -f /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf ]" + } + ] + }, + { + "id": "Gnome", + "description": "Gnome desktop", + "status": "Disabled", + "sub": [ + { + "id": "GNOME01", + "description": "Gnome desktop Install", + "command": [ + "manage_desktops 'gnome' 'install'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ ! -f /usr/share/xsessions/gnome.desktop ]" + }, + { + "id": "GNOME02", + "description": "Uninstall", + "command": [ + "manage_desktops 'gnome' 'uninstall'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/gnome.desktop ]" + }, + { + "id": "GNOME03", + "description": "Enable autologin", + "command": [ + "manage_desktops 'gnome' 'auto'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/gnome.desktop ] && ! cat /etc/gdm3/custom.conf 2>/dev/null | grep AutomaticLoginEnable | grep true >/dev/null" + }, + { + "id": "GNOME04", + "description": "Disable autologin", + "command": [ + "manage_desktops 'gnome' 'manual'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/gnome.desktop ] && cat /etc/gdm3/custom.conf 2>/dev/null | grep AutomaticLoginEnable | grep true >/dev/null" + } + ] + }, + { + "id": "I3WM", + "description": "i3-wm desktop", + "status": "Disabled", + "sub": [ + { + "id": "I3WM01", + "description": "i3 desktop Install", + "command": [ + "manage_desktops 'i3-wm' 'install'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ ! -f /usr/share/xsessions/i3.desktop ]" + }, + { + "id": "I3WM02", + "description": "i3 desktop uninstall", + "command": [ + "manage_desktops 'i3-wm' 'uninstall'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/i3.desktop ]" + }, + { + "id": "I3WM03", + "description": "Enable autologin", + "command": [ + "manage_desktops 'i3-wm' 'auto'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/i3.desktop ] && [ ! -f /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf ]" + }, + { + "id": "I3WM04", + "description": "Disable autologin", + "command": [ + "manage_desktops 'i3-wm' 'manual'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/i3.desktop ] && [ -f /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf ]" + } + ] + }, + { + "id": "Cinnamon", + "description": "Cinnamon desktop", + "status": "Disabled", + "sub": [ + { + "id": "CINNAMON01", + "description": "Cinnamon desktop Install", + "command": [ + "manage_desktops 'cinnamon' 'install'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ ! -f /usr/share/xsessions/cinnamon.desktop ] && [ ! -f /usr/share/xsessions/cinnamon2d.desktop ]" + }, + { + "id": "CINNAMON02", + "description": "Cinnamon desktop uninstall", + "command": [ + "manage_desktops 'cinnamon' 'uninstall'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/cinnamon.desktop ] || [ -f /usr/share/xsessions/cinnamon2d.desktop ]" + }, + { + "id": "CINNAMON03", + "description": "Enable autologin", + "command": [ + "manage_desktops 'cinnamon' 'auto'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/cinnamon.desktop ] && [ ! -f /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf ]" + }, + { + "id": "CINNAMON04", + "description": "Disable autologin", + "command": [ + "manage_desktops 'cinnamon' 'manual'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/cinnamon.desktop ] && [ -f /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf ]" + } + ] + }, + { + "id": "KDEN", + "description": "Kde-neon desktop", + "status": "Disabled", + "sub": [ + { + "id": "KDENEON01", + "description": "Kde-neon desktop Install", + "command": [ + "manage_desktops 'kde-neon' 'install'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ ! -f /usr/share/xsessions/gnome.desktop ]" + }, + { + "id": "KDENEON02", + "description": "Uninstall", + "command": [ + "manage_desktops 'kde-neon' 'uninstall'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/gnome.desktop ]" + }, + { + "id": "KDENEON03", + "description": "Enable autologin", + "command": [ + "manage_desktops 'kde-neon' 'auto'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/gnome.desktop ] && [ ! -f /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf ]" + }, + { + "id": "KDENEON04", + "description": "Disable autologin", + "command": [ + "manage_desktops 'kde-neon' 'manual'" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "[ -f /usr/share/xsessions/gnome.desktop ] && [ -f /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf ]" + } + ] + }, + { + "id": "Xapian", + "description": "Improve application search speed", + "command": [ + "update-apt-xapian-index -u; sleep 3" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "systemctl is-active --quiet service display-manager" + } + ] + }, + { + "id": "Downloaders", + "description": "P2P download managers for movies, TV shows, music and subtitles", + "sub": [ + { + "id": "DOW001", + "description": "qBittorrent BitTorrent server ", + "about": "This operation will install qBittorrent BitTorrent server", + "command": [ + "module_qbittorrent install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_qbittorrent status" + }, + { + "id": "DOW002", + "description": "qBittorrent remove", + "about": "This operation will remove qBittorrent BitTorrent server", + "command": [ + "module_qbittorrent remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_qbittorrent status" + }, + { + "id": "DOW003", + "description": "qBittorrent purge with data folder", + "about": "This operation will remove qBittorrent BitTorrent data folder", + "command": [ + "module_qbittorrent purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_qbittorrent status" + }, + { + "id": "DEL001", + "description": "Deluge BitTorrent server", + "about": "This operation will install BitTorrent server", + "command": [ + "module_deluge install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_deluge status" + }, + { + "id": "DEL002", + "description": "Deluge remove", + "about": "This operation will remove Deluge BitTorrent server", + "command": [ + "module_deluge remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_deluge status" + }, + { + "id": "DEL003", + "description": "Deluge purge with data folder", + "about": "This operation will remove Deluge BitTorrent server data folder", + "command": [ + "module_deluge purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_deluge status" + }, + { + "id": "TRA001", + "description": "Transmission BitTorrent server", + "about": "This operation will install Transmission BitTorrent server", + "command": [ + "module_transmission install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_transmission status" + }, + { + "id": "TRA002", + "description": "Transmission remove", + "about": "This operation will remove Transmission BitTorrent server", + "command": [ + "module_transmission remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_transmission status" + }, + { + "id": "TRA003", + "description": "Transmission purge with data folder", + "about": "This operation will remove Transmission BitTorrent server data folder", + "command": [ + "module_transmission purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_transmission status" + }, + { + "id": "SABN01", + "description": "SABnzbd newsgroup downloader", + "about": "This operation will install SABnzbd newsgroup downloader", + "command": [ + "module_sabnzbd install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_sabnzbd status" + }, + { + "id": "SABN02", + "description": "SABnzbd remove", + "about": "This operation will remove SABnzbd newsgroup downloader", + "command": [ + "module_sabnzbd remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_sabnzbd status" + }, + { + "id": "SABN03", + "description": "SABnzbd purge with data folder", + "about": "This operation will purge SABnzbd newsgroup data folder", + "command": [ + "module_sabnzbd purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_sabnzbd status" + }, + { + "id": "MDS001", + "description": "Medusa automatic downloader for TV shows", + "about": "This operation will install Medusa TV shows downloader", + "command": [ + "module_medusa install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_medusa status" + }, + { + "id": "MDS002", + "description": "Medusa TV shows downloader remove", + "about": "This operation will remove Medusa TV shows downloader", + "command": [ + "module_medusa remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_medusa status" + }, + { + "id": "MDS003", + "description": "Medusa TV shows downloader purge", + "about": "This operation will purge Medusa TV shows data folder", + "command": [ + "module_medusa purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_medusa status" + }, + { + "id": "SON001", + "description": "Sonarr automatic downloader for TV shows", + "about": "This operation will install Sonarr PVR for Usenet and BitTorrent", + "command": [ + "module_sonarr install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_sonarr status" + }, + { + "id": "SON002", + "description": "Sonarr remove", + "about": "This operation will remove Sonarr PVR for Usenet and BitTorrent", + "command": [ + "module_sonarr remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_sonarr status" + }, + { + "id": "SON003", + "description": "Sonarr purge with data folder", + "about": "This operation will purge Sonarr PVR for Usenet and BitTorrent purge data folder", + "command": [ + "module_sonarr purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_sonarr status" + }, + { + "id": "RAD001", + "description": "Radarr automatic downloader for movies", + "about": "This operation will install Radarr movie collection manager", + "command": [ + "module_radarr install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_radarr status" + }, + { + "id": "RAD002", + "description": "Radarr remove", + "about": "This operation will remove Radarr movie collection manager", + "command": [ + "module_radarr remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_radarr status" + }, + { + "id": "RAD003", + "description": "Radarr purge with data folder", + "about": "This operation will purge Radarr movie collection manager data folder", + "command": [ + "module_radarr purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_radarr status" + }, + { + "id": "BAZ001", + "description": "Bazarr automatic subtitles downloader for Sonarr and Radarr", + "about": "This operation will install Bazarr subtitles manager for Sonarr and Radarr", + "command": [ + "module_bazarr install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_bazarr status" + }, + { + "id": "BAZ002", + "description": "Bazarr remove", + "about": "This operation will remove Bazarr subtitles manager for Sonarr and Radarr", + "command": [ + "module_bazarr remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_bazarr status" + }, + { + "id": "BAZ003", + "description": "Bazarr purge with data folder", + "about": "This operation will purge Bazarr subtitles manager with data folder", + "command": [ + "module_bazarr purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_bazarr status" + }, + { + "id": "LID001", + "description": "Lidarr automatic music downloader", + "about": "This operation will install Lidarr music collection manager for Usenet and BitTorrent users", + "command": [ + "module_lidarr install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_lidarr status" + }, + { + "id": "LID002", + "description": "Lidarr remove", + "about": "This operation will remove Lidarr", + "command": [ + "module_lidarr remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_lidarr status" + }, + { + "id": "LID003", + "description": "Lidarr purge with data folder", + "about": "This operation will purge Lidarr with data folder", + "command": [ + "module_lidarr purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_lidarr status" + }, + { + "id": "RDR001", + "description": "Readarr automatic downloader for Ebooks", + "about": "This operation will install Readarr", + "command": [ + "module_readarr install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_readarr status" + }, + { + "id": "RDR002", + "description": "Readarr remove", + "about": "This operation will remove Readarr", + "command": [ + "module_readarr remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_readarr status" + }, + { + "id": "RDR003", + "description": "Readarr purge with data folder", + "about": "This operation will purge Readarr with data folder", + "command": [ + "module_readarr purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_readarr status" + }, + { + "id": "DOW025", + "description": "Prowlarr index manager and proxy for PVR", + "about": "This operation will install Prowlarr", + "command": [ + "module_prowlarr install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_prowlarr status" + }, + { + "id": "DOW026", + "description": "Prowlarr remove", + "about": "This operation will remove Prowlarr", + "command": [ + "module_prowlarr remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_prowlarr status" + }, + { + "id": "DOW027", + "description": "Prowlarr purge with data folder", + "about": "This operation will purge Prowlarr with data folder", + "command": [ + "module_prowlarr purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_prowlarr status" + }, + { + "id": "JEL001", + "description": "Jellyseerr Jellyfin/Emby/Plex integration install", + "about": "This operation will install Jellyseerr", + "command": [ + "module_jellyseerr install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_jellyseerr status" + }, + { + "id": "JEL002", + "description": "Jellyseerr remove", + "about": "This operation will remove Jellyseerr", + "command": [ + "module_jellyseerr remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_jellyseerr status" + }, + { + "id": "JEL003", + "description": "Jellyseerr purge with data folder", + "about": "This operation will purge Jellyseerr with data folder", + "command": [ + "module_jellyseerr purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_jellyseerr status ]]" + } + ] + }, + { + "id": "Database", + "description": "SQL database servers and web interface managers", + "sub": [ + { + "id": "DAT001", + "description": "Mariadb install", + "command": [ + "module_mariadb install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_mariadb status" + }, + { + "id": "DAT002", + "description": "Mariadb remove", + "command": [ + "module_mariadb remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_mariadb status" + }, + { + "id": "DAT003", + "description": "Mariadb purge", + "command": [ + "module_mariadb purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_mariadb status && [[ -d \"${SOFTWARE_FOLDER}/mariadb\" ]]" + }, + { + "id": "DAT005", + "description": "phpMyAdmin install", + "command": [ + "module_phpmyadmin install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_phpmyadmin status" + }, + { + "id": "DAT006", + "description": "phpMyAdmin remove", + "command": [ + "module_phpmyadmin remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_phpmyadmin status" + }, + { + "id": "DAT007", + "description": "phpMyAdmin purge", + "command": [ + "module_phpmyadmin purge" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_phpmyadmin status && [[ -d \"${SOFTWARE_FOLDER}/phpmyadmin\" ]]" + } + ] + }, + { + "id": "DevTools", + "description": "Applications and tools for development", + "sub": [ + { + "id": "DEV001", + "description": "Install tools for cloning and managing repositories (git)", + "command": [ + "get_user_continue \"This operation will install git.\n\nDo you wish to continue?\" process_input", + "pkg_install git" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! pkg_installed git" + }, + { + "id": "DEV002", + "description": "Remove tools for cloning and managing repositories (git)", + "command": [ + "get_user_continue \"This operation will remove git.\n\nDo you wish to continue?\" process_input", + "pkg_remove git" + ], + "status": "Stable", + "author": "@armbian", + "condition": "pkg_installed git" + } + ] }, { - "id": "UID04", - "description": "Description ... ", - "prompt": "Prompt\nContinue?", + "id": "Benchy", + "description": "System benchmaking and diagnostics", "command": [ - "show_message <<< \" Message ... \"" + "see_monitoring" ], - "status": "", - "author": "Github Username", - "condition": "" + "status": "Disabled", + "author": "@armbian", + "condition": "[ -f /usr/bin/armbianmonitor ]" + }, + { + "id": "Containers", + "description": "Docker containerization and KVM virtual machines", + "sub": [ + { + "id": "CON001", + "description": "Docker Minimal Install", + "about": "This operation will install Docker Minimal.", + "command": [ + "module_docker install minimal" + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "! module_docker status docker-ce" + }, + { + "id": "CON002", + "description": "Docker Engine Install", + "about": "This operation will install Docker Engine.", + "command": [ + "module_docker install engine" + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "! module_docker status docker-compose-plugin" + }, + { + "id": "CON003", + "description": "Docker Remove", + "about": "This operation will purge Docker.", + "command": [ + "module_docker remove" + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "module_docker status docker-ce" + }, + { + "id": "CON004", + "description": "Docker Purge all images, containers, and volumes", + "about": "This operation will delete all Docker images, containers, and volumes.", + "command": [ + "module_docker purge" + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "! module_docker status docker-ce && [ -d /var/lib/docker ]" + }, + { + "id": "CON005", + "description": "Portainer container management platform", + "prompt": "This operation will install Portainer container management platform.", + "command": [ + "module_portainer install" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! module_portainer status" + }, + { + "id": "CON006", + "description": "Portainer remove", + "prompt": "This operation will remove Portainer container management platform.", + "command": [ + "module_portainer remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_portainer status" + }, + { + "id": "CON007", + "description": "Portainer purge with with data folder", + "prompt": "This operation will remove Portainer container management platform.", + "command": [ + "module_portainer remove" + ], + "status": "Stable", + "author": "@armbian", + "condition": "module_portainer status" + } + ] + }, + { + "id": "Media", + "description": "Media servers, organizers and editors", + "sub": [ + { + "id": "MED001", + "description": "Plex Media server", + "about": "This operation will install Plex Media server.", + "command": [ + "module_plexmediaserver install" + ], + "status": "Disabled", + "author": "@schwar3kat", + "condition": "! module_plexmediaserver status" + }, + { + "id": "MED002", + "description": "Plex Media server remove", + "about": "This operation will purge Plex Media server.", + "command": [ + "module_plexmediaserver remove" + ], + "status": "Disabled", + "author": "@schwar3kat", + "condition": "module_plexmediaserver status" + }, + { + "id": "MED003", + "description": "Emby organizes video, music, live TV, and photos", + "about": "This operation will install Emby server.", + "command": [ + "module_embyserver install" + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "! module_embyserver status" + }, + { + "id": "MED004", + "description": "Emby server remove", + "about": "This operation will remove Emby server", + "command": [ + "module_embyserver remove" + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "module_embyserver status" + }, + { + "id": "MED005", + "description": "Emby server purge with data folder", + "command": [ + "module_embyserver purge" + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "module_embyserver status" + }, + { + "id": "MED010", + "description": "Stirling PDF tools for viewing and editing PDF files", + "about": "This operation will install Stirling-PDF tools.", + "command": [ + "module_stirling install" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "! module_stirling status" + }, + { + "id": "MED011", + "description": "Stirling PDF remove", + "about": "This operation will remove Stirling-PDF tools.", + "command": [ + "module_stirling remove" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_stirling status" + }, + { + "id": "MED012", + "description": "Stirling PDF purge with data folder", + "about": "This operation will purge Stirling-PDF tools with data folder.", + "command": [ + "module_stirling purge" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_stirling status" + }, + { + "id": "MED015", + "description": "Syncthing continuous file synchronization", + "command": [ + "module_syncthing install" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "! module_syncthing status" + }, + { + "id": "MED016", + "description": "Syncthing remove", + "command": [ + "module_syncthing remove" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_syncthing status" + }, + { + "id": "MED017", + "description": "Syncthing purge with data folder", + "command": [ + "module_syncthing purge" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_syncthing status" + }, + { + "id": "MED020", + "description": "Nextcloud content collaboration platform", + "command": [ + "module_nextcloud install" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "! module_nextcloud status" + }, + { + "id": "MED021", + "description": "Nextcloud remove", + "command": [ + "module_nextcloud remove" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_nextcloud status" + }, + { + "id": "MED022", + "description": "Nextcloud purge with data folder", + "command": [ + "module_nextcloud purge" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_nextcloud status" + }, + { + "id": "MED025", + "description": "Owncloud share files and folders, easy and secure", + "command": [ + "module_owncloud install" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "! module_owncloud status" + }, + { + "id": "MED026", + "description": "Owncloud remove", + "command": [ + "module_owncloud remove" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_owncloud status" + }, + { + "id": "MED027", + "description": "Owncloud purge with data folder", + "command": [ + "module_owncloud purge" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_owncloud status" + } + ] + }, + { + "id": "Monitoring", + "description": "Real-time monitoring, collecting metrics, up-time status", + "sub": [ + { + "id": "MON001", + "description": "Uptime Kuma self-hosted monitoring tool", + "about": "This operation will install Uptime Kuma", + "command": [ + "module_uptimekuma install" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "! module_uptimekuma status" + }, + { + "id": "MON002", + "description": "Uptime Kuma remove", + "about": "This operation will remove Uptime Kuma", + "command": [ + "module_uptimekuma remove" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_uptimekuma status" + }, + { + "id": "MON003", + "description": "Uptime Kuma purge with data folder", + "about": "This operation will remove Uptime Kuma with data folder", + "command": [ + "module_uptimekuma purge" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_uptimekuma status" + }, + { + "id": "MON005", + "description": "Netdata - monitoring real-time metrics", + "about": "This operation will install Netdata", + "command": [ + "module_netdata install" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "! module_netdata status" + }, + { + "id": "MON006", + "description": "Netdata remove", + "about": "This operation will remove Netdata", + "command": [ + "module_netdata remove" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_netdata status" + }, + { + "id": "MON007", + "description": "Netdata purge with data folder", + "about": "This operation will purge Netdata with data folder", + "command": [ + "module_netdata purge" + ], + "status": "Stable", + "author": "@igorpecovnik", + "condition": "module_netdata status" + } + + ] + }, + { + "id": "Management", + "description": "Remote Management tools", + "sub": [ + { + "id": "MAN001", + "description": "Install Cockpit web-based management tool", + "about": "This operation will install Cockpit.\ncockpit cockpit-ws cockpit-system cockpit-storaged", + "command": [ + "see_current_apt update", + "pkg_install cockpit cockpit-ws cockpit-system cockpit-storaged " + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "! pkg_installed cockpit" + }, + { + "id": "MAN002", + "description": "Purge Cockpit web-based management tool", + "about": "This operation will purge Cockpit.", + "command": [ + "pkg_remove cockpit" + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "pkg_installed cockpit" + }, + { + "id": "MAN003", + "description": "Start Cockpit Service", + "command": [ + "sudo systemctl enable --now cockpit.socket | show_infobox " + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "pkg_installed cockpit && ! systemctl is-enabled cockpit.socket > /dev/null 2>&1" + }, + { + "id": "MAN004", + "description": "Stop Cockpit Service", + "command": [ + "systemctl stop cockpit cockpit.socket", + "systemctl disable cockpit.socket | show_infobox " + ], + "status": "Stable", + "author": "@schwar3kat", + "condition": "pkg_installed cockpit && systemctl is-enabled cockpit.socket > /dev/null 2>&1" + }, + { + "id": "MAN005", + "description": "Webmin web-based management tool", + "command": [ + "see_menu module_webmin" + ], + "status": "Stable", + "author": "@Tearran", + "condition": "" + } + ] + }, + { + "id": "Netconfig", + "description": "Console network tools for measuring load and bandwidth", + "sub": [ + { + "id": "NET001", + "description": "nload -realtime console network usage monitor", + "prompt": "This operation will install nload.", + "command": [ + "pkg_install nload" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! pkg_installed nload" + }, + { + "id": "NET002", + "description": "nload - remove", + "prompt": "This operation will remove nload.", + "command": [ + "pkg_remove nload" + ], + "status": "Stable", + "author": "@armbian", + "condition": "pkg_installed nload" + }, + { + "id": "NET003", + "description": "iperf3 bandwidth measuring tool", + "prompt": "This operation will install iperf3.", + "command": [ + "pkg_install iperf3" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! pkg_installed iperf3" + }, + { + "id": "NET004", + "description": "iperf3 remove", + "prompt": "This operation will remove iperf3.", + "command": [ + "pkg_remove iperf3" + ], + "status": "Stable", + "author": "@armbian", + "condition": "pkg_installed iperf3" + }, + { + "id": "NET005", + "description": "iptraf-ng IP LAN monitor", + "prompt": "This operation will install iptraf-ng.", + "command": [ + "pkg_install iptraf-ng" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! pkg_installed iptraf-ng" + }, + { + "id": "NET006", + "description": "iptraf-ng remove", + "prompt": "This operation will remove iptraf-ng.", + "command": [ + "pkg_remove iptraf-ng" + ], + "status": "Stable", + "author": "@armbian", + "condition": "pkg_installed iptraf-ng" + }, + { + "id": "NET007", + "description": "avahi-daemon hostname broadcast via mDNS", + "prompt": "This operation will install avahi-daemon.", + "command": [ + "pkg_install avahi-daemon libnss-mdns", + "cp /usr/share/doc/avahi-daemon/examples/sftp-ssh.service /etc/avahi/services/", + "cp /usr/share/doc/avahi-daemon/examples/ssh.service /etc/avahi/services/", + "service restart avahi-daemon" + ], + "status": "Stable", + "author": "@armbian", + "condition": "! pkg_installed avahi-daemon" + }, + { + "id": "NET008", + "description": "avahi-daemon remove", + "prompt": "This operation will remove avahi-daemon.", + "command": [ + "systemctl stop avahi-daemon avahi-daemon.socket", + "pkg_remove avahi-daemon" + ], + "status": "Stable", + "author": "@armbian", + "condition": "pkg_installed avahi-daemon" + } + ] } ] } ] -} \ No newline at end of file +} diff --git a/tools/modules/docs/generate_json_data.sh b/tools/modules/docs/generate_json_data.sh new file mode 100644 index 000000000..c7031ee9d --- /dev/null +++ b/tools/modules/docs/generate_json_data.sh @@ -0,0 +1,142 @@ + +function set_json_data() { + local i=0 + + features=() + for key in "${!module_options[@]}"; do + if [[ $key == *",feature" ]]; then + features+=("${module_options[$key]}") + fi + done + +{ + echo -e "[" + + for feature in "${features[@]}"; do + feature_prefix=$(echo "${feature:0:3}" | tr '[:lower:]' '[:upper:]') # Extract first 3 letters and convert to uppercase + + i=$((i + 1)) + id=$(printf "%s%03d" "$feature_prefix" "$i") # Combine prefix with padded number + + # Get keys pairs + desc_key="${feature},desc" + example_key="${feature},example" + author_key="${feature},author" + ref_key="${feature},ref_link" + status_key="${feature},status" + doc_key="${feature},doc_link" + helpers_key="${feature},helpers" + group_key="${feature},group" + commands_key="${feature},commands" + port_key="${feature},port" + arch_key="${feature},arch" + + # Get array info + author="${module_options[$author_key]}" + ref_link="${module_options[$ref_key]}" + status="${module_options[$status_key]}" + doc_link="${module_options[$doc_key]}" + desc="${module_options[$desc_key]}" + example="${module_options[$example_key]}" + helpers="${module_options[$helpers_key]}" + group="${module_options[$group_key]}" + commands="${module_options[$commands_key]}" + port="${module_options[$port_key]}" + arch="${module_options[$arch_key]}" + + echo " {" + echo " \"id\": \"$id\"," + echo " \"feature\": \"$feature\"," + echo " \"helpers\": \"$helpers\"," + echo " \"description\": \"$desc ($feature)\"," + echo " \"command\": \"$feature\"," + echo " \"options\": \"$example\"," + echo " \"status\": \"$status\"," + echo " \"condition\": \" \"," + echo " \"reference\": \"$ref_link\"," + echo " \"author\": \"$author\"," + echo " \"group\": \"$group\"," + echo " \"commands\": \"$commands\"," + echo " \"port\": \"$port\"," + echo " \"arch\": \"$arch\"" + + if [ $i -ne ${#features[@]} ]; then + echo " }," + else + echo " }" + fi + done + echo "]" + +} | jq . + +} + + +function generate_software_json() { + set_json_data | jq ' + # Define an array of allowed software groups + def softwareGroups: ["WebHosting", "Netconfig", "Downloaders", "Database", "DNS", "DevTools", "HomeAutomation", "Benchy", "Containers", "Media", "Monitoring", "Management"]; + + { + "menu": [ + { + "id": "Software", + "description": "Run/Install 3rd party applications", + "sub": ( + group_by(.group) + # Skip grouped arrays where the group is null, empty, or not in softwareGroups + | map(select(.[0].group != null and .[0].group != "" and (.[0].group | IN(softwareGroups[])))) + | map({ + "id": .[0].group, + "description": .[0].group, + "sub": ( + map({ + "id": .id, + "description": .description, + "command": [("see_menu " + .feature)], + "options": ("help " + .options + " status"), + "status": .status, + "condition": "", + "author": .author + }) + ) + }) + ) + } + ] + } + ' + } + +# Test Function +interface_json_data() { + # Convert the example string to an array + local commands=("raw" "mnu" "top" "sub" "help") + json_data=$(generate_software_json) + case "$1" in + + "${commands[0]}") + echo "Setting JSON data to file..." + set_json_data | jq --tab --indent 4 '.' > tools/json/config.temp.json + ;; + "${commands[1]}") + echo "Generating JSON data..." + generate_software_json | jq --tab --indent 4 '.' > tools/json/config.temp.json + ;; + "${commands[2]}") + generate_top_menu "$json_data" + ;; + "${commands[3]}") + generate_menu "Software" "$json_data" + ;; + "${commands[-1]}") + echo "Usage: interface_json_data " + echo "Available commands:" + echo -e "\traw\t- Set flat JSON data to a file for inspection not used" + echo -e "\tmnu\t- Generate the Menu JSON data to file for inspection not used" + echo -e "\ttop\t- Show the top menu using the JSON data." + echo -e "\tsub\t- Show the Software menu using the JSON data." + ;; + esac +} diff --git a/tools/modules/functions/config_interface.sh b/tools/modules/functions/config_interface.sh index f4669824a..90f41e63a 100644 --- a/tools/modules/functions/config_interface.sh +++ b/tools/modules/functions/config_interface.sh @@ -103,8 +103,11 @@ parse_menu_items() { else # If the condition field is empty or null, add the menu item to the menu options+=("$id" " - $description ") + fi + done < <(echo "$json_data" | jq -r '.menu[] | '${parent_id:+".. | objects | select(.id==\"$parent_id\") | .sub[]? |"}' select(.status != "Disabled") | "\(.id)\n\(.description)\n\(.condition)"' || exit 1) + } module_options+=( @@ -128,15 +131,18 @@ generate_top_menu() { local menu_options=() parse_menu_items menu_options - + menu_options+=("Help" " - About this tool") local OPTION=$($DIALOG --backtitle "$backtitle" --title "$TITLE" --menu "$status" 0 80 9 "${menu_options[@]}" \ - --ok-button Select --cancel-button Exit 3>&1 1>&2 2>&3) + --ok-button Select --cancel-button Exit 3>&1 1>&2 2>&3) local exitstatus=$? if [ $exitstatus = 0 ]; then [ -z "$OPTION" ] && break - [[ -n "$debug" ]] && echo "$OPTION" - generate_menu "$OPTION" + if [[ "$OPTION" == "Help" ]]; then + show_message <<< "$(about_armbian_configng)" ; + else + generate_menu "$OPTION" + fi fi done } @@ -172,7 +178,7 @@ function generate_menu() { [ -z "$OPTION" ] && break # Check if the selected option has a submenu - local submenu_count=$(jq -r --arg id "$OPTION" '.menu[] | .. | objects | select(.id==$id) | .sub? | length' "$json_file") + local submenu_count=$(jq -r --arg id "$OPTION" '.menu[] | .. | objects | select(.id==$id) | .sub? | length' <(echo "$json_data")) submenu_count=${submenu_count:-0} # If submenu_count is null or empty, set it to 0 if [ "$submenu_count" -gt 0 ]; then # If it does, generate a new menu for the submenu @@ -208,7 +214,7 @@ function execute_command() { .. | objects | select(.id == $id) | - .command[]?' "$json_file") + .command[]?' <(echo "$json_data")) # Check if a about exists local about=$(jq -r --arg id "$id" ' @@ -216,7 +222,7 @@ function execute_command() { .. | objects | select(.id == $id) | - .about?' "$json_file") + .about?' <(echo "$json_data")) # If a about exists, display it and wait for user confirmation if [[ "$about" != "null" && $INPUTMODE != "cmd" ]]; then diff --git a/tools/modules/runtime/config.runtime.sh b/tools/modules/runtime/config.runtime.sh index 5dad1148c..8083737bc 100644 --- a/tools/modules/runtime/config.runtime.sh +++ b/tools/modules/runtime/config.runtime.sh @@ -54,7 +54,7 @@ module_options+=( ["update_sub_submenu_data,author"]="@Tearran" ["update_sub_submenu_data,feature"]="update_sub_submenu_data" ["update_sub_submenu_data,desc"]="Update sub-submenu descriptions based on conditions" - ["update_sub_submenu_data,example"]="update_sub_submenu_data \"MenuID\" \"SubID\" \"SubSubID\" \"CMD\"" + ["update_sub_submenu_data,example"]="update_sub_submenu_data MenuID SubID SubSubID CMD" ["update_sub_submenu_data,status"]="" ) # diff --git a/tools/modules/software/module_cockpit.sh b/tools/modules/software/module_cockpit.sh new file mode 100644 index 000000000..ff9a832c9 --- /dev/null +++ b/tools/modules/software/module_cockpit.sh @@ -0,0 +1,103 @@ +module_options+=( + ["module_cockpit,author"]="@tearran" + ["module_cockpit,maintainer"]="@igorpecovnik" + ["module_cockpit,feature"]="module_cockpit" + ["module_cockpit,example"]="help install remove start stop enable disable status check" + ["module_cockpit,desc"]="Cockpit setup and service setting." + ["module_cockpit,status"]="Stable" + ["module_cockpit,doc_link"]="https://cockpit-project.org/guide/latest/" + ["module_cockpit,group"]="Management" + ["module_cockpit,port"]="9090" + ["module_cockpit,arch"]="x86-64 arm64 armhf" +) + +function module_cockpit() { + local title="cockpit" + local condition=$(dpkg -s "cockpit" 2>/dev/null | sed -n "s/Status: //p") + # Convert the example string to an array + local commands + IFS=' ' read -r -a commands <<< "${module_options["module_cockpit,example"]}" + + case "$1" in + "${commands[0]}") + ## help/menu options for the module + echo -e "\nUsage: ${module_options["module_cockpit,feature"]} " + echo -e "Commands: ${module_options["module_cockpit,example"]}" + echo "Available commands:" + if [[ -z "$condition" ]]; then + echo -e " install\t- Install $title." + else + if [[ "$(systemctl is-active cockpit.socket 2>/dev/null)" == "active" ]]; then + echo -e "\tstop\t- Stop the $title service." + else + echo -e "\tstart\t- Start the $title service." + fi + if [[ $(systemctl is-enabled cockpit.socket) == "enabled" ]]; then + echo -e "\tdisable\t- Disable $title from starting on boot." + elif [[ $(systemctl is-enabled cockpit.socket) == "disabled" ]]; then + echo -e "\tenable\t- Enable $title to start on boot." + + fi + echo -e "\tstatus\t- Show the status of the $title service." + echo -e "\tremove\t- Remove $title." + fi + echo + ;; + "${commands[1]}") + ## install cockpit + pkg_update + pkg_install cockpit cockpit-ws cockpit-system cockpit-storaged + echo "Cockpit installed successfully." + ;; + "${commands[2]}") + ## remove cockpit + systemctl disable cockpit cockpit.socket + pkg_remove cockpit + echo "Cockpit removed successfully." + ;; + "${commands[3]}") + ## start cockpit + + systemctl start cockpit.socket + echo "Cockpit service started." + ;; + "${commands[4]}") + ## stop cockpit + + systemctl stop cockpit.socket + echo "Cockpit service stopped." + ;; + "${commands[5]}") + ## enable cockpit + #systemctl enable cockpit + systemctl enable cockpit.socket + echo "Cockpit service enabled." + ;; + "${commands[6]}") + ## disable cockpit + #systemctl disable cockpit + systemctl disable cockpit.socket + echo "Cockpit service disabled." + ;; + "${commands[7]}") + ## status cockpit + #systemctl status cockpit + systemctl status cockpit.socket + ;; + "${commands[-1]}") + ## check cockpit status + if [[ $(systemctl is-active cockpit.socket) == "active" ]]; then + echo "Cockpit service is active." + return 0 + elif [[ $(systemctl is-enabled cockpit.socket) == "disabled" ]]; then + echo "Cockpit service is disabled." + return 0 + else + return 1 + fi + ;; + *) + echo "Invalid command. Try: '${module_options["module_cockpit,example"]}'" + ;; + esac +}