修改了Gunicorn标签内容
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
343
app.log
343
app.log
@@ -65,3 +65,346 @@ sudo: a password is required
|
||||
|
||||
2025-08-28 20:37:01.109 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 20:41:24.800 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 20:51:01.943 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 20:51:04.428 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 20:51:05.201 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 20:51:05.730 | ERROR | threads:run:836 - 服务状态查询失败: sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
|
||||
sudo: a password is required
|
||||
|
||||
2025-08-28 20:51:05.734 | ERROR | gunicorn_tab:on_manage_service_result:285 - 服务操作失败: sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
|
||||
sudo: a password is required
|
||||
|
||||
2025-08-28 20:52:55.800 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 20:52:58.689 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 20:52:59.622 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 20:53:05.630 | ERROR | threads:run:836 - 服务状态查询失败: [sudo] password for xiaji: Unit django_gunicorn.service could not be found.
|
||||
|
||||
2025-08-28 20:53:05.631 | ERROR | gunicorn_tab:on_manage_service_result:338 - 服务操作失败: [sudo] password for xiaji: Unit django_gunicorn.service could not be found.
|
||||
|
||||
2025-08-28 20:54:39.385 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 20:54:45.328 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 20:54:46.326 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 20:54:53.497 | INFO | threads:run:862 - 执行服务管理命令: systemctl status django_gunicorn
|
||||
2025-08-28 20:54:53.505 | ERROR | threads:run:871 - 服务文件不存在: /etc/systemd/system/django_gunicorn.service, 错误: ls: cannot access '/etc/systemd/system/django_gunicorn.service': No such file or directory
|
||||
|
||||
2025-08-28 20:54:53.507 | ERROR | gunicorn_tab:on_manage_service_result:338 - 服务操作失败: 服务文件不存在: django_gunicorn.service
|
||||
2025-08-28 21:00:17.337 | INFO | remote_command_tab:on_list_directory_result:186 - 目录列表成功
|
||||
2025-08-28 21:00:17.337 | INFO | threads:run:157 - 目录列表成功: /home/xiaji/
|
||||
2025-08-28 21:00:56.560 | ERROR | threads:run:559 - Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 21:00:56.560 | ERROR | django_tab:on_check_django_status_result:274 - Django状态检查失败: Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 21:01:14.969 | INFO | threads:run:157 - 目录列表成功: /home/xiaji/
|
||||
2025-08-28 21:01:14.969 | INFO | remote_command_tab:on_list_directory_result:186 - 目录列表成功
|
||||
2025-08-28 21:01:28.149 | ERROR | threads:run:559 - Django项目不存在: /home/xiaji/statuspage/
|
||||
2025-08-28 21:01:28.149 | ERROR | django_tab:on_check_django_status_result:274 - Django状态检查失败: Django项目不存在: /home/xiaji/statuspage/
|
||||
2025-08-28 21:01:32.368 | ERROR | threads:run:363 - Django项目不存在: /home/xiaji/statuspage/
|
||||
2025-08-28 21:01:32.370 | ERROR | django_tab:on_test_django_result:167 - Django测试启动失败: Django项目不存在: /home/xiaji/statuspage/
|
||||
2025-08-28 21:01:36.279 | INFO | threads:run:304 - Django已安装: 5.2.5
|
||||
2025-08-28 21:01:36.280 | INFO | django_tab:on_install_django_result:135 - Django安装成功: Django已安装: 5.2.5
|
||||
2025-08-28 21:01:39.699 | ERROR | threads:run:363 - Django项目不存在: /home/xiaji/statuspage/
|
||||
2025-08-28 21:01:39.700 | ERROR | django_tab:on_test_django_result:167 - Django测试启动失败: Django项目不存在: /home/xiaji/statuspage/
|
||||
2025-08-28 21:02:37.594 | INFO | server_connection_tab:save_config:34 - 配置文件保存成功
|
||||
2025-08-28 21:02:47.403 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:03:06.423 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:03:13.531 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:03:18.362 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:06:04.148 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:06:04.183 | ERROR | remote_command_tab:load_git_config:113 - 加载git配置失败: [Errno 2] No such file or directory: 'C:\\Users\\xiaji\\Documents\\个人文件夹\\夏骥\\config.json'
|
||||
2025-08-28 21:06:32.121 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:06:32.155 | ERROR | remote_command_tab:load_git_config:113 - 加载git配置失败: 'gbk' codec can't decode byte 0xa8 in position 56: illegal multibyte sequence
|
||||
2025-08-28 21:06:47.698 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:06:47.729 | 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-28 21:06:52.075 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:08:17.090 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:08:17.130 | 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-28 21:08:17.131 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/statuspage
|
||||
2025-08-28 21:12:20.285 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:12:28.603 | ERROR | django_tab:on_test_django_result:184 - Django测试启动失败: Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 21:12:28.603 | ERROR | threads:run:363 - Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 21:13:22.162 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:13:22.202 | 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-28 21:13:22.203 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/statuspage
|
||||
2025-08-28 21:13:27.903 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:13:39.808 | ERROR | threads:run:363 - Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 21:13:39.809 | ERROR | django_tab:on_test_django_result:184 - Django测试启动失败: Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 21:13:48.684 | INFO | threads:run:157 - 目录列表成功: /home/xiaji/
|
||||
2025-08-28 21:13:48.688 | INFO | remote_command_tab:on_list_directory_result:199 - 目录列表成功
|
||||
2025-08-28 21:16:20.769 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:16:20.810 | 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-28 21:16:20.811 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/statuspage
|
||||
2025-08-28 21:16:22.780 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:16:25.519 | ERROR | threads:run:363 - Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 21:16:25.519 | ERROR | django_tab:on_test_django_result:184 - Django测试启动失败: Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 21:16:29.049 | INFO | threads:run:157 - 目录列表成功: /home/xiaji/
|
||||
2025-08-28 21:16:29.051 | INFO | remote_command_tab:on_list_directory_result:199 - 目录列表成功:
|
||||
total 176
|
||||
drwxr-x--- 9 xiaji xiaji 4096 Aug 27 20:52 .
|
||||
drwxr-xr-x 3 root root 4096 Aug 27 04:10 ..
|
||||
drwx------ 3 xiaji xiaji 4096 Aug 26 22:21 .cache
|
||||
-rw-rw-r-- 1 xiaji xiaji 135168 Aug 26 22:18 db.sqlite3
|
||||
drwxrwxr-x 8 xiaji xiaji 4096 Aug 26 22:18 .git
|
||||
drwxrwxr-x 3 xiaji xiaji 4096 Aug 27 20:51 home
|
||||
drwxrwxr-x 4 xiaji xiaji 4096 Aug 26 22:25 .local
|
||||
-rw-rw-r-- 1 xiaji xiaji 666 Aug 26 22:18 manage.py
|
||||
-rw-rw-r-- 1 xiaji xiaji 13 Aug 26 22:18 requirements.txt
|
||||
drwxrwxr-x 3 xiaji xiaji 4096 Aug 27 20:52 static
|
||||
drwxrwxr-x 5 xiaji xiaji 4096 Aug 26 22:18 status
|
||||
drwxrwxr-x 3 xiaji xiaji 4096 Aug 28 04:20 statuspage
|
||||
-rw-r--r-- 1 xiaji xiaji 0 Aug 27 20:03 .sudo_as_admin_successful
|
||||
|
||||
2025-08-28 21:17:03.711 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:17:03.777 | 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-28 21:17:03.782 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/statuspage
|
||||
2025-08-28 21:17:09.386 | INFO | server_connection_tab:save_config:34 - 配置文件保存成功
|
||||
2025-08-28 21:17:11.652 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:17:16.174 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 21:17:18.319 | ERROR | django_tab:on_test_django_result:184 - Django测试启动失败: 依赖安装失败: error: externally-managed-environment
|
||||
|
||||
× This environment is externally managed
|
||||
╰─> To install Python packages system-wide, try apt install
|
||||
python3-xyz, where xyz is the package you are trying to
|
||||
install.
|
||||
|
||||
If you wish to install a non-Debian-packaged Python package,
|
||||
create a virtual environment using python3 -m venv path/to/venv.
|
||||
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
|
||||
sure you have python3-full installed.
|
||||
|
||||
If you wish to install a non-Debian packaged Python application,
|
||||
it may be easiest to use pipx install xyz, which will manage a
|
||||
virtual environment for you. Make sure you have pipx installed.
|
||||
|
||||
See /usr/share/doc/python3.12/README.venv for more information.
|
||||
|
||||
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
|
||||
hint: See PEP 668 for the detailed specification.
|
||||
|
||||
2025-08-28 21:17:18.319 | ERROR | threads:run:381 - 依赖安装失败: error: externally-managed-environment
|
||||
|
||||
× This environment is externally managed
|
||||
╰─> To install Python packages system-wide, try apt install
|
||||
python3-xyz, where xyz is the package you are trying to
|
||||
install.
|
||||
|
||||
If you wish to install a non-Debian-packaged Python package,
|
||||
create a virtual environment using python3 -m venv path/to/venv.
|
||||
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
|
||||
sure you have python3-full installed.
|
||||
|
||||
If you wish to install a non-Debian packaged Python application,
|
||||
it may be easiest to use pipx install xyz, which will manage a
|
||||
virtual environment for you. Make sure you have pipx installed.
|
||||
|
||||
See /usr/share/doc/python3.12/README.venv for more information.
|
||||
|
||||
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
|
||||
hint: See PEP 668 for the detailed specification.
|
||||
|
||||
2025-08-28 21:17:50.278 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:17:50.317 | 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-28 21:17:50.319 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 21:18:00.995 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:18:02.871 | INFO | threads:run:304 - Django已安装: 5.2.5
|
||||
2025-08-28 21:18:02.873 | INFO | django_tab:on_install_django_result:152 - Django安装成功: Django已安装: 5.2.5
|
||||
2025-08-28 21:19:24.402 | ERROR | threads:run:381 - 依赖安装失败:
|
||||
2025-08-28 21:19:36.038 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:19:36.077 | 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-28 21:19:36.079 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 21:19:39.142 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:21:54.132 | INFO | server_connection_tab:save_config:34 - 配置文件保存成功
|
||||
2025-08-28 21:23:22.197 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:23:22.228 | 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-28 21:23:22.229 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 21:23:24.309 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:26:27.449 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:26:27.484 | 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-28 21:26:27.485 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 21:26:29.358 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:26:39.130 | INFO | threads:run:397 - Django测试服务器启动成功
|
||||
2025-08-28 21:26:39.131 | INFO | django_tab:on_test_django_result:181 - Django测试启动成功: Django测试服务器启动成功
|
||||
2025-08-28 21:26:52.767 | INFO | threads:run:598 - Django状态检查完成
|
||||
2025-08-28 21:26:52.786 | INFO | django_tab:on_check_django_status_result:288 - Django状态检查成功
|
||||
2025-08-28 21:26:56.002 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 21:27:03.503 | INFO | threads:run:867 - 执行服务管理命令: systemctl status django_gunicorn
|
||||
2025-08-28 21:27:03.511 | ERROR | threads:run:876 - 服务文件不存在: /etc/systemd/system/django_gunicorn.service, 错误: ls: cannot access '/etc/systemd/system/django_gunicorn.service': No such file or directory
|
||||
|
||||
2025-08-28 21:27:03.512 | ERROR | gunicorn_tab:on_manage_service_result:338 - 服务操作失败: 服务文件不存在: django_gunicorn.service
|
||||
2025-08-28 21:27:54.858 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 21:28:00.516 | INFO | threads:run:867 - 执行服务管理命令: systemctl status django_gunicorn
|
||||
2025-08-28 21:28:00.525 | ERROR | threads:run:876 - 服务文件不存在: /etc/systemd/system/django_gunicorn.service, 错误: ls: cannot access '/etc/systemd/system/django_gunicorn.service': No such file or directory
|
||||
|
||||
2025-08-28 21:28:00.527 | ERROR | gunicorn_tab:on_manage_service_result:338 - 服务操作失败: 服务文件不存在: django_gunicorn.service
|
||||
2025-08-28 21:28:02.915 | ERROR | threads:run:702 - wsgi.py文件不存在: /home/xiaji///wsgi.py
|
||||
2025-08-28 21:28:02.916 | ERROR | gunicorn_tab:on_test_gunicorn_result:265 - Gunicorn测试失败: wsgi.py文件不存在: /home/xiaji///wsgi.py
|
||||
2025-08-28 21:45:10.338 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 21:45:10.373 | 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-28 21:45:10.374 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 21:45:12.542 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 21:45:14.597 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 21:45:18.259 | INFO | threads:run:875 - 执行服务管理命令: systemctl status gunicorn_django
|
||||
2025-08-28 21:45:18.269 | ERROR | threads:run:884 - 服务文件不存在: /etc/systemd/system/gunicorn_django.service, 错误: ls: cannot access '/etc/systemd/system/gunicorn_django.service': No such file or directory
|
||||
|
||||
2025-08-28 21:45:18.270 | ERROR | gunicorn_tab:on_manage_service_result:386 - 服务操作失败: 服务文件不存在: gunicorn_django.service
|
||||
2025-08-28 21:45:26.168 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 21:45:30.745 | INFO | threads:run:875 - 执行服务管理命令: systemctl status gunicorn_django
|
||||
2025-08-28 21:45:30.754 | ERROR | threads:run:884 - 服务文件不存在: /etc/systemd/system/gunicorn_django.service, 错误: ls: cannot access '/etc/systemd/system/gunicorn_django.service': No such file or directory
|
||||
|
||||
2025-08-28 21:45:30.755 | ERROR | gunicorn_tab:on_manage_service_result:386 - 服务操作失败: 服务文件不存在: gunicorn_django.service
|
||||
2025-08-28 22:01:41.803 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 22:01:41.845 | 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-28 22:01:41.846 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 22:01:43.842 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:01:44.537 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 22:01:48.082 | INFO | threads:run:875 - 执行服务管理命令: systemctl status gunicorn_django
|
||||
2025-08-28 22:01:48.090 | ERROR | threads:run:884 - 服务文件不存在: /etc/systemd/system/gunicorn_django.service, 错误: ls: cannot access '/etc/systemd/system/gunicorn_django.service': No such file or directory
|
||||
|
||||
2025-08-28 22:01:48.091 | ERROR | gunicorn_tab:on_manage_service_result:386 - 服务操作失败: 服务文件不存在: gunicorn_django.service
|
||||
2025-08-28 22:01:55.720 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 22:01:59.324 | INFO | threads:run:875 - 执行服务管理命令: systemctl status gunicorn_django
|
||||
2025-08-28 22:01:59.333 | ERROR | threads:run:884 - 服务文件不存在: /etc/systemd/system/gunicorn_django.service, 错误: ls: cannot access '/etc/systemd/system/gunicorn_django.service': No such file or directory
|
||||
|
||||
2025-08-28 22:01:59.334 | ERROR | gunicorn_tab:on_manage_service_result:386 - 服务操作失败: 服务文件不存在: gunicorn_django.service
|
||||
2025-08-28 22:04:31.027 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 22:04:31.062 | 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-28 22:04:31.063 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 22:05:26.599 | INFO | __main__:<module>:114 - 应用程序启动
|
||||
2025-08-28 22:05:26.631 | 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-28 22:05:26.632 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 22:05:28.618 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:05:29.755 | INFO | __main__:on_tab_changed:107 - 切换到Gunicorn标签,自动检测服务状态
|
||||
2025-08-28 22:05:34.219 | INFO | threads:run:875 - 执行服务管理命令: systemctl status gunicorn_django
|
||||
2025-08-28 22:05:34.227 | ERROR | threads:run:884 - 服务文件不存在: /etc/systemd/system/gunicorn_django.service, 错误: ls: cannot access '/etc/systemd/system/gunicorn_django.service': No such file or directory
|
||||
|
||||
2025-08-28 22:05:34.229 | ERROR | gunicorn_tab:on_manage_service_result:424 - 服务操作失败: 服务文件不存在: gunicorn_django.service
|
||||
2025-08-28 22:06:09.440 | INFO | threads:run:756 - 准备上传服务文件: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:06:09.454 | INFO | threads:run:763 - 临时服务文件创建成功: /tmp/gunicorn_django.service
|
||||
2025-08-28 22:06:09.477 | INFO | threads:run:781 - 服务文件移动成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:06:09.538 | INFO | threads:run:799 - 服务文件权限设置成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:06:09.590 | INFO | threads:run:807 - 服务文件验证成功: -rw-r--r-- 1 xiaji xiaji 705 Aug 28 22:06 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:06:09.888 | INFO | threads:run:831 - systemd重新加载成功
|
||||
2025-08-28 22:06:10.453 | INFO | threads:run:839 - 服务被systemd识别: gunicorn_django.service disabled enabled
|
||||
2025-08-28 22:06:10.454 | INFO | threads:run:847 - 服务文件上传成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:06:10.456 | INFO | gunicorn_tab:on_upload_service_result:373 - 服务文件上传成功: 服务文件上传成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:06:20.044 | INFO | threads:run:875 - 执行服务管理命令: systemctl restart gunicorn_django
|
||||
2025-08-28 22:06:20.059 | INFO | threads:run:889 - 服务文件存在: -rw-r--r-- 1 xiaji xiaji 705 Aug 28 22:06 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:06:20.139 | INFO | threads:run:920 - 服务restart成功: gunicorn_django
|
||||
2025-08-28 22:06:20.140 | INFO | gunicorn_tab:on_manage_service_result:421 - 服务操作成功: 服务restart成功: gunicorn_django
|
||||
2025-08-28 22:07:59.648 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-28 22:07:59.692 | 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-28 22:07:59.697 | INFO | django_tab:load_django_path:117 - 从配置文件加载django路径: /home/xiaji/
|
||||
2025-08-28 22:08:02.096 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:10:45.949 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-28 22:10:45.986 | 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-28 22:10:45.987 | INFO | django_tab:load_django_path:115 - 从当前服务器配置加载django路径: /home/xiaji/
|
||||
2025-08-28 22:10:45.987 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-28 22:10:53.292 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:13:07.349 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-28 22:13:07.387 | 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-28 22:13:07.388 | INFO | django_tab:load_django_path:115 - 从当前服务器配置加载django路径: /home/xiaji/
|
||||
2025-08-28 22:13:07.390 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-28 22:13:07.391 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-28 22:13:09.561 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:13:22.767 | INFO | threads:run:756 - 准备上传服务文件: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:13:22.782 | INFO | threads:run:763 - 临时服务文件创建成功: /tmp/gunicorn_django.service
|
||||
2025-08-28 22:13:22.803 | INFO | threads:run:781 - 服务文件移动成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:13:22.865 | INFO | threads:run:799 - 服务文件权限设置成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:13:22.917 | INFO | threads:run:807 - 服务文件验证成功: -rw-r--r-- 1 xiaji xiaji 778 Aug 28 22:13 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:13:23.219 | INFO | threads:run:831 - systemd重新加载成功
|
||||
2025-08-28 22:13:23.845 | INFO | threads:run:839 - 服务被systemd识别: gunicorn_django.service disabled enabled
|
||||
2025-08-28 22:13:23.846 | INFO | threads:run:847 - 服务文件上传成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:13:23.847 | INFO | gunicorn_tab:on_upload_service_result:377 - 服务文件上传成功: 服务文件上传成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:13:28.149 | INFO | threads:run:875 - 执行服务管理命令: systemctl restart gunicorn_django
|
||||
2025-08-28 22:13:28.158 | INFO | threads:run:889 - 服务文件存在: -rw-r--r-- 1 xiaji xiaji 778 Aug 28 22:13 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:13:28.228 | INFO | threads:run:920 - 服务restart成功: gunicorn_django
|
||||
2025-08-28 22:13:28.230 | INFO | gunicorn_tab:on_manage_service_result:425 - 服务操作成功: 服务restart成功: gunicorn_django
|
||||
2025-08-28 22:15:05.213 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-28 22:15:05.248 | 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-28 22:15:05.249 | INFO | django_tab:load_django_path:115 - 从当前服务器配置加载django路径: /home/xiaji/
|
||||
2025-08-28 22:15:05.249 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-28 22:15:05.250 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-28 22:15:08.328 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:18:00.966 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-28 22:18:01.005 | 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-28 22:18:01.007 | INFO | django_tab:load_django_path:115 - 从当前服务器配置加载django路径: /home/xiaji/
|
||||
2025-08-28 22:18:01.007 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-28 22:18:01.008 | INFO | gunicorn_tab:load_gunicorn_config:175 - 从当前服务器配置加载Gunicorn配置: django_path=/home/xiaji/, project_name=statuspage
|
||||
2025-08-28 22:18:01.009 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-28 22:18:03.033 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:18:10.456 | INFO | threads:run:707 - 找到wsgi.py文件: /home/xiaji/statuspage/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/django/core/handlers/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/django/core/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/asgiref/wsgi.py
|
||||
2025-08-28 22:18:15.531 | ERROR | threads:run:732 - Gunicorn测试失败
|
||||
2025-08-28 22:18:15.531 | ERROR | gunicorn_tab:on_test_gunicorn_result:367 - Gunicorn测试失败: Gunicorn测试失败
|
||||
2025-08-28 22:18:21.513 | INFO | threads:run:707 - 找到wsgi.py文件: /home/xiaji/statuspage/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/django/core/handlers/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/django/core/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/asgiref/wsgi.py
|
||||
2025-08-28 22:18:26.582 | ERROR | threads:run:732 - Gunicorn测试失败
|
||||
2025-08-28 22:18:26.585 | ERROR | gunicorn_tab:on_test_gunicorn_result:367 - Gunicorn测试失败: Gunicorn测试失败
|
||||
2025-08-28 22:20:04.518 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-28 22:20:04.553 | 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-28 22:20:04.556 | INFO | django_tab:load_django_path:115 - 从当前服务器配置加载django路径: /home/xiaji/statuspage
|
||||
2025-08-28 22:20:04.556 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-28 22:20:04.558 | INFO | gunicorn_tab:load_gunicorn_config:175 - 从当前服务器配置加载Gunicorn配置: django_path=/home/xiaji/statuspage, project_name=statuspage
|
||||
2025-08-28 22:20:04.559 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-28 22:20:12.042 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:20:15.094 | ERROR | threads:run:689 - Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 22:20:15.095 | ERROR | gunicorn_tab:on_test_gunicorn_result:367 - Gunicorn测试失败: Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 22:20:24.016 | INFO | threads:run:707 - 找到wsgi.py文件: /home/xiaji/statuspage/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/django/core/handlers/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/django/core/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/asgiref/wsgi.py
|
||||
2025-08-28 22:20:59.164 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-28 22:20:59.201 | 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-28 22:20:59.203 | INFO | django_tab:load_django_path:115 - 从当前服务器配置加载django路径: /home/xiaji/statuspage
|
||||
2025-08-28 22:20:59.203 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-28 22:20:59.204 | INFO | gunicorn_tab:load_gunicorn_config:175 - 从当前服务器配置加载Gunicorn配置: django_path=/home/xiaji/statuspage, project_name=statuspage
|
||||
2025-08-28 22:20:59.204 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-28 22:21:00.318 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:21:07.110 | ERROR | threads:run:689 - Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 22:21:07.112 | ERROR | gunicorn_tab:on_test_gunicorn_result:367 - Gunicorn测试失败: Django项目不存在: /home/xiaji/statuspage
|
||||
2025-08-28 22:24:30.595 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-28 22:24:30.635 | 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-28 22:24:30.636 | INFO | django_tab:load_django_path:115 - 从当前服务器配置加载django路径: /home/xiaji/statuspage
|
||||
2025-08-28 22:24:30.636 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-28 22:24:30.637 | INFO | gunicorn_tab:load_gunicorn_config:175 - 从当前服务器配置加载Gunicorn配置: django_path=/home/xiaji/statuspage, project_name=statuspage
|
||||
2025-08-28 22:24:30.638 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-28 22:24:32.673 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:26:19.189 | INFO | __main__:<module>:109 - 应用程序启动
|
||||
2025-08-28 22:26:19.228 | 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-28 22:26:19.229 | INFO | django_tab:load_django_path:115 - 从当前服务器配置加载django路径: /home/xiaji/statuspage
|
||||
2025-08-28 22:26:19.229 | INFO | django_tab:__init__:22 - Django标签已连接到服务器切换信号
|
||||
2025-08-28 22:26:19.231 | INFO | gunicorn_tab:load_gunicorn_config:175 - 从当前服务器配置加载Gunicorn配置: django_path=/home/xiaji/statuspage, project_name=statuspage
|
||||
2025-08-28 22:26:19.231 | INFO | gunicorn_tab:__init__:50 - Gunicorn标签已连接到服务器切换信号
|
||||
2025-08-28 22:26:25.092 | INFO | threads:run:47 - SSH连接成功: 192.168.3.157
|
||||
2025-08-28 22:26:31.515 | INFO | threads:run:707 - 找到wsgi.py文件: /home/xiaji/statuspage/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/django/core/handlers/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/django/core/wsgi.py
|
||||
/home/xiaji/.local/lib/python3.12/site-packages/asgiref/wsgi.py
|
||||
2025-08-28 22:26:36.591 | ERROR | threads:run:732 - Gunicorn测试失败
|
||||
2025-08-28 22:26:36.592 | ERROR | gunicorn_tab:on_test_gunicorn_result:367 - Gunicorn测试失败: Gunicorn测试失败
|
||||
2025-08-28 22:27:18.620 | INFO | threads:run:756 - 准备上传服务文件: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:18.634 | INFO | threads:run:763 - 临时服务文件创建成功: /tmp/gunicorn_django.service
|
||||
2025-08-28 22:27:18.654 | INFO | threads:run:781 - 服务文件移动成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:18.717 | INFO | threads:run:799 - 服务文件权限设置成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:18.768 | INFO | threads:run:807 - 服务文件验证成功: -rw-r--r-- 1 xiaji xiaji 703 Aug 28 22:27 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:19.090 | INFO | threads:run:831 - systemd重新加载成功
|
||||
2025-08-28 22:27:19.712 | INFO | threads:run:839 - 服务被systemd识别: gunicorn_django.service disabled enabled
|
||||
2025-08-28 22:27:19.714 | INFO | threads:run:847 - 服务文件上传成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:19.715 | INFO | gunicorn_tab:on_upload_service_result:408 - 服务文件上传成功: 服务文件上传成功: /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:24.287 | INFO | threads:run:875 - 执行服务管理命令: systemctl restart gunicorn_django
|
||||
2025-08-28 22:27:24.295 | INFO | threads:run:889 - 服务文件存在: -rw-r--r-- 1 xiaji xiaji 703 Aug 28 22:27 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:24.366 | INFO | threads:run:920 - 服务restart成功: gunicorn_django
|
||||
2025-08-28 22:27:24.367 | INFO | gunicorn_tab:on_manage_service_result:456 - 服务操作成功: 服务restart成功: gunicorn_django
|
||||
2025-08-28 22:27:28.045 | INFO | threads:run:875 - 执行服务管理命令: systemctl enable gunicorn_django
|
||||
2025-08-28 22:27:28.054 | INFO | threads:run:889 - 服务文件存在: -rw-r--r-- 1 xiaji xiaji 703 Aug 28 22:27 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:28.368 | INFO | threads:run:920 - 服务enable成功: gunicorn_django
|
||||
2025-08-28 22:27:28.371 | INFO | gunicorn_tab:on_manage_service_result:456 - 服务操作成功: 服务enable成功: gunicorn_django
|
||||
2025-08-28 22:27:32.509 | INFO | threads:run:875 - 执行服务管理命令: systemctl status gunicorn_django
|
||||
2025-08-28 22:27:32.518 | INFO | threads:run:889 - 服务文件存在: -rw-r--r-- 1 xiaji xiaji 703 Aug 28 22:27 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:32.587 | ERROR | threads:run:907 - 服务状态查询失败: [sudo] password for xiaji:
|
||||
2025-08-28 22:27:32.588 | ERROR | gunicorn_tab:on_manage_service_result:459 - 服务操作失败: [sudo] password for xiaji:
|
||||
2025-08-28 22:27:52.590 | INFO | threads:run:875 - 执行服务管理命令: systemctl status gunicorn_django
|
||||
2025-08-28 22:27:52.599 | INFO | threads:run:889 - 服务文件存在: -rw-r--r-- 1 xiaji xiaji 703 Aug 28 22:27 /etc/systemd/system/gunicorn_django.service
|
||||
2025-08-28 22:27:52.670 | ERROR | threads:run:907 - 服务状态查询失败: [sudo] password for xiaji:
|
||||
2025-08-28 22:27:52.671 | ERROR | gunicorn_tab:on_manage_service_result:459 - 服务操作失败: [sudo] password for xiaji:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"project_name": "statuspage",
|
||||
"git_url": "http://192.168.3.241:3000/xiaji/webstatus",
|
||||
"remote_directory": "/home/xiaji/",
|
||||
"django_path": "/home/xiaji/"
|
||||
"django_path": "/home/xiaji/statuspage"
|
||||
},
|
||||
{
|
||||
"alias": "生产服务器",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import json
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QPushButton, QComboBox, QMessageBox, QTextEdit,
|
||||
@@ -15,6 +16,10 @@ class DjangoTab(QWidget):
|
||||
self.parent = parent
|
||||
self.init_ui()
|
||||
|
||||
# 连接服务器切换信号
|
||||
if self.parent and hasattr(self.parent, 'server_changed'):
|
||||
self.parent.server_changed.connect(self.on_server_changed)
|
||||
logger.info("Django标签已连接到服务器切换信号")
|
||||
def init_ui(self):
|
||||
layout = QVBoxLayout()
|
||||
|
||||
@@ -100,9 +105,31 @@ class DjangoTab(QWidget):
|
||||
self.load_django_path()
|
||||
|
||||
def load_django_path(self):
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
django_path = self.parent.server_connection_tab.django_path_input.text()
|
||||
self.django_path_input.setText(django_path)
|
||||
"""从当前服务器配置加载Django路径"""
|
||||
try:
|
||||
if self.parent and hasattr(self.parent, 'get_current_config'):
|
||||
config = self.parent.get_current_config()
|
||||
if config:
|
||||
django_path = config.get('django_path', '')
|
||||
self.django_path_input.setText(django_path)
|
||||
logger.info(f"从当前服务器配置加载django路径: {django_path}")
|
||||
else:
|
||||
logger.warning("未找到当前服务器配置")
|
||||
else:
|
||||
# 兼容旧的加载方式
|
||||
config_path = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
if config and 'servers' in config and len(config['servers']) > 0:
|
||||
server_config = config['servers'][0]
|
||||
django_path = server_config.get('django_path', '')
|
||||
self.django_path_input.setText(django_path)
|
||||
logger.info(f"从配置文件加载django路径: {django_path}")
|
||||
except Exception as e:
|
||||
logger.error(f"加载django路径失败: {str(e)}")
|
||||
# 不显示警告,避免影响用户体验
|
||||
QMessageBox.warning(self, "警告", f"加载django路径失败: {str(e)}")
|
||||
|
||||
def check_ssh_connection(self):
|
||||
if not self.parent or not self.parent.ssh_client:
|
||||
|
||||
259
gunicorn_tab.py
259
gunicorn_tab.py
@@ -2,19 +2,52 @@ import os
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QPushButton, QComboBox, QMessageBox, QTextEdit,
|
||||
QGroupBox, QGridLayout, QProgressBar)
|
||||
QGroupBox, QGridLayout, QProgressBar, QDialog,
|
||||
QDialogButtonBox)
|
||||
from PySide6.QtCore import Qt
|
||||
|
||||
from threads import (GunicornInstallThread, GunicornTestThread,
|
||||
UploadGunicornServiceThread, ManageGunicornServiceThread)
|
||||
|
||||
|
||||
class PasswordDialog(QDialog):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("输入密码")
|
||||
self.setMinimumWidth(300)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
|
||||
# 密码输入
|
||||
password_layout = QHBoxLayout()
|
||||
password_layout.addWidget(QLabel("密码:"))
|
||||
self.password_input = QLineEdit()
|
||||
self.password_input.setEchoMode(QLineEdit.Password)
|
||||
password_layout.addWidget(self.password_input)
|
||||
layout.addLayout(password_layout)
|
||||
|
||||
# 按钮
|
||||
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 GunicornTab(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.parent = parent
|
||||
self.init_ui()
|
||||
|
||||
# 连接服务器切换信号
|
||||
if self.parent and hasattr(self.parent, 'server_changed'):
|
||||
self.parent.server_changed.connect(self.on_server_changed)
|
||||
logger.info("Gunicorn标签已连接到服务器切换信号")
|
||||
def init_ui(self):
|
||||
layout = QVBoxLayout()
|
||||
|
||||
@@ -120,32 +153,130 @@ class GunicornTab(QWidget):
|
||||
self.load_gunicorn_config()
|
||||
|
||||
def load_gunicorn_config(self):
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
django_path = self.parent.server_connection_tab.django_path_input.text()
|
||||
self.django_path_input.setText(django_path)
|
||||
|
||||
# 生成默认的服务文件内容
|
||||
service_name = self.service_name_input.text()
|
||||
port = self.port_input.text()
|
||||
workers = self.workers_input.text()
|
||||
|
||||
service_content = self.generate_service_file(service_name, django_path, port, workers)
|
||||
self.service_editor.setText(service_content)
|
||||
"""加载Gunicorn配置,使用config.json中的值"""
|
||||
try:
|
||||
if self.parent and hasattr(self.parent, 'get_current_config'):
|
||||
config = self.parent.get_current_config()
|
||||
if config:
|
||||
django_path = config.get('django_path', '')
|
||||
project_name = config.get('project_name', 'myproject')
|
||||
username = config.get('username', 'www-data')
|
||||
|
||||
# 设置Django项目路径
|
||||
self.django_path_input.setText(django_path)
|
||||
|
||||
# 设置服务名称为项目名
|
||||
self.service_name_input.setText(project_name)
|
||||
|
||||
# 生成服务文件内容
|
||||
service_content = self.generate_service_file_from_config(config)
|
||||
self.service_editor.setText(service_content)
|
||||
|
||||
logger.info(f"从当前服务器配置加载Gunicorn配置: django_path={django_path}, project_name={project_name}")
|
||||
else:
|
||||
logger.warning("未找到当前服务器配置")
|
||||
else:
|
||||
# 兼容旧的加载方式
|
||||
config_path = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
if config and 'servers' in config and len(config['servers']) > 0:
|
||||
server_config = config['servers'][0]
|
||||
django_path = server_config.get('remote_directory', '')
|
||||
project_name = server_config.get('project_name', 'myproject')
|
||||
username = server_config.get('username', 'www-data')
|
||||
|
||||
# 设置Django项目路径
|
||||
self.django_path_input.setText(django_path)
|
||||
|
||||
# 设置服务名称为项目名
|
||||
self.service_name_input.setText(project_name)
|
||||
|
||||
# 生成服务文件内容
|
||||
service_content = self.generate_service_file_from_config(server_config)
|
||||
self.service_editor.setText(service_content)
|
||||
|
||||
logger.info(f"从配置文件加载Gunicorn配置: django_path={django_path}, project_name={project_name}")
|
||||
except Exception as e:
|
||||
logger.error(f"加载Gunicorn配置失败: {str(e)}")
|
||||
# 不显示警告,避免影响用户体验
|
||||
|
||||
def generate_service_file(self, service_name, django_path, port, workers):
|
||||
def generate_service_file_from_config(self, config):
|
||||
"""根据config.json配置生成服务文件内容"""
|
||||
username = config.get('username', 'www-data')
|
||||
project_name = config.get('project_name', 'myproject')
|
||||
django_path = config.get('remote_directory', '/home/user')
|
||||
|
||||
# 构建完整的项目路径
|
||||
project_path = f"{django_path.rstrip('/')}/{project_name}"
|
||||
|
||||
return f"""[Unit]
|
||||
Description={service_name} daemon
|
||||
Description=Gunicorn daemon for {project_name}
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory={django_path}
|
||||
ExecStart=/usr/local/bin/gunicorn --workers {workers} --bind 0.0.0.0:{port} {os.path.basename(django_path)}.wsgi:application
|
||||
User={username}
|
||||
Group={username}
|
||||
WorkingDirectory={project_path}
|
||||
# 所有Gunicorn参数直接在这里配置
|
||||
ExecStart=/usr/local/bin/gunicorn \\
|
||||
--bind 127.0.0.1:8000 \\
|
||||
--workers $(nproc --all * 2 + 1) \\
|
||||
--worker-class sync \\
|
||||
--timeout 60 \\
|
||||
--name {project_name} \\
|
||||
--access-logfile {project_path}/logs/gunicorn_access.log \\
|
||||
--error-logfile {project_path}/logs/gunicorn_error.log \\
|
||||
--log-level info \\
|
||||
{project_name}.wsgi:application
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
PrivateTmp=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
WantedBy=multi-user.target"""
|
||||
|
||||
def generate_service_file(self, service_name, django_path, port, workers):
|
||||
"""保持向后兼容的方法"""
|
||||
# 获取config.json中的配置信息
|
||||
config = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
config = self.parent.server_connection_tab.get_current_config()
|
||||
|
||||
if config:
|
||||
return self.generate_service_file_from_config(config)
|
||||
else:
|
||||
# 如果没有config,使用默认值
|
||||
username = 'www-data'
|
||||
project_name = service_name
|
||||
project_path = f"{django_path.rstrip('/')}/{project_name}"
|
||||
|
||||
return f"""[Unit]
|
||||
Description=Gunicorn daemon for {project_name}
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User={username}
|
||||
Group={username}
|
||||
WorkingDirectory={project_path}
|
||||
# 所有Gunicorn参数直接在这里配置
|
||||
ExecStart=/usr/local/bin/gunicorn \\
|
||||
--bind 127.0.0.1:{port} \\
|
||||
--workers $(nproc --all * 2 + 1) \\
|
||||
--worker-class sync \\
|
||||
--timeout 60 \\
|
||||
--name {project_name} \\
|
||||
--access-logfile {project_path}/logs/gunicorn_access.log \\
|
||||
--error-logfile {project_path}/logs/gunicorn_error.log \\
|
||||
--log-level info \\
|
||||
{project_name}.wsgi:application
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
PrivateTmp=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"""
|
||||
|
||||
def check_ssh_connection(self):
|
||||
if not self.parent or not self.parent.ssh_client:
|
||||
@@ -153,6 +284,25 @@ WantedBy=multi-user.target
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_password(self):
|
||||
# 获取密码
|
||||
password = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
password = self.parent.server_connection_tab.password_input.text()
|
||||
|
||||
# 如果密码为空,弹出密码输入对话框
|
||||
if not password:
|
||||
dialog = PasswordDialog(self)
|
||||
if dialog.exec_() == QDialog.Accepted:
|
||||
password = dialog.get_password()
|
||||
# 保存密码到服务器连接标签页
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
self.parent.server_connection_tab.password_input.setText(password)
|
||||
else:
|
||||
return None
|
||||
|
||||
return password
|
||||
|
||||
def install_gunicorn(self):
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
@@ -163,9 +313,11 @@ WantedBy=multi-user.target
|
||||
self.progress_bar.setValue(0)
|
||||
|
||||
# 获取密码
|
||||
password = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
password = self.parent.server_connection_tab.password_input.text()
|
||||
password = self.get_password()
|
||||
if password is None:
|
||||
self.install_gunicorn_btn.setEnabled(True)
|
||||
self.progress_bar.setVisible(False)
|
||||
return
|
||||
|
||||
self.gunicorn_install_thread = GunicornInstallThread(self.parent.ssh_client, password)
|
||||
self.gunicorn_install_thread.progress_updated.connect(self.update_progress)
|
||||
@@ -218,20 +370,32 @@ WantedBy=multi-user.target
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
|
||||
service_name = self.service_name_input.text().strip()
|
||||
# 获取config.json中的配置信息
|
||||
config = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
config = self.parent.server_connection_tab.get_current_config()
|
||||
|
||||
if config:
|
||||
project_name = config.get('project_name', 'django')
|
||||
else:
|
||||
project_name = 'django'
|
||||
|
||||
# 使用gunicorn_[project_name].service格式作为服务名称
|
||||
service_name = f"gunicorn_{project_name}"
|
||||
service_content = self.service_editor.toPlainText()
|
||||
|
||||
if not service_name or not service_content:
|
||||
QMessageBox.warning(self, "警告", "请输入服务名称并编辑服务文件内容")
|
||||
QMessageBox.warning(self, "警告", "请编辑服务文件内容")
|
||||
return
|
||||
|
||||
self.output_text.append(f"正在上传服务文件 {service_name}...")
|
||||
self.upload_service_btn.setEnabled(False)
|
||||
|
||||
# 获取密码
|
||||
password = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
password = self.parent.server_connection_tab.password_input.text()
|
||||
password = self.get_password()
|
||||
if password is None:
|
||||
self.upload_service_btn.setEnabled(True)
|
||||
return
|
||||
|
||||
self.upload_thread = UploadGunicornServiceThread(self.parent.ssh_client, service_name, service_content, password)
|
||||
self.upload_thread.result_ready.connect(self.on_upload_service_result)
|
||||
@@ -250,10 +414,18 @@ WantedBy=multi-user.target
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
|
||||
service_name = self.service_name_input.text().strip()
|
||||
if not service_name:
|
||||
QMessageBox.warning(self, "警告", "请输入服务名称")
|
||||
return
|
||||
# 获取config.json中的配置信息
|
||||
config = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
config = self.parent.server_connection_tab.get_current_config()
|
||||
|
||||
if config:
|
||||
project_name = config.get('project_name', 'django')
|
||||
else:
|
||||
project_name = 'django'
|
||||
|
||||
# 使用gunicorn_[project_name].service格式作为服务名称
|
||||
service_name = f"gunicorn_{project_name}"
|
||||
|
||||
self.output_text.append(f"正在执行服务 {action} 操作...")
|
||||
|
||||
@@ -264,9 +436,11 @@ WantedBy=multi-user.target
|
||||
btn.setEnabled(False)
|
||||
|
||||
# 获取密码
|
||||
password = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
password = self.parent.server_connection_tab.password_input.text()
|
||||
password = self.get_password()
|
||||
if password is None:
|
||||
for btn in buttons:
|
||||
btn.setEnabled(True)
|
||||
return
|
||||
|
||||
self.manage_thread = ManageGunicornServiceThread(self.parent.ssh_client, service_name, action, password)
|
||||
self.manage_thread.result_ready.connect(lambda s, m: self.on_manage_service_result(s, m, buttons))
|
||||
@@ -291,8 +465,17 @@ WantedBy=multi-user.target
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
|
||||
service_name = self.service_name_input.text().strip()
|
||||
if not service_name:
|
||||
return
|
||||
# 获取config.json中的配置信息
|
||||
config = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
config = self.parent.server_connection_tab.get_current_config()
|
||||
|
||||
if config:
|
||||
project_name = config.get('project_name', 'django')
|
||||
else:
|
||||
project_name = 'django'
|
||||
|
||||
# 使用gunicorn_[project_name].service格式作为服务名称
|
||||
service_name = f"gunicorn_{project_name}"
|
||||
|
||||
self.manage_service("status")
|
||||
7
main.py
7
main.py
@@ -101,12 +101,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def on_tab_changed(self, index):
|
||||
"""标签切换事件处理"""
|
||||
tab_text = self.tab_widget.tabText(index)
|
||||
if tab_text == "Gunicorn":
|
||||
# 切换到Gunicorn标签时自动检测服务状态
|
||||
logger.info("切换到Gunicorn标签,自动检测服务状态")
|
||||
# 延迟执行以确保UI完全加载
|
||||
QTimer.singleShot(500, self.gunicorn_tab.check_service_status)
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import json
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QPushButton, QComboBox, QMessageBox, QTextEdit,
|
||||
@@ -6,7 +7,7 @@ from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineE
|
||||
from PySide6.QtCore import Qt
|
||||
|
||||
from threads import (GitInstallThread, GitCloneThread, ListDirectoryThread,
|
||||
DeleteDirectoryThread, SetTimezoneAndRestartThread,
|
||||
SetTimezoneAndRestartThread,
|
||||
CheckFirewallThread, OpenPortThread)
|
||||
|
||||
|
||||
@@ -33,11 +34,6 @@ class RemoteCommandTab(QWidget):
|
||||
self.project_path_input.setPlaceholderText("/home/user/project")
|
||||
git_layout.addWidget(self.project_path_input, 1, 1)
|
||||
|
||||
git_layout.addWidget(QLabel("删除目录:"), 2, 0)
|
||||
self.delete_dir_input = QLineEdit()
|
||||
self.delete_dir_input.setPlaceholderText("/home/user/old_project")
|
||||
git_layout.addWidget(self.delete_dir_input, 2, 1)
|
||||
|
||||
self.install_git_btn = QPushButton("安装Git")
|
||||
self.install_git_btn.clicked.connect(self.install_git)
|
||||
git_layout.addWidget(self.install_git_btn, 0, 2)
|
||||
@@ -50,10 +46,6 @@ class RemoteCommandTab(QWidget):
|
||||
self.list_dir_btn.clicked.connect(self.list_directory)
|
||||
git_layout.addWidget(self.list_dir_btn, 2, 2)
|
||||
|
||||
self.delete_dir_btn = QPushButton("删除目录")
|
||||
self.delete_dir_btn.clicked.connect(self.delete_directory)
|
||||
git_layout.addWidget(self.delete_dir_btn, 3, 2)
|
||||
|
||||
self.set_timezone_btn = QPushButton("设置时区并重启")
|
||||
self.set_timezone_btn.clicked.connect(self.set_timezone_and_restart)
|
||||
git_layout.addWidget(self.set_timezone_btn, 3, 0, 1, 2)
|
||||
@@ -80,17 +72,6 @@ class RemoteCommandTab(QWidget):
|
||||
firewall_group.setLayout(firewall_layout)
|
||||
layout.addWidget(firewall_group)
|
||||
|
||||
# Settings.py编辑器
|
||||
settings_group = QGroupBox("Settings.py编辑器")
|
||||
settings_layout = QVBoxLayout()
|
||||
|
||||
self.settings_editor = QTextEdit()
|
||||
self.settings_editor.setPlaceholderText("settings.py内容将在这里显示...")
|
||||
settings_layout.addWidget(self.settings_editor)
|
||||
|
||||
settings_group.setLayout(settings_layout)
|
||||
layout.addWidget(settings_group)
|
||||
|
||||
# 操作输出
|
||||
output_group = QGroupBox("操作输出")
|
||||
output_layout = QVBoxLayout()
|
||||
@@ -106,15 +87,31 @@ class RemoteCommandTab(QWidget):
|
||||
layout.addStretch()
|
||||
self.setLayout(layout)
|
||||
|
||||
# 加载Git配置
|
||||
# 从配置文件加载git配置
|
||||
self.load_git_config()
|
||||
|
||||
def load_git_config(self):
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
git_url = self.parent.server_connection_tab.git_url_input.text()
|
||||
remote_dir = self.parent.server_connection_tab.remote_dir_input.text()
|
||||
self.git_url_input.setText(git_url)
|
||||
self.project_path_input.setText(remote_dir)
|
||||
try:
|
||||
# 从config.json文件读取配置
|
||||
config_path = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# 获取第一个服务器的配置
|
||||
if config and 'servers' in config and len(config['servers']) > 0:
|
||||
server_config = config['servers'][0]
|
||||
git_url = server_config.get('git_url', '')
|
||||
project_path = server_config.get('remote_directory', '')
|
||||
|
||||
self.git_url_input.setText(git_url)
|
||||
self.project_path_input.setText(project_path)
|
||||
|
||||
logger.info(f"从配置文件加载git配置: git_url={git_url}, project_path={project_path}")
|
||||
else:
|
||||
logger.warning("配置文件中未找到服务器配置")
|
||||
except Exception as e:
|
||||
logger.error(f"加载git配置失败: {str(e)}")
|
||||
QMessageBox.warning(self, "警告", f"加载git配置失败: {str(e)}")
|
||||
|
||||
def install_git(self):
|
||||
if not self.check_ssh_connection():
|
||||
@@ -147,6 +144,22 @@ class RemoteCommandTab(QWidget):
|
||||
QMessageBox.warning(self, "警告", "请填写Git仓库URL和项目路径")
|
||||
return
|
||||
|
||||
# 从config.json获取django_path作为克隆目标路径
|
||||
try:
|
||||
config_path = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
if config and 'servers' in config and len(config['servers']) > 0:
|
||||
server_config = config['servers'][0]
|
||||
django_path = server_config.get('django_path', '')
|
||||
|
||||
if django_path:
|
||||
project_path = django_path
|
||||
logger.info(f"使用django_path作为克隆目标路径: {django_path}")
|
||||
except Exception as e:
|
||||
logger.error(f"获取django_path失败: {str(e)}")
|
||||
|
||||
self.output_text.append(f"正在克隆 {git_url} 到 {project_path}...")
|
||||
self.clone_btn.setEnabled(False)
|
||||
|
||||
@@ -183,42 +196,11 @@ class RemoteCommandTab(QWidget):
|
||||
self.list_dir_btn.setEnabled(True)
|
||||
if success:
|
||||
self.output_text.append(f"目录列表:\n{message}")
|
||||
logger.info(f"目录列表成功")
|
||||
logger.info(f"目录列表成功:\n{message}")
|
||||
else:
|
||||
self.output_text.append(f"列出目录失败: {message}")
|
||||
logger.error(f"列出目录失败: {message}")
|
||||
|
||||
def delete_directory(self):
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
|
||||
path = self.delete_dir_input.text().strip()
|
||||
if not path:
|
||||
QMessageBox.warning(self, "警告", "请输入要删除的目录路径")
|
||||
return
|
||||
|
||||
reply = QMessageBox.question(self, "确认删除",
|
||||
f"确定要删除目录 {path} 吗?此操作不可撤销!",
|
||||
QMessageBox.Yes | QMessageBox.No)
|
||||
if reply == QMessageBox.No:
|
||||
return
|
||||
|
||||
self.output_text.append(f"正在删除目录 {path}...")
|
||||
self.delete_dir_btn.setEnabled(False)
|
||||
|
||||
self.delete_dir_thread = DeleteDirectoryThread(self.parent.ssh_client, path)
|
||||
self.delete_dir_thread.result_ready.connect(self.on_delete_directory_result)
|
||||
self.delete_dir_thread.start()
|
||||
|
||||
def on_delete_directory_result(self, success, message):
|
||||
self.delete_dir_btn.setEnabled(True)
|
||||
if success:
|
||||
self.output_text.append(f"目录删除成功: {message}")
|
||||
logger.info(f"目录删除成功: {message}")
|
||||
else:
|
||||
self.output_text.append(f"目录删除失败: {message}")
|
||||
logger.error(f"目录删除失败: {message}")
|
||||
|
||||
def set_timezone_and_restart(self):
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
|
||||
@@ -3,13 +3,16 @@ import os
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QPushButton, QComboBox, QMessageBox)
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtCore import Qt, Signal # 添加Signal导入
|
||||
import paramiko
|
||||
|
||||
from threads import SSHConnectionThread
|
||||
|
||||
|
||||
class ServerConnectionTab(QWidget):
|
||||
# 添加服务器切换信号
|
||||
server_changed = Signal(dict)
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.ssh_client = None
|
||||
@@ -154,6 +157,9 @@ class ServerConnectionTab(QWidget):
|
||||
self.git_url_input.setText(server.get("git_url", ""))
|
||||
self.remote_dir_input.setText(server.get("remote_directory", ""))
|
||||
self.django_path_input.setText(server.get("django_path", ""))
|
||||
|
||||
# 发送服务器切换信号
|
||||
self.server_changed.emit(server)
|
||||
break
|
||||
|
||||
def save_server_config(self):
|
||||
@@ -222,4 +228,20 @@ class ServerConnectionTab(QWidget):
|
||||
else:
|
||||
self.status_label.setText(f"连接失败: {message}")
|
||||
self.status_label.setStyleSheet("color: red;")
|
||||
self.ssh_client = None
|
||||
self.ssh_client = None
|
||||
|
||||
def get_current_config(self):
|
||||
"""获取当前选中的服务器配置"""
|
||||
try:
|
||||
alias = self.server_combo.currentText()
|
||||
if not alias:
|
||||
return None
|
||||
|
||||
servers = self.config.get("servers", [])
|
||||
for server in servers:
|
||||
if server.get("alias") == alias:
|
||||
return server
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"获取当前服务器配置失败: {e}")
|
||||
return None
|
||||
110
threads.py
110
threads.py
@@ -307,7 +307,7 @@ class DjangoInstallThread(QThread):
|
||||
self.progress_updated.emit(30)
|
||||
|
||||
# 尝试使用pip安装
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("pip3 install django")
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("pip3 install --break-system-packages django")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status == 0:
|
||||
@@ -372,7 +372,7 @@ class DjangoTestThread(QThread):
|
||||
if exit_status == 0:
|
||||
self.progress_updated.emit(50)
|
||||
# 安装依赖
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"cd {self.django_path} && pip3 install -r requirements.txt")
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"cd {self.django_path} && pip3 install --break-system-packages -r requirements.txt")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status != 0:
|
||||
@@ -384,7 +384,7 @@ class DjangoTestThread(QThread):
|
||||
self.progress_updated.emit(70)
|
||||
|
||||
# 运行Django测试服务器
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"cd {self.django_path} && python3 manage.py runserver 0.0.0.0:8000 --noreload &")
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"cd {self.django_path} && timeout 10 python3 manage.py runserver 0.0.0.0:8000 --noreload &")
|
||||
time.sleep(3) # 等待服务器启动
|
||||
|
||||
# 检查服务器是否运行
|
||||
@@ -692,15 +692,23 @@ class GunicornTestThread(QThread):
|
||||
self.progress_updated.emit(30)
|
||||
|
||||
# 检查wsgi.py文件
|
||||
project_name = os.path.basename(self.django_path)
|
||||
wsgi_path = f"{self.django_path}/{project_name}/wsgi.py"
|
||||
project_name = os.path.basename(self.django_path.rstrip('/'))
|
||||
wsgi_path = f"{self.django_path.rstrip('/')}/{project_name}/wsgi.py"
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"ls -la {wsgi_path}")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status != 0:
|
||||
self.result_ready.emit(False, f"wsgi.py文件不存在: {wsgi_path}")
|
||||
logger.error(f"wsgi.py文件不存在: {wsgi_path}")
|
||||
return
|
||||
# 尝试在Django项目根目录下查找wsgi.py文件
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"find {self.django_path} -name wsgi.py")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status == 0:
|
||||
wsgi_path = stdout.read().decode().strip()
|
||||
logger.info(f"找到wsgi.py文件: {wsgi_path}")
|
||||
else:
|
||||
self.result_ready.emit(False, f"wsgi.py文件不存在: {wsgi_path}")
|
||||
logger.error(f"wsgi.py文件不存在: {wsgi_path}")
|
||||
return
|
||||
|
||||
self.progress_updated.emit(50)
|
||||
|
||||
@@ -745,11 +753,15 @@ class UploadGunicornServiceThread(QThread):
|
||||
service_file = f"/etc/systemd/system/{self.service_name}.service"
|
||||
temp_file = f"/tmp/{self.service_name}.service"
|
||||
|
||||
logger.info(f"准备上传服务文件: {service_file}")
|
||||
|
||||
sftp = self.ssh_client.open_sftp()
|
||||
|
||||
with sftp.file(temp_file, 'w') as f:
|
||||
f.write(self.service_content)
|
||||
|
||||
logger.info(f"临时服务文件创建成功: {temp_file}")
|
||||
|
||||
# 移动到systemd目录
|
||||
if self.password:
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo -S mv {temp_file} {service_file}")
|
||||
@@ -761,11 +773,13 @@ class UploadGunicornServiceThread(QThread):
|
||||
|
||||
if exit_status != 0:
|
||||
error = stderr.read().decode()
|
||||
self.result_ready.emit(False, f"服务文件移动失败: {error}")
|
||||
logger.error(f"服务文件移动失败: {error}")
|
||||
self.result_ready.emit(False, f"服务文件移动失败: {error}")
|
||||
sftp.close()
|
||||
return
|
||||
|
||||
logger.info(f"服务文件移动成功: {service_file}")
|
||||
|
||||
# 设置权限
|
||||
if self.password:
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo -S chmod 644 {service_file}")
|
||||
@@ -777,8 +791,24 @@ class UploadGunicornServiceThread(QThread):
|
||||
|
||||
if exit_status != 0:
|
||||
error = stderr.read().decode()
|
||||
self.result_ready.emit(False, f"权限设置失败: {error}")
|
||||
logger.error(f"权限设置失败: {error}")
|
||||
self.result_ready.emit(False, f"权限设置失败: {error}")
|
||||
sftp.close()
|
||||
return
|
||||
|
||||
logger.info(f"服务文件权限设置成功: {service_file}")
|
||||
|
||||
# 验证服务文件是否存在
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"ls -la {service_file}")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status == 0:
|
||||
file_info = stdout.read().decode().strip()
|
||||
logger.info(f"服务文件验证成功: {file_info}")
|
||||
else:
|
||||
error = stderr.read().decode()
|
||||
logger.error(f"服务文件验证失败: {error}")
|
||||
self.result_ready.emit(False, f"服务文件验证失败: {error}")
|
||||
sftp.close()
|
||||
return
|
||||
|
||||
@@ -789,6 +819,27 @@ class UploadGunicornServiceThread(QThread):
|
||||
stdin.flush()
|
||||
else:
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("sudo systemctl daemon-reload")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status != 0:
|
||||
error = stderr.read().decode()
|
||||
logger.error(f"systemd重新加载失败: {error}")
|
||||
self.result_ready.emit(False, f"systemd重新加载失败: {error}")
|
||||
sftp.close()
|
||||
return
|
||||
|
||||
logger.info(f"systemd重新加载成功")
|
||||
|
||||
# 验证服务是否被systemd识别
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"systemctl list-unit-files | grep {self.service_name}")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status == 0:
|
||||
service_info = stdout.read().decode().strip()
|
||||
logger.info(f"服务被systemd识别: {service_info}")
|
||||
else:
|
||||
error = stderr.read().decode()
|
||||
logger.warning(f"服务未被systemd识别: {error}")
|
||||
|
||||
sftp.close()
|
||||
|
||||
@@ -797,8 +848,8 @@ class UploadGunicornServiceThread(QThread):
|
||||
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
self.result_ready.emit(False, error_msg)
|
||||
logger.error(f"服务文件上传异常: {error_msg}")
|
||||
self.result_ready.emit(False, error_msg)
|
||||
|
||||
|
||||
class ManageGunicornServiceThread(QThread):
|
||||
@@ -814,7 +865,28 @@ class ManageGunicornServiceThread(QThread):
|
||||
def run(self):
|
||||
try:
|
||||
# 构建systemd命令
|
||||
cmd = f"systemctl {self.action} {self.service_name}"
|
||||
# 注意:systemd命令中不需要.service后缀
|
||||
service_name_for_systemd = self.service_name
|
||||
if service_name_for_systemd.endswith('.service'):
|
||||
service_name_for_systemd = service_name_for_systemd[:-8] # 移除.service后缀
|
||||
|
||||
cmd = f"systemctl {self.action} {service_name_for_systemd}"
|
||||
|
||||
logger.info(f"执行服务管理命令: {cmd}")
|
||||
|
||||
# 首先检查服务文件是否存在
|
||||
service_file = f"/etc/systemd/system/{self.service_name}.service"
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"ls -la {service_file}")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status != 0:
|
||||
error = stderr.read().decode()
|
||||
logger.error(f"服务文件不存在: {service_file}, 错误: {error}")
|
||||
self.result_ready.emit(False, f"服务文件不存在: {self.service_name}.service")
|
||||
return
|
||||
|
||||
file_info = stdout.read().decode().strip()
|
||||
logger.info(f"服务文件存在: {file_info}")
|
||||
|
||||
if self.action == "status":
|
||||
# 状态命令需要特殊处理
|
||||
@@ -828,12 +900,12 @@ class ManageGunicornServiceThread(QThread):
|
||||
|
||||
if exit_status == 0:
|
||||
output = stdout.read().decode()
|
||||
logger.info(f"服务状态查询成功: {service_name_for_systemd}")
|
||||
self.result_ready.emit(True, output)
|
||||
logger.info(f"服务状态查询成功: {self.service_name}")
|
||||
else:
|
||||
error = stderr.read().decode()
|
||||
self.result_ready.emit(False, error)
|
||||
logger.error(f"服务状态查询失败: {error}")
|
||||
self.result_ready.emit(False, error)
|
||||
else:
|
||||
# 其他操作(start, stop, restart, enable, disable)
|
||||
if self.password:
|
||||
@@ -845,14 +917,14 @@ class ManageGunicornServiceThread(QThread):
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status == 0:
|
||||
self.result_ready.emit(True, f"服务{self.action}成功: {self.service_name}")
|
||||
logger.info(f"服务{self.action}成功: {self.service_name}")
|
||||
logger.info(f"服务{self.action}成功: {service_name_for_systemd}")
|
||||
self.result_ready.emit(True, f"服务{self.action}成功: {service_name_for_systemd}")
|
||||
else:
|
||||
error = stderr.read().decode()
|
||||
self.result_ready.emit(False, error)
|
||||
logger.error(f"服务{self.action}失败: {error}")
|
||||
self.result_ready.emit(False, error)
|
||||
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
self.result_ready.emit(False, error_msg)
|
||||
logger.error(f"服务管理异常: {error_msg}")
|
||||
logger.error(f"服务管理异常: {error_msg}")
|
||||
self.result_ready.emit(False, error_msg)
|
||||
Reference in New Issue
Block a user