Files
condor 679e0b4184 init
2026-07-24 18:54:53 +08:00

9.7 KiB
Raw Permalink Blame History

2026-07-18

ServerStack: 修复 Ubuntu 依赖安装的 libcurl 冲突

问题:在 Ubuntu 22.04 上跑 installDepsUbuntu 时出现

  • 图片 1: libcurl4-gnutls-devlibcurl4-openssl-dev 互相 Conflicts,导致 E: Unable to correct problems, you have held broken packages,整批依赖装不下去。
  • 图片 2: 大量老包被 filter_pkglist 跳过(libpng12-0/-devlibpng3libidn11libcloog-ppl1sysv-rclibjpeg62-turbo-dev),虽然不报错, 但每次都刷一堆 Skip unavailable package: ... 噪音。

根因lib/check_sw.shinstallDepsUbuntuline 119)的 pkgList 同时列了 libcurl4-gnutls-devlibcurl4-openssl-dev 这两个互斥的 -dev 包。 注释里说"Modern Debian/Ubuntu removed several legacy package names",但实际 pkgList 自身并没有清理这些老包。

修复E:\workbuddy\ServerStack\lib\check_sw.sh,仅改 Ubuntu 列表 line 119):

  • 删掉 libcurl4-gnutls-dev(保留 libcurl3-gnutls 这个 runtime)。 依据:modules/php/php-7.4.shphp-8.0.shphp-8.1.sh 全部用 libcurl4-openssl-dev,没有任何地方用 gnutls dev。
  • 顺手清理在新版 Ubuntu 上永远被 filter 跳过的死链包: libjpeg62-turbo-devlibpng12-0/-devlibpng3libidn11libcloog-ppl1sysv-rclibidn11-dev 保留(仍可用),Debian 分支的 列表不动(不同发行版软件源不同)。
  • 加了一段说明注释,避免后人重新加回 libcurl4-gnutls-dev

验证bash -n 通过;图片 1 的冲突不会再出现,图片 2 的 Skip 噪音也基本清零。

补充:用户反馈同样的报错仍在出现

用户第二轮贴出完全相同的报错文本(含 7.81.0-1ubuntu1.25 版本号和 No VM guests are running outdated hypervisor (qemu) 这条云 VM 特征消息)。 排查结论:

  • 本地 lib/check_sw.sh 的 Ubuntu 列表(line 141)已经是干净的,没有 libcurl4-gnutls-dev
  • backup/runtime/ 都是空目录,全项目只有一份 check_sw.sh,没有其它副本。
  • 报错来自远程 Ubuntu 22.04 服务器上跑的旧版脚本,本地修改还没同步过去。

