yum list查询时部门包查找不到流程分析

打印 上一主题 下一主题

主题 1953|帖子 1953|积分 5859

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
以下是针对 yum list available -c xxx.repo(对应 DNF 的命令行操纵)的详细流程解读,包括参数解析、配置初始化、元数据加载、数据库查询,以及读取不到特定包的场景分析。

1. 命令行参数解析与入口函数

代码入口: dnf.cli.main.main() -> user_main(sys.argv[1:])


  • 参数处置惩罚流程:

    • 参数分割:

      • sys.argv[1:] 接收命令行参数,比方 ["list", "available", "-c", "xxx.repo"]。
      • -c 参数指定自界说配置文件路径(覆盖默认的 /etc/dnf/dnf.conf)。
      • xxx.repo 是用户自界说仓库文件(需明白路径,如 /path/to/xxx.repo)。

    • CLI 解析逻辑:

      • DNF 利用 argparse 解析参数,关键模块在 dnf.cli.cli.Cli 中。
      • list 是子命令,对应 dnf.cli.commands.list.ListCommand 类。
      • available 是 list 的子参数,表现列出未安装但仓库中存在的包。
      • 关键代码片段:
        1. # dnf/cli/cli.py
        2. def parse_commands(self):
        3.     parser = argparse.ArgumentParser()
        4.     subparsers = parser.add_subparsers(dest='command')
        5.     list_parser = subparsers.add_parser('list')
        6.     list_parser.add_argument('available', action='store_true')
        7.     list_parser.add_argument('-c', '--config', dest='config_file')
        8.     return parser.parse_args()
        复制代码



2. 配置初始化与仓库加载

代码模块: dnf.base.Base, dnf.conf.Conf


  • 配置加载次序:

    • 默认配置:

      • 读取 /etc/dnf/dnf.conf,初始化全局配置对象 Conf。

    • 自界说配置:

      • -c xxx.repo 参数触发加载用户指定的仓库文件(可能覆盖默认仓库)。
      • 仓库文件解析逻辑在 dnf.repo.RepoDict 中,关键方法为 _parse_repo_file()。


  • 仓库初始化:

    • 自界说仓库文件路径处置惩罚:
      1. # dnf/cli/cli.py
      2. if opts.config_file:
      3.     conf.reposdir = [os.path.abspath(opts.config_file)]
      复制代码
    • 所有仓库(包括自界说仓库)生成 Repo 对象,存储在 Base.repos 中。


3. 元数据下载与 Sack 构建

代码模块: dnf.repo.Repo, dnf.sack.Sack


  • 元数据加载流程:

    • 元数据下载:

      • 对每个启用的仓库(包括 xxx.repo 中的仓库),调用 Repo.load() 方法。
      • 下载 repomd.xml 并验证署名(若配置了 gpgcheck=1)。
      • 下载 primary.xml、filelists.xml 等元数据文件到缓存目录(如 /var/cache/dnf/)。

    • Sack 构建:

      • Base.fill_sack() 方法将所有仓库的元数据解析为 Package 对象。
      • 关键代码:
        1. # dnf/base.py
        2. def fill_sack(self):
        3.     for repo in self.repos.iter_enabled():
        4.         repo.load()  # 触发元数据下载
        5.     self.sack = dnf.sack.Sack()
        6.     self.sack.add_cmdline_packages()  # 添加本地 RPM(此处无)
        7.     self.sack.load_repos(self.repos)  # 加载仓库元数据到 Sack
        复制代码



4. 查询可用包 (list available)

代码模块: dnf.query.Query


  • 查询逻辑:

    • 初始化查询对象:
      1. # dnf/commands/list.py
      2. query = self.base.sack.query()
      3. available = query.available()  # 过滤未安装的包
      复制代码
    • 过滤与输出:

      • 根据 name、version 等条件过滤包。
      • 输出效果到终端,格式化为表格。


  • 关键数据布局:

    • Sack 中的 packages 列表存储所有 Package 对象。
    • Query 对象通过 filter() 方法实现高效检索(如 name="bash")。


5. 读取不到特定包的可能场景

以下场景可能导致无法读取仓库中的特定包信息:
场景 1: 仓库配置错误



  • 缘故原由:

    • xxx.repo 文件中的 baseurl 或 metalink 配置错误(如 URL 不可达)。
    • 仓库未启用(enabled=0)。

  • 征象:

    • 实验 dnf repolist 时目的仓库未列出。
    • 日志中提示 Repository 'xxx' is missing valid metadata。

场景 2: 元数据未更新



  • 缘故原由:

    • 本地缓存逾期(metadata_expire 超时)且未主动实验 dnf clean all 或 dnf makecache。
    • 仓库元数据破坏(如 repodata 文件不完备)。

  • 征象:

    • 包存在于仓库服务器但本地查询不到。
    • 日志提示 Cannot retrieve metalink for repository。

场景 3: 包被清除规则过滤



  • 缘故原由:

    • 全局配置或仓库配置中设置了 exclude=package_name。
    • 启用了 --exclude 命令行参数。

  • 征象:

    • dnf list available 不表现目的包,但 dnf repoquery --repo=xxx package_name 可查到。

场景 4: 架构或版本不匹配



  • 缘故原由:

    • 包的 arch 不在系统支持的架构列表中(如 i686 包在 x86_64 系统上默认隐藏)。
    • 包的 epoch:version-release 不符合仓库元数据中的界说。

  • 征象:

    • dnf list available 表现部门包,但特定包缺失。

场景 5: 仓库元数据未包含该包



  • 缘故原由:

    • 仓库服务器未正确生成元数据(如 createrepo_c 实验失败)。
    • 包被手动上传到仓库目录但未添加到元数据。

  • 征象:

    • 通过 HTTP 直接访问仓库 URL 可看到 RPM 文件,但元数据中无记录。


完备流程示例(代码视角)


  • 参数解析:
    1. # main.user_main(["list", "available", "-c", "xxx.repo"])
    2. args = Cli().parse_commands()  # 解析为 {command: 'list', available: True, config_file: 'xxx.repo'}
    复制代码
  • 配置初始化:
    1. base = dnf.Base()
    2. base.conf.config_file_path = args.config_file  # 加载 xxx.repo
    3. base.repos.repopulate()  # 重新生成仓库列表
    复制代码
  • 元数据加载:
    1. base.repos.all().enable()  # 启用所有仓库(包括自定义仓库)
    2. base.fill_sack()  # 构建 Sack
    复制代码
  • 实验查询:
    1. query = base.sack.query().available()
    2. for pkg in query:
    3.     print(pkg.name, pkg.version)
    复制代码

调试与排查方法


  • 检察仓库状态:
    1. dnf repolist -v --config=xxx.repo
    复制代码
  • 检查元数据缓存:
    1. ls /var/cache/dnf/xxx*/  # 确认 primary.xml 存在
    复制代码
  • 手动下载元数据:
    1. curl [baseurl]/repodata/repomd.xml  # 验证仓库可达性
    复制代码
通过以上分析,可系统化定位包信息缺失的根本缘故原由。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

知者何南

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表