增加修改测试Gunicorn的问题

This commit is contained in:
2025-08-29 21:33:35 +08:00
parent 901b978cc8
commit c59ba98e8c
5 changed files with 222 additions and 25 deletions

View File

@@ -617,8 +617,16 @@ class GunicornInstallThread(QThread):
self.progress_updated.emit(10)
# 检查Gunicorn是否已安装
logger.info("检查Gunicorn是否已安装")
stdin, stdout, stderr = self.ssh_client.exec_command("gunicorn --version")
exit_status = stdout.channel.recv_exit_status()
gunicorn_version = stdout.read().decode().strip()
version_error = stderr.read().decode()
logger.info(f"Gunicorn版本检查状态: {exit_status}")
logger.info(f"Gunicorn版本信息: {gunicorn_version}")
if version_error:
logger.error(f"Gunicorn版本检查错误: {version_error}")
if gunicorn_version:
self.result_ready.emit(True, f"Gunicorn已安装: {gunicorn_version}")
@@ -628,34 +636,80 @@ class GunicornInstallThread(QThread):
self.progress_updated.emit(30)
# 尝试使用pip安装
logger.info("开始使用pip安装Gunicorn")
stdin, stdout, stderr = self.ssh_client.exec_command("pip3 install gunicorn")
exit_status = stdout.channel.recv_exit_status()
install_output = stdout.read().decode()
install_error = stderr.read().decode()
logger.info(f"Gunicorn pip安装命令执行状态: {exit_status}")
logger.info(f"Gunicorn pip安装输出: {install_output}")
if install_error:
logger.error(f"Gunicorn pip安装错误: {install_error}")
if exit_status == 0:
self.progress_updated.emit(90)
# 验证安装
logger.info("验证Gunicorn安装")
stdin, stdout, stderr = self.ssh_client.exec_command("gunicorn --version")
version_exit_status = stdout.channel.recv_exit_status()
gunicorn_version = stdout.read().decode().strip()
self.result_ready.emit(True, f"Gunicorn安装成功: {gunicorn_version}")
logger.info(f"Gunicorn安装成功: {gunicorn_version}")
version_error = stderr.read().decode()
logger.info(f"Gunicorn版本检查状态: {version_exit_status}")
logger.info(f"Gunicorn版本信息: {gunicorn_version}")
if version_error:
logger.error(f"Gunicorn版本检查错误: {version_error}")
if gunicorn_version:
self.result_ready.emit(True, f"Gunicorn安装成功: {gunicorn_version}")
logger.info(f"Gunicorn安装成功: {gunicorn_version}")
else:
self.result_ready.emit(False, "Gunicorn安装后无法获取版本信息")
logger.error("Gunicorn安装后无法获取版本信息")
return
self.progress_updated.emit(50)
# 如果pip安装失败尝试使用apt安装
logger.info("pip安装失败尝试使用apt安装Gunicorn")
if self.password:
logger.info("使用密码进行sudo apt安装")
stdin, stdout, stderr = self.ssh_client.exec_command("sudo -S apt update && sudo -S apt install -y gunicorn")
stdin.write(f"{self.password}\n")
stdin.flush()
else:
logger.info("无密码进行sudo apt安装")
stdin, stdout, stderr = self.ssh_client.exec_command("sudo apt update && sudo apt install -y gunicorn")
exit_status = stdout.channel.recv_exit_status()
apt_output = stdout.read().decode()
apt_error = stderr.read().decode()
logger.info(f"Gunicorn apt安装命令执行状态: {exit_status}")
logger.info(f"Gunicorn apt安装输出: {apt_output}")
if apt_error:
logger.error(f"Gunicorn apt安装错误: {apt_error}")
if exit_status == 0:
self.progress_updated.emit(90)
# 验证安装
logger.info("验证apt安装的Gunicorn")
stdin, stdout, stderr = self.ssh_client.exec_command("gunicorn --version")
version_exit_status = stdout.channel.recv_exit_status()
gunicorn_version = stdout.read().decode().strip()
self.result_ready.emit(True, f"Gunicorn安装成功: {gunicorn_version}")
logger.info(f"Gunicorn安装成功: {gunicorn_version}")
version_error = stderr.read().decode()
logger.info(f"Gunicorn版本检查状态: {version_exit_status}")
logger.info(f"Gunicorn版本信息: {gunicorn_version}")
if version_error:
logger.error(f"Gunicorn版本检查错误: {version_error}")
if gunicorn_version:
self.result_ready.emit(True, f"Gunicorn安装成功: {gunicorn_version}")
logger.info(f"Gunicorn安装成功: {gunicorn_version}")
else:
self.result_ready.emit(False, "Gunicorn安装后无法获取版本信息")
logger.error("Gunicorn安装后无法获取版本信息")
else:
error = stderr.read().decode()
self.result_ready.emit(False, f"Gunicorn安装失败: {error}")
@@ -671,10 +725,12 @@ class GunicornTestThread(QThread):
result_ready = Signal(bool, str)
progress_updated = Signal(int)
def __init__(self, ssh_client, django_path):
def __init__(self, ssh_client, django_path, port="8000"):
super().__init__()
self.ssh_client = ssh_client
self.django_path = django_path
self.port = port
logger.info(f"GunicornTestThread初始化 - Django路径: {django_path}, 端口: {port}")
def run(self):
try:
@@ -716,38 +772,45 @@ class GunicornTestThread(QThread):
# wsgi.py在项目根目录中使用manage.py所在目录名作为项目名
project_name = os.path.basename(self.django_path.rstrip('/'))
logger.info(f"使用项目名: {project_name}, 工作目录: {self.django_path}")
self.progress_updated.emit(50)
# 测试Gunicorn启动
test_command = f"cd {self.django_path} && timeout 10 gunicorn --workers 1 --bind 0.0.0.0:8001 {project_name}.wsgi:application --timeout 5"
# 测试Gunicorn启动,使用构造函数中传入的端口参数
test_command = f"cd {self.django_path} && timeout 10 gunicorn --workers 1 --bind 0.0.0.0:{self.port} {project_name}.wsgi:application --timeout 5"
logger.info(f"执行Gunicorn测试命令: {test_command}")
stdin, stdout, stderr = self.ssh_client.exec_command(test_command)
time.sleep(3) # 等待Gunicorn启动
# 检查Gunicorn是否运行
stdin, stdout, stderr = self.ssh_client.exec_command("ps aux | grep gunicorn")
output = stdout.read().decode()
logger.info(f"Gunicorn进程检查结果: {output}")
# 清理测试进程
stdin, stdout, stderr = self.ssh_client.exec_command("pkill -f 'gunicorn.*8001'")
stdin, stdout, stderr = self.ssh_client.exec_command(f"pkill -f 'gunicorn.*{self.port}'")
if "gunicorn" in output and "8001" in output:
if "gunicorn" in output and f":{self.port}" in output:
self.progress_updated.emit(100)
self.result_ready.emit(True, f"Gunicorn测试成功 - 项目: {project_name}")
logger.info(f"Gunicorn测试成功 - 项目: {project_name}")
self.result_ready.emit(True, f"Gunicorn测试成功 - 项目: {project_name}, 端口: {self.port}")
logger.info(f"Gunicorn测试成功 - 项目: {project_name}, 端口: {self.port}")
else:
# 尝试更简单的测试方式
self.progress_updated.emit(80)
test_command2 = f"cd {self.django_path} && python3 -c \"import {project_name}.wsgi; print('WSGI导入成功')\""
logger.info(f"执行WSGI导入测试: {test_command2}")
stdin, stdout, stderr = self.ssh_client.exec_command(test_command2)
exit_status = stdout.channel.recv_exit_status()
if exit_status == 0:
wsgi_output = stdout.read().decode()
logger.info(f"WSGI导入测试成功: {wsgi_output}")
self.result_ready.emit(True, f"WSGI配置验证成功 - 项目: {project_name}")
logger.info(f"WSGI配置验证成功 - 项目: {project_name}")
else:
error_output = stderr.read().decode()
self.result_ready.emit(False, f"Gunicorn测试失败: {error_output}")
logger.error(f"Gunicorn测试失败: {error_output}")
self.result_ready.emit(False, f"Gunicorn测试失败: {error_output}")
except Exception as e:
error_msg = str(e)
@@ -873,12 +936,14 @@ class UploadGunicornServiceThread(QThread):
class ManageGunicornServiceThread(QThread):
result_ready = Signal(bool, str)
def __init__(self, ssh_client, service_name, action, password=None):
def __init__(self, ssh_client, service_name, action, password=None, port="8000"):
super().__init__()
self.ssh_client = ssh_client
self.service_name = service_name
self.action = action
self.password = password
self.port = port
logger.info(f"ManageGunicornServiceThread初始化 - 服务名: {service_name}, 操作: {action}, 端口: {port}")
def run(self):
try:
@@ -910,32 +975,77 @@ class ManageGunicornServiceThread(QThread):
# 状态命令需要特殊处理
if self.password:
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo -S {cmd}")
# 立即写入密码并关闭stdin
stdin.write(f"{self.password}\n")
stdin.flush()
stdin.close()
# 等待命令执行完成
exit_status = stdout.channel.recv_exit_status()
logger.info(f"服务状态查询命令执行完成,退出状态: {exit_status}")
# 读取输出和错误
output = stdout.read().decode()
error = stderr.read().decode()
# 检查是否仍然提示输入密码
if "password for" in error.lower() and exit_status != 0:
logger.error(f"密码传递失败,仍然提示输入密码: {error}")
self.result_ready.emit(False, error)
return
else:
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo {cmd}")
exit_status = stdout.channel.recv_exit_status()
exit_status = stdout.channel.recv_exit_status()
# 读取输出和错误
output = stdout.read().decode()
error = stderr.read().decode()
if exit_status == 0:
output = stdout.read().decode()
logger.info(f"服务状态查询成功: {service_name_for_systemd}")
self.result_ready.emit(True, output)
else:
error = stderr.read().decode()
logger.error(f"服务状态查询失败: {error}")
self.result_ready.emit(False, error)
else:
# 其他操作start, stop, restart, enable, disable
if self.password:
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo -S {cmd}")
# 立即写入密码并关闭stdin
stdin.write(f"{self.password}\n")
stdin.flush()
stdin.close()
# 等待命令执行完成
exit_status = stdout.channel.recv_exit_status()
logger.info(f"服务{self.action}命令执行完成,退出状态: {exit_status}")
# 读取错误输出
error = stderr.read().decode()
# 检查是否仍然提示输入密码
if "password for" in error.lower() and exit_status != 0:
logger.error(f"密码传递失败,仍然提示输入密码: {error}")
self.result_ready.emit(False, error)
return
else:
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo {cmd}")
exit_status = stdout.channel.recv_exit_status()
exit_status = stdout.channel.recv_exit_status()
if exit_status == 0:
logger.info(f"服务{self.action}成功: {service_name_for_systemd}")
# 如果是启动操作,额外检查服务状态
if self.action == "start":
time.sleep(2) # 等待服务完全启动
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo systemctl status {service_name_for_systemd}")
status_exit_status = stdout.channel.recv_exit_status()
status_output = stdout.read().decode()
status_error = stderr.read().decode()
if status_exit_status == 0:
logger.info(f"服务启动后状态检查成功: {status_output}")
# 检查端口是否被监听,从服务名称中提取端口
port = "8000" # 默认端口
if hasattr(self, 'port') and self.port:
port = self.port
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo netstat -tlnp | grep :{port}")
netstat_output = stdout.read().decode()
logger.info(f"端口{port}监听状态: {netstat_output}")
else:
logger.warning(f"服务启动后状态检查失败: {status_error}")
self.result_ready.emit(True, f"服务{self.action}成功: {service_name_for_systemd}")
else:
error = stderr.read().decode()