加防御层(filter_pkglist() 末尾,line 33-47

为了即使旧版 pkgList 被部署上去也不炸,在 filter_pkglist() 末尾加了一段 互斥冲突消解:检测列表里同时有 libcurl4-gnutls-devlibcurl4-openssl-dev 时,自动 sed 摘掉 gnutls dev 版,保留 openssl 版(PHP 各模块用的就是它), libcurl3-gnutls runtime 不动。

隔离测试通过:libcurl3-gnutls 保留 / libcurl4-openssl-dev 保留 / libcurl4-gnutls-dev 被移除。bash -n 语法通过。

给用户的行动项

需要把更新后的 lib/check_sw.sh 重新同步到服务器(rsync/scp/git pull 等), 然后重跑安装。同步后两层防护都会生效:

  1. Ubuntu 列表源头已无 libcurl4-gnutls-dev(也不会再有 Skip 噪音)。
  2. 即便将来有人把互斥包加回去,filter_pkglist 会自动摘掉。

第三轮:修复"卡很久"的黑屏问题

用户反馈"在运行到此处时会卡很久"。分析 install_pkgs() 的卡顿来源:

  1. 批量 apt-get 遇冲突时静默求解apt 的依赖求解器遇到 libcurl4-gnutls-dev vs libcurl4-openssl-dev 互斥时,会花 30s~2min 尝试各种组合才放弃,期间 无任何输出,看起来像冻住。
  2. 逐包回退循环全静默:批量失败后循环 ~60 个包,每个 apt-get install 输出 全 redirect 到 /dev/null,用户看到几分钟黑屏。

改动(lib/check_sw.shinstall_pkgs()line 74-109

  • 批量安装前再补一道冲突消解(防御纵深,防 filter_pkglist 被绕过或 pkgList 被中间修改)。
  • 回退循环改成可见进度:每个包先 printf 包名(cyan,左对齐 40 列),再装, 装完打 OK(绿)/FAILED(红)。屏幕永不空白。
  • 颜色变量复用 lib/color.sh 里已定义的 CMSG/CSUCCESS/CFAILURE/CEND
  • cat -v 验证对齐和转义正确,bash -n 语法通过。

三层防护总览(都已在本地 lib/check_sw.sh

  1. installDepsUbuntu 的 pkgList 源头已删 libcurl4-gnutls-dev + 死链包。
  2. filter_pkglist() 末尾自动消解 libcurl dev 互斥冲突。
  3. install_pkgs() 开头再消解一次 + 回退循环可见进度。

用户必须做的:把 lib/check_sw.sh 同步到服务器再重跑。当前服务器上跑的 还是旧版,所以三轮都看到同样的报错。

第四轮:审视整个项目,杜绝静默安装

用户要求"不要静默安装, 要有相关提示"。全项目扫描结论:

扫描发现

  • 大多数 make -j / ./configure 没有/dev/null 吞输出(调用方 run_install()Install_X | tee 会显示并写日志),只是缺起始提示
  • 唯一真正把安装输出吞掉的只有 lib/check_sw.sh 逐包回退的 apt-get ... >/dev/null 2>&1(第三轮已改成可见进度,本轮再改成完全不吞)。
  • 下载环节 lib/download.shDownload_src()wget -c(无 -q),带进度,OK。
  • 所有模块安装统一经 lib/loader.shrun_install(),是加统一提示的单点

改动清单(7 个文件,bash -n 全通过)

  1. lib/loader.sh run_install():加 >> Installing: <func> 横幅(带 module 路径)。 改这一处覆盖全部 47 个模块 + 主流程。
  2. lib/check_sw.sh install_pkgs() 回退循环:去掉 >/dev/null,每个包打印 "Installing X ..." → "X installed OK / install FAILED"apt 下载进度可见。
  3. lib/openssl.sh Install_openSSL():开头加 ">> Installing: openSSL ver"。
  4. modules/web/jemalloc.sh Install_Jemalloc():开头加 ">> Installing: jemalloc ver"。
  5. lib/check_sw.sh installDepsBySrc()ICU):开头加 ">> Installing: ICU ver"。
  6. core/environment.sh prepare_install()${PM} -y install wget gcc curl python 加提示 + tee 写日志(与上方 apt-get update 一致)。
  7. core/os/init_Ubuntu.sh / init_Debian.shiptables 安装两处 apt-get 加提示。

验证

  • grep 'apt-get.*install.*>/dev/null' 全项目无匹配 → 再无静默 apt 安装。
  • 编译步骤输出仍可经 | tee 看到并落日志。
  • 收尾仍要提醒:所有改动需 rsync/git pull 到服务器才会生效。

ServerStack: apt-get 依赖安装改为静默(-y) + 写日志

需求变更:上一轮把逐包回退改成屏幕逐行可见;这轮用户改口要 「apt-get 静默安装(-y) + 输出安装日志」。

改动lib/check_sw.shinstall_pkgs()):

  • 统一 export DEBIAN_FRONTEND=noninteractive,apt 完全非交互(不再卡 debconf 提示)。
  • 批量安装:apt-get --no-install-recommends -y install ${pkgList} >> runtime/install.log 2>&1 屏幕只打印 Installing dependency packages (... -> install.log) 起始行 + 成功后 All dependency packages installed successfully.
  • 逐包回退:每个包同样 apt-get -y ... >> install.log 2>&1,屏幕只保留一行 -> <pkg> ... OK/FAILEDprintf 左对齐 40 列,OK 绿/FAILED 红)。
  • 日志路径 local _log="${oneinstack_dir:-.}/runtime/install.log",与外层 installDepsUbuntu 2>&1 | tee 同一文件;apt 详细输出直接追加、屏幕状态经 tee 落一份,无重复。
  • 同步更新函数顶部注释,去掉旧的 /dev/null 描述。bash -n 通过。

设计要点:屏幕保留简洁状态(可读、不黑屏),完整 apt 输出进 install.log(可 grep 排障)。

第五轮:修复安装摘要 URL 显示 http:/// IPADDR 为空)

根因IPADDRcore/environment.shprepare_install()./lib/py/get_ipaddr.py 获取, 该脚本靠 shebang #!/usr/bin/env python 启动;Ubuntu 22.04+ 只有 python3python 命令, 且 base-tools 装的是不存在的 python 包、symlink 补救被 ~/.oneinstack 判断限制, 导致脚本静默失败 → 标准输出空 → IPADDR 空 → 摘要 URL 变成 http:///ocp.php 等。

修复(仅 environment.sh + bin/upgrade.shbash -n 均通过):

  1. 新增纯 shell 函数 get_local_ipaddr()environment.sh),按 ip route get srchostname -Iip -o -4 addr show scope global127.0.0.1 回退,不依赖 python
  2. IPADDR=$(./lib/py/get_ipaddr.py) 改为 IPADDR=$(get_local_ipaddr)
  3. base-tools 安装 pythonpython3/usr/bin/python 软链改无条件创建, 让 get_public_ipaddr.py / get_ipaddr_state.py 也能跑。
  4. bin/upgrade.sh 独立入口同样加无条件 python 软链兜底。

验证mock 命令测 get_local_ipaddr 三种场景均正确(有路由取 src / 无路由回退 hostname / 全无回退 127.0.0.1)。 注意:改动仍在本地,需同步到服务器后重装/重跑 install 生效。

第五轮补充:VPC/私网场景让摘要 URL 改用公网 IP

用户指出服务器是 VPC 网络。澄清:空 IP bug 与 VPC 无关(是 python 缺失);但 VPC 决定了 "显示哪个 IP"——ip route get 在 VPC 取到的是私网 RFC1918 地址,从外部经公网 IP/EIP 访问时 私网 URL 打不开。

补充改动core/environment.sh):

  1. 取 IP 顺序改为先 PUBLIC_IPADDR=$(get_public_ipaddr.py)IPADDR=$(get_local_ipaddr), 让本地检测函数能引用已解析的公网 IP。
  2. get_local_ipaddr() 末尾加 case10.* / 172.16-31.* / 192.168.* 私网段且 PUBLIC_IPADDR 非空时,改用公网 IP;公网取不到则安全保留私网 IP。

验证:mock 四场景全过(VPC私网+公网→公网 / VPC私网+公网失败→私网 / 经典VM公网→公网 / 纯内网192.168+失败→192.168)。