惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
PCI Perspectives
PCI Perspectives
H
Help Net Security
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
S
Secure Thoughts
Jina AI
Jina AI
Attack and Defense Labs
Attack and Defense Labs
大猫的无限游戏
大猫的无限游戏
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Security @ Cisco Blogs
阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
T
Tor Project blog
小众软件
小众软件
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
博客园 - 【当耐特】
G
Google Developers Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
I
Intezer
S
Schneier on Security
S
Securelist
W
WeLiveSecurity
C
Cybersecurity and Infrastructure Security Agency CISA
P
Palo Alto Networks Blog
Scott Helme
Scott Helme
Project Zero
Project Zero
Google Online Security Blog
Google Online Security Blog
T
Threatpost
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Engineering at Meta
Engineering at Meta
Blog — PlanetScale
Blog — PlanetScale
V
Visual Studio Blog
Last Week in AI
Last Week in AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
人人都是产品经理
人人都是产品经理
Y
Y Combinator Blog
A
Arctic Wolf
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LangChain Blog

Leo’s blog

RISC-V 函数调用约定 [译] Understanding Incremental Decoding in fairseq 将化学分子的 ChEMBL ID 转化为 SMILES 的两种方法 通过 PDM 和 GitHub Actions 在 PyPI 上自动化发布你的 Python 包吧 为友治藏书印一方 忙忙碌碌中匆匆过眼我的 2023 年 Cloudflare + Backblaze 实现免费的博客图床方案 新服务器必做的基本设置——服务器迁移之记录 把博客站点交给了 Cloudflare 托管 RIME 脚本食用方法举隅:以输入苏州码为例 通过 SSH 在 Pycharm 上使用 Docker 容器中的 Python 解释器 如何在 X86 设备上使用 Docker 构建 ARM 镜像 文献总结|结构诱导的预训练 文献总结|MTGL-ADMET:一种通过地位理论与最大流增强并用于 ADMET 预测的多任务图学习框架 文献总结|探测图表示 四月十二奉新纸一试 文献总结|可以同时完成分子语言序列回归和生成的 Regression Transformer 旧书市场淘书记 文献总结|一种用于基于结构药物设计的 3D 生成模型
华为云踩坑:由 URL 编码导致 yum 安装时的 No such file or directory 错误
Leo · 2024-03-15 · via Leo’s blog

最近想要在华为云的 BMS 上部署一个 Web 应用,咨询了华为的工程师后,得到了可行的明确答复。那么首先就需要安装 Nginx,在安装 Nginx 所需的依赖遇到了 [Errno 2] No such file or directory 的错误,一层层查找后发现这可能是一个由代理设置引起 URL 编码错误而导致的 bug。由于网络上几乎没有找到任何相关的资料,就把整个过程留下来作为记录。

首先从安装 Nginx 所需的依赖开始:

$ sudo yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel
...
Error:
 Problem: package pcre-devel-8.32-15.1.h6.aarch64 requires libpcre16.so.0()(64bit), but none of the providers can be installed
  - package pcre-devel-8.32-15.1.h6.aarch64 requires libpcre32.so.0()(64bit), but none of the providers can be installed
  - package pcre-devel-8.32-15.1.h6.aarch64 requires libpcrecpp.so.0()(64bit), but none of the providers can be installed
  - cannot install both pcre-8.32-15.1.h1.aarch64 and pcre-8.42-4.h3.eulerosv2r8.aarch64
  - cannot install both pcre-8.32-15.1.h6.aarch64 and pcre-8.42-4.h3.eulerosv2r8.aarch64
  - cannot install the best candidate for the job

竟然提示没有找到可用的包,按理来说 BMS 已经配置了华为官方的源,既不会有网络问题也不会缺失 pcre-devel 这样的常见包。于是我开始排查 yum 源的问题,先检查设备的系统和架构:

$ uname -m
aarch64
$ cat /etc/os-release
NAME="EulerOS"
VERSION="2.0 (SP8)"
ID="euleros"
ID_LIKE="rhel fedora centos"
VERSION_ID="2.0"
PRETTY_NAME="EulerOS 2.0 (SP8)"
ANSI_COLOR="0;31"

可以看到操作系统是华为的 EulerOS 2.0 (SP8),架构是 aarch64。再检查默认的 yum 源:

