From 47f3669dc426948b2577618e93fed81aa1e4e87a Mon Sep 17 00:00:00 2001 From: xiaji Date: Sun, 31 Aug 2025 20:35:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0nginx=E7=9A=84=E6=A0=87?= =?UTF-8?q?=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/gunicorn_tab.cpython-38.pyc | Bin 26598 -> 28686 bytes __pycache__/nginx_tab.cpython-38.pyc | Bin 0 -> 22784 bytes app.log | 455 ++++++++++++++ gunicorn_tab.py | 77 +++ main.py | 25 + nginx_tab.py | 785 ++++++++++++++++++++++++ 6 files changed, 1342 insertions(+) create mode 100644 __pycache__/nginx_tab.cpython-38.pyc create mode 100644 nginx_tab.py diff --git a/__pycache__/gunicorn_tab.cpython-38.pyc b/__pycache__/gunicorn_tab.cpython-38.pyc index 0edf5c2260bc9f551ab08ccecd6a42433eedbb28..9be301e18e627a0b70f4c167cd84530d1b65b670 100644 GIT binary patch delta 3395 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 E1;%!z^8f$< delta 1877 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:164 - 启动应用程序 +2025-08-31 20:03:04.413 | INFO | __main__:__init__:16 - 初始化主窗口 +2025-08-31 20:03:04.421 | INFO | __main__:__init__:31 - 设置状态栏显示当前目录: C:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署 +2025-08-31 20:03:04.421 | INFO | server_connection_tab:__init__:14 - 初始化服务器连接标签页 +2025-08-31 20:03:04.422 | INFO | server_connection_tab:init_ui:93 - 服务器连接标签页UI初始化完成 +2025-08-31 20:03:04.423 | INFO | server_connection_tab:load_config:96 - 加载配置文件 +2025-08-31 20:03:04.423 | INFO | server_connection_tab:load_config:103 - 成功加载配置文件: c:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署\config.json +2025-08-31 20:03:04.424 | INFO | server_connection_tab:on_alias_changed:122 - 选择别名: 测试机 +2025-08-31 20:03:04.425 | INFO | remote_commands_tab:__init__:145 - 初始化远程命令标签页 +2025-08-31 20:03:04.427 | INFO | remote_commands_tab:init_ui:286 - 远程命令标签页UI初始化完成 +2025-08-31 20:03:04.429 | INFO | __main__:__init__:52 - 主窗口初始化完成 +2025-08-31 20:04:26.465 | INFO | __main__::189 - 启动应用程序 +2025-08-31 20:04:26.488 | INFO | __main__:__init__:17 - 初始化主窗口 +2025-08-31 20:04:26.494 | INFO | __main__:__init__:32 - 设置状态栏显示当前目录: C:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署 +2025-08-31 20:04:26.495 | INFO | server_connection_tab:__init__:14 - 初始化服务器连接标签页 +2025-08-31 20:04:26.496 | INFO | server_connection_tab:init_ui:93 - 服务器连接标签页UI初始化完成 +2025-08-31 20:04:26.497 | INFO | server_connection_tab:load_config:96 - 加载配置文件 +2025-08-31 20:04:26.497 | INFO | server_connection_tab:load_config:103 - 成功加载配置文件: C:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署\config.json +2025-08-31 20:04:26.498 | INFO | server_connection_tab:on_alias_changed:122 - 选择别名: 测试机 +2025-08-31 20:04:26.499 | INFO | remote_commands_tab:__init__:145 - 初始化远程命令标签页 +2025-08-31 20:04:26.500 | INFO | remote_commands_tab:init_ui:286 - 远程命令标签页UI初始化完成 +2025-08-31 20:04:26.503 | INFO | __main__:__init__:57 - 主窗口初始化完成 +2025-08-31 20:05:12.806 | INFO | __main__::189 - 启动应用程序 +2025-08-31 20:05:12.830 | INFO | __main__:__init__:17 - 初始化主窗口 +2025-08-31 20:05:12.836 | INFO | __main__:__init__:32 - 设置状态栏显示当前目录: C:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署 +2025-08-31 20:05:12.836 | INFO | server_connection_tab:__init__:14 - 初始化服务器连接标签页 +2025-08-31 20:05:12.837 | INFO | server_connection_tab:init_ui:93 - 服务器连接标签页UI初始化完成 +2025-08-31 20:05:12.838 | INFO | server_connection_tab:load_config:96 - 加载配置文件 +2025-08-31 20:05:12.838 | INFO | server_connection_tab:load_config:103 - 成功加载配置文件: c:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署\config.json +2025-08-31 20:05:12.839 | INFO | server_connection_tab:on_alias_changed:122 - 选择别名: 测试机 +2025-08-31 20:05:12.840 | INFO | remote_commands_tab:__init__:145 - 初始化远程命令标签页 +2025-08-31 20:05:12.841 | INFO | remote_commands_tab:init_ui:286 - 远程命令标签页UI初始化完成 +2025-08-31 20:05:12.844 | INFO | __main__:__init__:57 - 主窗口初始化完成 +2025-08-31 20:05:14.296 | INFO | server_connection_tab:connect_to_server:188 - 尝试连接服务器 +2025-08-31 20:05:14.392 | INFO | server_connection_tab:connect_to_server:207 - 成功连接到服务器: 192.168.3.157 +2025-08-31 20:05:16.217 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 4 +2025-08-31 20:05:16.217 | INFO | nginx_tab:set_ssh_client:400 - Nginx标签页已设置SSH客户端 +2025-08-31 20:05:16.218 | INFO | nginx_tab:set_username:405 - Nginx标签页已设置用户名: xiaji +2025-08-31 20:05:16.218 | INFO | nginx_tab:set_project_info:411 - Nginx标签页已设置项目信息: statuspage, 192.168.3.157 +2025-08-31 20:05:16.219 | INFO | __main__:on_tab_changed:185 - 状态栏更新为Nginx服务: nginx, 项目: statuspage +2025-08-31 20:05:21.255 | INFO | nginx_tab:run:48 - 开始安装Nginx +2025-08-31 20:05:33.240 | INFO | nginx_tab:run:59 - 验证Nginx安装 +2025-08-31 20:05:33.292 | INFO | nginx_tab:run:65 - Nginx版本检查状态: 0 +2025-08-31 20:05:33.293 | INFO | nginx_tab:run:66 - Nginx版本信息: +2025-08-31 20:05:33.293 | ERROR | nginx_tab:run:68 - Nginx版本检查错误: nginx version: nginx/1.26.0 (Ubuntu) + +2025-08-31 20:05:33.293 | ERROR | nginx_tab:run:75 - Nginx安装后无法获取版本信息 +2025-08-31 20:05:33.294 | ERROR | nginx_tab:on_install_result:447 - Nginx安装失败: Nginx安装后无法获取版本信息 +2025-08-31 20:05:56.948 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: status +2025-08-31 20:05:56.978 | INFO | nginx_tab:run:193 - Nginx status 操作成功 +2025-08-31 20:05:56.980 | INFO | nginx_tab:on_control_result:623 - Nginx服务控制成功: Nginx status 操作成功 +● nginx.service - A high performance web server and a reverse proxy server + Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled) + Active: active (running) since Sun 2025-08-31 20:05:29 CST; 26s ago + Invocation: 3d4c27ce154b47519464a7db671a941a + Docs: man:nginx(8) + Process: 1820 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Process: 1821 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Main PID: 1849 (nginx) + Tasks: 3 (limit: 1846) + Memory: 2.7M (peak: 6.5M) + CPU: 32ms + CGroup: /system.slice/nginx.service + ├─1849 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;" + ├─1852 "nginx: worker process" + └─1853 "nginx: worker process" + +Aug 31 20:05:29 statuspage systemd[1]: Starting nginx.service - A high performance web server and a reverse proxy server... +Aug 31 20:05:29 statuspage systemd[1]: Started nginx.service - A high performance web server and a reverse proxy server. + +2025-08-31 20:06:13.735 | INFO | nginx_tab:run:99 - 开始处理Nginx配置文件: /etc/nginx/nginx.conf, 操作: upload +2025-08-31 20:06:15.847 | WARNING | nginx_tab:run:123 - 备份原配置文件失败: [sudo] password for xiaji: Sorry, try again. +[sudo] password for xiaji: +sudo: no password was provided +sudo: 1 incorrect password attempt + +2025-08-31 20:06:17.894 | ERROR | nginx_tab:run:136 - 配置文件上传失败: [sudo] password for xiaji: Sorry, try again. +[sudo] password for xiaji: +sudo: no password was provided +sudo: 1 incorrect password attempt + +2025-08-31 20:06:17.895 | ERROR | nginx_tab:on_upload_main_config_result:508 - Nginx主配置文件上传失败: 配置文件上传失败: [sudo] password for xiaji: Sorry, try again. +[sudo] password for xiaji: +sudo: no password was provided +sudo: 1 incorrect password attempt + +2025-08-31 20:06:20.242 | INFO | nginx_tab:run:99 - 开始处理Nginx配置文件: /etc/nginx/nginx.conf, 操作: upload +2025-08-31 20:06:20.381 | INFO | nginx_tab:run:132 - 配置文件上传成功: /etc/nginx/nginx.conf +2025-08-31 20:06:20.381 | INFO | nginx_tab:on_upload_main_config_result:504 - Nginx主配置文件上传成功: 配置文件上传成功: /etc/nginx/nginx.conf +2025-08-31 20:06:27.533 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: restart +2025-08-31 20:06:32.607 | ERROR | nginx_tab:run:196 - Nginx restart 操作失败: [sudo] password for xiaji: Job for nginx.service failed because the control process exited with error code. +See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details. + +2025-08-31 20:06:32.607 | ERROR | nginx_tab:on_control_result:627 - Nginx服务控制失败: Nginx restart 操作失败: [sudo] password for xiaji: Job for nginx.service failed because the control process exited with error code. +See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details. + +2025-08-31 20:06:50.982 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: restart +2025-08-31 20:06:51.025 | ERROR | nginx_tab:run:196 - Nginx restart 操作失败: [sudo] password for xiaji: Job for nginx.service failed because the control process exited with error code. +See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details. + +2025-08-31 20:06:51.026 | ERROR | nginx_tab:on_control_result:627 - Nginx服务控制失败: Nginx restart 操作失败: [sudo] password for xiaji: Job for nginx.service failed because the control process exited with error code. +See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details. + +2025-08-31 20:09:35.805 | INFO | __main__::189 - 启动应用程序 +2025-08-31 20:09:35.826 | INFO | __main__:__init__:17 - 初始化主窗口 +2025-08-31 20:09:35.832 | INFO | __main__:__init__:32 - 设置状态栏显示当前目录: C:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署 +2025-08-31 20:09:35.832 | INFO | server_connection_tab:__init__:14 - 初始化服务器连接标签页 +2025-08-31 20:09:35.833 | INFO | server_connection_tab:init_ui:93 - 服务器连接标签页UI初始化完成 +2025-08-31 20:09:35.834 | INFO | server_connection_tab:load_config:96 - 加载配置文件 +2025-08-31 20:09:35.834 | INFO | server_connection_tab:load_config:103 - 成功加载配置文件: c:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署\config.json +2025-08-31 20:09:35.835 | INFO | server_connection_tab:on_alias_changed:122 - 选择别名: 测试机 +2025-08-31 20:09:35.836 | INFO | remote_commands_tab:__init__:145 - 初始化远程命令标签页 +2025-08-31 20:09:35.837 | INFO | remote_commands_tab:init_ui:286 - 远程命令标签页UI初始化完成 +2025-08-31 20:09:35.840 | INFO | __main__:__init__:57 - 主窗口初始化完成 +2025-08-31 20:09:37.357 | INFO | server_connection_tab:connect_to_server:188 - 尝试连接服务器 +2025-08-31 20:09:37.464 | INFO | server_connection_tab:connect_to_server:207 - 成功连接到服务器: 192.168.3.157 +2025-08-31 20:09:39.038 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 4 +2025-08-31 20:09:39.038 | INFO | nginx_tab:set_ssh_client:402 - Nginx标签页已设置SSH客户端 +2025-08-31 20:09:39.039 | INFO | nginx_tab:set_username:407 - Nginx标签页已设置用户名: xiaji +2025-08-31 20:09:39.039 | INFO | nginx_tab:set_project_info:413 - Nginx标签页已设置项目信息: statuspage, 192.168.3.157 +2025-08-31 20:09:39.040 | INFO | __main__:on_tab_changed:185 - 状态栏更新为Nginx服务: nginx, 项目: statuspage +2025-08-31 20:09:45.220 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: configtest +2025-08-31 20:09:45.246 | ERROR | nginx_tab:run:198 - Nginx configtest 操作失败: [sudo] password for xiaji: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok +2025/08/31 20:09:45 [emerg] 2045#2045: no "events" section in configuration +nginx: configuration file /etc/nginx/nginx.conf test failed + +2025-08-31 20:09:45.246 | ERROR | nginx_tab:on_configtest_result:695 - Nginx配置文件语法检查失败: Nginx configtest 操作失败: [sudo] password for xiaji: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok +2025/08/31 20:09:45 [emerg] 2045#2045: no "events" section in configuration +nginx: configuration file /etc/nginx/nginx.conf test failed + +2025-08-31 20:10:10.671 | INFO | nginx_tab:run:99 - 开始处理Nginx配置文件: /etc/nginx/nginx.conf, 操作: download +2025-08-31 20:10:10.697 | INFO | nginx_tab:run:147 - 配置文件下载成功: /etc/nginx/nginx.conf +2025-08-31 20:10:10.697 | INFO | nginx_tab:on_download_main_config_result:476 - Nginx主配置文件下载成功 +2025-08-31 20:10:23.115 | INFO | nginx_tab:run:99 - 开始处理Nginx配置文件: /etc/nginx/nginx.conf, 操作: upload +2025-08-31 20:10:23.256 | INFO | nginx_tab:run:132 - 配置文件上传成功: /etc/nginx/nginx.conf +2025-08-31 20:10:23.257 | INFO | nginx_tab:on_upload_main_config_result:506 - Nginx主配置文件上传成功: 配置文件上传成功: /etc/nginx/nginx.conf +2025-08-31 20:10:28.385 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: configtest +2025-08-31 20:10:28.410 | ERROR | nginx_tab:run:198 - Nginx configtest 操作失败: [sudo] password for xiaji: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok +2025/08/31 20:10:28 [emerg] 2069#2069: no "events" section in configuration +nginx: configuration file /etc/nginx/nginx.conf test failed + +2025-08-31 20:10:28.410 | ERROR | nginx_tab:on_upload_configtest_result:535 - Nginx主配置文件上传后语法检查失败: Nginx configtest 操作失败: [sudo] password for xiaji: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok +2025/08/31 20:10:28 [emerg] 2069#2069: no "events" section in configuration +nginx: configuration file /etc/nginx/nginx.conf test failed + +2025-08-31 20:10:43.984 | INFO | nginx_tab:run:99 - 开始处理Nginx配置文件: /etc/nginx/nginx.conf, 操作: download +2025-08-31 20:10:44.010 | INFO | nginx_tab:run:147 - 配置文件下载成功: /etc/nginx/nginx.conf +2025-08-31 20:10:44.012 | INFO | nginx_tab:on_download_main_config_result:476 - Nginx主配置文件下载成功 +2025-08-31 20:13:11.436 | INFO | nginx_tab:run:99 - 开始处理Nginx配置文件: /etc/nginx/nginx.conf, 操作: upload +2025-08-31 20:13:11.579 | INFO | nginx_tab:run:132 - 配置文件上传成功: /etc/nginx/nginx.conf +2025-08-31 20:13:11.580 | INFO | nginx_tab:on_upload_main_config_result:506 - Nginx主配置文件上传成功: 配置文件上传成功: /etc/nginx/nginx.conf +2025-08-31 20:13:16.875 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: configtest +2025-08-31 20:13:16.902 | INFO | nginx_tab:run:195 - Nginx configtest 操作成功 +2025-08-31 20:13:16.903 | INFO | nginx_tab:on_upload_configtest_result:532 - Nginx主配置文件上传后语法检查通过 +2025-08-31 20:13:23.150 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: configtest +2025-08-31 20:13:23.176 | INFO | nginx_tab:run:195 - Nginx configtest 操作成功 +2025-08-31 20:13:27.020 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: restart +2025-08-31 20:13:27.083 | INFO | nginx_tab:run:195 - Nginx restart 操作成功 +2025-08-31 20:13:27.084 | INFO | nginx_tab:on_control_result:721 - Nginx服务控制成功: Nginx restart 操作成功 + +2025-08-31 20:15:08.973 | INFO | nginx_tab:run:219 - 开始处理Nginx站点配置: statuspage, 操作: create +2025-08-31 20:15:09.050 | INFO | nginx_tab:run:245 - 站点配置文件创建成功: /etc/nginx/sites-available/statuspage +2025-08-31 20:15:09.051 | INFO | nginx_tab:on_create_site_config_result:567 - Nginx站点配置创建成功: 站点配置文件创建成功: /etc/nginx/sites-available/statuspage +2025-08-31 20:15:13.244 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: configtest +2025-08-31 20:15:13.273 | INFO | nginx_tab:run:195 - Nginx configtest 操作成功 +2025-08-31 20:15:13.273 | INFO | nginx_tab:on_create_configtest_result:593 - Nginx站点配置文件创建后语法检查通过 +2025-08-31 20:15:18.686 | INFO | nginx_tab:run:219 - 开始处理Nginx站点配置: statuspage, 操作: enable +2025-08-31 20:15:18.709 | INFO | nginx_tab:run:259 - 站点配置启用成功: statuspage +2025-08-31 20:15:18.709 | INFO | nginx_tab:on_enable_site_config_result:626 - Nginx站点配置启用成功: 站点配置启用成功: statuspage +2025-08-31 20:15:23.294 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: configtest +2025-08-31 20:15:23.323 | INFO | nginx_tab:run:195 - Nginx configtest 操作成功 +2025-08-31 20:15:23.323 | INFO | nginx_tab:on_enable_configtest_result:652 - Nginx站点配置启用后语法检查通过 +2025-08-31 20:15:27.604 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: configtest +2025-08-31 20:15:27.638 | INFO | nginx_tab:run:195 - Nginx configtest 操作成功 +2025-08-31 20:15:31.970 | INFO | nginx_tab:run:170 - 开始执行Nginx服务操作: restart +2025-08-31 20:15:32.068 | INFO | nginx_tab:run:195 - Nginx restart 操作成功 +2025-08-31 20:15:32.069 | INFO | nginx_tab:on_control_result:721 - Nginx服务控制成功: Nginx restart 操作成功 + +2025-08-31 20:16:11.376 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 3 +2025-08-31 20:16:11.377 | INFO | gunicorn_tab:set_ssh_client:620 - Gunicorn标签页已设置SSH客户端 +2025-08-31 20:16:11.377 | INFO | __main__:on_tab_changed:158 - 构建的Django路径: /home/xiaji/webstatus/, 项目名: statuspage +2025-08-31 20:16:11.377 | INFO | gunicorn_tab:set_username:625 - Gunicorn标签页已设置用户名: xiaji +2025-08-31 20:16:11.377 | INFO | gunicorn_tab:set_project_info:631 - Gunicorn标签页已设置项目信息: statuspage, /home/xiaji/webstatus/ +2025-08-31 20:16:11.380 | INFO | gunicorn_tab:update_command_editor:658 - Gunicorn命令编辑器已更新项目名称: statuspage +2025-08-31 20:16:11.380 | INFO | __main__:on_tab_changed:165 - 状态栏更新为Gunicorn服务: gunicorn_statuspage, 目录: /home/xiaji/webstatus/ +2025-08-31 20:17:00.751 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 4 +2025-08-31 20:17:00.752 | INFO | nginx_tab:set_ssh_client:402 - Nginx标签页已设置SSH客户端 +2025-08-31 20:17:00.752 | INFO | nginx_tab:set_username:407 - Nginx标签页已设置用户名: xiaji +2025-08-31 20:17:00.752 | INFO | nginx_tab:set_project_info:413 - Nginx标签页已设置项目信息: statuspage, 192.168.3.157 +2025-08-31 20:17:00.756 | INFO | __main__:on_tab_changed:185 - 状态栏更新为Nginx服务: nginx, 项目: statuspage +2025-08-31 20:18:09.915 | INFO | __main__::189 - 启动应用程序 +2025-08-31 20:18:09.942 | INFO | __main__:__init__:17 - 初始化主窗口 +2025-08-31 20:18:09.953 | INFO | __main__:__init__:32 - 设置状态栏显示当前目录: C:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署 +2025-08-31 20:18:09.953 | INFO | server_connection_tab:__init__:14 - 初始化服务器连接标签页 +2025-08-31 20:18:09.955 | INFO | server_connection_tab:init_ui:93 - 服务器连接标签页UI初始化完成 +2025-08-31 20:18:09.955 | INFO | server_connection_tab:load_config:96 - 加载配置文件 +2025-08-31 20:18:09.956 | INFO | server_connection_tab:load_config:103 - 成功加载配置文件: c:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署\config.json +2025-08-31 20:18:09.956 | INFO | server_connection_tab:on_alias_changed:122 - 选择别名: 测试机 +2025-08-31 20:18:09.959 | INFO | remote_commands_tab:__init__:145 - 初始化远程命令标签页 +2025-08-31 20:18:09.961 | INFO | remote_commands_tab:init_ui:286 - 远程命令标签页UI初始化完成 +2025-08-31 20:18:09.964 | INFO | __main__:__init__:57 - 主窗口初始化完成 +2025-08-31 20:18:11.202 | INFO | server_connection_tab:connect_to_server:188 - 尝试连接服务器 +2025-08-31 20:18:11.290 | INFO | server_connection_tab:connect_to_server:207 - 成功连接到服务器: 192.168.3.157 +2025-08-31 20:18:13.987 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 3 +2025-08-31 20:18:13.988 | INFO | gunicorn_tab:set_ssh_client:620 - Gunicorn标签页已设置SSH客户端 +2025-08-31 20:18:13.988 | INFO | __main__:on_tab_changed:158 - 构建的Django路径: /home/xiaji/webstatus/, 项目名: statuspage +2025-08-31 20:18:13.988 | INFO | gunicorn_tab:set_username:625 - Gunicorn标签页已设置用户名: xiaji +2025-08-31 20:18:13.988 | INFO | gunicorn_tab:set_project_info:631 - Gunicorn标签页已设置项目信息: statuspage, /home/xiaji/webstatus/ +2025-08-31 20:18:13.990 | INFO | gunicorn_tab:update_command_editor:658 - Gunicorn命令编辑器已更新项目名称: statuspage +2025-08-31 20:18:13.990 | INFO | __main__:on_tab_changed:165 - 状态栏更新为Gunicorn服务: gunicorn_statuspage, 目录: /home/xiaji/webstatus/ +2025-08-31 20:18:15.291 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 4 +2025-08-31 20:18:15.291 | INFO | nginx_tab:set_ssh_client:461 - Nginx标签页已设置SSH客户端 +2025-08-31 20:18:15.291 | INFO | nginx_tab:set_username:466 - Nginx标签页已设置用户名: xiaji +2025-08-31 20:18:15.292 | INFO | nginx_tab:set_project_info:472 - Nginx标签页已设置项目信息: statuspage, 192.168.3.157 +2025-08-31 20:18:15.295 | INFO | __main__:on_tab_changed:185 - 状态栏更新为Nginx服务: nginx, 项目: statuspage +2025-08-31 20:18:36.697 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 2 +2025-08-31 20:18:36.697 | INFO | django_tab:set_ssh_client:142 - Django标签页已设置SSH客户端 +2025-08-31 20:18:36.698 | INFO | django_tab:set_username:147 - Django标签页已设置用户名: xiaji +2025-08-31 20:18:36.698 | INFO | __main__:on_tab_changed:123 - 状态栏更新为Django项目: statuspage, 目录: /home/xiaji +2025-08-31 20:18:37.758 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 3 +2025-08-31 20:18:37.759 | INFO | gunicorn_tab:set_ssh_client:620 - Gunicorn标签页已设置SSH客户端 +2025-08-31 20:18:37.759 | INFO | __main__:on_tab_changed:158 - 构建的Django路径: /home/xiaji/webstatus/, 项目名: statuspage +2025-08-31 20:18:37.759 | INFO | gunicorn_tab:set_username:625 - Gunicorn标签页已设置用户名: xiaji +2025-08-31 20:18:37.759 | INFO | gunicorn_tab:set_project_info:631 - Gunicorn标签页已设置项目信息: statuspage, /home/xiaji/webstatus/ +2025-08-31 20:18:37.761 | INFO | gunicorn_tab:update_command_editor:658 - Gunicorn命令编辑器已更新项目名称: statuspage +2025-08-31 20:18:37.761 | INFO | __main__:on_tab_changed:165 - 状态栏更新为Gunicorn服务: gunicorn_statuspage, 目录: /home/xiaji/webstatus/ +2025-08-31 20:18:38.211 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 2 +2025-08-31 20:18:38.211 | INFO | django_tab:set_ssh_client:142 - Django标签页已设置SSH客户端 +2025-08-31 20:18:38.212 | INFO | django_tab:set_username:147 - Django标签页已设置用户名: xiaji +2025-08-31 20:18:38.212 | INFO | __main__:on_tab_changed:123 - 状态栏更新为Django项目: statuspage, 目录: /home/xiaji +2025-08-31 20:18:39.043 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 3 +2025-08-31 20:18:39.043 | INFO | gunicorn_tab:set_ssh_client:620 - Gunicorn标签页已设置SSH客户端 +2025-08-31 20:18:39.043 | INFO | __main__:on_tab_changed:158 - 构建的Django路径: /home/xiaji/webstatus/, 项目名: statuspage +2025-08-31 20:18:39.043 | INFO | gunicorn_tab:set_username:625 - Gunicorn标签页已设置用户名: xiaji +2025-08-31 20:18:39.044 | INFO | gunicorn_tab:set_project_info:631 - Gunicorn标签页已设置项目信息: statuspage, /home/xiaji/webstatus/ +2025-08-31 20:18:39.045 | INFO | gunicorn_tab:update_command_editor:658 - Gunicorn命令编辑器已更新项目名称: statuspage +2025-08-31 20:18:39.045 | INFO | __main__:on_tab_changed:165 - 状态栏更新为Gunicorn服务: gunicorn_statuspage, 目录: /home/xiaji/webstatus/ +2025-08-31 20:18:44.382 | INFO | gunicorn_tab:run:388 - Gunicorn服务状态查询成功: gunicorn_statuspage +● gunicorn_statuspage.service - Gunicorn Daemon for statuspage Project + Loaded: loaded (/etc/systemd/system/gunicorn_statuspage.service; enabled; preset: enabled) + Active: active (running) since Sun 2025-08-31 19:53:52 CST; 24min ago + Invocation: 1dd86392ae0e443fb566af6798a730ca + Main PID: 910 (gunicorn) + Tasks: 4 (limit: 1846) + Memory: 117.2M (peak: 121.9M) + CPU: 1.373s + CGroup: /system.slice/gunicorn_statuspage.service + ├─ 910 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + ├─1073 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + ├─1075 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + └─1961 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + +Aug 31 20:06:38 statuspage gunicorn[1065]: d = self.chunk() +Aug 31 20:06:38 statuspage gunicorn[1065]: ^^^^^^^^^^^^ +Aug 31 20:06:38 statuspage gunicorn[1065]: File "/usr/lib/python3/dist-packages/gunicorn/http/unreader.py", line 63, in chunk +Aug 31 20:06:38 statuspage gunicorn[1065]: return self.sock.recv(self.mxchunk) +Aug 31 20:06:38 statuspage gunicorn[1065]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Aug 31 20:06:38 statuspage gunicorn[1065]: File "/usr/lib/python3/dist-packages/gunicorn/workers/base.py", line 204, in handle_abort +Aug 31 20:06:38 statuspage gunicorn[1065]: sys.exit(1) +Aug 31 20:06:38 statuspage gunicorn[1065]: SystemExit: 1 +Aug 31 20:06:38 statuspage gunicorn[1065]: [2025-08-31 20:06:38 +0800] [1065] [INFO] Worker exiting (pid: 1065) +Aug 31 20:06:38 statuspage gunicorn[1961]: [2025-08-31 20:06:38 +0800] [1961] [INFO] Booting worker with pid: 1961 + +2025-08-31 20:18:44.384 | INFO | gunicorn_tab:on_control_result:894 - Gunicorn服务控制成功: Gunicorn服务状态查询成功: gunicorn_statuspage +● gunicorn_statuspage.service - Gunicorn Daemon for statuspage Project + Loaded: loaded (/etc/systemd/system/gunicorn_statuspage.service; enabled; preset: enabled) + Active: active (running) since Sun 2025-08-31 19:53:52 CST; 24min ago + Invocation: 1dd86392ae0e443fb566af6798a730ca + Main PID: 910 (gunicorn) + Tasks: 4 (limit: 1846) + Memory: 117.2M (peak: 121.9M) + CPU: 1.373s + CGroup: /system.slice/gunicorn_statuspage.service + ├─ 910 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + ├─1073 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + ├─1075 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + └─1961 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + +Aug 31 20:06:38 statuspage gunicorn[1065]: d = self.chunk() +Aug 31 20:06:38 statuspage gunicorn[1065]: ^^^^^^^^^^^^ +Aug 31 20:06:38 statuspage gunicorn[1065]: File "/usr/lib/python3/dist-packages/gunicorn/http/unreader.py", line 63, in chunk +Aug 31 20:06:38 statuspage gunicorn[1065]: return self.sock.recv(self.mxchunk) +Aug 31 20:06:38 statuspage gunicorn[1065]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Aug 31 20:06:38 statuspage gunicorn[1065]: File "/usr/lib/python3/dist-packages/gunicorn/workers/base.py", line 204, in handle_abort +Aug 31 20:06:38 statuspage gunicorn[1065]: sys.exit(1) +Aug 31 20:06:38 statuspage gunicorn[1065]: SystemExit: 1 +Aug 31 20:06:38 statuspage gunicorn[1065]: [2025-08-31 20:06:38 +0800] [1065] [INFO] Worker exiting (pid: 1065) +Aug 31 20:06:38 statuspage gunicorn[1961]: [2025-08-31 20:06:38 +0800] [1961] [INFO] Booting worker with pid: 1961 + +2025-08-31 20:28:58.014 | INFO | __main__::189 - 启动应用程序 +2025-08-31 20:28:58.038 | INFO | __main__:__init__:17 - 初始化主窗口 +2025-08-31 20:28:58.043 | INFO | __main__:__init__:32 - 设置状态栏显示当前目录: C:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署 +2025-08-31 20:28:58.043 | INFO | server_connection_tab:__init__:14 - 初始化服务器连接标签页 +2025-08-31 20:28:58.045 | INFO | server_connection_tab:init_ui:93 - 服务器连接标签页UI初始化完成 +2025-08-31 20:28:58.045 | INFO | server_connection_tab:load_config:96 - 加载配置文件 +2025-08-31 20:28:58.045 | INFO | server_connection_tab:load_config:103 - 成功加载配置文件: c:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署\config.json +2025-08-31 20:28:58.046 | INFO | server_connection_tab:on_alias_changed:122 - 选择别名: 测试机 +2025-08-31 20:28:58.046 | INFO | remote_commands_tab:__init__:145 - 初始化远程命令标签页 +2025-08-31 20:28:58.049 | INFO | remote_commands_tab:init_ui:286 - 远程命令标签页UI初始化完成 +2025-08-31 20:28:58.052 | INFO | __main__:__init__:57 - 主窗口初始化完成 +2025-08-31 20:29:00.294 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 4 +2025-08-31 20:29:00.294 | INFO | nginx_tab:set_ssh_client:461 - Nginx标签页已设置SSH客户端 +2025-08-31 20:29:00.294 | INFO | nginx_tab:set_username:466 - Nginx标签页已设置用户名: xiaji +2025-08-31 20:29:00.294 | INFO | nginx_tab:set_project_info:472 - Nginx标签页已设置项目信息: statuspage, 192.168.3.157 +2025-08-31 20:29:00.297 | INFO | __main__:on_tab_changed:185 - 状态栏更新为Nginx服务: nginx, 项目: statuspage +2025-08-31 20:29:01.792 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 3 +2025-08-31 20:29:01.793 | INFO | gunicorn_tab:set_ssh_client:620 - Gunicorn标签页已设置SSH客户端 +2025-08-31 20:29:01.793 | INFO | __main__:on_tab_changed:158 - 构建的Django路径: /home/xiaji/webstatus/, 项目名: statuspage +2025-08-31 20:29:01.794 | INFO | gunicorn_tab:set_username:625 - Gunicorn标签页已设置用户名: xiaji +2025-08-31 20:29:01.794 | INFO | gunicorn_tab:set_project_info:631 - Gunicorn标签页已设置项目信息: statuspage, /home/xiaji/webstatus/ +2025-08-31 20:29:01.796 | INFO | gunicorn_tab:update_command_editor:658 - Gunicorn命令编辑器已更新项目名称: statuspage +2025-08-31 20:29:01.796 | INFO | __main__:on_tab_changed:165 - 状态栏更新为Gunicorn服务: gunicorn_statuspage, 目录: /home/xiaji/webstatus/ +2025-08-31 20:29:29.642 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 0 +2025-08-31 20:29:30.447 | INFO | server_connection_tab:connect_to_server:188 - 尝试连接服务器 +2025-08-31 20:29:30.545 | INFO | server_connection_tab:connect_to_server:207 - 成功连接到服务器: 192.168.3.157 +2025-08-31 20:29:31.844 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 3 +2025-08-31 20:29:31.844 | INFO | gunicorn_tab:set_ssh_client:620 - Gunicorn标签页已设置SSH客户端 +2025-08-31 20:29:31.844 | INFO | __main__:on_tab_changed:158 - 构建的Django路径: /home/xiaji/webstatus/, 项目名: statuspage +2025-08-31 20:29:31.845 | INFO | gunicorn_tab:set_username:625 - Gunicorn标签页已设置用户名: xiaji +2025-08-31 20:29:31.845 | INFO | gunicorn_tab:set_project_info:631 - Gunicorn标签页已设置项目信息: statuspage, /home/xiaji/webstatus/ +2025-08-31 20:29:31.856 | INFO | gunicorn_tab:update_command_editor:658 - Gunicorn命令编辑器已更新项目名称: statuspage +2025-08-31 20:29:31.856 | INFO | __main__:on_tab_changed:165 - 状态栏更新为Gunicorn服务: gunicorn_statuspage, 目录: /home/xiaji/webstatus/ +2025-08-31 20:29:40.458 | INFO | gunicorn_tab:run:326 - Gunicorn服务文件上传成功: gunicorn_statuspage.service +2025-08-31 20:29:40.458 | INFO | gunicorn_tab:on_upload_result:764 - Gunicorn服务文件上传成功: Gunicorn服务文件上传成功: gunicorn_statuspage.service +2025-08-31 20:30:13.972 | INFO | gunicorn_tab:run:388 - Gunicorn服务状态查询成功: gunicorn_statuspage +● gunicorn_statuspage.service - Gunicorn Daemon for statuspage Project + Loaded: loaded (/etc/systemd/system/gunicorn_statuspage.service; enabled; preset: enabled) + Active: active (running) since Sun 2025-08-31 19:53:52 CST; 36min ago + Invocation: 1dd86392ae0e443fb566af6798a730ca + Main PID: 910 (gunicorn) + Tasks: 4 (limit: 1846) + Memory: 117.2M (peak: 121.9M) + CPU: 1.455s + CGroup: /system.slice/gunicorn_statuspage.service + ├─ 910 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + ├─1073 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + ├─1075 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + └─1961 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + +Aug 31 20:06:38 statuspage gunicorn[1065]: d = self.chunk() +Aug 31 20:06:38 statuspage gunicorn[1065]: ^^^^^^^^^^^^ +Aug 31 20:06:38 statuspage gunicorn[1065]: File "/usr/lib/python3/dist-packages/gunicorn/http/unreader.py", line 63, in chunk +Aug 31 20:06:38 statuspage gunicorn[1065]: return self.sock.recv(self.mxchunk) +Aug 31 20:06:38 statuspage gunicorn[1065]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Aug 31 20:06:38 statuspage gunicorn[1065]: File "/usr/lib/python3/dist-packages/gunicorn/workers/base.py", line 204, in handle_abort +Aug 31 20:06:38 statuspage gunicorn[1065]: sys.exit(1) +Aug 31 20:06:38 statuspage gunicorn[1065]: SystemExit: 1 +Aug 31 20:06:38 statuspage gunicorn[1065]: [2025-08-31 20:06:38 +0800] [1065] [INFO] Worker exiting (pid: 1065) +Aug 31 20:06:38 statuspage gunicorn[1961]: [2025-08-31 20:06:38 +0800] [1961] [INFO] Booting worker with pid: 1961 + +2025-08-31 20:30:13.974 | INFO | gunicorn_tab:on_control_result:894 - Gunicorn服务控制成功: Gunicorn服务状态查询成功: gunicorn_statuspage +● gunicorn_statuspage.service - Gunicorn Daemon for statuspage Project + Loaded: loaded (/etc/systemd/system/gunicorn_statuspage.service; enabled; preset: enabled) + Active: active (running) since Sun 2025-08-31 19:53:52 CST; 36min ago + Invocation: 1dd86392ae0e443fb566af6798a730ca + Main PID: 910 (gunicorn) + Tasks: 4 (limit: 1846) + Memory: 117.2M (peak: 121.9M) + CPU: 1.455s + CGroup: /system.slice/gunicorn_statuspage.service + ├─ 910 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + ├─1073 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + ├─1075 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + └─1961 /usr/bin/python3 /usr/bin/gunicorn --pythonpath /home/xiaji/webstatus/ --workers 3 --bind 0.0.0.0:8000 statuspage.wsgi:application + +Aug 31 20:06:38 statuspage gunicorn[1065]: d = self.chunk() +Aug 31 20:06:38 statuspage gunicorn[1065]: ^^^^^^^^^^^^ +Aug 31 20:06:38 statuspage gunicorn[1065]: File "/usr/lib/python3/dist-packages/gunicorn/http/unreader.py", line 63, in chunk +Aug 31 20:06:38 statuspage gunicorn[1065]: return self.sock.recv(self.mxchunk) +Aug 31 20:06:38 statuspage gunicorn[1065]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Aug 31 20:06:38 statuspage gunicorn[1065]: File "/usr/lib/python3/dist-packages/gunicorn/workers/base.py", line 204, in handle_abort +Aug 31 20:06:38 statuspage gunicorn[1065]: sys.exit(1) +Aug 31 20:06:38 statuspage gunicorn[1065]: SystemExit: 1 +Aug 31 20:06:38 statuspage gunicorn[1065]: [2025-08-31 20:06:38 +0800] [1065] [INFO] Worker exiting (pid: 1065) +Aug 31 20:06:38 statuspage gunicorn[1961]: [2025-08-31 20:06:38 +0800] [1961] [INFO] Booting worker with pid: 1961 + +2025-08-31 20:30:35.664 | INFO | gunicorn_tab:run:416 - 开始设置服务器时区为Asia/Shanghai +2025-08-31 20:30:35.744 | INFO | gunicorn_tab:run:427 - 开始重启服务器 +2025-08-31 20:30:35.793 | INFO | gunicorn_tab:run:431 - 时区设置成功,服务器正在重启 +2025-08-31 20:30:35.795 | INFO | gunicorn_tab:on_server_control_result:924 - 服务器控制成功: 时区设置成功,服务器正在重启 +2025-08-31 20:30:38.823 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 0 +2025-08-31 20:30:40.783 | INFO | server_connection_tab:connect_to_server:188 - 尝试连接服务器 +2025-08-31 20:30:45.069 | INFO | server_connection_tab:connect_to_server:207 - 成功连接到服务器: 192.168.3.157 +2025-08-31 20:30:46.082 | INFO | server_connection_tab:connect_to_server:188 - 尝试连接服务器 +2025-08-31 20:30:46.165 | INFO | server_connection_tab:connect_to_server:207 - 成功连接到服务器: 192.168.3.157 +2025-08-31 20:30:47.787 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 3 +2025-08-31 20:30:47.787 | INFO | gunicorn_tab:set_ssh_client:620 - Gunicorn标签页已设置SSH客户端 +2025-08-31 20:30:47.787 | INFO | __main__:on_tab_changed:158 - 构建的Django路径: /home/xiaji/webstatus/, 项目名: statuspage +2025-08-31 20:30:47.788 | INFO | gunicorn_tab:set_username:625 - Gunicorn标签页已设置用户名: xiaji +2025-08-31 20:30:47.788 | INFO | gunicorn_tab:set_project_info:631 - Gunicorn标签页已设置项目信息: statuspage, /home/xiaji/webstatus/ +2025-08-31 20:30:47.789 | INFO | gunicorn_tab:update_command_editor:658 - Gunicorn命令编辑器已更新项目名称: statuspage +2025-08-31 20:30:47.790 | INFO | __main__:on_tab_changed:165 - 状态栏更新为Gunicorn服务: gunicorn_statuspage, 目录: /home/xiaji/webstatus/ +2025-08-31 20:30:51.917 | INFO | gunicorn_tab:run:388 - Gunicorn服务状态查询成功: gunicorn_statuspage +● gunicorn_statuspage.service - Gunicorn daemon for myproject + Loaded: loaded (/etc/systemd/system/gunicorn_statuspage.service; enabled; preset: enabled) + Active: activating (auto-restart) (Result: exit-code) since Sun 2025-08-31 20:30:49 CST; 2s ago + Invocation: 2532f0798f384dd5b2a0c33ede7832b2 + Process: 1327 ExecStart=/usr/bin/gunicorn \ (code=exited, status=3) + Main PID: 1327 (code=exited, status=3) + Mem peak: 26.7M + CPU: 158ms + +2025-08-31 20:30:51.918 | INFO | gunicorn_tab:on_control_result:894 - Gunicorn服务控制成功: Gunicorn服务状态查询成功: gunicorn_statuspage +● gunicorn_statuspage.service - Gunicorn daemon for myproject + Loaded: loaded (/etc/systemd/system/gunicorn_statuspage.service; enabled; preset: enabled) + Active: activating (auto-restart) (Result: exit-code) since Sun 2025-08-31 20:30:49 CST; 2s ago + Invocation: 2532f0798f384dd5b2a0c33ede7832b2 + Process: 1327 ExecStart=/usr/bin/gunicorn \ (code=exited, status=3) + Main PID: 1327 (code=exited, status=3) + Mem peak: 26.7M + CPU: 158ms + +2025-08-31 20:33:16.122 | INFO | __main__::189 - 启动应用程序 +2025-08-31 20:33:16.147 | INFO | __main__:__init__:17 - 初始化主窗口 +2025-08-31 20:33:16.155 | INFO | __main__:__init__:32 - 设置状态栏显示当前目录: C:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署 +2025-08-31 20:33:16.155 | INFO | server_connection_tab:__init__:14 - 初始化服务器连接标签页 +2025-08-31 20:33:16.156 | INFO | server_connection_tab:init_ui:93 - 服务器连接标签页UI初始化完成 +2025-08-31 20:33:16.157 | INFO | server_connection_tab:load_config:96 - 加载配置文件 +2025-08-31 20:33:16.157 | INFO | server_connection_tab:load_config:103 - 成功加载配置文件: c:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署\config.json +2025-08-31 20:33:16.158 | INFO | server_connection_tab:on_alias_changed:122 - 选择别名: 测试机 +2025-08-31 20:33:16.160 | INFO | remote_commands_tab:__init__:145 - 初始化远程命令标签页 +2025-08-31 20:33:16.162 | INFO | remote_commands_tab:init_ui:286 - 远程命令标签页UI初始化完成 +2025-08-31 20:33:16.165 | INFO | __main__:__init__:57 - 主窗口初始化完成 +2025-08-31 20:33:17.505 | INFO | server_connection_tab:connect_to_server:188 - 尝试连接服务器 +2025-08-31 20:33:17.590 | INFO | server_connection_tab:connect_to_server:207 - 成功连接到服务器: 192.168.3.157 +2025-08-31 20:33:19.109 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 3 +2025-08-31 20:33:19.109 | INFO | gunicorn_tab:set_ssh_client:660 - Gunicorn标签页已设置SSH客户端 +2025-08-31 20:33:19.110 | INFO | __main__:on_tab_changed:158 - 构建的Django路径: /home/xiaji/webstatus/, 项目名: statuspage +2025-08-31 20:33:19.110 | INFO | gunicorn_tab:set_username:665 - Gunicorn标签页已设置用户名: xiaji +2025-08-31 20:33:19.110 | INFO | gunicorn_tab:set_project_info:671 - Gunicorn标签页已设置项目信息: statuspage, /home/xiaji/webstatus/ +2025-08-31 20:33:19.111 | INFO | gunicorn_tab:update_command_editor:698 - Gunicorn命令编辑器已更新项目名称: statuspage +2025-08-31 20:33:19.111 | INFO | __main__:on_tab_changed:165 - 状态栏更新为Gunicorn服务: gunicorn_statuspage, 目录: /home/xiaji/webstatus/ +2025-08-31 20:33:30.668 | INFO | gunicorn_tab:run:388 - Gunicorn服务状态查询成功: gunicorn_statuspage +● gunicorn_statuspage.service - Gunicorn daemon for myproject + Loaded: loaded (/etc/systemd/system/gunicorn_statuspage.service; enabled; preset: enabled) + Active: activating (auto-restart) (Result: exit-code) since Sun 2025-08-31 20:33:28 CST; 2s ago + Invocation: 257596c8154a443da28aa4787e800443 + Process: 1587 ExecStart=/usr/bin/gunicorn \ (code=exited, status=3) + Main PID: 1587 (code=exited, status=3) + Mem peak: 26.6M + CPU: 157ms + +2025-08-31 20:33:30.669 | INFO | gunicorn_tab:on_control_result:971 - Gunicorn服务控制成功: Gunicorn服务状态查询成功: gunicorn_statuspage +● gunicorn_statuspage.service - Gunicorn daemon for myproject + Loaded: loaded (/etc/systemd/system/gunicorn_statuspage.service; enabled; preset: enabled) + Active: activating (auto-restart) (Result: exit-code) since Sun 2025-08-31 20:33:28 CST; 2s ago + Invocation: 257596c8154a443da28aa4787e800443 + Process: 1587 ExecStart=/usr/bin/gunicorn \ (code=exited, status=3) + Main PID: 1587 (code=exited, status=3) + Mem peak: 26.6M + CPU: 157ms + +2025-08-31 20:33:35.661 | INFO | gunicorn_tab:run:419 - 查看Gunicorn服务日志: bash -c 'echo "xiaji" | sudo -S journalctl -u gunicorn_statuspage -n 100' +2025-08-31 20:33:35.720 | INFO | gunicorn_tab:run:429 - Gunicorn服务日志查看成功 +2025-08-31 20:33:35.726 | INFO | gunicorn_tab:on_log_result:961 - Gunicorn服务日志查看成功 diff --git a/gunicorn_tab.py b/gunicorn_tab.py index d9313a2..ac610a9 100644 --- a/gunicorn_tab.py +++ b/gunicorn_tab.py @@ -401,6 +401,41 @@ class GunicornServiceControlThread(QThread): self.result_ready.emit(False, error_msg) logger.error(f"Gunicorn服务控制异常: {error_msg}") +class GunicornLogThread(QThread): + """查看Gunicorn服务日志的线程""" + result_ready = Signal(bool, str) + + def __init__(self, ssh_client, service_name, password, lines=100): + super().__init__() + self.ssh_client = ssh_client + self.service_name = service_name + self.password = password + self.lines = lines # 要查看的日志行数 + + def run(self): + try: + # 使用journalctl查看Gunicorn服务的日志 + command = f"bash -c 'echo \"{self.password}\" | sudo -S journalctl -u {self.service_name} -n {self.lines}'" + logger.info(f"查看Gunicorn服务日志: {command}") + + stdin, stdout, stderr = self.ssh_client.exec_command(command) + exit_status = stdout.channel.recv_exit_status() + + output = stdout.read().decode() + error = stderr.read().decode() + + if exit_status == 0: + self.result_ready.emit(True, output) + logger.info(f"Gunicorn服务日志查看成功") + else: + self.result_ready.emit(False, f"查看日志失败: {error}") + logger.error(f"Gunicorn服务日志查看失败: {error}") + + except Exception as e: + error_msg = str(e) + self.result_ready.emit(False, error_msg) + logger.error(f"Gunicorn服务日志查看异常: {error_msg}") + class ServerControlThread(QThread): """控制服务器设置的线程""" result_ready = Signal(bool, str) @@ -538,6 +573,11 @@ class GunicornTab(QWidget): self.check_status_btn.clicked.connect(self.check_service_status) service_btn_layout.addWidget(self.check_status_btn) + # 查看服务日志按钮 + self.view_logs_btn = QPushButton("查看服务日志") + self.view_logs_btn.clicked.connect(self.view_service_logs) + service_btn_layout.addWidget(self.view_logs_btn) + service_layout.addLayout(service_btn_layout) layout.addLayout(service_layout) @@ -887,6 +927,43 @@ class GunicornTab(QWidget): else: self.append_output("用户取消了密码输入") + def view_service_logs(self): + """查看Gunicorn服务日志""" + if not self.ssh_client: + self.append_output("错误: 未连接到服务器") + return + + if not self.project_name: + self.append_output("错误: 未设置项目名") + return + + service_name = f"gunicorn_{self.project_name}" + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + self.append_output(f"正在查看Gunicorn服务日志: {service_name}...") + + # 创建并启动日志查看线程 + self.log_thread = GunicornLogThread(self.ssh_client, service_name, password) + self.log_thread.result_ready.connect(self.on_log_result) + self.log_thread.start() + else: + self.append_output("用户取消了密码输入") + + def on_log_result(self, success, message): + """处理日志查看结果""" + if success: + self.append_output("--- Gunicorn服务日志 ---") + self.append_output(message) + self.append_output("--- 日志结束 ---") + logger.info("Gunicorn服务日志查看成功") + else: + self.append_output(f"查看日志失败: {message}") + logger.error(f"Gunicorn服务日志查看失败: {message}") + QMessageBox.warning(self, "错误", f"Gunicorn服务日志查看失败: {message}") + def on_control_result(self, success, message): """处理控制结果""" if success: diff --git a/main.py b/main.py index 9135152..1064c73 100644 --- a/main.py +++ b/main.py @@ -8,6 +8,7 @@ from server_connection_tab import ServerConnectionTab from remote_commands_tab import RemoteCommandsTab from django_tab import DjangoTab from gunicorn_tab import GunicornTab +from nginx_tab import NginxTab class MainWindow(QMainWindow): def __init__(self): @@ -46,6 +47,10 @@ class MainWindow(QMainWindow): self.gunicorn_tab = GunicornTab() self.tabs.addTab(self.gunicorn_tab, "Gunicorn") + # 添加Nginx管理标签页 + self.nginx_tab = NginxTab() + self.tabs.addTab(self.nginx_tab, "Nginx") + # 连接标签页切换信号 self.tabs.currentChanged.connect(self.on_tab_changed) @@ -158,6 +163,26 @@ class MainWindow(QMainWindow): # 更新状态栏显示Gunicorn服务信息 self.status_bar.showMessage(f"远程服务器: {current_alias} | Gunicorn服务: gunicorn_{project_name} | 服务目录: {django_path}") logger.info(f"状态栏更新为Gunicorn服务: gunicorn_{project_name}, 目录: {django_path}") + + # 当切换到Nginx标签页时,传递SSH客户端、用户名和项目信息 + elif index == 4: # Nginx标签页 + ssh_client = self.server_connection_tab.get_ssh_client() + self.nginx_tab.set_ssh_client(ssh_client) + + # 获取当前选中的服务器配置中的用户名和项目信息 + current_alias = self.server_connection_tab.alias_combo.currentText() + if current_alias and current_alias in self.server_connection_tab.config_data: + server_config = self.server_connection_tab.config_data[current_alias] + username = server_config.get("username", "") + project_name = server_config.get("project", "") + server_ip = server_config.get("ip", "") + + self.nginx_tab.set_username(username) + self.nginx_tab.set_project_info(project_name, server_ip) + + # 更新状态栏显示Nginx服务信息 + self.status_bar.showMessage(f"远程服务器: {current_alias} | Nginx服务: nginx | 项目: {project_name}") + logger.info(f"状态栏更新为Nginx服务: nginx, 项目: {project_name}") if __name__ == "__main__": logger.add("app.log", rotation="10 MB") diff --git a/nginx_tab.py b/nginx_tab.py new file mode 100644 index 0000000..512a942 --- /dev/null +++ b/nginx_tab.py @@ -0,0 +1,785 @@ +import os +import sys +from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton, + QLabel, QTextEdit, QFileDialog, QMessageBox, + QLineEdit, QDialog, QDialogButtonBox) +from PySide6.QtCore import QThread, Signal +from loguru import logger + +class PasswordDialog(QDialog): + def __init__(self, parent=None): + super().__init__(parent) + self.setWindowTitle("输入密码") + self.setMinimumWidth(300) + + layout = QVBoxLayout() + + # 提示标签 + label = QLabel("请输入sudo密码:") + layout.addWidget(label) + + # 密码输入框 + self.password_input = QLineEdit() + self.password_input.setEchoMode(QLineEdit.Password) + layout.addWidget(self.password_input) + + # 按钮 + button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + button_box.accepted.connect(self.accept) + button_box.rejected.connect(self.reject) + layout.addWidget(button_box) + + self.setLayout(layout) + + def get_password(self): + return self.password_input.text() + +class NginxInstallThread(QThread): + """安装Nginx的线程""" + result_ready = Signal(bool, str) + + def __init__(self, ssh_client, password): + super().__init__() + self.ssh_client = ssh_client + self.password = password + + def run(self): + try: + logger.info("开始安装Nginx") + + # 使用bash -c将命令组合在一起,确保密码对所有sudo命令有效 + stdin, stdout, stderr = self.ssh_client.exec_command(f"bash -c 'echo \"{self.password}\" | sudo -S apt update && echo \"{self.password}\" | sudo -S apt install -y nginx'") + exit_status = stdout.channel.recv_exit_status() + + output = stdout.read().decode() + error = stderr.read().decode() + + if exit_status == 0: + # 验证安装 + logger.info("验证Nginx安装") + stdin, stdout, stderr = self.ssh_client.exec_command("nginx -v") + version_exit_status = stdout.channel.recv_exit_status() + nginx_version = stdout.read().decode().strip() + version_error = stderr.read().decode() + + logger.info(f"Nginx版本检查状态: {version_exit_status}") + logger.info(f"Nginx版本信息: {nginx_version}") + if version_error: + logger.error(f"Nginx版本检查错误: {version_error}") + + if nginx_version: + self.result_ready.emit(True, f"Nginx安装成功: {nginx_version}") + logger.info(f"Nginx安装成功: {nginx_version}") + else: + self.result_ready.emit(False, "Nginx安装后无法获取版本信息") + logger.error("Nginx安装后无法获取版本信息") + else: + self.result_ready.emit(False, f"Nginx安装失败: {error}") + logger.error(f"Nginx安装失败: {error}") + + except Exception as e: + error_msg = str(e) + self.result_ready.emit(False, error_msg) + logger.error(f"Nginx安装异常: {error_msg}") + +class NginxConfigThread(QThread): + """处理Nginx配置文件的线程""" + result_ready = Signal(bool, str) + + def __init__(self, ssh_client, config_content, config_path, password, operation="upload"): + super().__init__() + self.ssh_client = ssh_client + self.config_content = config_content + self.config_path = config_path + self.password = password + self.operation = operation # "upload" 或 "download" + + def run(self): + try: + logger.info(f"开始处理Nginx配置文件: {self.config_path}, 操作: {self.operation}") + + if self.operation == "upload": + # 上传配置文件 + # 创建临时文件 + temp_file = "/tmp/nginx_config.conf" + + # 将配置内容写入临时文件 + stdin, stdout, stderr = self.ssh_client.exec_command(f"cat > {temp_file} << 'EOF'\n{self.config_content}\nEOF") + exit_status = stdout.channel.recv_exit_status() + + if exit_status != 0: + error = stderr.read().decode() + self.result_ready.emit(False, f"创建临时文件失败: {error}") + logger.error(f"创建临时文件失败: {error}") + return + + # 备份原配置文件 + backup_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S cp {self.config_path} {self.config_path}.bak'" + stdin, stdout, stderr = self.ssh_client.exec_command(backup_cmd) + backup_status = stdout.channel.recv_exit_status() + + if backup_status != 0: + error = stderr.read().decode() + logger.warning(f"备份原配置文件失败: {error}") + + # 移动临时文件到目标位置 + move_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S mv {temp_file} {self.config_path}'" + stdin, stdout, stderr = self.ssh_client.exec_command(move_cmd) + move_status = stdout.channel.recv_exit_status() + + if move_status == 0: + self.result_ready.emit(True, f"配置文件上传成功: {self.config_path}") + logger.info(f"配置文件上传成功: {self.config_path}") + else: + error = stderr.read().decode() + self.result_ready.emit(False, f"配置文件上传失败: {error}") + logger.error(f"配置文件上传失败: {error}") + + elif self.operation == "download": + # 下载配置文件 + download_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S cat {self.config_path}'" + stdin, stdout, stderr = self.ssh_client.exec_command(download_cmd) + exit_status = stdout.channel.recv_exit_status() + + if exit_status == 0: + config_content = stdout.read().decode() + self.result_ready.emit(True, config_content) + logger.info(f"配置文件下载成功: {self.config_path}") + else: + error = stderr.read().decode() + self.result_ready.emit(False, f"配置文件下载失败: {error}") + logger.error(f"配置文件下载失败: {error}") + + except Exception as e: + error_msg = str(e) + self.result_ready.emit(False, error_msg) + logger.error(f"Nginx配置文件处理异常: {error_msg}") + +class NginxControlThread(QThread): + """控制Nginx服务的线程""" + result_ready = Signal(bool, str) + + def __init__(self, ssh_client, password, action): + super().__init__() + self.ssh_client = ssh_client + self.password = password + self.action = action # "restart", "enable", "disable", "status" + + def run(self): + try: + logger.info(f"开始执行Nginx服务操作: {self.action}") + + if self.action == "restart": + command = f"bash -c 'echo \"{self.password}\" | sudo -S systemctl restart nginx'" + elif self.action == "enable": + command = f"bash -c 'echo \"{self.password}\" | sudo -S systemctl enable nginx'" + elif self.action == "disable": + command = f"bash -c 'echo \"{self.password}\" | sudo -S systemctl disable nginx'" + elif self.action == "status": + command = f"bash -c 'echo \"{self.password}\" | sudo -S systemctl status nginx'" + elif self.action == "configtest": + command = f"bash -c 'echo \"{self.password}\" | sudo -S nginx -t'" + else: + self.result_ready.emit(False, f"不支持的操作: {self.action}") + logger.error(f"不支持的操作: {self.action}") + return + + stdin, stdout, stderr = self.ssh_client.exec_command(command) + exit_status = stdout.channel.recv_exit_status() + + output = stdout.read().decode() + error = stderr.read().decode() + + if exit_status == 0: + self.result_ready.emit(True, f"Nginx {self.action} 操作成功\n{output}") + logger.info(f"Nginx {self.action} 操作成功") + else: + self.result_ready.emit(False, f"Nginx {self.action} 操作失败: {error}") + logger.error(f"Nginx {self.action} 操作失败: {error}") + + except Exception as e: + error_msg = str(e) + self.result_ready.emit(False, error_msg) + logger.error(f"Nginx服务控制异常: {error_msg}") + +class NginxSiteThread(QThread): + """处理Nginx站点配置的线程""" + result_ready = Signal(bool, str) + + def __init__(self, ssh_client, site_config, site_name, password, operation="create"): + super().__init__() + self.ssh_client = ssh_client + self.site_config = site_config + self.site_name = site_name + self.password = password + self.operation = operation # "create" 或 "enable" + + def run(self): + try: + logger.info(f"开始处理Nginx站点配置: {self.site_name}, 操作: {self.operation}") + + if self.operation == "create": + # 创建站点配置文件 + site_path = f"/etc/nginx/sites-available/{self.site_name}" + + # 创建临时文件 + temp_file = f"/tmp/{self.site_name}.conf" + + # 将配置内容写入临时文件 + stdin, stdout, stderr = self.ssh_client.exec_command(f"cat > {temp_file} << 'EOF'\n{self.site_config}\nEOF") + exit_status = stdout.channel.recv_exit_status() + + if exit_status != 0: + error = stderr.read().decode() + self.result_ready.emit(False, f"创建临时文件失败: {error}") + logger.error(f"创建临时文件失败: {error}") + return + + # 移动临时文件到目标位置 + move_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S mv {temp_file} {site_path}'" + stdin, stdout, stderr = self.ssh_client.exec_command(move_cmd) + move_status = stdout.channel.recv_exit_status() + + if move_status == 0: + self.result_ready.emit(True, f"站点配置文件创建成功: {site_path}") + logger.info(f"站点配置文件创建成功: {site_path}") + else: + error = stderr.read().decode() + self.result_ready.emit(False, f"站点配置文件创建失败: {error}") + logger.error(f"站点配置文件创建失败: {error}") + + elif self.operation == "enable": + # 启用站点配置 + enable_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S ln -s /etc/nginx/sites-available/{self.site_name} /etc/nginx/sites-enabled/'" + stdin, stdout, stderr = self.ssh_client.exec_command(enable_cmd) + exit_status = stdout.channel.recv_exit_status() + + if exit_status == 0: + self.result_ready.emit(True, f"站点配置启用成功: {self.site_name}") + logger.info(f"站点配置启用成功: {self.site_name}") + else: + error = stderr.read().decode() + self.result_ready.emit(False, f"站点配置启用失败: {error}") + logger.error(f"站点配置启用失败: {error}") + + except Exception as e: + error_msg = str(e) + self.result_ready.emit(False, error_msg) + logger.error(f"Nginx站点配置处理异常: {error_msg}") + +class NginxTab(QWidget): + def __init__(self): + super().__init__() + self.ssh_client = None + self.username = "" + self.project_name = "" + self.server_ip = "" + self.init_ui() + + def init_ui(self): + layout = QVBoxLayout() + + # Nginx安装区域 + install_layout = QHBoxLayout() + + # 安装Nginx按钮 + self.install_nginx_btn = QPushButton("安装Nginx") + self.install_nginx_btn.clicked.connect(self.install_nginx) + install_layout.addWidget(self.install_nginx_btn) + + layout.addLayout(install_layout) + + # Nginx主配置文件区域 + main_config_layout = QVBoxLayout() + main_config_layout.addWidget(QLabel("Nginx主配置文件编辑器:")) + + # 主配置文件编辑文本框 + self.main_config_editor = QTextEdit() + self.main_config_editor.setReadOnly(False) + main_config_layout.addWidget(self.main_config_editor) + + # 主配置文件操作按钮 + main_config_btn_layout = QHBoxLayout() + + # 下载主配置文件按钮 + self.download_main_config_btn = QPushButton("下载主配置文件") + self.download_main_config_btn.clicked.connect(self.download_main_config) + main_config_btn_layout.addWidget(self.download_main_config_btn) + + # 上传主配置文件按钮 + self.upload_main_config_btn = QPushButton("上传主配置文件") + self.upload_main_config_btn.clicked.connect(self.upload_main_config) + main_config_btn_layout.addWidget(self.upload_main_config_btn) + + main_config_layout.addLayout(main_config_btn_layout) + layout.addLayout(main_config_layout) + + # Nginx站点配置区域 + site_config_layout = QVBoxLayout() + site_config_layout.addWidget(QLabel("Nginx站点配置编辑器:")) + + # 站点配置编辑文本框 + self.site_config_editor = QTextEdit() + self.site_config_editor.setReadOnly(False) + site_config_layout.addWidget(self.site_config_editor) + + # 站点配置操作按钮 + site_config_btn_layout = QHBoxLayout() + + # 创建站点配置按钮 + self.create_site_config_btn = QPushButton("创建站点配置") + self.create_site_config_btn.clicked.connect(self.create_site_config) + site_config_btn_layout.addWidget(self.create_site_config_btn) + + # 启用站点配置按钮 + self.enable_site_config_btn = QPushButton("启用站点配置") + self.enable_site_config_btn.clicked.connect(self.enable_site_config) + site_config_btn_layout.addWidget(self.enable_site_config_btn) + + site_config_layout.addLayout(site_config_btn_layout) + layout.addLayout(site_config_layout) + + # Nginx控制区域 + control_layout = QHBoxLayout() + + # 重启Nginx按钮 + self.restart_nginx_btn = QPushButton("重启Nginx") + self.restart_nginx_btn.clicked.connect(self.restart_nginx) + control_layout.addWidget(self.restart_nginx_btn) + + # 查看Nginx状态按钮 + self.check_nginx_status_btn = QPushButton("查看Nginx状态") + self.check_nginx_status_btn.clicked.connect(self.check_nginx_status) + control_layout.addWidget(self.check_nginx_status_btn) + + layout.addLayout(control_layout) + + # 输出区域 + self.output_text = QTextEdit() + self.output_text.setReadOnly(True) + layout.addWidget(self.output_text) + + self.setLayout(layout) + + # 初始化配置文件内容 + self.init_config_content() + + def init_config_content(self): + """初始化配置文件内容""" + # 初始化主配置文件内容 + main_config_content = '''# 全局块:配置Nginx进程的基本运行参数 +user www-data; # Nginx进程运行的用户/组(默认是www-data,不是你的登录用户xiaji) +worker_processes auto; # 工作进程数,auto表示自动匹配CPU核心数 +pid /run/nginx.pid; # Nginx进程PID文件路径 +include /etc/nginx/modules-enabled/*.conf; # 加载启用的模块配置 + + +# events块:配置Nginx与客户端的网络连接 +events { + worker_connections 768; # 每个工作进程的最大并发连接数 + # multi_accept on; # 可选:允许工作进程同时接受多个连接(默认注释) +} + + +# http块:配置HTTP服务的全局参数(核心部分) +http { + ## + # 基础配置 + ## + sendfile on; # 启用高效文件传输模式 + tcp_nopush on; # 配合sendfile使用,优化TCP传输 + tcp_nodelay on; # 禁用Nagle算法,减少小数据包延迟 + keepalive_timeout 65; # 长连接超时时间(秒) + types_hash_max_size 2048; # 类型哈希表的最大大小(优化MIME类型查找) + + include /etc/nginx/mime.types; # 加载MIME类型映射文件 + default_type application/octet-stream; # 默认MIME类型(未匹配时返回二进制流) + + ## + # 日志配置 + ## + access_log /var/log/nginx/access.log; # 访问日志路径 + error_log /var/log/nginx/error.log; # 错误日志路径 + + ## + # SSL/TLS配置(全局默认值) + ## + ssl_protocols TLSv1.2 TLSv1.3; # 支持的SSL/TLS协议(禁用不安全的旧协议) + ssl_prefer_server_ciphers on; # 优先使用服务器端指定的加密套件 + + ## + # Gzip压缩配置 + ## + gzip on; # 启用Gzip压缩 + # gzip_vary on; # 可选:在响应头添加Vary: Accept-Encoding(默认注释) + # gzip_proxied any; # 可选:对代理请求也启用压缩(默认注释) + # gzip_comp_level 6; # 可选:压缩级别(1-9,默认6)(默认注释) + # gzip_buffers 16 8k; # 可选:压缩缓冲区大小(默认注释) + # gzip_http_version 1.1; # 可选:支持的HTTP版本(默认注释) + # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # 可选:指定压缩的MIME类型(默认注释) + + ## + # 加载站点配置(关键:默认站点配置不在nginx.conf里,而是通过include引入) + ## + include /etc/nginx/conf.d/*.conf; # 加载conf.d目录下的自定义配置 + include /etc/nginx/sites-enabled/*; # 加载启用的站点配置(默认站点在这里) +} + + +# 可选:加载流处理配置(如TCP/UDP代理,默认注释) +# include /etc/nginx/streams-enabled/*.conf;''' + self.main_config_editor.setPlainText(main_config_content) + + # 初始化站点配置文件内容 + site_config_content = "server {\n" + site_config_content += " listen 80;\n" + site_config_content += " server_name 【IP地址】;\n\n" + site_config_content += " # 转发动态请求到Gunicorn\n" + site_config_content += " location / {\n" + site_config_content += " proxy_pass http://【IP地址】:8000;\n" + site_config_content += " proxy_set_header Host $host;\n" + site_config_content += " proxy_set_header X-Real-IP $remote_addr;\n" + site_config_content += " }\n" + site_config_content += "}\n" + self.site_config_editor.setPlainText(site_config_content) + + def update_config_content(self): + """更新配置文件内容""" + # 更新主配置文件内容 + main_config_content = self.main_config_editor.toPlainText() + main_config_content = main_config_content.replace("xiaji", self.username) + self.main_config_editor.setPlainText(main_config_content) + + # 更新站点配置文件内容 + site_config_content = self.site_config_editor.toPlainText() + site_config_content = site_config_content.replace("【IP地址】", self.server_ip) + self.site_config_editor.setPlainText(site_config_content) + + def set_ssh_client(self, ssh_client): + """设置SSH客户端""" + self.ssh_client = ssh_client + logger.info("Nginx标签页已设置SSH客户端") + + def set_username(self, username): + """设置用户名""" + self.username = username + logger.info(f"Nginx标签页已设置用户名: {username}") + + def set_project_info(self, project_name, server_ip): + """设置项目信息""" + self.project_name = project_name + self.server_ip = server_ip + logger.info(f"Nginx标签页已设置项目信息: {project_name}, {server_ip}") + + # 更新配置文件内容 + self.update_config_content() + + def append_output(self, text): + """添加输出到文本框""" + self.output_text.append(text) + + def install_nginx(self): + """安装Nginx""" + if not self.ssh_client: + self.append_output("错误: 未连接到服务器") + return + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + self.append_output("正在安装Nginx...") + + # 创建并启动Nginx安装线程 + self.install_thread = NginxInstallThread(self.ssh_client, password) + self.install_thread.result_ready.connect(self.on_install_result) + self.install_thread.start() + else: + self.append_output("用户取消了密码输入") + + def on_install_result(self, success, message): + """处理安装结果""" + if success: + self.append_output(f"安装成功: {message}") + logger.info(f"Nginx安装成功: {message}") + QMessageBox.information(self, "成功", message) + else: + self.append_output(f"安装失败: {message}") + logger.error(f"Nginx安装失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx安装失败: {message}") + + def download_main_config(self): + """下载主配置文件""" + if not self.ssh_client: + self.append_output("错误: 未连接到服务器") + return + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + self.append_output("正在下载Nginx主配置文件...") + + # 创建并启动配置文件下载线程 + self.config_thread = NginxConfigThread(self.ssh_client, "", "/etc/nginx/nginx.conf", password, "download") + self.config_thread.result_ready.connect(self.on_download_main_config_result) + self.config_thread.start() + else: + self.append_output("用户取消了密码输入") + + def on_download_main_config_result(self, success, message): + """处理下载主配置文件结果""" + if success: + self.main_config_editor.setPlainText(message) + self.append_output("主配置文件下载成功") + logger.info("Nginx主配置文件下载成功") + else: + self.append_output(f"主配置文件下载失败: {message}") + logger.error(f"Nginx主配置文件下载失败: {message}") + + def upload_main_config(self): + """上传主配置文件""" + if not self.ssh_client: + self.append_output("错误: 未连接到服务器") + return + + config_content = self.main_config_editor.toPlainText() + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + self.append_output("正在上传Nginx主配置文件...") + + # 创建并启动配置文件上传线程 + self.config_thread = NginxConfigThread(self.ssh_client, config_content, "/etc/nginx/nginx.conf", password, "upload") + self.config_thread.result_ready.connect(self.on_upload_main_config_result) + self.config_thread.start() + else: + self.append_output("用户取消了密码输入") + + def on_upload_main_config_result(self, success, message): + """处理上传主配置文件结果""" + if success: + self.append_output(f"上传成功: {message}") + logger.info(f"Nginx主配置文件上传成功: {message}") + QMessageBox.information(self, "成功", message) + + # 上传主配置文件后检查配置文件语法 + self.append_output("正在检查Nginx配置文件语法...") + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + + # 创建并启动Nginx配置检查线程 + self.check_thread = NginxControlThread(self.ssh_client, password, "configtest") + self.check_thread.result_ready.connect(self.on_upload_configtest_result) + self.check_thread.start() + else: + self.append_output("用户取消了密码输入") + else: + self.append_output(f"上传失败: {message}") + logger.error(f"Nginx主配置文件上传失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx主配置文件上传失败: {message}") + + def on_upload_configtest_result(self, success, message): + """处理上传主配置文件后的配置测试结果""" + if success: + self.append_output("配置文件语法检查通过") + logger.info("Nginx主配置文件上传后语法检查通过") + else: + self.append_output(f"配置文件语法检查失败: {message}") + logger.error(f"Nginx主配置文件上传后语法检查失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx配置文件语法检查失败: {message}") + + def create_site_config(self): + """创建站点配置""" + if not self.ssh_client: + self.append_output("错误: 未连接到服务器") + return + + if not self.project_name: + self.append_output("错误: 未设置项目名") + return + + site_config = self.site_config_editor.toPlainText() + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + self.append_output(f"正在创建站点配置文件: {self.project_name}...") + + # 创建并启动站点配置创建线程 + self.site_thread = NginxSiteThread(self.ssh_client, site_config, self.project_name, password, "create") + self.site_thread.result_ready.connect(self.on_create_site_config_result) + self.site_thread.start() + else: + self.append_output("用户取消了密码输入") + + def on_create_site_config_result(self, success, message): + """处理创建站点配置结果""" + if success: + self.append_output(f"创建成功: {message}") + logger.info(f"Nginx站点配置创建成功: {message}") + QMessageBox.information(self, "成功", message) + + # 创建站点配置文件后检查配置文件语法 + self.append_output("正在检查Nginx配置文件语法...") + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + + # 创建并启动Nginx配置检查线程 + self.check_thread = NginxControlThread(self.ssh_client, password, "configtest") + self.check_thread.result_ready.connect(self.on_create_configtest_result) + self.check_thread.start() + else: + self.append_output("用户取消了密码输入") + else: + self.append_output(f"创建失败: {message}") + logger.error(f"Nginx站点配置创建失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx站点配置创建失败: {message}") + + def on_create_configtest_result(self, success, message): + """处理创建站点配置文件后的配置测试结果""" + if success: + self.append_output("配置文件语法检查通过") + logger.info("Nginx站点配置文件创建后语法检查通过") + else: + self.append_output(f"配置文件语法检查失败: {message}") + logger.error(f"Nginx站点配置文件创建后语法检查失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx配置文件语法检查失败: {message}") + + def enable_site_config(self): + """启用站点配置""" + if not self.ssh_client: + self.append_output("错误: 未连接到服务器") + return + + if not self.project_name: + self.append_output("错误: 未设置项目名") + return + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + self.append_output(f"正在启用站点配置: {self.project_name}...") + + # 创建并启动站点配置启用线程 + self.site_thread = NginxSiteThread(self.ssh_client, "", self.project_name, password, "enable") + self.site_thread.result_ready.connect(self.on_enable_site_config_result) + self.site_thread.start() + else: + self.append_output("用户取消了密码输入") + + def on_enable_site_config_result(self, success, message): + """处理启用站点配置结果""" + if success: + self.append_output(f"启用成功: {message}") + logger.info(f"Nginx站点配置启用成功: {message}") + QMessageBox.information(self, "成功", message) + + # 启用站点后检查配置文件语法 + self.append_output("正在检查Nginx配置文件语法...") + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + + # 创建并启动Nginx配置检查线程 + self.check_thread = NginxControlThread(self.ssh_client, password, "configtest") + self.check_thread.result_ready.connect(self.on_enable_configtest_result) + self.check_thread.start() + else: + self.append_output("用户取消了密码输入") + else: + self.append_output(f"启用失败: {message}") + logger.error(f"Nginx站点配置启用失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx站点配置启用失败: {message}") + + def on_enable_configtest_result(self, success, message): + """处理启用站点后的配置测试结果""" + if success: + self.append_output("配置文件语法检查通过") + logger.info("Nginx站点配置启用后语法检查通过") + else: + self.append_output(f"配置文件语法检查失败: {message}") + logger.error(f"Nginx站点配置启用后语法检查失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx配置文件语法检查失败: {message}") + + def restart_nginx(self): + """重启Nginx""" + if not self.ssh_client: + self.append_output("错误: 未连接到服务器") + return + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + self.append_output("正在检查Nginx配置文件语法...") + + # 创建并启动Nginx配置检查线程 + self.check_thread = NginxControlThread(self.ssh_client, password, "configtest") + self.check_thread.result_ready.connect(self.on_configtest_result) + self.check_thread.start() + else: + self.append_output("用户取消了密码输入") + + def on_configtest_result(self, success, message): + """处理配置测试结果""" + if success: + self.append_output("配置文件语法检查通过,正在重启Nginx...") + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + + # 创建并启动Nginx控制线程 + self.control_thread = NginxControlThread(self.ssh_client, password, "restart") + self.control_thread.result_ready.connect(self.on_control_result) + self.control_thread.start() + else: + self.append_output("用户取消了密码输入") + else: + self.append_output(f"配置文件语法检查失败: {message}") + logger.error(f"Nginx配置文件语法检查失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx配置文件语法检查失败: {message}") + + def check_nginx_status(self): + """查看Nginx状态""" + if not self.ssh_client: + self.append_output("错误: 未连接到服务器") + return + + # 请求用户输入sudo密码 + dialog = PasswordDialog(self) + if dialog.exec_() == QDialog.Accepted: + password = dialog.get_password() + self.append_output("正在查看Nginx状态...") + + # 创建并启动Nginx控制线程 + self.control_thread = NginxControlThread(self.ssh_client, password, "status") + self.control_thread.result_ready.connect(self.on_control_result) + self.control_thread.start() + else: + self.append_output("用户取消了密码输入") + + def on_control_result(self, success, message): + """处理控制结果""" + if success: + self.append_output(f"操作成功: {message}") + logger.info(f"Nginx服务控制成功: {message}") + QMessageBox.information(self, "成功", message) + else: + self.append_output(f"操作失败: {message}") + logger.error(f"Nginx服务控制失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx服务控制失败: {message}") \ No newline at end of file