1125 lines
51 KiB
Python
1125 lines
51 KiB
Python
import os
|
||
import sys
|
||
import json
|
||
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
|
||
QLabel, QTextEdit, QFileDialog, QMessageBox,
|
||
QLineEdit, QDialog, QDialogButtonBox)
|
||
from PySide6.QtCore import QThread, Signal
|
||
from loguru import logger
|
||
|
||
class PasswordDialog(QDialog):
|
||
def __init__(self, parent=None):
|
||
super().__init__(parent)
|
||
self.setWindowTitle("输入密码")
|
||
self.setMinimumWidth(300)
|
||
|
||
layout = QVBoxLayout()
|
||
|
||
# 提示标签
|
||
label = QLabel("请输入sudo密码:")
|
||
layout.addWidget(label)
|
||
|
||
# 密码输入框
|
||
self.password_input = QLineEdit()
|
||
self.password_input.setEchoMode(QLineEdit.Password)
|
||
layout.addWidget(self.password_input)
|
||
|
||
# 按钮
|
||
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||
button_box.accepted.connect(self.accept)
|
||
button_box.rejected.connect(self.reject)
|
||
layout.addWidget(button_box)
|
||
|
||
self.setLayout(layout)
|
||
|
||
def get_password(self):
|
||
return self.password_input.text()
|
||
|
||
class NginxInstallThread(QThread):
|
||
"""安装Nginx的线程"""
|
||
result_ready = Signal(bool, str)
|
||
|
||
def __init__(self, ssh_client, password):
|
||
super().__init__()
|
||
self.ssh_client = ssh_client
|
||
self.password = password
|
||
|
||
def run(self):
|
||
try:
|
||
logger.info("开始安装Nginx")
|
||
|
||
# 使用bash -c将命令组合在一起,确保密码对所有sudo命令有效
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(f"bash -c 'echo \"{self.password}\" | sudo -S apt update && echo \"{self.password}\" | sudo -S apt install -y nginx'")
|
||
exit_status = stdout.channel.recv_exit_status()
|
||
|
||
output = stdout.read().decode()
|
||
error = stderr.read().decode()
|
||
|
||
if exit_status == 0:
|
||
# 验证安装
|
||
logger.info("验证Nginx安装")
|
||
stdin, stdout, stderr = self.ssh_client.exec_command("nginx -v")
|
||
version_exit_status = stdout.channel.recv_exit_status()
|
||
nginx_version = stdout.read().decode().strip()
|
||
version_error = stderr.read().decode()
|
||
|
||
logger.info(f"Nginx版本检查状态: {version_exit_status}")
|
||
logger.info(f"Nginx版本信息: {nginx_version}")
|
||
if version_error:
|
||
logger.error(f"Nginx版本检查错误: {version_error}")
|
||
|
||
if nginx_version:
|
||
self.result_ready.emit(True, f"Nginx安装成功: {nginx_version}")
|
||
logger.info(f"Nginx安装成功: {nginx_version}")
|
||
else:
|
||
self.result_ready.emit(False, "Nginx安装后无法获取版本信息")
|
||
logger.error("Nginx安装后无法获取版本信息")
|
||
else:
|
||
self.result_ready.emit(False, f"Nginx安装失败: {error}")
|
||
logger.error(f"Nginx安装失败: {error}")
|
||
|
||
except Exception as e:
|
||
error_msg = str(e)
|
||
self.result_ready.emit(False, error_msg)
|
||
logger.error(f"Nginx安装异常: {error_msg}")
|
||
|
||
class NginxConfigThread(QThread):
|
||
"""处理Nginx配置文件的线程"""
|
||
result_ready = Signal(bool, str)
|
||
|
||
def __init__(self, ssh_client, config_content, config_path, password, operation="upload"):
|
||
super().__init__()
|
||
self.ssh_client = ssh_client
|
||
self.config_content = config_content
|
||
self.config_path = config_path
|
||
self.password = password
|
||
self.operation = operation # "upload" 或 "download"
|
||
|
||
def run(self):
|
||
try:
|
||
logger.info(f"开始处理Nginx配置文件: {self.config_path}, 操作: {self.operation}")
|
||
|
||
if self.operation == "upload":
|
||
# 上传配置文件
|
||
# 创建临时文件
|
||
temp_file = "/tmp/nginx_config.conf"
|
||
|
||
# 将配置内容写入临时文件
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(f"cat > {temp_file} << 'EOF'\n{self.config_content}\nEOF")
|
||
exit_status = stdout.channel.recv_exit_status()
|
||
|
||
if exit_status != 0:
|
||
error = stderr.read().decode()
|
||
self.result_ready.emit(False, f"创建临时文件失败: {error}")
|
||
logger.error(f"创建临时文件失败: {error}")
|
||
return
|
||
|
||
# 备份原配置文件
|
||
backup_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S cp {self.config_path} {self.config_path}.bak'"
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(backup_cmd)
|
||
backup_status = stdout.channel.recv_exit_status()
|
||
|
||
if backup_status != 0:
|
||
error = stderr.read().decode()
|
||
logger.warning(f"备份原配置文件失败: {error}")
|
||
|
||
# 移动临时文件到目标位置
|
||
move_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S mv {temp_file} {self.config_path}'"
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(move_cmd)
|
||
move_status = stdout.channel.recv_exit_status()
|
||
|
||
if move_status == 0:
|
||
self.result_ready.emit(True, f"配置文件上传成功: {self.config_path}")
|
||
logger.info(f"配置文件上传成功: {self.config_path}")
|
||
else:
|
||
error = stderr.read().decode()
|
||
self.result_ready.emit(False, f"配置文件上传失败: {error}")
|
||
logger.error(f"配置文件上传失败: {error}")
|
||
|
||
elif self.operation == "download":
|
||
# 下载配置文件
|
||
download_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S cat {self.config_path}'"
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(download_cmd)
|
||
exit_status = stdout.channel.recv_exit_status()
|
||
|
||
if exit_status == 0:
|
||
config_content = stdout.read().decode()
|
||
self.result_ready.emit(True, config_content)
|
||
logger.info(f"配置文件下载成功: {self.config_path}")
|
||
else:
|
||
error = stderr.read().decode()
|
||
self.result_ready.emit(False, f"配置文件下载失败: {error}")
|
||
logger.error(f"配置文件下载失败: {error}")
|
||
|
||
except Exception as e:
|
||
error_msg = str(e)
|
||
self.result_ready.emit(False, error_msg)
|
||
logger.error(f"Nginx配置文件处理异常: {error_msg}")
|
||
|
||
class NginxControlThread(QThread):
|
||
"""控制Nginx服务的线程"""
|
||
result_ready = Signal(bool, str)
|
||
|
||
def __init__(self, ssh_client, password, action):
|
||
super().__init__()
|
||
self.ssh_client = ssh_client
|
||
self.password = password
|
||
self.action = action # "restart", "enable", "disable", "status"
|
||
|
||
def run(self):
|
||
try:
|
||
logger.info(f"开始执行Nginx服务操作: {self.action}")
|
||
|
||
if self.action == "restart":
|
||
command = f"bash -c 'echo \"{self.password}\" | sudo -S systemctl restart nginx'"
|
||
elif self.action == "enable":
|
||
command = f"bash -c 'echo \"{self.password}\" | sudo -S systemctl enable nginx'"
|
||
elif self.action == "disable":
|
||
command = f"bash -c 'echo \"{self.password}\" | sudo -S systemctl disable nginx'"
|
||
elif self.action == "status":
|
||
command = f"bash -c 'echo \"{self.password}\" | sudo -S systemctl status nginx'"
|
||
elif self.action == "configtest":
|
||
command = f"bash -c 'echo \"{self.password}\" | sudo -S nginx -t'"
|
||
else:
|
||
self.result_ready.emit(False, f"不支持的操作: {self.action}")
|
||
logger.error(f"不支持的操作: {self.action}")
|
||
return
|
||
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(command)
|
||
exit_status = stdout.channel.recv_exit_status()
|
||
|
||
output = stdout.read().decode()
|
||
error = stderr.read().decode()
|
||
|
||
if exit_status == 0:
|
||
self.result_ready.emit(True, f"Nginx {self.action} 操作成功\n{output}")
|
||
logger.info(f"Nginx {self.action} 操作成功")
|
||
else:
|
||
self.result_ready.emit(False, f"Nginx {self.action} 操作失败: {error}")
|
||
logger.error(f"Nginx {self.action} 操作失败: {error}")
|
||
|
||
except Exception as e:
|
||
error_msg = str(e)
|
||
self.result_ready.emit(False, error_msg)
|
||
logger.error(f"Nginx服务控制异常: {error_msg}")
|
||
|
||
class NginxPermissionsThread(QThread):
|
||
"""设置Nginx权限的线程"""
|
||
result_ready = Signal(bool, str)
|
||
|
||
def __init__(self, ssh_client, commands, password):
|
||
super().__init__()
|
||
self.ssh_client = ssh_client
|
||
self.commands = commands # 命令列表
|
||
self.password = password
|
||
|
||
def run(self):
|
||
try:
|
||
logger.info("开始执行Nginx权限设置操作")
|
||
|
||
# 执行所有命令
|
||
for i, command in enumerate(self.commands):
|
||
logger.info(f"执行命令 {i+1}/{len(self.commands)}: {command}")
|
||
|
||
# 使用bash -c将命令组合在一起,确保密码对所有sudo命令有效
|
||
# 使用-S选项让sudo从标准输入读取密码
|
||
full_command = f"bash -c 'echo \"{self.password}\" | sudo -S {command}'"
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(full_command)
|
||
exit_status = stdout.channel.recv_exit_status()
|
||
|
||
output = stdout.read().decode()
|
||
error = stderr.read().decode()
|
||
|
||
if exit_status != 0:
|
||
error_msg = f"命令执行失败: {command}\n错误信息: {error}"
|
||
self.result_ready.emit(False, error_msg)
|
||
logger.error(error_msg)
|
||
return
|
||
|
||
logger.info(f"命令执行成功: {command}")
|
||
|
||
# 所有命令执行成功
|
||
success_msg = "所有权限设置命令执行成功"
|
||
self.result_ready.emit(True, success_msg)
|
||
logger.info(success_msg)
|
||
|
||
except Exception as e:
|
||
error_msg = str(e)
|
||
self.result_ready.emit(False, error_msg)
|
||
logger.error(f"Nginx权限设置异常: {error_msg}")
|
||
|
||
class NginxSiteThread(QThread):
|
||
"""处理Nginx站点配置的线程"""
|
||
result_ready = Signal(bool, str)
|
||
|
||
def __init__(self, ssh_client, site_config, site_name, password, operation="create"):
|
||
super().__init__()
|
||
self.ssh_client = ssh_client
|
||
self.site_config = site_config
|
||
self.site_name = site_name
|
||
self.password = password
|
||
self.operation = operation # "create" 或 "enable" 或 "download"
|
||
|
||
def run(self):
|
||
try:
|
||
logger.info(f"开始处理Nginx站点配置: {self.site_name}, 操作: {self.operation}")
|
||
|
||
if self.operation == "create":
|
||
# 创建站点配置文件
|
||
site_path = f"/etc/nginx/sites-available/{self.site_name}"
|
||
|
||
# 创建临时文件
|
||
temp_file = f"/tmp/{self.site_name}.conf"
|
||
|
||
# 将配置内容写入临时文件
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(f"cat > {temp_file} << 'EOF'\n{self.site_config}\nEOF")
|
||
exit_status = stdout.channel.recv_exit_status()
|
||
|
||
if exit_status != 0:
|
||
error = stderr.read().decode()
|
||
self.result_ready.emit(False, f"创建临时文件失败: {error}")
|
||
logger.error(f"创建临时文件失败: {error}")
|
||
return
|
||
|
||
# 移动临时文件到目标位置
|
||
move_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S mv {temp_file} {site_path}'"
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(move_cmd)
|
||
move_status = stdout.channel.recv_exit_status()
|
||
|
||
if move_status == 0:
|
||
self.result_ready.emit(True, f"站点配置文件创建成功: {site_path}")
|
||
logger.info(f"站点配置文件创建成功: {site_path}")
|
||
else:
|
||
error = stderr.read().decode()
|
||
self.result_ready.emit(False, f"站点配置文件创建失败: {error}")
|
||
logger.error(f"站点配置文件创建失败: {error}")
|
||
|
||
elif self.operation == "enable":
|
||
# 启用站点配置
|
||
# 首先检查目标链接是否存在,如果存在则先删除
|
||
check_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S test -f /etc/nginx/sites-enabled/{self.site_name}'"
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(check_cmd)
|
||
check_status = stdout.channel.recv_exit_status()
|
||
|
||
if check_status == 0:
|
||
# 目标链接存在,先删除
|
||
remove_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S rm -f /etc/nginx/sites-enabled/{self.site_name}'"
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(remove_cmd)
|
||
remove_status = stdout.channel.recv_exit_status()
|
||
|
||
if remove_status != 0:
|
||
error = stderr.read().decode()
|
||
self.result_ready.emit(False, f"删除现有符号链接失败: {error}")
|
||
logger.error(f"删除现有符号链接失败: {error}")
|
||
return
|
||
|
||
# 创建符号链接
|
||
enable_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S ln -s /etc/nginx/sites-available/{self.site_name} /etc/nginx/sites-enabled/'"
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(enable_cmd)
|
||
exit_status = stdout.channel.recv_exit_status()
|
||
|
||
if exit_status == 0:
|
||
self.result_ready.emit(True, f"站点配置启用成功: {self.site_name}")
|
||
logger.info(f"站点配置启用成功: {self.site_name}")
|
||
else:
|
||
error = stderr.read().decode()
|
||
self.result_ready.emit(False, f"站点配置启用失败: {error}")
|
||
logger.error(f"站点配置启用失败: {error}")
|
||
|
||
elif self.operation == "download":
|
||
# 下载站点配置文件
|
||
site_path = f"/etc/nginx/sites-enabled/{self.site_name}"
|
||
download_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S cat {site_path}'"
|
||
stdin, stdout, stderr = self.ssh_client.exec_command(download_cmd)
|
||
exit_status = stdout.channel.recv_exit_status()
|
||
|
||
if exit_status == 0:
|
||
config_content = stdout.read().decode()
|
||
self.result_ready.emit(True, config_content)
|
||
logger.info(f"站点配置文件下载成功: {site_path}")
|
||
else:
|
||
error = stderr.read().decode()
|
||
self.result_ready.emit(False, f"站点配置文件下载失败: {error}")
|
||
logger.error(f"站点配置文件下载失败: {error}")
|
||
|
||
except Exception as e:
|
||
error_msg = str(e)
|
||
self.result_ready.emit(False, error_msg)
|
||
logger.error(f"Nginx站点配置处理异常: {error_msg}")
|
||
|
||
class NginxTab(QWidget):
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.ssh_client = None
|
||
self.username = ""
|
||
self.project_name = ""
|
||
self.server_ip = ""
|
||
self.init_ui()
|
||
|
||
def init_ui(self):
|
||
layout = QVBoxLayout()
|
||
|
||
# Nginx安装区域
|
||
install_layout = QHBoxLayout()
|
||
|
||
# 安装Nginx按钮
|
||
self.install_nginx_btn = QPushButton("安装Nginx")
|
||
self.install_nginx_btn.clicked.connect(self.install_nginx)
|
||
install_layout.addWidget(self.install_nginx_btn)
|
||
|
||
layout.addLayout(install_layout)
|
||
|
||
# Nginx主配置文件区域
|
||
main_config_layout = QVBoxLayout()
|
||
main_config_layout.addWidget(QLabel("Nginx主配置文件编辑器:"))
|
||
|
||
# 主配置文件编辑文本框
|
||
self.main_config_editor = QTextEdit()
|
||
self.main_config_editor.setReadOnly(False)
|
||
main_config_layout.addWidget(self.main_config_editor)
|
||
|
||
# 主配置文件操作按钮
|
||
main_config_btn_layout = QHBoxLayout()
|
||
|
||
# 下载主配置文件按钮
|
||
self.download_main_config_btn = QPushButton("下载主配置文件")
|
||
self.download_main_config_btn.clicked.connect(self.download_main_config)
|
||
main_config_btn_layout.addWidget(self.download_main_config_btn)
|
||
|
||
# 上传主配置文件按钮
|
||
self.upload_main_config_btn = QPushButton("上传主配置文件")
|
||
self.upload_main_config_btn.clicked.connect(self.upload_main_config)
|
||
main_config_btn_layout.addWidget(self.upload_main_config_btn)
|
||
|
||
main_config_layout.addLayout(main_config_btn_layout)
|
||
layout.addLayout(main_config_layout)
|
||
|
||
# Nginx站点配置区域
|
||
site_config_layout = QVBoxLayout()
|
||
site_config_layout.addWidget(QLabel("Nginx站点配置编辑器:"))
|
||
|
||
# 站点配置编辑文本框
|
||
self.site_config_editor = QTextEdit()
|
||
self.site_config_editor.setReadOnly(False)
|
||
site_config_layout.addWidget(self.site_config_editor)
|
||
|
||
# 站点配置操作按钮
|
||
site_config_btn_layout = QHBoxLayout()
|
||
|
||
# 创建站点配置按钮
|
||
self.create_site_config_btn = QPushButton("创建站点配置")
|
||
self.create_site_config_btn.clicked.connect(self.create_site_config)
|
||
site_config_btn_layout.addWidget(self.create_site_config_btn)
|
||
|
||
# 启用站点配置按钮
|
||
self.enable_site_config_btn = QPushButton("启用站点配置")
|
||
self.enable_site_config_btn.clicked.connect(self.enable_site_config)
|
||
site_config_btn_layout.addWidget(self.enable_site_config_btn)
|
||
|
||
# 下载站点配置按钮
|
||
self.download_site_config_btn = QPushButton("下载站点配置")
|
||
self.download_site_config_btn.clicked.connect(self.download_site_config)
|
||
site_config_btn_layout.addWidget(self.download_site_config_btn)
|
||
|
||
# 添加静态文件映射按钮
|
||
self.add_static_mappings_btn = QPushButton("添加静态文件映射")
|
||
self.add_static_mappings_btn.clicked.connect(self.add_static_mappings)
|
||
site_config_btn_layout.addWidget(self.add_static_mappings_btn)
|
||
|
||
# 修改为Unix socket连接按钮
|
||
self.modify_to_unix_socket_btn = QPushButton("修改为Unix Socket连接")
|
||
self.modify_to_unix_socket_btn.clicked.connect(self.modify_to_unix_socket)
|
||
site_config_btn_layout.addWidget(self.modify_to_unix_socket_btn)
|
||
|
||
site_config_layout.addLayout(site_config_btn_layout)
|
||
layout.addLayout(site_config_layout)
|
||
|
||
# Nginx控制区域
|
||
control_layout = QHBoxLayout()
|
||
|
||
# 重启Nginx按钮
|
||
self.restart_nginx_btn = QPushButton("重启Nginx")
|
||
self.restart_nginx_btn.clicked.connect(self.restart_nginx)
|
||
control_layout.addWidget(self.restart_nginx_btn)
|
||
|
||
# 查看Nginx状态按钮
|
||
self.check_nginx_status_btn = QPushButton("查看Nginx状态")
|
||
self.check_nginx_status_btn.clicked.connect(self.check_nginx_status)
|
||
control_layout.addWidget(self.check_nginx_status_btn)
|
||
|
||
# 一键赋予权限按钮
|
||
self.set_permissions_btn = QPushButton("一键赋予权限")
|
||
self.set_permissions_btn.clicked.connect(self.set_permissions)
|
||
control_layout.addWidget(self.set_permissions_btn)
|
||
|
||
layout.addLayout(control_layout)
|
||
|
||
# 输出区域
|
||
self.output_text = QTextEdit()
|
||
self.output_text.setReadOnly(True)
|
||
layout.addWidget(self.output_text)
|
||
|
||
self.setLayout(layout)
|
||
|
||
# 初始化配置文件内容
|
||
self.init_config_content()
|
||
|
||
def init_config_content(self):
|
||
"""初始化配置文件内容"""
|
||
# 初始化主配置文件内容
|
||
main_config_content = '''# 全局块:配置Nginx进程的基本运行参数
|
||
user www-data; # Nginx进程运行的用户/组(默认是www-data,不是你的登录用户xiaji)
|
||
worker_processes auto; # 工作进程数,auto表示自动匹配CPU核心数
|
||
pid /run/nginx.pid; # Nginx进程PID文件路径
|
||
include /etc/nginx/modules-enabled/*.conf; # 加载启用的模块配置
|
||
|
||
|
||
# events块:配置Nginx与客户端的网络连接
|
||
events {
|
||
worker_connections 768; # 每个工作进程的最大并发连接数
|
||
# multi_accept on; # 可选:允许工作进程同时接受多个连接(默认注释)
|
||
}
|
||
|
||
|
||
# http块:配置HTTP服务的全局参数(核心部分)
|
||
http {
|
||
##
|
||
# 基础配置
|
||
##
|
||
sendfile on; # 启用高效文件传输模式
|
||
tcp_nopush on; # 配合sendfile使用,优化TCP传输
|
||
tcp_nodelay on; # 禁用Nagle算法,减少小数据包延迟
|
||
keepalive_timeout 65; # 长连接超时时间(秒)
|
||
types_hash_max_size 2048; # 类型哈希表的最大大小(优化MIME类型查找)
|
||
|
||
include /etc/nginx/mime.types; # 加载MIME类型映射文件
|
||
default_type application/octet-stream; # 默认MIME类型(未匹配时返回二进制流)
|
||
|
||
##
|
||
# 日志配置
|
||
##
|
||
access_log /var/log/nginx/access.log; # 访问日志路径
|
||
error_log /var/log/nginx/error.log; # 错误日志路径
|
||
|
||
##
|
||
# SSL/TLS配置(全局默认值)
|
||
##
|
||
ssl_protocols TLSv1.2 TLSv1.3; # 支持的SSL/TLS协议(禁用不安全的旧协议)
|
||
ssl_prefer_server_ciphers on; # 优先使用服务器端指定的加密套件
|
||
|
||
##
|
||
# Gzip压缩配置
|
||
##
|
||
gzip on; # 启用Gzip压缩
|
||
# gzip_vary on; # 可选:在响应头添加Vary: Accept-Encoding(默认注释)
|
||
# gzip_proxied any; # 可选:对代理请求也启用压缩(默认注释)
|
||
# gzip_comp_level 6; # 可选:压缩级别(1-9,默认6)(默认注释)
|
||
# gzip_buffers 16 8k; # 可选:压缩缓冲区大小(默认注释)
|
||
# gzip_http_version 1.1; # 可选:支持的HTTP版本(默认注释)
|
||
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # 可选:指定压缩的MIME类型(默认注释)
|
||
|
||
##
|
||
# 加载站点配置(关键:默认站点配置不在nginx.conf里,而是通过include引入)
|
||
##
|
||
include /etc/nginx/conf.d/*.conf; # 加载conf.d目录下的自定义配置
|
||
include /etc/nginx/sites-enabled/*; # 加载启用的站点配置(默认站点在这里)
|
||
}
|
||
|
||
|
||
# 可选:加载流处理配置(如TCP/UDP代理,默认注释)
|
||
# include /etc/nginx/streams-enabled/*.conf;'''
|
||
self.main_config_editor.setPlainText(main_config_content)
|
||
|
||
# 初始化站点配置文件内容
|
||
site_config_content = "server {\n"
|
||
site_config_content += " listen 80;\n"
|
||
site_config_content += " server_name 【IP地址】;\n\n"
|
||
site_config_content += " # 转发动态请求到Gunicorn\n"
|
||
site_config_content += " location / {\n"
|
||
site_config_content += " proxy_pass http://【IP地址】:8000;\n"
|
||
site_config_content += " proxy_set_header Host $host;\n"
|
||
site_config_content += " proxy_set_header X-Real-IP $remote_addr;\n"
|
||
site_config_content += " }\n"
|
||
site_config_content += "}\n"
|
||
self.site_config_editor.setPlainText(site_config_content)
|
||
|
||
def update_config_content(self):
|
||
"""更新配置文件内容"""
|
||
# 更新主配置文件内容
|
||
main_config_content = self.main_config_editor.toPlainText()
|
||
main_config_content = main_config_content.replace("xiaji", self.username)
|
||
self.main_config_editor.setPlainText(main_config_content)
|
||
|
||
# 更新站点配置文件内容
|
||
site_config_content = self.site_config_editor.toPlainText()
|
||
site_config_content = site_config_content.replace("【IP地址】", self.server_ip)
|
||
self.site_config_editor.setPlainText(site_config_content)
|
||
|
||
def set_ssh_client(self, ssh_client):
|
||
"""设置SSH客户端"""
|
||
self.ssh_client = ssh_client
|
||
logger.info("Nginx标签页已设置SSH客户端")
|
||
|
||
def set_username(self, username):
|
||
"""设置用户名"""
|
||
self.username = username
|
||
logger.info(f"Nginx标签页已设置用户名: {username}")
|
||
|
||
def set_project_info(self, project_name, server_ip):
|
||
"""设置项目信息"""
|
||
self.project_name = project_name
|
||
self.server_ip = server_ip
|
||
logger.info(f"Nginx标签页已设置项目信息: {project_name}, {server_ip}")
|
||
|
||
# 更新配置文件内容
|
||
self.update_config_content()
|
||
|
||
def append_output(self, text):
|
||
"""添加输出到文本框"""
|
||
self.output_text.append(text)
|
||
|
||
def install_nginx(self):
|
||
"""安装Nginx"""
|
||
if not self.ssh_client:
|
||
self.append_output("错误: 未连接到服务器")
|
||
return
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
self.append_output("正在安装Nginx...")
|
||
|
||
# 创建并启动Nginx安装线程
|
||
self.install_thread = NginxInstallThread(self.ssh_client, password)
|
||
self.install_thread.result_ready.connect(self.on_install_result)
|
||
self.install_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
|
||
def on_install_result(self, success, message):
|
||
"""处理安装结果"""
|
||
if success:
|
||
self.append_output(f"安装成功: {message}")
|
||
logger.info(f"Nginx安装成功: {message}")
|
||
QMessageBox.information(self, "成功", message)
|
||
else:
|
||
self.append_output(f"安装失败: {message}")
|
||
logger.error(f"Nginx安装失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx安装失败: {message}")
|
||
|
||
def download_main_config(self):
|
||
"""下载主配置文件"""
|
||
if not self.ssh_client:
|
||
self.append_output("错误: 未连接到服务器")
|
||
return
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
self.append_output("正在下载Nginx主配置文件...")
|
||
|
||
# 创建并启动配置文件下载线程
|
||
self.config_thread = NginxConfigThread(self.ssh_client, "", "/etc/nginx/nginx.conf", password, "download")
|
||
self.config_thread.result_ready.connect(self.on_download_main_config_result)
|
||
self.config_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
|
||
def on_download_main_config_result(self, success, message):
|
||
"""处理下载主配置文件结果"""
|
||
if success:
|
||
self.main_config_editor.setPlainText(message)
|
||
self.append_output("主配置文件下载成功")
|
||
logger.info("Nginx主配置文件下载成功")
|
||
else:
|
||
self.append_output(f"主配置文件下载失败: {message}")
|
||
logger.error(f"Nginx主配置文件下载失败: {message}")
|
||
|
||
def upload_main_config(self):
|
||
"""上传主配置文件"""
|
||
if not self.ssh_client:
|
||
self.append_output("错误: 未连接到服务器")
|
||
return
|
||
|
||
config_content = self.main_config_editor.toPlainText()
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
self.append_output("正在上传Nginx主配置文件...")
|
||
|
||
# 创建并启动配置文件上传线程
|
||
self.config_thread = NginxConfigThread(self.ssh_client, config_content, "/etc/nginx/nginx.conf", password, "upload")
|
||
self.config_thread.result_ready.connect(self.on_upload_main_config_result)
|
||
self.config_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
|
||
def on_upload_main_config_result(self, success, message):
|
||
"""处理上传主配置文件结果"""
|
||
if success:
|
||
self.append_output(f"上传成功: {message}")
|
||
logger.info(f"Nginx主配置文件上传成功: {message}")
|
||
QMessageBox.information(self, "成功", message)
|
||
|
||
# 上传主配置文件后检查配置文件语法
|
||
self.append_output("正在检查Nginx配置文件语法...")
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
|
||
# 创建并启动Nginx配置检查线程
|
||
self.check_thread = NginxControlThread(self.ssh_client, password, "configtest")
|
||
self.check_thread.result_ready.connect(self.on_upload_configtest_result)
|
||
self.check_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
else:
|
||
self.append_output(f"上传失败: {message}")
|
||
logger.error(f"Nginx主配置文件上传失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx主配置文件上传失败: {message}")
|
||
|
||
def on_upload_configtest_result(self, success, message):
|
||
"""处理上传主配置文件后的配置测试结果"""
|
||
if success:
|
||
self.append_output("配置文件语法检查通过")
|
||
logger.info("Nginx主配置文件上传后语法检查通过")
|
||
else:
|
||
self.append_output(f"配置文件语法检查失败: {message}")
|
||
logger.error(f"Nginx主配置文件上传后语法检查失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx配置文件语法检查失败: {message}")
|
||
|
||
def create_site_config(self):
|
||
"""创建站点配置"""
|
||
if not self.ssh_client:
|
||
self.append_output("错误: 未连接到服务器")
|
||
return
|
||
|
||
if not self.project_name:
|
||
self.append_output("错误: 未设置项目名")
|
||
return
|
||
|
||
site_config = self.site_config_editor.toPlainText()
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
self.append_output(f"正在创建站点配置文件: {self.project_name}...")
|
||
|
||
# 创建并启动站点配置创建线程
|
||
self.site_thread = NginxSiteThread(self.ssh_client, site_config, self.project_name, password, "create")
|
||
self.site_thread.result_ready.connect(self.on_create_site_config_result)
|
||
self.site_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
|
||
def on_create_site_config_result(self, success, message):
|
||
"""处理创建站点配置结果"""
|
||
if success:
|
||
self.append_output(f"创建成功: {message}")
|
||
logger.info(f"Nginx站点配置创建成功: {message}")
|
||
QMessageBox.information(self, "成功", message)
|
||
|
||
# 创建站点配置文件后检查配置文件语法
|
||
self.append_output("正在检查Nginx配置文件语法...")
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
|
||
# 创建并启动Nginx配置检查线程
|
||
self.check_thread = NginxControlThread(self.ssh_client, password, "configtest")
|
||
self.check_thread.result_ready.connect(self.on_create_configtest_result)
|
||
self.check_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
else:
|
||
self.append_output(f"创建失败: {message}")
|
||
logger.error(f"Nginx站点配置创建失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx站点配置创建失败: {message}")
|
||
|
||
def on_create_configtest_result(self, success, message):
|
||
"""处理创建站点配置文件后的配置测试结果"""
|
||
if success:
|
||
self.append_output("配置文件语法检查通过")
|
||
logger.info("Nginx站点配置文件创建后语法检查通过")
|
||
else:
|
||
self.append_output(f"配置文件语法检查失败: {message}")
|
||
logger.error(f"Nginx站点配置文件创建后语法检查失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx配置文件语法检查失败: {message}")
|
||
|
||
def enable_site_config(self):
|
||
"""启用站点配置"""
|
||
if not self.ssh_client:
|
||
self.append_output("错误: 未连接到服务器")
|
||
return
|
||
|
||
if not self.project_name:
|
||
self.append_output("错误: 未设置项目名")
|
||
return
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
self.append_output(f"正在启用站点配置: {self.project_name}...")
|
||
|
||
# 创建并启动站点配置启用线程
|
||
self.site_thread = NginxSiteThread(self.ssh_client, "", self.project_name, password, "enable")
|
||
self.site_thread.result_ready.connect(self.on_enable_site_config_result)
|
||
self.site_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
|
||
def on_enable_site_config_result(self, success, message):
|
||
"""处理启用站点配置结果"""
|
||
if success:
|
||
self.append_output(f"启用成功: {message}")
|
||
logger.info(f"Nginx站点配置启用成功: {message}")
|
||
QMessageBox.information(self, "成功", message)
|
||
|
||
# 启用站点后检查配置文件语法
|
||
self.append_output("正在检查Nginx配置文件语法...")
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
|
||
# 创建并启动Nginx配置检查线程
|
||
self.check_thread = NginxControlThread(self.ssh_client, password, "configtest")
|
||
self.check_thread.result_ready.connect(self.on_enable_configtest_result)
|
||
self.check_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
else:
|
||
self.append_output(f"启用失败: {message}")
|
||
logger.error(f"Nginx站点配置启用失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx站点配置启用失败: {message}")
|
||
|
||
def on_enable_configtest_result(self, success, message):
|
||
"""处理启用站点后的配置测试结果"""
|
||
if success:
|
||
self.append_output("配置文件语法检查通过")
|
||
logger.info("Nginx站点配置启用后语法检查通过")
|
||
else:
|
||
self.append_output(f"配置文件语法检查失败: {message}")
|
||
logger.error(f"Nginx站点配置启用后语法检查失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx配置文件语法检查失败: {message}")
|
||
|
||
def download_site_config(self):
|
||
"""下载站点配置文件"""
|
||
if not self.ssh_client:
|
||
self.append_output("错误: 未连接到服务器")
|
||
return
|
||
|
||
if not self.project_name:
|
||
self.append_output("错误: 未设置项目名")
|
||
return
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
self.append_output(f"正在下载站点配置文件: {self.project_name}...")
|
||
|
||
# 创建并启动站点配置下载线程
|
||
self.site_thread = NginxSiteThread(self.ssh_client, "", self.project_name, password, "download")
|
||
self.site_thread.result_ready.connect(self.on_download_site_config_result)
|
||
self.site_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
|
||
def on_download_site_config_result(self, success, message):
|
||
"""处理下载站点配置结果"""
|
||
if success:
|
||
# 将下载的配置内容显示在站点配置编辑器中
|
||
self.site_config_editor.setPlainText(message)
|
||
self.append_output("站点配置文件下载成功")
|
||
logger.info("Nginx站点配置文件下载成功")
|
||
|
||
# 尝试添加静态文件映射配置
|
||
self.add_static_mappings()
|
||
else:
|
||
self.append_output(f"下载失败: {message}")
|
||
logger.error(f"Nginx站点配置文件下载失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx站点配置文件下载失败: {message}")
|
||
|
||
def add_static_mappings(self):
|
||
"""添加静态文件映射配置"""
|
||
# 读取config.json文件获取项目信息
|
||
try:
|
||
with open('config.json', 'r', encoding='utf-8') as f:
|
||
config = json.load(f)
|
||
|
||
# 获取第一个服务器配置(假设只有一个服务器配置)
|
||
server_config = next(iter(config.values()))
|
||
username = server_config.get('username', '')
|
||
project_name = server_config.get('project', '')
|
||
git_url = server_config.get('git_url', '')
|
||
|
||
# 从git_url中提取项目名(.git前的值)
|
||
if git_url:
|
||
# 提取git_url中最后一个/和.git之间的部分
|
||
if '/' in git_url:
|
||
git_project_name = git_url.split('/')[-1]
|
||
if git_project_name.endswith('.git'):
|
||
git_project_name = git_project_name[:-4] # 移除.git后缀
|
||
else:
|
||
git_project_name = 'webstatus' # 默认值
|
||
else:
|
||
git_project_name = 'webstatus' # 默认值
|
||
|
||
# 根据要求构建静态文件路径
|
||
# 静态文件结构为: /home/[username]/[git_url中的项目名]/[project]/static
|
||
# 媒体文件结构为: /home/[username]/[git_url中的项目名]/[project]/media
|
||
static_path = f"/home/{username}/{git_project_name}/static"
|
||
media_path = f"/home/{username}/{git_project_name}/media"
|
||
|
||
# 获取当前配置内容
|
||
current_config = self.site_config_editor.toPlainText()
|
||
|
||
# 检查是否已经包含静态文件映射
|
||
if "location /static/" not in current_config:
|
||
# 添加静态文件映射配置
|
||
static_mapping = f"\n # 静态文件映射 (路径: /home/{username}/{git_project_name}/{project_name}/static)\n"
|
||
static_mapping += f" location /static/ {{\n"
|
||
static_mapping += f" alias {static_path}/;\n"
|
||
static_mapping += f" expires 30d;\n"
|
||
static_mapping += f" }}\n"
|
||
|
||
# 添加媒体文件映射配置
|
||
static_mapping += f"\n # 媒体文件映射 (路径: /home/{username}/{git_project_name}/{project_name}/media)\n"
|
||
static_mapping += f" location /media/ {{\n"
|
||
static_mapping += f" alias {media_path}/;\n"
|
||
static_mapping += f" expires 30d;\n"
|
||
static_mapping += f" }}\n"
|
||
|
||
# 在server块的末尾添加静态文件映射(在最后一个}之前)
|
||
last_brace_pos = current_config.rfind('}')
|
||
if last_brace_pos != -1:
|
||
new_config = current_config[:last_brace_pos] + static_mapping + current_config[last_brace_pos:]
|
||
self.site_config_editor.setPlainText(new_config)
|
||
self.append_output("已添加静态文件映射配置")
|
||
logger.info("已添加静态文件映射配置")
|
||
else:
|
||
self.append_output("无法添加静态文件映射配置:未找到server块的结束位置")
|
||
logger.warning("无法添加静态文件映射配置:未找到server块的结束位置")
|
||
else:
|
||
self.append_output("配置文件已包含静态文件映射")
|
||
logger.info("配置文件已包含静态文件映射")
|
||
|
||
except Exception as e:
|
||
error_msg = str(e)
|
||
self.append_output(f"添加静态文件映射失败: {error_msg}")
|
||
logger.error(f"添加静态文件映射失败: {error_msg}")
|
||
|
||
def modify_to_unix_socket(self):
|
||
"""修改站点配置文件中的proxy_pass为Unix socket连接"""
|
||
# 读取config.json文件获取项目信息
|
||
try:
|
||
with open('config.json', 'r', encoding='utf-8') as f:
|
||
config = json.load(f)
|
||
|
||
# 获取第一个服务器配置(假设只有一个服务器配置)
|
||
server_config = next(iter(config.values()))
|
||
username = server_config.get('username', '')
|
||
git_url = server_config.get('git_url', '')
|
||
|
||
# 从git_url中提取项目名(.git前的值)
|
||
if git_url:
|
||
# 提取git_url中最后一个/和.git之间的部分
|
||
if '/' in git_url:
|
||
project_name = git_url.split('/')[-1]
|
||
if project_name.endswith('.git'):
|
||
project_name = project_name[:-4] # 移除.git后缀
|
||
else:
|
||
project_name = 'webstatus' # 默认值
|
||
else:
|
||
project_name = 'webstatus' # 默认值
|
||
|
||
# 构建Unix socket路径
|
||
unix_socket_path = f"http://unix:/home/{username}/{project_name}/sock/gunicorn.sock"
|
||
|
||
# 获取当前配置内容
|
||
current_config = self.site_config_editor.toPlainText()
|
||
|
||
# 查找并替换proxy_pass的值
|
||
import re
|
||
# 使用正则表达式匹配proxy_pass行
|
||
pattern = r'(\s+proxy_pass\s+)(http://[^;]+|unix:[^;]+);'
|
||
replacement = f'\1{unix_socket_path};'
|
||
|
||
new_config = re.sub(pattern, replacement, current_config)
|
||
|
||
if new_config != current_config:
|
||
# 更新配置内容
|
||
self.site_config_editor.setPlainText(new_config)
|
||
self.append_output(f"已将proxy_pass修改为: {unix_socket_path}")
|
||
logger.info(f"已将proxy_pass修改为: {unix_socket_path}")
|
||
else:
|
||
# 检查是否已经是Unix socket连接
|
||
if unix_socket_path in current_config:
|
||
self.append_output("配置文件已经是Unix socket连接")
|
||
logger.info("配置文件已经是Unix socket连接")
|
||
else:
|
||
self.append_output("未找到可修改的proxy_pass配置")
|
||
logger.warning("未找到可修改的proxy_pass配置")
|
||
|
||
except Exception as e:
|
||
error_msg = str(e)
|
||
self.append_output(f"修改为Unix socket连接失败: {error_msg}")
|
||
logger.error(f"修改为Unix socket连接失败: {error_msg}")
|
||
|
||
def restart_nginx(self):
|
||
"""重启Nginx"""
|
||
if not self.ssh_client:
|
||
self.append_output("错误: 未连接到服务器")
|
||
return
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
self.append_output("正在检查Nginx配置文件语法...")
|
||
|
||
# 创建并启动Nginx配置检查线程
|
||
self.check_thread = NginxControlThread(self.ssh_client, password, "configtest")
|
||
self.check_thread.result_ready.connect(self.on_configtest_result)
|
||
self.check_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
|
||
def on_configtest_result(self, success, message):
|
||
"""处理配置测试结果"""
|
||
if success:
|
||
self.append_output("配置文件语法检查通过,正在重启Nginx...")
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
|
||
# 创建并启动Nginx控制线程
|
||
self.control_thread = NginxControlThread(self.ssh_client, password, "restart")
|
||
self.control_thread.result_ready.connect(self.on_control_result)
|
||
self.control_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
else:
|
||
self.append_output(f"配置文件语法检查失败: {message}")
|
||
logger.error(f"Nginx配置文件语法检查失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx配置文件语法检查失败: {message}")
|
||
|
||
def check_nginx_status(self):
|
||
"""查看Nginx状态"""
|
||
if not self.ssh_client:
|
||
self.append_output("错误: 未连接到服务器")
|
||
return
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
self.append_output("正在查看Nginx状态...")
|
||
|
||
# 创建并启动Nginx控制线程
|
||
self.control_thread = NginxControlThread(self.ssh_client, password, "status")
|
||
self.control_thread.result_ready.connect(self.on_control_result)
|
||
self.control_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
|
||
def on_control_result(self, success, message):
|
||
"""处理控制结果"""
|
||
if success:
|
||
self.append_output(f"操作成功: {message}")
|
||
logger.info(f"Nginx服务控制成功: {message}")
|
||
QMessageBox.information(self, "成功", message)
|
||
else:
|
||
self.append_output(f"操作失败: {message}")
|
||
logger.error(f"Nginx服务控制失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"Nginx服务控制失败: {message}")
|
||
|
||
def set_permissions(self):
|
||
"""一键赋予权限"""
|
||
if not self.ssh_client:
|
||
self.append_output("错误: 未连接到服务器")
|
||
return
|
||
|
||
# 读取config.json文件获取username和git_url
|
||
try:
|
||
with open('config.json', 'r', encoding='utf-8') as f:
|
||
config = json.load(f)
|
||
|
||
# 获取第一个服务器配置(假设只有一个服务器配置)
|
||
server_config = next(iter(config.values()))
|
||
username = server_config.get('username', '')
|
||
git_url = server_config.get('git_url', '')
|
||
|
||
# 从git_url中提取项目名(.git前的值)
|
||
if git_url:
|
||
# 提取git_url中最后一个/和.git之间的部分
|
||
if '/' in git_url:
|
||
project_name = git_url.split('/')[-1]
|
||
if project_name.endswith('.git'):
|
||
project_name = project_name[:-4] # 移除.git后缀
|
||
else:
|
||
project_name = 'webstatus' # 默认值
|
||
else:
|
||
project_name = 'webstatus' # 默认值
|
||
|
||
logger.info(f"从配置文件获取用户名: {username}, 项目名: {project_name}")
|
||
|
||
except Exception as e:
|
||
error_msg = str(e)
|
||
self.append_output(f"读取配置文件失败: {error_msg}")
|
||
logger.error(f"读取配置文件失败: {error_msg}")
|
||
QMessageBox.warning(self, "错误", f"读取配置文件失败: {error_msg}")
|
||
return
|
||
|
||
# 请求用户输入sudo密码
|
||
dialog = PasswordDialog(self)
|
||
if dialog.exec_() == QDialog.Accepted:
|
||
password = dialog.get_password()
|
||
self.append_output("正在设置权限...")
|
||
|
||
# 构建命令序列
|
||
commands = [
|
||
f"sudo chmod g+x /home/{username}/",
|
||
f"sudo chown -R {username}:www-data /home/{username}/{project_name}",
|
||
f"sudo chmod g+x /home/{username}/{project_name}",
|
||
f"sudo chown -R {username}:www-data /home/{username}/{project_name}/sock",
|
||
f"sudo chmod -R 770 /home/{username}/{project_name}/sock",
|
||
# 修复/home/xiaji目录权限
|
||
f"sudo chmod o+r /home/{username}",
|
||
# 修复后验证权限(应显示drwxr-xr-x)
|
||
f"ls -ld /home/{username}",
|
||
# 验证www-data能否正常访问目录
|
||
f"sudo -u www-data ls /home/{username}/{project_name}/static/admin/css/"
|
||
]
|
||
|
||
# 创建并启动权限设置线程
|
||
self.permissions_thread = NginxPermissionsThread(self.ssh_client, commands, password)
|
||
self.permissions_thread.result_ready.connect(self.on_permissions_result)
|
||
self.permissions_thread.start()
|
||
else:
|
||
self.append_output("用户取消了密码输入")
|
||
|
||
def on_permissions_result(self, success, message):
|
||
"""处理权限设置结果"""
|
||
if success:
|
||
self.append_output(f"权限设置成功: {message}")
|
||
logger.info(f"权限设置成功: {message}")
|
||
QMessageBox.information(self, "成功", message)
|
||
else:
|
||
self.append_output(f"权限设置失败: {message}")
|
||
logger.error(f"权限设置失败: {message}")
|
||
QMessageBox.warning(self, "错误", f"权限设置失败: {message}") |