From fffed991650584daf47a5c43a96fe557974fab78 Mon Sep 17 00:00:00 2001 From: xiaji Date: Sun, 7 Sep 2025 12:42:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E7=AB=99=E7=82=B9=E9=85=8D=E7=BD=AE=E7=9A=84=E6=8C=89=E9=92=AE?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=BA=86=E5=A2=9E=E5=8A=A0=E9=9D=99?= =?UTF-8?q?=E6=80=81=E6=96=87=E4=BB=B6=E9=85=8D=E7=BD=AE=E7=9A=84=E6=8C=89?= =?UTF-8?q?=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/nginx_tab.cpython-38.pyc | Bin 26118 -> 28864 bytes app.log | 42 ++++++++++ nginx_tab.py | 116 ++++++++++++++++++++++++++- 3 files changed, 157 insertions(+), 1 deletion(-) diff --git a/__pycache__/nginx_tab.cpython-38.pyc b/__pycache__/nginx_tab.cpython-38.pyc index 9df4b129e7038419c0c95d2c2292681f841b3633..92287b02621e82b79aaa97c824289e3b34ed45e2 100644 GIT binary patch delta 5019 zcmb_gd2~}{7Jpw}wq|RZw4{YD=>`TUt-~f1Sz8c+un9rP@9tWF@QCI%5B} z?-D`mbo}h_g7@=q`Sk#Lq9z8FNlU$~RkM_dSuYY_Y=2gdiul;7?D?dLoydO2(F~q{ zx}i%mbV+CJ#tQa*&Ij6cV5bkUBc^=zb?&4LJ2Y`&GqBrEQ4l)B&^@uTylEs=4J1_3__siSOOe&(5UkSZP5zS<5O4ULvbvKNMIP|Dy7w6XS)j=Y;dKCy>8reMs*PH zLCopOXZ5bxk$_4vwGmmU&IWZh-*}-hXEy|1)^XQtE|aKU)}a(Iv_XPZ=Yn@GB!W3% z#X)nqEJPt85|VSbK$PvWxc_B@r-~oie4%@z8#f}D3vD+`86GtTZ6KaMvE@Qf59=B} zhvdgD4xd2^Go_ZbzNQwBRLvt?*Wz2*P+wge@b#u&vBdI5mJ>q+y4PcX8<|v65!+L8 z*i>{$>x5s}5K@H=ZkI^6fKRWdPLbDwV@3Auz`^&hCG0-yL z(W|50)+SG#m&)KocOYy}hrsOVY3VIwyxaH(t zc5?RQp*$A+32VT6pGH~1QSA8&LeeshL3;~3v|voE@!mCr9Aw|jxijy&dHG0u@*3=Y z1lO;99mE$@?8jyKZ1vnPwQXqWX6||JDQi*Wk+UX6j_1!-G~GUYYuM-WCR`Iae$rfB zGMl)x{%|--+LV_WRh+i#L(X>w^ZCpap>aP*}`< zEHuxg|DOn^FTHsLwQs{@qR0*}7|nJqJ*9+kB*bhmJFqMj!$?lE_GRO59zD%F&^w3y zuxt*yT${q8i=vTWCa9ER-T(5A{zqTGxUs#z=TP4>kDWht>`G+8CFlg`JJ=n6_N7~S zPju3A;G{$!59C| ziOyj0fCJEyS&39hQ4S$~99>&HdhH$wPRoEN&`?+1>}hRn@YVb2%__=}-@#;)fjRmy zwFQ+LD2ag>M1#r-w4pK!VrggQnWhL9@d2uN8V=bG5?U1yBqBjzBz3#E)fy%N5>?@$ zA66|B#tI9CMZ*0;Kny^jFpzBoSe__j=rodcw<@gWvX09dF6+6hm9@Y@Q)CUGp-Uas z$=b+(!Uzh8bt6O^h-ivrl2caeItaZ_GKUSaL9&b&_&pVAC=gjO(N0U;ZHc=*aZgX& zQ)T^a{39vR6e$Cq%qSbBL90cWaI%~tIb`ETRhA$d9DCjPedD{X1?)&+VE)Z5$wWLRpTv=uBN zU8$0cA#G{1S8DKt(wbW8AUj)p&V;2jI2bbw$y%ZF#`Q!Dp-i;h(9QWPL&$;_{CS!h zJbq_LEG;*LG8C25>0Q^_K)rtF=rXC?Ks#ZUr1L4MGy zp(`7F(oLyb4cO^)gc%4}OI)dJXsxr3GhI$J@awh8m?%5=Ayj4HyUjm}sw{OuO1-{7 zwUSd+mTT)%m8Hq!4^-Du;Mvu!E&eKl&$~9^%kpi5Bfp2y=V7Iq34$Q1iIt>_R`_s& zKe$^(tXgWK2fd!?MYs|Y)H9L|Uht8HA6jr(R5or6We*$&Hz}BPP~`@GB8#lpT)7e2 ziL)(<0Dc3Ny|r&@_KYa`azM`a3Yf^_-P6^ zy(J0pviGaTk$sG;uxo3uFXv8aUx2tB1BWLzlz76FSewiOs19*$7`DTs?L*PeJ=Ytn&dYlI?xJ9BbkXhaN&V&dD^`<7`az;0RUu zW2o&0aMO2Dd=KG$gg+qgBvXn^eM6u+NSkU5k5os3&LLkSf{5fuLfJUjB7LN_e_|APv$Zytp0E4-;3}$0$<(NDDn4T4oY(o z6atNskJH$vL3}^&8V2 z=qPB=QiL)D8$twOJ3<%2a|q8PL=iYY*o+c>4$^jn*ASjWIEH}V7PJH5O@y})kib%8 zjuZ(XMIuFukTOtw8!2Wk{Q?2^T1fzWMEV^&BjwmbAU+5$k$(~hdScS+YuS&|uzZI; zRX<*D*Jr?G)R$BAa}DWLwfK8Q|3iNIF)Qs? AD*ylh delta 2751 zcmb_e32c-_6#nNg`|r}-cDJ-;3v_!QY!3>`eJzEpAcdBzmZGvP?e?H$Tc_L7E?cM; z0RB2bXaALSCkD<%SBLQvC00Yg*>YBa>eV8r)k2`ooRjQ+`fdGn5$H{ZN@ zvnMaHWv5waK}bljgx~II2P;#z9SA*ZVjlH7(?G`NsK#FB87l*aVpjhO-x!4Adh_4r zQuJ=eU%d`N$9k|}*`V-JsM9eCijrs#_C|yU1m~?kx8C3x5;a4V=X51*ZT}*datQNW|CX-g_K2mO&g`n zatC8lp)^D)!-&Pk*;0|@l4s*+rew9iUZWWhz!JMA;Rc@!FuEbr*i=i{wqLh%!JUE?fhlE}hMayt&b74$M z5$sKg!$r=fSj=wpxq-g`c0+aCjZ|6WYZ4@+{t&!e>LJaE!32jvTK@xbK7&g!5%638 z4Ax(bu{s#MnP!33v?#sSr^Su;rY*wpv?=4g%%}5eY3L4alf0568qLwji-B}#CHH6{ zOFoO2-I8KDB<5!%1fEGh1hxzti&d9oOknEonFCmG3#MC0dntpoEW7H?>NF&IlsNoa zf<1CeaGo`YzkohnhI*%aT1`onYnHRg%~wPAXuIZBG#rE%NB=lbxai%rw>`SF+*wys zQtIR$bmFfOtS0ahybc{>tSksljk(N>uz&0p=7D@$Bx1*yaA>lHun1UYI~u>}c7&0n z;RJ6WU{Z8Sd=V7eqM&(P80!No$9WlmE_(<|fU((!*kbr2yMk?jx#L@v<>;IuLve*! zy)jt!&=YJ0 zU(Q73EfTjwM^U)45=Faz9m``ASuD}w-@6FEvk4m+-liDM0Tc^ih}>&SF(Hl)iWm`<=Cu20G^Q*zcGezsbjKS*ADUFPE!k(#v@PsZ*jZ!GqPm}U4ifd#zS`-h%^1fA`B}+T>&Cjznkmy6O zngVDNr6Vft;as_4NB)SrXcEmVAitMz>J6%K+6rdcNlU2&x2W1NeN@hWpo(S^4d@`G z&PX@iO&WhsoYDvAq#`{xltU;rJOZ1Z>Izv^^va}1QW6-A{(f&RunhDAYds@{k5Rv0TdP&{$CVcEbNBDlbFLVRAEpt`L(dTb9#?qgy-%)CMXa+B+yn+*W#%`9b)+G%0{L z%^KA90!KxxnqHR9MmfpJM?gu6qZNmoXASe;(Qc2W6xKS2_7$Zi`j3s`dlHD-_lITPD7yI~_V#X0f6MRA-))oy?vlhoARY!%1T25W%5QDfp zd>6U-Ym_3U27$w#sQz53l_x(>CQ+mweQB+$ysBcr{Q6o~7vmmHgS$L)xRrJ3oUYQ^ zvMN`F|FNM8?$TCNxg8C>hP!Zdt7DCw5U zYFJk@LL8FS02fQ*lEmBg8BWGUyU8VK3W2|UkW?cs@hd3KR#O*b(Y^~^miza84n2VO z-5d6~;#e$v>55!JuQR7tR=j$A14$bRHW7&4yqu(M1oZfDdQCVrc1~@TQ`h9wz&N!L zeu98*BtJ<&Wz4D2IGsPI!||UOrOVIZUloZDg2ho$;Z3N>WB4~=C<;1e(CMCrt+lEB u!gZ0laGhQ^ij#-6Uzc24-xXBfT+dIz)!L;dQQOrto9GTru(&Rp&HM+urL9Z= diff --git a/app.log b/app.log index 3dc0fc8..96484f4 100644 --- a/app.log +++ b/app.log @@ -4861,3 +4861,45 @@ sudo systemctl restart nginx 2025-09-07 10:10:27.679 | INFO | django_threads:run:198 - 命令输出: 119 static files copied to '/home/xiaji/webstatus/static'. 2025-09-07 10:10:27.730 | INFO | django_threads:run:211 - 命令执行成功: cd /home/xiaji/webstatus && python3 manage.py collectstatic --noinput 2025-09-07 10:10:27.732 | INFO | django_tab:on_command_finished:155 - Django命令执行完成 +2025-09-07 12:18:46.163 | INFO | __main__::189 - 启动应用程序 +2025-09-07 12:18:46.183 | INFO | __main__:__init__:17 - 初始化主窗口 +2025-09-07 12:18:46.187 | INFO | __main__:__init__:32 - 设置状态栏显示当前目录: C:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署 +2025-09-07 12:18:46.188 | INFO | server_connection_tab:__init__:14 - 初始化服务器连接标签页 +2025-09-07 12:18:46.189 | INFO | server_connection_tab:init_ui:93 - 服务器连接标签页UI初始化完成 +2025-09-07 12:18:46.189 | INFO | server_connection_tab:load_config:96 - 加载配置文件 +2025-09-07 12:18:46.190 | INFO | server_connection_tab:load_config:103 - 成功加载配置文件: c:\Users\xiaji\Documents\个人文件夹\夏骥\桌面部署\config.json +2025-09-07 12:18:46.190 | INFO | server_connection_tab:on_alias_changed:122 - 选择别名: 测试机 +2025-09-07 12:18:46.191 | INFO | remote_commands_tab:__init__:151 - 初始化远程命令标签页 +2025-09-07 12:18:46.192 | INFO | remote_commands_tab:init_ui:290 - 远程命令标签页UI初始化完成 +2025-09-07 12:18:46.196 | INFO | __main__:__init__:57 - 主窗口初始化完成 +2025-09-07 12:18:47.348 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 4 +2025-09-07 12:18:47.348 | INFO | nginx_tab:set_ssh_client:530 - Nginx标签页已设置SSH客户端 +2025-09-07 12:18:47.348 | INFO | nginx_tab:set_username:535 - Nginx标签页已设置用户名: xiaji +2025-09-07 12:18:47.349 | INFO | nginx_tab:set_project_info:541 - Nginx标签页已设置项目信息: statuspage, 192.168.3.157 +2025-09-07 12:18:47.351 | INFO | __main__:on_tab_changed:185 - 状态栏更新为Nginx服务: nginx, 项目: statuspage +2025-09-07 12:19:34.328 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 0 +2025-09-07 12:19:35.401 | INFO | server_connection_tab:connect_to_server:188 - 尝试连接服务器 +2025-09-07 12:19:35.485 | INFO | server_connection_tab:connect_to_server:207 - 成功连接到服务器: 192.168.3.157 +2025-09-07 12:19:36.758 | INFO | __main__:on_tab_changed:60 - 标签页切换到: 4 +2025-09-07 12:19:36.758 | INFO | nginx_tab:set_ssh_client:530 - Nginx标签页已设置SSH客户端 +2025-09-07 12:19:36.759 | INFO | nginx_tab:set_username:535 - Nginx标签页已设置用户名: xiaji +2025-09-07 12:19:36.759 | INFO | nginx_tab:set_project_info:541 - Nginx标签页已设置项目信息: statuspage, 192.168.3.157 +2025-09-07 12:19:36.763 | INFO | __main__:on_tab_changed:185 - 状态栏更新为Nginx服务: nginx, 项目: statuspage +2025-09-07 12:19:41.713 | INFO | nginx_tab:run:171 - 开始执行Nginx服务操作: configtest +2025-09-07 12:19:41.741 | INFO | nginx_tab:run:196 - Nginx configtest 操作成功 +2025-09-07 12:19:47.103 | INFO | nginx_tab:run:171 - 开始执行Nginx服务操作: restart +2025-09-07 12:19:51.347 | INFO | nginx_tab:run:196 - Nginx restart 操作成功 +2025-09-07 12:19:51.348 | INFO | nginx_tab:on_control_result:849 - Nginx服务控制成功: Nginx restart 操作成功 + +2025-09-07 12:20:03.247 | INFO | nginx_tab:run:100 - 开始处理Nginx配置文件: /etc/nginx/nginx.conf, 操作: upload +2025-09-07 12:20:03.392 | INFO | nginx_tab:run:133 - 配置文件上传成功: /etc/nginx/nginx.conf +2025-09-07 12:20:03.392 | INFO | nginx_tab:on_upload_main_config_result:634 - Nginx主配置文件上传成功: 配置文件上传成功: /etc/nginx/nginx.conf +2025-09-07 12:20:07.097 | INFO | nginx_tab:run:171 - 开始执行Nginx服务操作: configtest +2025-09-07 12:20:07.127 | INFO | nginx_tab:run:196 - Nginx configtest 操作成功 +2025-09-07 12:20:07.128 | INFO | nginx_tab:on_upload_configtest_result:660 - Nginx主配置文件上传后语法检查通过 +2025-09-07 12:20:13.227 | INFO | nginx_tab:run:171 - 开始执行Nginx服务操作: configtest +2025-09-07 12:20:13.256 | INFO | nginx_tab:run:196 - Nginx configtest 操作成功 +2025-09-07 12:20:17.323 | INFO | nginx_tab:run:171 - 开始执行Nginx服务操作: restart +2025-09-07 12:20:20.519 | INFO | nginx_tab:run:196 - Nginx restart 操作成功 +2025-09-07 12:20:20.521 | INFO | nginx_tab:on_control_result:849 - Nginx服务控制成功: Nginx restart 操作成功 + diff --git a/nginx_tab.py b/nginx_tab.py index 6892207..ee7da47 100644 --- a/nginx_tab.py +++ b/nginx_tab.py @@ -258,7 +258,7 @@ class NginxSiteThread(QThread): self.site_config = site_config self.site_name = site_name self.password = password - self.operation = operation # "create" 或 "enable" + self.operation = operation # "create" 或 "enable" 或 "download" def run(self): try: @@ -326,6 +326,22 @@ class NginxSiteThread(QThread): self.result_ready.emit(False, f"站点配置启用失败: {error}") logger.error(f"站点配置启用失败: {error}") + elif self.operation == "download": + # 下载站点配置文件 + site_path = f"/etc/nginx/sites-enabled/{self.site_name}" + download_cmd = f"bash -c 'echo \"{self.password}\" | sudo -S cat {site_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"站点配置文件下载成功: {site_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) @@ -400,6 +416,11 @@ class NginxTab(QWidget): self.enable_site_config_btn.clicked.connect(self.enable_site_config) site_config_btn_layout.addWidget(self.enable_site_config_btn) + # 下载站点配置按钮 + self.download_site_config_btn = QPushButton("下载站点配置") + self.download_site_config_btn.clicked.connect(self.download_site_config) + site_config_btn_layout.addWidget(self.download_site_config_btn) + site_config_layout.addLayout(site_config_btn_layout) layout.addLayout(site_config_layout) @@ -783,6 +804,99 @@ http { logger.error(f"Nginx站点配置启用后语法检查失败: {message}") QMessageBox.warning(self, "错误", f"Nginx配置文件语法检查失败: {message}") + def download_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, "download") + self.site_thread.result_ready.connect(self.on_download_site_config_result) + self.site_thread.start() + else: + self.append_output("用户取消了密码输入") + + def on_download_site_config_result(self, success, message): + """处理下载站点配置结果""" + if success: + # 将下载的配置内容显示在站点配置编辑器中 + self.site_config_editor.setPlainText(message) + self.append_output("站点配置文件下载成功") + logger.info("Nginx站点配置文件下载成功") + + # 尝试添加静态文件映射配置 + self.add_static_mappings() + else: + self.append_output(f"下载失败: {message}") + logger.error(f"Nginx站点配置文件下载失败: {message}") + QMessageBox.warning(self, "错误", f"Nginx站点配置文件下载失败: {message}") + + def add_static_mappings(self): + """添加静态文件映射配置""" + # 读取config.json文件获取项目信息 + try: + with open('config.json', 'r', encoding='utf-8') as f: + config = json.load(f) + + # 获取第一个服务器配置(假设只有一个服务器配置) + server_config = next(iter(config.values())) + username = server_config.get('username', '') + project_name = server_config.get('project', '') + remote_dir = server_config.get('remote_dir', '') + + # 构建静态文件路径 + static_path = f"{remote_dir}/{project_name}/static" + media_path = f"{remote_dir}/{project_name}/media" + + # 获取当前配置内容 + current_config = self.site_config_editor.toPlainText() + + # 检查是否已经包含静态文件映射 + if "location /static/" not in current_config: + # 添加静态文件映射配置 + static_mapping = f"\n # 静态文件映射\n" + static_mapping += f" location /static/ {{\n" + static_mapping += f" alias {static_path}/;\n" + static_mapping += f" expires 30d;\n" + static_mapping += f" }}\n" + + # 添加媒体文件映射配置 + static_mapping += f"\n # 媒体文件映射\n" + static_mapping += f" location /media/ {{\n" + static_mapping += f" alias {media_path}/;\n" + static_mapping += f" expires 30d;\n" + static_mapping += f" }}\n" + + # 在server块的末尾添加静态文件映射(在最后一个}之前) + last_brace_pos = current_config.rfind('}') + if last_brace_pos != -1: + new_config = current_config[:last_brace_pos] + static_mapping + current_config[last_brace_pos:] + self.site_config_editor.setPlainText(new_config) + self.append_output("已添加静态文件映射配置") + logger.info("已添加静态文件映射配置") + else: + self.append_output("无法添加静态文件映射配置:未找到server块的结束位置") + logger.warning("无法添加静态文件映射配置:未找到server块的结束位置") + else: + self.append_output("配置文件已包含静态文件映射") + logger.info("配置文件已包含静态文件映射") + + except Exception as e: + error_msg = str(e) + self.append_output(f"添加静态文件映射失败: {error_msg}") + logger.error(f"添加静态文件映射失败: {error_msg}") + def restart_nginx(self): """重启Nginx""" if not self.ssh_client: