From d2980d84ac1bc985beb7d46565f180e3037429ef Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Sat, 17 Jan 2026 13:18:35 +0100 Subject: [PATCH] feat(mmpm): Complete MMPM integration with LuCI and portal - Fix pip install with --break-system-packages for Debian Trixie PEP 668 - Fix MMPM binary path detection (/usr/local/bin/mmpm) - Fix RPCD backend to detect MMPM UI status with correct PATH - Add Services section to portal navigation - Update MMPM commands to use full path in container - Configure MMPM environment for /opt/magic_mirror Co-Authored-By: Claude Opus 4.5 --- package/secubox/luci-app-mmpm/Makefile | 2 +- .../root/usr/libexec/rpcd/luci.mmpm | 49 +++++++++++++------ .../secubox/luci-app-secubox-portal/Makefile | 2 +- .../resources/view/secubox-portal/index.js | 11 ++++- package/secubox/secubox-app-mmpm/Makefile | 2 +- .../secubox-app-mmpm/files/usr/sbin/mmpmctl | 31 +++++++----- 6 files changed, 64 insertions(+), 33 deletions(-) diff --git a/package/secubox/luci-app-mmpm/Makefile b/package/secubox/luci-app-mmpm/Makefile index bd7f0afa..d1c44bd9 100644 --- a/package/secubox/luci-app-mmpm/Makefile +++ b/package/secubox/luci-app-mmpm/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-mmpm PKG_VERSION:=0.2.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_ARCH:=all PKG_LICENSE:=MIT diff --git a/package/secubox/luci-app-mmpm/root/usr/libexec/rpcd/luci.mmpm b/package/secubox/luci-app-mmpm/root/usr/libexec/rpcd/luci.mmpm index 64fbcc38..f7508f1e 100644 --- a/package/secubox/luci-app-mmpm/root/usr/libexec/rpcd/luci.mmpm +++ b/package/secubox/luci-app-mmpm/root/usr/libexec/rpcd/luci.mmpm @@ -7,6 +7,7 @@ . /lib/functions.sh LXC_NAME="magicmirror2" +MMPM_BIN="/usr/local/bin/mmpm" # Get MMPM status get_status() { @@ -22,22 +23,22 @@ get_status() { mm2_running=1 # Check if MMPM is installed - if lxc-attach -n "$LXC_NAME" -- sh -c "command -v mmpm >/dev/null 2>&1" 2>/dev/null; then + if lxc-attach -n "$LXC_NAME" -- test -x "$MMPM_BIN" 2>/dev/null; then installed=1 - version=$(lxc-attach -n "$LXC_NAME" -- mmpm --version 2>/dev/null || echo "unknown") + version=$(lxc-attach -n "$LXC_NAME" -- $MMPM_BIN version 2>/dev/null | head -1 || echo "unknown") + + # Check GUI status from MMPM ui --url (needs PATH for pm2) + local ui_url=$(lxc-attach -n "$LXC_NAME" -- sh -c "export PATH=/usr/local/bin:/opt/nodejs/node-v24.13.0/bin:\$PATH && $MMPM_BIN ui --url 2>/dev/null" | grep -oE 'http://[^[:space:]]+') + if [ -n "$ui_url" ]; then + gui_running=1 + web_url="$ui_url" + fi fi fi - # Check GUI status - if pgrep -f "mmpm gui" >/dev/null 2>&1; then - gui_running=1 - fi - local enabled=$(uci -q get mmpm.main.enabled || echo "0") - local port=$(uci -q get mmpm.main.port || echo "7891") - local router_ip=$(uci -q get network.lan.ipaddr || echo "192.168.1.1") - - [ "$gui_running" = "1" ] && web_url="http://${router_ip}:${port}" + local port=$(echo "$web_url" | grep -oE ':[0-9]+$' | tr -d ':') + [ -z "$port" ] && port="7890" cat </dev/null) + local results=$(lxc-attach -n "$LXC_NAME" -- $MMPM_BIN search "$query" --json 2>/dev/null) if [ -n "$results" ]; then echo "$results" @@ -142,7 +143,7 @@ list_modules() { return fi - local results=$(lxc-attach -n "$LXC_NAME" -- mmpm list --json 2>/dev/null) + local results=$(lxc-attach -n "$LXC_NAME" -- $MMPM_BIN list --json 2>/dev/null) if [ -n "$results" ]; then echo "$results" @@ -208,12 +209,28 @@ upgrade_modules() { # Get web URL for iframe get_web_url() { - local router_ip=$(uci -q get network.lan.ipaddr || echo "192.168.1.1") - local port=$(uci -q get mmpm.main.port || echo "7891") + local web_url="" + local port="7890" + + # Get actual URL from MMPM if available + if lxc-info -n "$LXC_NAME" -s 2>/dev/null | grep -q "RUNNING"; then + if lxc-attach -n "$LXC_NAME" -- test -x "$MMPM_BIN" 2>/dev/null; then + web_url=$(lxc-attach -n "$LXC_NAME" -- sh -c "export PATH=/usr/local/bin:/opt/nodejs/node-v24.13.0/bin:\$PATH && $MMPM_BIN ui --url 2>/dev/null" | grep -oE 'http://[^[:space:]]+') + if [ -n "$web_url" ]; then + port=$(echo "$web_url" | grep -oE ':[0-9]+$' | tr -d ':') + fi + fi + fi + + # Fallback if not running + if [ -z "$web_url" ]; then + local router_ip=$(uci -q get network.lan.ipaddr || echo "192.168.1.1") + web_url="http://$router_ip:$port" + fi cat < diff --git a/package/secubox/luci-app-secubox-portal/htdocs/luci-static/resources/view/secubox-portal/index.js b/package/secubox/luci-app-secubox-portal/htdocs/luci-static/resources/view/secubox-portal/index.js index 82b1a27d..97f2d8e2 100644 --- a/package/secubox/luci-app-secubox-portal/htdocs/luci-static/resources/view/secubox-portal/index.js +++ b/package/secubox/luci-app-secubox-portal/htdocs/luci-static/resources/view/secubox-portal/index.js @@ -122,7 +122,8 @@ return view.extend({ this.renderSecuritySection(), this.renderNetworkSection(), this.renderMonitoringSection(), - this.renderSystemSection() + this.renderSystemSection(), + this.renderServicesSection() ]) ]); @@ -137,7 +138,7 @@ return view.extend({ var sections = portal.getSections(); // Sections that link to other pages vs tabs within portal var linkSections = ['portal', 'hub', 'admin']; - var tabSections = ['security', 'network', 'monitoring', 'system']; + var tabSections = ['security', 'network', 'monitoring', 'system', 'services']; return E('div', { 'class': 'sb-portal-header' }, [ // Brand @@ -360,6 +361,12 @@ return view.extend({ 'System administration and configuration tools', apps); }, + renderServicesSection: function() { + var apps = portal.getAppsBySection('services'); + return this.renderAppSection('services', 'Services', + 'Application services and server platforms', apps); + }, + renderAppSection: function(sectionId, title, subtitle, apps) { var self = this; diff --git a/package/secubox/secubox-app-mmpm/Makefile b/package/secubox/secubox-app-mmpm/Makefile index 99cd8ffd..25f4d8e3 100644 --- a/package/secubox/secubox-app-mmpm/Makefile +++ b/package/secubox/secubox-app-mmpm/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=secubox-app-mmpm PKG_VERSION:=0.2.0 -PKG_RELEASE:=1 +PKG_RELEASE:=3 PKG_ARCH:=all PKG_MAINTAINER:=CyberMind Studio PKG_LICENSE:=MIT diff --git a/package/secubox/secubox-app-mmpm/files/usr/sbin/mmpmctl b/package/secubox/secubox-app-mmpm/files/usr/sbin/mmpmctl index abd72114..7ad54c50 100644 --- a/package/secubox/secubox-app-mmpm/files/usr/sbin/mmpmctl +++ b/package/secubox/secubox-app-mmpm/files/usr/sbin/mmpmctl @@ -60,9 +60,12 @@ check_mm2_running() { return 0 } +# MMPM binary path inside container +MMPM_BIN="/usr/local/bin/mmpm" + # Check if MMPM is installed in container is_mmpm_installed() { - lxc-attach -n "$LXC_NAME" -- sh -c "command -v mmpm >/dev/null 2>&1" + lxc-attach -n "$LXC_NAME" -- test -x "$MMPM_BIN" } # Install MMPM in container @@ -83,12 +86,15 @@ cmd_install() { # Install Python and pip if not present if ! command -v pip3 >/dev/null 2>&1; then - apt-get install -y python3 python3-pip 2>/dev/null || \ + apt-get install -y python3 python3-pip python3-venv 2>/dev/null || \ apk add python3 py3-pip 2>/dev/null || true fi - # Install MMPM via pip - pip3 install --upgrade mmpm || pip install --upgrade mmpm + # Install MMPM via pip (--break-system-packages for Debian Trixie PEP 668) + pip3 install --upgrade --break-system-packages mmpm 2>/dev/null || \ + pip3 install --upgrade mmpm 2>/dev/null || \ + pip install --upgrade --break-system-packages mmpm 2>/dev/null || \ + pip install --upgrade mmpm # Initialize MMPM database mmpm db --yes 2>/dev/null || true @@ -111,6 +117,7 @@ cmd_update() { fi log_info "Updating MMPM..." + lxc-attach -n "$LXC_NAME" -- pip3 install --upgrade --break-system-packages mmpm 2>/dev/null || \ lxc-attach -n "$LXC_NAME" -- pip3 install --upgrade mmpm || { log_error "Failed to update MMPM" return 1 @@ -135,7 +142,7 @@ cmd_status() { echo "MagicMirror2 container: RUNNING" if is_mmpm_installed; then - local version=$(lxc-attach -n "$LXC_NAME" -- mmpm --version 2>/dev/null || echo "unknown") + local version=$(lxc-attach -n "$LXC_NAME" -- $MMPM_BIN version 2>/dev/null | head -1 || echo "unknown") echo "MMPM installed: YES (v$version)" else echo "MMPM installed: NO" @@ -185,7 +192,7 @@ cmd_service_run() { log_info "Starting MMPM GUI on port $port..." # Run MMPM GUI inside container - exec lxc-attach -n "$LXC_NAME" -- mmpm gui --port "$port" --host "$address" + exec lxc-attach -n "$LXC_NAME" -- $MMPM_BIN ui --port "$port" --host "$address" } # Stop MMPM GUI @@ -210,7 +217,7 @@ cmd_search() { return 1 fi - lxc-attach -n "$LXC_NAME" -- mmpm search "$query" + lxc-attach -n "$LXC_NAME" -- $MMPM_BIN search "$query" } # List installed modules @@ -222,7 +229,7 @@ cmd_list() { return 1 fi - lxc-attach -n "$LXC_NAME" -- mmpm list + lxc-attach -n "$LXC_NAME" -- $MMPM_BIN list } # Install module via MMPM @@ -241,7 +248,7 @@ cmd_module_install() { fi log_info "Installing module: $module" - lxc-attach -n "$LXC_NAME" -- mmpm install "$module" --yes + lxc-attach -n "$LXC_NAME" -- $MMPM_BIN install "$module" --yes } # Remove module via MMPM @@ -260,7 +267,7 @@ cmd_module_remove() { fi log_info "Removing module: $module" - lxc-attach -n "$LXC_NAME" -- mmpm remove "$module" --yes + lxc-attach -n "$LXC_NAME" -- $MMPM_BIN remove "$module" --yes } # Upgrade modules @@ -275,10 +282,10 @@ cmd_upgrade() { if [ -n "$module" ]; then log_info "Upgrading module: $module" - lxc-attach -n "$LXC_NAME" -- mmpm upgrade "$module" --yes + lxc-attach -n "$LXC_NAME" -- $MMPM_BIN upgrade "$module" --yes else log_info "Upgrading all modules..." - lxc-attach -n "$LXC_NAME" -- mmpm upgrade --yes + lxc-attach -n "$LXC_NAME" -- $MMPM_BIN upgrade --yes fi }