diff --git a/web_interface/blueprints/api_v3.py b/web_interface/blueprints/api_v3.py index 5911fd5a..cc551588 100644 --- a/web_interface/blueprints/api_v3.py +++ b/web_interface/blueprints/api_v3.py @@ -2,6 +2,7 @@ from flask import Blueprint, request, jsonify, Response, send_from_directory import json import os import re +import shutil import socket import sys import subprocess @@ -16,6 +17,11 @@ from typing import Optional, Tuple, Dict, Any, Type logger = logging.getLogger(__name__) +SUDO_BIN = shutil.which("sudo") or "/usr/bin/sudo" +SYSTEMCTL_BIN = shutil.which("systemctl") or "/usr/bin/systemctl" +REBOOT_BIN = shutil.which("reboot") or "/usr/sbin/reboot" +POWEROFF_BIN = shutil.which("poweroff") or "/usr/sbin/poweroff" + # Import new infrastructure from src.web_interface.api_helpers import success_response, error_response, validate_request_json from src.web_interface.errors import ErrorCode @@ -218,7 +224,7 @@ def _ensure_display_service_running(): if status.get('active'): status['started'] = False return status - result = _run_systemctl_command(['sudo', 'systemctl', 'start', 'ledmatrix.service']) + result = _run_systemctl_command([SUDO_BIN, SYSTEMCTL_BIN, 'start', 'ledmatrix.service']) service_status = _get_display_service_status() result['started'] = result.get('returncode') == 0 result['active'] = service_status.get('active') @@ -227,7 +233,7 @@ def _ensure_display_service_running(): def _stop_display_service(): """Stop the ledmatrix display service.""" - result = _run_systemctl_command(['sudo', 'systemctl', 'stop', 'ledmatrix.service']) + result = _run_systemctl_command([SUDO_BIN, SYSTEMCTL_BIN, 'stop', 'ledmatrix.service']) status = _get_display_service_status() result['active'] = status.get('active') result['status'] = status @@ -1716,7 +1722,7 @@ def execute_system_action(): if mode: # For on-demand modes, we would need to integrate with the display controller # For now, just start the display service - result = subprocess.run(['sudo', 'systemctl', 'start', 'ledmatrix.service'], + result = subprocess.run([SUDO_BIN, SYSTEMCTL_BIN, 'start', 'ledmatrix.service'], capture_output=True, text=True, timeout=15) return jsonify({ 'status': 'success' if result.returncode == 0 else 'error', @@ -1727,22 +1733,22 @@ def execute_system_action(): 'stderr': result.stderr }) else: - result = subprocess.run(['sudo', 'systemctl', 'start', 'ledmatrix.service'], + result = subprocess.run([SUDO_BIN, SYSTEMCTL_BIN, 'start', 'ledmatrix.service'], capture_output=True, text=True, timeout=15) elif action == 'stop_display': - result = subprocess.run(['sudo', 'systemctl', 'stop', 'ledmatrix.service'], + result = subprocess.run([SUDO_BIN, SYSTEMCTL_BIN, 'stop', 'ledmatrix.service'], capture_output=True, text=True, timeout=15) elif action == 'enable_autostart': - result = subprocess.run(['sudo', 'systemctl', 'enable', 'ledmatrix.service'], + result = subprocess.run([SUDO_BIN, SYSTEMCTL_BIN, 'enable', 'ledmatrix.service'], capture_output=True, text=True, timeout=15) elif action == 'disable_autostart': - result = subprocess.run(['sudo', 'systemctl', 'disable', 'ledmatrix.service'], + result = subprocess.run([SUDO_BIN, SYSTEMCTL_BIN, 'disable', 'ledmatrix.service'], capture_output=True, text=True, timeout=15) elif action == 'reboot_system': - result = subprocess.run(['sudo', 'reboot'], + result = subprocess.run([SUDO_BIN, REBOOT_BIN], capture_output=True, text=True, timeout=10) elif action == 'shutdown_system': - result = subprocess.run(['sudo', 'poweroff'], + result = subprocess.run([SUDO_BIN, POWEROFF_BIN], capture_output=True, text=True, timeout=10) elif action == 'git_pull': # Use PROJECT_ROOT instead of hardcoded path @@ -1824,10 +1830,10 @@ def execute_system_action(): 'stderr': result.stderr }) elif action == 'restart_display_service': - result = subprocess.run(['sudo', 'systemctl', 'restart', 'ledmatrix.service'], + result = subprocess.run([SUDO_BIN, SYSTEMCTL_BIN, 'restart', 'ledmatrix.service'], capture_output=True, text=True, timeout=15) elif action == 'restart_web_service': - result = subprocess.run(['sudo', 'systemctl', 'restart', 'ledmatrix-web.service'], + result = subprocess.run([SUDO_BIN, SYSTEMCTL_BIN, 'restart', 'ledmatrix-web.service'], capture_output=True, text=True, timeout=15) else: return jsonify({'status': 'error', 'message': f'Unknown action: {action}'}), 400