增加修改测试Gunicorn的问题
This commit is contained in:
Binary file not shown.
Binary file not shown.
59
app.log
59
app.log
@@ -115,3 +115,62 @@
|
||||
2025-08-29 21:18:18.748 | INFO | threads:run:907 - 服务文件存在: -rw-r--r-- 1 xiaji xiaji 703 Aug 28 22:27 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-29 21:18:18.818 | ERROR | threads:run:925 - 服务状态查询失败: [sudo] password for xiaji:
|
||||
2025-08-29 21:18:18.819 | ERROR | gunicorn_tab:on_manage_service_result:476 - 服务操作失败: [sudo] password for xiaji:
|
||||
2025-08-29 21:22:59.668 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-29 21:22:59.708 | INFO | remote_command_tab:load_git_config:109 - 从配置文件加载git配置: git_url=http://192.168.3.241:3000/xiaji/webstatus, project_path=/home/xiaji/
|
||||
2025-08-29 21:22:59.710 | INFO | django_tab:load_django_path:116 - 从当前服务器配置加载Django路径: /home/xiaji/
|
||||
2025-08-29 21:22:59.710 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-29 21:22:59.712 | INFO | gunicorn_tab:load_gunicorn_config:191 - 从当前服务器配置加载Gunicorn配置: remote_directory=/home/xiaji/, project_name=statuspage
|
||||
2025-08-29 21:22:59.712 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-29 21:23:01.913 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-29 21:23:08.980 | INFO | gunicorn_tab:manage_service:451 - 正在执行服务 status 操作,服务名称: gunicorn_django
|
||||
2025-08-29 21:23:08.984 | INFO | gunicorn_tab:get_password:313 - 密码为空,弹出密码输入对话框
|
||||
2025-08-29 21:23:12.876 | INFO | gunicorn_tab:get_password:317 - 从对话框获取密码,长度: 5
|
||||
2025-08-29 21:23:12.877 | INFO | gunicorn_tab:manage_service:468 - 获取到密码,长度: 5,创建ManageGunicornServiceThread线程
|
||||
2025-08-29 21:23:12.878 | INFO | threads:run:893 - 执行服务管理命令: systemctl status gunicorn_django
|
||||
2025-08-29 21:23:12.886 | INFO | threads:run:907 - 服务文件存在: -rw-r--r-- 1 xiaji xiaji 703 Aug 28 22:27 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-29 21:23:12.955 | INFO | threads:run:917 - 服务状态查询命令执行完成,退出状态: 3
|
||||
2025-08-29 21:23:12.956 | ERROR | threads:run:928 - 服务状态查询失败: [sudo] password for xiaji:
|
||||
2025-08-29 21:23:12.957 | ERROR | gunicorn_tab:on_manage_service_result:483 - 服务操作失败: [sudo] password for xiaji:
|
||||
2025-08-29 21:23:12.957 | WARNING | gunicorn_tab:on_manage_service_result:487 - 检测到可能的密码问题,提示用户重新输入密码
|
||||
2025-08-29 21:24:05.472 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-29 21:24:05.509 | INFO | remote_command_tab:load_git_config:109 - 从配置文件加载git配置: git_url=http://192.168.3.241:3000/xiaji/webstatus, project_path=/home/xiaji/
|
||||
2025-08-29 21:24:05.510 | INFO | django_tab:load_django_path:116 - 从当前服务器配置加载Django路径: /home/xiaji/
|
||||
2025-08-29 21:24:05.511 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-29 21:24:05.512 | INFO | gunicorn_tab:load_gunicorn_config:191 - 从当前服务器配置加载Gunicorn配置: remote_directory=/home/xiaji/, project_name=statuspage
|
||||
2025-08-29 21:24:05.512 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-29 21:24:07.760 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-29 21:24:09.577 | INFO | gunicorn_tab:manage_service:451 - 正在执行服务 status 操作,服务名称: gunicorn_django
|
||||
2025-08-29 21:24:09.582 | INFO | gunicorn_tab:get_password:313 - 密码为空,弹出密码输入对话框
|
||||
2025-08-29 21:24:12.781 | INFO | gunicorn_tab:get_password:317 - 从对话框获取密码,长度: 5
|
||||
2025-08-29 21:24:12.781 | INFO | gunicorn_tab:manage_service:468 - 获取到密码,长度: 5,创建ManageGunicornServiceThread线程
|
||||
2025-08-29 21:24:12.783 | INFO | threads:run:893 - 执行服务管理命令: systemctl status gunicorn_django
|
||||
2025-08-29 21:24:12.791 | INFO | threads:run:907 - 服务文件存在: -rw-r--r-- 1 xiaji xiaji 703 Aug 28 22:27 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-29 21:24:12.862 | INFO | threads:run:918 - 服务状态查询命令执行完成,退出状态: 0
|
||||
2025-08-29 21:24:12.863 | INFO | threads:run:933 - 服务状态查询成功: gunicorn_django
|
||||
2025-08-29 21:24:12.866 | INFO | gunicorn_tab:on_manage_service_result:480 - 服务操作成功:
|
||||
2025-08-29 21:26:22.602 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-29 21:26:22.655 | INFO | remote_command_tab:load_git_config:109 - 从配置文件加载git配置: git_url=http://192.168.3.241:3000/xiaji/webstatus, project_path=/home/xiaji/
|
||||
2025-08-29 21:26:22.656 | INFO | django_tab:load_django_path:116 - 从当前服务器配置加载Django路径: /home/xiaji/
|
||||
2025-08-29 21:26:22.656 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-29 21:26:22.657 | INFO | gunicorn_tab:load_gunicorn_config:191 - 从当前服务器配置加载Gunicorn配置: remote_directory=/home/xiaji/, project_name=statuspage
|
||||
2025-08-29 21:26:22.658 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-29 21:26:24.338 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-29 21:27:33.792 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-29 21:27:33.828 | INFO | remote_command_tab:load_git_config:109 - 从配置文件加载git配置: git_url=http://192.168.3.241:3000/xiaji/webstatus, project_path=/home/xiaji/
|
||||
2025-08-29 21:27:33.829 | INFO | django_tab:load_django_path:116 - 从当前服务器配置加载Django路径: /home/xiaji/
|
||||
2025-08-29 21:27:33.830 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-29 21:27:33.831 | INFO | gunicorn_tab:load_gunicorn_config:191 - 从当前服务器配置加载Gunicorn配置: remote_directory=/home/xiaji/, project_name=statuspage
|
||||
2025-08-29 21:27:33.832 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-29 21:27:36.356 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-29 21:27:40.666 | INFO | threads:run:705 - 找到wsgi.py文件: /home/xiaji/statuspage/wsgi.py
|
||||
2025-08-29 21:27:43.798 | INFO | threads:run:736 - Gunicorn测试成功 - 项目: statuspage
|
||||
2025-08-29 21:27:43.799 | INFO | gunicorn_tab:on_test_gunicorn_result:385 - Gunicorn测试成功: Gunicorn测试成功 - 项目: statuspage
|
||||
2025-08-29 21:27:54.236 | INFO | threads:run:397 - Django测试服务器启动成功
|
||||
2025-08-29 21:27:54.238 | INFO | django_tab:on_test_django_result:193 - Django测试启动成功: Django测试服务器启动成功
|
||||
2025-08-29 21:28:12.058 | INFO | threads:run:705 - 找到wsgi.py文件: /home/xiaji/statuspage/wsgi.py
|
||||
2025-08-29 21:28:15.177 | INFO | threads:run:736 - Gunicorn测试成功 - 项目: statuspage
|
||||
2025-08-29 21:28:15.179 | INFO | gunicorn_tab:on_test_gunicorn_result:385 - Gunicorn测试成功: Gunicorn测试成功 - 项目: statuspage
|
||||
2025-08-29 21:28:21.359 | INFO | gunicorn_tab:get_password:313 - 密码为空,弹出密码输入对话框
|
||||
2025-08-29 21:28:25.808 | INFO | gunicorn_tab:get_password:317 - 从对话框获取密码,长度: 5
|
||||
2025-08-29 21:28:27.972 | INFO | gunicorn_tab:get_password:313 - 密码为空,弹出密码输入对话框
|
||||
2025-08-29 21:28:31.580 | INFO | gunicorn_tab:get_password:317 - 从对话框获取密码,长度: 5
|
||||
|
||||
@@ -223,7 +223,8 @@ class GunicornTab(QWidget):
|
||||
"""根据config.json配置生成服务文件内容"""
|
||||
username = config.get('username', 'www-data')
|
||||
project_name = config.get('project_name', 'myproject')
|
||||
django_path = config.get('remote_directory', '/home/user')
|
||||
remote_directory = config.get('remote_directory', '/home/user')
|
||||
django_path = config.get('django_path', remote_directory)
|
||||
|
||||
# 构建完整的项目路径
|
||||
project_path = f"{django_path.rstrip('/')}"
|
||||
@@ -238,8 +239,8 @@ Group={username}
|
||||
WorkingDirectory={project_path}
|
||||
# 所有Gunicorn参数直接在这里配置
|
||||
ExecStart=/usr/local/bin/gunicorn \\
|
||||
--bind 127.0.0.1:8000 \\
|
||||
--workers $(nproc --all * 2 + 1) \\
|
||||
--bind 0.0.0.0:8000 \\
|
||||
--workers 3 \\
|
||||
--worker-class sync \\
|
||||
--timeout 60 \\
|
||||
--name {project_name} \\
|
||||
@@ -306,16 +307,20 @@ WantedBy=multi-user.target"""
|
||||
password = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
password = self.parent.server_connection_tab.password_input.text()
|
||||
logger.info(f"从server_connection_tab获取密码,长度: {len(password) if password else 0}")
|
||||
|
||||
# 如果密码为空,弹出密码输入对话框
|
||||
if not password:
|
||||
logger.info("密码为空,弹出密码输入对话框")
|
||||
dialog = PasswordDialog(self)
|
||||
if dialog.exec_() == QDialog.Accepted:
|
||||
password = dialog.get_password()
|
||||
logger.info(f"从对话框获取密码,长度: {len(password) if password else 0}")
|
||||
# 保存密码到服务器连接标签页
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
self.parent.server_connection_tab.password_input.setText(password)
|
||||
else:
|
||||
logger.warning("用户取消了密码输入")
|
||||
return None
|
||||
|
||||
return password
|
||||
@@ -355,6 +360,7 @@ WantedBy=multi-user.target"""
|
||||
logger.error(f"Gunicorn安装失败: {message}")
|
||||
|
||||
def test_gunicorn(self):
|
||||
"""测试Gunicorn配置"""
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
|
||||
@@ -362,16 +368,26 @@ WantedBy=multi-user.target"""
|
||||
if not django_path:
|
||||
QMessageBox.warning(self, "警告", "请输入Django项目路径")
|
||||
return
|
||||
|
||||
# 获取端口配置
|
||||
port = self.port_input.text().strip() or "8000"
|
||||
|
||||
self.output_text.append(f"正在测试Gunicorn {django_path}...")
|
||||
# 记录测试参数
|
||||
logger.info(f"开始测试Gunicorn,Django路径: {django_path}, 端口: {port}")
|
||||
|
||||
self.output_text.append(f"正在测试Gunicorn {django_path} (端口: {port})...")
|
||||
self.test_gunicorn_btn.setEnabled(False)
|
||||
self.progress_bar.setVisible(True)
|
||||
self.progress_bar.setValue(0)
|
||||
|
||||
self.gunicorn_test_thread = GunicornTestThread(self.parent.ssh_client, django_path)
|
||||
logger.info("创建Gunicorn测试线程")
|
||||
# 注意:GunicornTestThread构造函数可能需要更新以接受端口参数
|
||||
# 确保测试时使用的端口与实际服务启动时一致
|
||||
self.gunicorn_test_thread = GunicornTestThread(self.parent.ssh_client, django_path, port)
|
||||
self.gunicorn_test_thread.progress_updated.connect(self.update_progress)
|
||||
self.gunicorn_test_thread.result_ready.connect(self.on_test_gunicorn_result)
|
||||
self.gunicorn_test_thread.start()
|
||||
logger.info("Gunicorn测试线程已启动")
|
||||
|
||||
def on_test_gunicorn_result(self, success, message):
|
||||
self.test_gunicorn_btn.setEnabled(True)
|
||||
@@ -444,6 +460,7 @@ WantedBy=multi-user.target"""
|
||||
# 使用gunicorn_[project_name].service格式作为服务名称
|
||||
service_name = f"gunicorn_{project_name}"
|
||||
|
||||
logger.info(f"正在执行服务 {action} 操作,服务名称: {service_name}")
|
||||
self.output_text.append(f"正在执行服务 {action} 操作...")
|
||||
|
||||
# 禁用所有服务管理按钮
|
||||
@@ -455,13 +472,20 @@ WantedBy=multi-user.target"""
|
||||
# 获取密码
|
||||
password = self.get_password()
|
||||
if password is None:
|
||||
logger.warning("未获取到密码,取消服务操作")
|
||||
for btn in buttons:
|
||||
btn.setEnabled(True)
|
||||
return
|
||||
|
||||
self.manage_thread = ManageGunicornServiceThread(self.parent.ssh_client, service_name, action, password)
|
||||
# 获取端口配置
|
||||
port = self.port_input.text().strip() or "8000"
|
||||
|
||||
logger.info(f"获取到密码,长度: {len(password)},创建ManageGunicornServiceThread线程")
|
||||
logger.info(f"开始管理Gunicorn服务 - 服务名: {service_name}, 操作: {action}, 端口: {port}")
|
||||
self.manage_thread = ManageGunicornServiceThread(self.parent.ssh_client, service_name, action, password, port)
|
||||
self.manage_thread.result_ready.connect(lambda s, m: self.on_manage_service_result(s, m, buttons))
|
||||
self.manage_thread.start()
|
||||
logger.info(f"Gunicorn服务管理线程已启动 - 操作: {action}")
|
||||
|
||||
def on_manage_service_result(self, success, message, buttons):
|
||||
# 重新启用所有服务管理按钮
|
||||
@@ -474,6 +498,10 @@ WantedBy=multi-user.target"""
|
||||
else:
|
||||
self.output_text.append(f"服务操作失败: {message}")
|
||||
logger.error(f"服务操作失败: {message}")
|
||||
# 如果是密码相关错误,提供更详细的提示
|
||||
if "password" in message.lower() or "sudo" in message.lower():
|
||||
self.output_text.append("提示:请检查sudo密码是否正确,或尝试重新输入密码")
|
||||
logger.warning("检测到可能的密码问题,提示用户重新输入密码")
|
||||
|
||||
def on_server_changed(self):
|
||||
self.load_gunicorn_config()
|
||||
|
||||
148
threads.py
148
threads.py
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user