$ sudo cat /etc/yum.repos.d/EulerOS.repo
[euler-base]
name=EulerOS-2.0SP8 base
baseurl=http://mirrors.huaweicloud.com/euler/2.3/os/aarch64/
enabled=1
gpgcheck=1
gpgkey=http://mirrors.huaweicloud.com/euler/2.3/os/RPM-GPG-KEY-EulerOS

仔细看默认的 yum 源,系统版本明明是 2.0 (SP8),URL 却指向了 2.3。测试直接替换后的链接 http://mirrors.huaweicloud.com/euler/2.8/os/aarch64/ 可达,那么就尝试改为使用该 yum 源。

这里的修改很简单,我就没有额外备份,使用 vim 直接编辑文件 /etc/yum.repos.d/EulerOS.repo 并保存,修改后的 yum 源信息为

[euler-base]
name=EulerOS-2.0SP8 base
baseurl=http://mirrors.huaweicloud.com/euler/2.8/os/aarch64/
enabled=1
gpgcheck=1
gpgkey=http://mirrors.huaweicloud.com/euler/2.8/os/RPM-GPG-KEY-EulerOS

通过以下命令更新 yum 源:

$ sudo yum clean all            # 清除旧 yum 源缓存
$ sudo yum makecache            # 生成新 yum 源缓存
$ sudo yum repolist             # 检查 yum 源连接状态
EulerOS-2.0SP8 local repo for internal use          0.0  B/s |   0  B     00:00
EulerOS-2.0SP8 base                                 7.4 MB/s |  17 MB     00:02
Failed to synchronize cache for repo 'base', ignoring this repo.
Last metadata expiration check: 0:00:06 ago on Fri 15 Mar 2024 09:54:47 AM CST.
repo id                           repo name                              status
euler-base                        EulerOS-2.0SP8 base                    16,599

上述信息中的 Fail 指示 EulerOS-2.0SP8 local repo for internal use 这个源不可用,看名字应该是内部使用的 yum 源,在此处没有影响。列举出的 repolist 中有 EulerOS-2.0SP8 base 一项,说明更改后的源已经可用。

[Errno 2] No such file or directory

再次尝试安装 Nginx 的依赖:

$ sudo yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel
...
(19/29): gcc-c++-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm         6.2 MB/s | 7.4 MB     00:01
...
[Errno 2] No such file or directory: '/var/cache/dnf/euler-base-85cc05102200a8ac/packages/gcc-c++-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm'
The downloaded packages were saved in cache until the next successful transaction.
You can remove cached packages by executing 'dnf clean packages'.

提示 [Errno 2] No such file or directory,没有找到 gcc-c++ 的 RPM 文件,奇怪的是在安装输出的信息中分明提示已经成功下载了 gcc-c++

错误信息中指引了一个文件目录 /var/cache/dnf/euler-base-85cc05102200a8ac/packages/,不妨检查一下其中的文件:

$ sudo ls /var/cache/dnf/euler-base-85cc05102200a8ac/packages/
cpp-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm                  make-4.2.1-10.h3.eulerosv2r8.aarch64.rpm
gcc-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm                  openssl-1.1.1-3.h31.eulerosv2r8.aarch64.rpm
gcc-c%2b%2b-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm          openssl-devel-1.1.1-3.h31.eulerosv2r8.aarch64.rpm
gcc-gfortran-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm         openssl-libs-1.1.1-3.h31.eulerosv2r8.aarch64.rpm
keyutils-libs-devel-1.5.10-8.h4.eulerosv2r8.aarch64.rpm         pcre2-devel-10.32-3.h1.eulerosv2r8.aarch64.rpm
krb5-devel-1.16.1-21.h1.eulerosv2r8.aarch64.rpm                 pcre2-utf16-10.32-3.h1.eulerosv2r8.aarch64.rpm
libcom_err-devel-1.44.3-1.h4.eulerosv2r8.aarch64.rpm            pcre2-utf32-10.32-3.h1.eulerosv2r8.aarch64.rpm
libgfortran-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm          pcre-8.42-4.h3.eulerosv2r8.aarch64.rpm
libgomp-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm              pcre-cpp-8.42-4.h3.eulerosv2r8.aarch64.rpm
libkadm5-1.16.1-21.h1.eulerosv2r8.aarch64.rpm                   pcre-devel-8.42-4.h3.eulerosv2r8.aarch64.rpm
libselinux-devel-2.8-4.h2.eulerosv2r8.aarch64.rpm               pcre-utf16-8.42-4.h3.eulerosv2r8.aarch64.rpm
libsepol-devel-2.8-2.eulerosv2r8.aarch64.rpm                    pcre-utf32-8.42-4.h3.eulerosv2r8.aarch64.rpm
libstdc%2b%2b-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm        zlib-1.2.11-14.h4.eulerosv2r8.aarch64.rpm
libstdc%2b%2b-devel-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm  zlib-devel-1.2.11-14.h4.eulerosv2r8.aarch64.rpm
libverto-devel-0.3.0-6.h1.eulerosv2r8.aarch64.rpm

