|
|
@@ -15,6 +15,8 @@ from django.utils import timezone
|
|
|
import threading
|
|
|
import sys
|
|
|
import signal
|
|
|
+import platform
|
|
|
+import subprocess
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@@ -426,40 +428,18 @@ def restore_to_point(request):
|
|
|
def _shutdown_system(delay=5):
|
|
|
"""延迟关闭系统"""
|
|
|
def shutdown():
|
|
|
- logger.critical("系统正在关闭...")
|
|
|
try:
|
|
|
- # 停止调度器
|
|
|
if scheduler.running:
|
|
|
scheduler.shutdown(wait=False)
|
|
|
logger.info("定时任务调度器已停止")
|
|
|
except Exception as e:
|
|
|
logger.error(f"停止调度器失败: {str(e)}")
|
|
|
-
|
|
|
- # 记录关闭日志
|
|
|
- try:
|
|
|
- OperationLog.objects.create(
|
|
|
- operator="系统远程关闭",
|
|
|
- operation_content="系统已通过远程接口关闭",
|
|
|
- operation_level="critical",
|
|
|
- operation_result="success",
|
|
|
- ip_address=None,
|
|
|
- user_agent="系统远程关闭接口",
|
|
|
- request_method="SHUTDOWN",
|
|
|
- request_path="/backup/shutdown",
|
|
|
- module_name="系统管理"
|
|
|
- )
|
|
|
- except Exception as log_error:
|
|
|
- logger.error(f"关闭日志记录失败: {str(log_error)}")
|
|
|
-
|
|
|
- # 强制退出
|
|
|
- logger.critical("系统关闭完成,正在退出...")
|
|
|
os._exit(0)
|
|
|
|
|
|
# 使用线程延迟执行关闭
|
|
|
timer = threading.Timer(delay, shutdown)
|
|
|
timer.daemon = True
|
|
|
timer.start()
|
|
|
- logger.warning(f"系统将在 {delay} 秒后关闭")
|
|
|
|
|
|
@csrf_exempt
|
|
|
@require_POST
|
|
|
@@ -473,41 +453,80 @@ def shutdown_system(request):
|
|
|
if delay < 1 or delay > 60:
|
|
|
delay = 5
|
|
|
|
|
|
- # 记录关闭请求日志
|
|
|
- try:
|
|
|
- operator_name = request.user.username if hasattr(request, 'user') and request.user.is_authenticated else "未知用户"
|
|
|
- ip_address = request.META.get('REMOTE_ADDR', '未知IP')
|
|
|
- log_success_operation(
|
|
|
- request=request,
|
|
|
- operation_content=f"远程关闭系统请求,延迟时间: {delay}秒",
|
|
|
- operation_level="critical",
|
|
|
- module_name="系统管理"
|
|
|
- )
|
|
|
- except Exception as log_error:
|
|
|
- logger.error(f"关闭请求日志记录失败: {str(log_error)}")
|
|
|
-
|
|
|
- logger.critical(f"收到系统关闭请求,将在 {delay} 秒后关闭系统")
|
|
|
-
|
|
|
- # 启动延迟关闭
|
|
|
_shutdown_system(delay=delay)
|
|
|
|
|
|
return JsonResponse({
|
|
|
'status': 'success',
|
|
|
- 'message': f'系统将在 {delay} 秒后关闭',
|
|
|
+ 'message': f' {delay} ',
|
|
|
'delay': delay
|
|
|
})
|
|
|
|
|
|
except Exception as e:
|
|
|
logger.error(f"处理系统关闭请求失败: {str(e)}", exc_info=True)
|
|
|
+
|
|
|
+
|
|
|
+ return JsonResponse({
|
|
|
+ 'status': 'error',
|
|
|
+ 'message': f'{str(e)}'
|
|
|
+ }, status=500)
|
|
|
+
|
|
|
+@csrf_exempt
|
|
|
+@require_POST
|
|
|
+def shutdown_computer(request):
|
|
|
+
|
|
|
+ try:
|
|
|
+ data = json.loads(request.body) if request.body else {}
|
|
|
+ delay = int(data.get('delay', 60))
|
|
|
+
|
|
|
+ if delay < 0 or delay > 600:
|
|
|
+ delay = 60
|
|
|
+ system = platform.system()
|
|
|
try:
|
|
|
- log_failure_operation(
|
|
|
- request=request,
|
|
|
- operation_content=f"远程关闭系统请求失败: {str(e)}",
|
|
|
- operation_level="critical",
|
|
|
- module_name="系统管理"
|
|
|
- )
|
|
|
- except Exception as log_error:
|
|
|
- logger.error(f"关闭失败日志记录失败: {str(log_error)}")
|
|
|
+ if system == "Windows":
|
|
|
+
|
|
|
+ subprocess.run(["shutdown", "/s", "/t", str(delay), "/f"], check=True)
|
|
|
+ elif system == "Linux":
|
|
|
+
|
|
|
+ subprocess.run(["shutdown", "-h", "+" + str(delay // 60) if delay >= 60 else "now"], check=True)
|
|
|
+ elif system == "Darwin":
|
|
|
+
|
|
|
+ subprocess.run(["sudo", "shutdown", "-h", "+" + str(delay // 60) if delay >= 60 else "now"], check=True)
|
|
|
+ else:
|
|
|
+ return JsonResponse({
|
|
|
+ 'status': 'error',
|
|
|
+ 'message': f'不支持的操作系统: {system}'
|
|
|
+ }, status=400)
|
|
|
+
|
|
|
+ return JsonResponse({
|
|
|
+ 'status': 'success',
|
|
|
+ 'message': f' {delay} 秒',
|
|
|
+ 'delay': delay,
|
|
|
+ 'system': system
|
|
|
+ })
|
|
|
+
|
|
|
+ except subprocess.CalledProcessError as e:
|
|
|
+ logger.error(f"执行失败: {str(e)}")
|
|
|
+
|
|
|
+ return JsonResponse({
|
|
|
+ 'status': 'error',
|
|
|
+ 'message': f'{str(e)}'
|
|
|
+ }, status=500)
|
|
|
+ except PermissionError:
|
|
|
+ logger.error("关闭失败: 权限不足")
|
|
|
+
|
|
|
+ return JsonResponse({
|
|
|
+ 'status': 'error',
|
|
|
+ 'message': '权限不足'
|
|
|
+ }, status=403)
|
|
|
+
|
|
|
+ except ValueError:
|
|
|
+ return JsonResponse({
|
|
|
+ 'status': 'error',
|
|
|
+ 'message': '无效的延迟时间参数'
|
|
|
+ }, status=400)
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"关闭失败: {str(e)}", exc_info=True)
|
|
|
+
|
|
|
return JsonResponse({
|
|
|
'status': 'error',
|
|
|
'message': f'处理关闭请求失败: {str(e)}'
|