secubox-openwrt/package/secubox/secubox-app-mmpm/files/usr/sbin/mmpmctl
CyberMind-FR a83cde0885 feat(magicmirror2): Add MagicMirror² and MMPM packages
New packages:
- secubox-app-magicmirror2 (0.4.0): MagicMirror² smart display platform
  - LXC container with Docker image extraction
  - mm2ctl CLI for management
  - Support for gzip/zstd compressed layers
  - Default port 8082

- luci-app-magicmirror2 (0.4.0): LuCI web interface
  - Dashboard, modules, webui, settings views
  - RPCD backend for service control
  - Module management integration

- secubox-app-mmpm (0.2.0): MMPM package manager
  - Installs MMPM in MagicMirror2 container
  - mmpmctl CLI for module management
  - Web GUI on port 7891

- luci-app-mmpm (0.2.0): LuCI interface for MMPM
  - Dashboard with install/update controls
  - Module search and management
  - Embedded web GUI view

Portal integration:
- Added MagicMirror² and MMPM to Services section
- Portal version bumped to 0.6.0

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 12:00:18 +01:00

308 lines
6.8 KiB
Bash

#!/bin/sh
# MMPM - MagicMirror Package Manager controller
# Manages MMPM inside MagicMirror2 LXC container
# Copyright (C) 2024-2026 CyberMind.fr
CONFIG="mmpm"
LXC_NAME="magicmirror2"
MMPM_REPO="https://github.com/Bee-Mar/mmpm.git"
usage() {
cat <<'EOF'
Usage: mmpmctl <command> [options]
Commands:
install Install MMPM in MagicMirror2 container
update Update MMPM to latest version
status Show MMPM status
logs Show MMPM logs (use -f to follow)
shell Open shell in container (MMPM context)
service-run Internal: run MMPM GUI under procd
service-stop Stop MMPM GUI
Module Management (via MMPM):
search <query> Search for modules
list List installed modules
install <module> Install a module
remove <module> Remove a module
upgrade [module] Upgrade module(s)
Examples:
mmpmctl install
mmpmctl search weather
mmpmctl install MMM-WeatherChart
mmpmctl list
MMPM Web GUI: http://<router-ip>:7891
EOF
}
log_info() { echo "[INFO] $*"; }
log_warn() { echo "[WARN] $*" >&2; }
log_error() { echo "[ERROR] $*" >&2; }
uci_get() { uci -q get ${CONFIG}.$1; }
uci_set() { uci set ${CONFIG}.$1="$2" && uci commit ${CONFIG}; }
load_config() {
port="$(uci_get main.port || echo 7891)"
address="$(uci_get main.address || echo 0.0.0.0)"
enabled="$(uci_get main.enabled || echo 0)"
}
# Check if MagicMirror2 LXC is running
check_mm2_running() {
if ! lxc-info -n "$LXC_NAME" -s 2>/dev/null | grep -q "RUNNING"; then
log_error "MagicMirror2 container not running"
log_error "Start it first: /etc/init.d/magicmirror2 start"
return 1
fi
return 0
}
# Check if MMPM is installed in container
is_mmpm_installed() {
lxc-attach -n "$LXC_NAME" -- sh -c "command -v mmpm >/dev/null 2>&1"
}
# Install MMPM in container
cmd_install() {
check_mm2_running || return 1
if is_mmpm_installed; then
log_info "MMPM is already installed"
return 0
fi
log_info "Installing MMPM in MagicMirror2 container..."
# Install dependencies and MMPM via pip
lxc-attach -n "$LXC_NAME" -- sh -c '
# Update package lists
apt-get update 2>/dev/null || apk update 2>/dev/null || true
# 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 || \
apk add python3 py3-pip 2>/dev/null || true
fi
# Install MMPM via pip
pip3 install --upgrade mmpm || pip install --upgrade mmpm
# Initialize MMPM database
mmpm db --yes 2>/dev/null || true
' || {
log_error "Failed to install MMPM"
return 1
}
log_info "MMPM installed successfully"
log_info "Enable and start the GUI: /etc/init.d/mmpm enable && /etc/init.d/mmpm start"
}
# Update MMPM
cmd_update() {
check_mm2_running || return 1
if ! is_mmpm_installed; then
log_error "MMPM not installed. Run 'mmpmctl install' first"
return 1
fi
log_info "Updating MMPM..."
lxc-attach -n "$LXC_NAME" -- pip3 install --upgrade mmpm || {
log_error "Failed to update MMPM"
return 1
}
log_info "MMPM updated successfully"
}
# Show status
cmd_status() {
load_config
echo "=== MMPM Status ==="
echo ""
if ! lxc-info -n "$LXC_NAME" -s 2>/dev/null | grep -q "RUNNING"; then
echo "MagicMirror2 container: NOT RUNNING"
echo "MMPM: N/A (container not running)"
return
fi
echo "MagicMirror2 container: RUNNING"
if is_mmpm_installed; then
local version=$(lxc-attach -n "$LXC_NAME" -- mmpm --version 2>/dev/null || echo "unknown")
echo "MMPM installed: YES (v$version)"
else
echo "MMPM installed: NO"
echo ""
echo "Install with: mmpmctl install"
return
fi
echo ""
echo "=== Configuration ==="
echo "GUI Port: $port"
echo "GUI Address: $address"
echo "GUI Enabled: $enabled"
# Check if GUI is running
if pgrep -f "mmpm gui" >/dev/null 2>&1; then
local router_ip=$(uci -q get network.lan.ipaddr || echo "192.168.1.1")
echo ""
echo "GUI Status: RUNNING"
echo "GUI URL: http://$router_ip:$port"
else
echo ""
echo "GUI Status: NOT RUNNING"
fi
}
# Show logs
cmd_logs() {
if [ "$1" = "-f" ]; then
logread -f -e mmpm
else
logread -e mmpm | tail -100
fi
}
# Run MMPM GUI (called by procd)
cmd_service_run() {
check_mm2_running || return 1
if ! is_mmpm_installed; then
log_error "MMPM not installed"
return 1
fi
load_config
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"
}
# Stop MMPM GUI
cmd_service_stop() {
# Kill mmpm gui process in container
lxc-attach -n "$LXC_NAME" -- pkill -f "mmpm gui" 2>/dev/null || true
log_info "MMPM GUI stopped"
}
# Search modules
cmd_search() {
local query="$1"
check_mm2_running || return 1
if ! is_mmpm_installed; then
log_error "MMPM not installed"
return 1
fi
if [ -z "$query" ]; then
log_error "Search query required"
return 1
fi
lxc-attach -n "$LXC_NAME" -- mmpm search "$query"
}
# List installed modules
cmd_list() {
check_mm2_running || return 1
if ! is_mmpm_installed; then
log_error "MMPM not installed"
return 1
fi
lxc-attach -n "$LXC_NAME" -- mmpm list
}
# Install module via MMPM
cmd_module_install() {
local module="$1"
check_mm2_running || return 1
if ! is_mmpm_installed; then
log_error "MMPM not installed"
return 1
fi
if [ -z "$module" ]; then
log_error "Module name required"
return 1
fi
log_info "Installing module: $module"
lxc-attach -n "$LXC_NAME" -- mmpm install "$module" --yes
}
# Remove module via MMPM
cmd_module_remove() {
local module="$1"
check_mm2_running || return 1
if ! is_mmpm_installed; then
log_error "MMPM not installed"
return 1
fi
if [ -z "$module" ]; then
log_error "Module name required"
return 1
fi
log_info "Removing module: $module"
lxc-attach -n "$LXC_NAME" -- mmpm remove "$module" --yes
}
# Upgrade modules
cmd_upgrade() {
local module="$1"
check_mm2_running || return 1
if ! is_mmpm_installed; then
log_error "MMPM not installed"
return 1
fi
if [ -n "$module" ]; then
log_info "Upgrading module: $module"
lxc-attach -n "$LXC_NAME" -- mmpm upgrade "$module" --yes
else
log_info "Upgrading all modules..."
lxc-attach -n "$LXC_NAME" -- mmpm upgrade --yes
fi
}
# Open shell in container
cmd_shell() {
check_mm2_running || return 1
lxc-attach -n "$LXC_NAME" -- /bin/sh
}
# Main entry point
case "${1:-}" in
install) shift; cmd_install "$@" ;;
update) shift; cmd_update "$@" ;;
status) shift; cmd_status "$@" ;;
logs) shift; cmd_logs "$@" ;;
shell) shift; cmd_shell "$@" ;;
service-run) shift; cmd_service_run "$@" ;;
service-stop) shift; cmd_service_stop "$@" ;;
search) shift; cmd_search "$@" ;;
list) shift; cmd_list "$@" ;;
install-module) shift; cmd_module_install "$@" ;;
remove) shift; cmd_module_remove "$@" ;;
upgrade) shift; cmd_upgrade "$@" ;;
help|--help|-h|'') usage ;;
*) echo "Unknown command: $1" >&2; usage >&2; exit 1 ;;
esac