可以看到下载的 29 个文件都在其中,从中寻找报错的 gcc-c++,看到文件名时恍然大悟,gcc-c++ 被转义成了 gcc-c%2b%2b。同样带有 +libstdc++libstdc++-devel 两个安装文件也都被用 %2b 转义,用未转义前的名称自然无法寻找到这些文件。

起初以为这是 yum 在处理特殊符号时 URL 编码的 bug,但在互联网上用关键词检索找不到任何相关的信息。仔细一想,yum 是无数 Linux 平台上默认的包管理器,怎么可能犯这么低级的错误,况且在安装这么常见的依赖时就能引发的 bug 理应很快就被修复了。

在许久漫无目的地寻找后,偶然发现了 GitHub 上的一篇 Issue,大意是说代理软件应当支持识别 yum.conf 中的 URL 编码,否则会导致一些问题。这倒提醒了我,会不会是代理导致的问题呢?

修改 yum 源代理

设备可能带有华为用来日常管理维护设备的内部默认代理,不宜擅自修改,最好是仅修改 yum 源所使用的代理,不影响其他服务的运作。同样用 vim 修改 /etc/yum.repos.d/EulerOS.repo 文件的内容,仅在最后添加一行:

[euler-base]
name=EulerOS-2.0SP8 base
baseurl=http://mirrors.huaweicloud.com/euler/2.8/os/aarch64/
enabled=1
gpgcheck=1
gpgkey=http://mirrors.huaweicloud.com/euler/2.8/os/RPM-GPG-KEY-EulerOS
proxy=_none_

然后用同样的操作尝试更新 yum 源:

$ sudo yum clean all
$ sudo yum makecache
EulerOS-2.0SP8 local repo for internal use                          0.0  B/s |   0  B     00:00
EulerOS-2.0SP8 base                                                 0.0  B/s |   0  B     00:01
Failed to synchronize cache for repo 'base', ignoring this repo.
Failed to synchronize cache for repo 'euler-base', ignoring this repo.
Metadata cache created.

发现禁止源 EulerOS-2.0SP8 base 使用代理后,就无法连接上源仓库了。可以确定华为云上的 BMS 确实设置有供 yum 安装所使用的特殊代理,文件名的 URL 编码异常可能由该代理导致,从而引起 [Errno 2] No such file or directory 的错误。

解决方案

由于华为云 BMS 获取 yum 源仓库必须通过默认代理,不能通过取消代理解决该问题。那么就只能通过最朴素、最直接的方法解决这个问题了——手动改文件名。注意核对 cache 文件目录,手动将文件名中的 %2b 改回为 +,我这里有 gcc-c%2b%2b libstdc%2b%2b libstdc%2b%2b-devel 三个文件需要修改:

$ cd /var/cache/dnf/
$ sudo mv ./euler-base-85cc05102200a8ac/packages/gcc-c%2b%2b-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm ./euler-base-85cc05102200a8ac/packages/gcc-c++-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm
$ sudo mv ./euler-base-85cc05102200a8ac/packages/libstdc%2b%2b-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm ./euler-base-85cc05102200a8ac/packages/libstdc++-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm
$ sudo mv ./euler-base-85cc05102200a8ac/packages/libstdc%2b%2b-devel-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm ./euler-base-85cc05102200a8ac/packages/libstdc++-devel-7.3.0-20190804.h29.eulerosv2r8.aarch64.rpm

然后再尝试原先的安装命令,就发现先前提示无法找到的安装包能够成功安装上了。


References