修改了Gunicorn标签内容

This commit is contained in:
2025-08-28 22:30:17 +08:00
parent d559a85feb
commit 59b1f0e92a
13 changed files with 752 additions and 128 deletions

Binary file not shown.

343
app.log
View File

@@ -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:

View File

@@ -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": "生产服务器",

View File

@@ -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:

View File

@@ -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")

View File

@@ -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__":

View File

@@ -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

View File

@@ -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

View File

@@ -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)