古典lash网站带后台源码下载,天津seo推广软件,做爰全过程免费的视频的网站,90设计官网探索 Python 应用的分层依赖#xff1a;解决 UOS 环境中的 libvirt-python 安装问题 背景Python 版本升级 问题描述原因分析与解决方案 Python 应用的分层依赖#xff1a;安装与部署的视角libvirt-python的分层依赖尝试的解决方案 使用编译好的 .whl 文件嫁接整个…探索 Python 应用的分层依赖解决 UOS 环境中的 libvirt-python 安装问题 背景Python 版本升级 问题描述原因分析与解决方案 Python 应用的分层依赖安装与部署的视角libvirt-python的分层依赖尝试的解决方案 使用编译好的 .whl 文件嫁接整个package 小结参考附录 Python 应用分层依赖的完整结构 探索 Python 应用的分层依赖解决 UOS 环境中的 libvirt-python 安装问题
背景
在 Ubuntu-22.0 和 UOS1070 上用 Python 开发基于 libvrt-python 的应用在 Ubuntu 平台的开发过程中一切顺利但在 UOS 上开发时遇到了两个关键问题 Python 版本限制应用需要 Python 3.10 及以上版本而 UOS 自带的 Python 版本为 3.7.3因此需要升级 Python 版本。 libvirt-python 包不可用在 Ubuntu 平台libvirt-python 包能够正常安装和使用但在 UOS 上即使升级了 Python 版本依然无法成功安装和使用此包成为开发的主要障碍。
本文将重点分析和解决 libvirt-python 包不可用的问题。在此之前简单回顾 Python 版本升级的过程。
Python 版本升级
问题描述
UOS 1070 自带的 Python 版本为 3.7.3但应用需要 Python 3.10 及以上版本。尝试升级 Python 到 3.10.15 版本时遇到了以下问题
系统权限限制UOS 系统默认需要开启“开发者模式”才能使用 sudo 命令安装软件包。安装失败即使开启了“开发者模式”在源码安装 Python 3.10.15 的过程中仍然出现 “Segment Fault” 错误导致安装失败。
原因分析与解决方案
煎熬了两天各种搜索未果后我已经准备上gdb来调试了偶然获得高人指点发现问题的根源在于 UOS 的应用安全机制1。UOS 默认启用了应用签名限制只允许运行经过签名的应用程序即使是编译过程中生成的工具也不允许运行从而引发了异常。
为了完成 Python 的安装需要调整安全设置
开始 — 安全中心 — 安全工具 — 应用安全 将默认选项 “仅允许签名应用” 修改为 “允许任意应用”。
完成上述步骤后重新尝试从源码安装 Python 3.10.15 即可成功。
虽然 Python 升级问题解决起来有些“曲折”但相较于接下来的 libvirt-python 包问题这只是一个小插曲。接下来将继续复盘如何处理 libvirt-python 包的不可用问题。
Python 应用的分层依赖安装与部署的视角 在安装和部署 Python 应用时依赖关系往往分为多个层次。从 Python 包的直接依赖到系统级的共享库最终到硬件支持每一层的正确配置对于成功安装并运行 Python 应用至关重要。特别是在像 UOS 这样的操作系统环境中理解这些层次关系对于顺利解决诸如 libvirt-python 这样的包安装问题具有重要意义。以下是 Python 应用安装和部署过程中的分层依赖结构 这种依赖关系可以简单归纳如下
应用层依赖Python 包及其嵌套依赖如 scikit-learn 的 numpy 依赖。
环境层依赖Python 解释器、包管理工具pip及虚拟环境如 venv。
二进制层依赖Python 包中的 C 扩展模块和相关共享库它们通常以 .so 文件形式存在运行时候需要正确链接系统共享库。
系统层依赖系统级共享库如 glibc、平台特定库如 GPU 驱动它们是二进制模块运行的基础。
硬件与内核层依赖Linux 内核调用及硬件驱动支持。 接下来我将基于这一分层模型详细分析和解决 libvirt-python 的不可用问题。
libvirt-python的分层依赖
libvirt-python2 是一个通过 C 扩展形式实现的 Python 包用于调用底层 libvirt 库函数提供对虚拟化管理的接口支持。它的依赖关系横跨 Python 包层、二进制层、系统层因此使用过程中容易出现多层依赖之间的兼容性问题。以下对具体报错情况进行分层分析。
libvirt-python 在官方文档中声明了以下编译限制条件
Python 版本Python 3.6libvirt 版本libvirt 0.9.11
虽然这些要求表面上看起来较为宽松但在 UOS 环境下安装 libvirt-python 10.8.0(默认就是这个版本)时却出现了以下报错
$ /usr/local/python3.10/bin/python3 -m pip install libvirt-python
...
Building wheel for libvirt-python (pyproject.toml) did not run successfully.│ exit code: 1╰─ [55 lines of output]running bdist_wheelrunning buildrunning build_pyMissing type converters:virTypedParameterPtr *:1int *:1ERROR: failed virDomainGetLaunchDigest
...从错误信息中可以看出问题出现在构建 C 扩展的过程中。libvirt 库的接口通过 /usr/share/libvirt/api/libvirt-api.xml 文件进行定义和描述。而在构建 C 扩展时libvirt-python 的 generator.py 脚本会检查每个绑定函数的签名是否与 libvirt 库提供的接口匹配。具体问题出在 virDomainGetLaunchDigest 函数其签名中存在类型不匹配的情况导致构建失败。
尝试的解决方案
使用编译好的 .whl 文件
针对接口类型检查失败的问题最直接的解决方案是使用预编译的 .whl 文件安装 libvirt-python。由于实际使用的 API 接口较少抱着侥幸心理我尝试将 Ubuntu 22.04 上编译好的 libvirt-python-10.7.0-cp310-cp310-linux_x86_64.whl 文件安装到 UOS 1070 环境中。
安装过程顺利完成但在 import libvirt 时却报如下错误 import libvirt
Traceback (most recent call last):File /home/test/.local/lib/python3.10/site-packages/libvirt.py, line 16, in moduleimport cygvirtmod as libvirtmod # type: ignore
ModuleNotFoundError: No module named cygvirtmodDuring handling of the above exception, another exception occurred:Traceback (most recent call last):File stdin, line 1, in moduleFile /home/test/.local/lib/python3.10/site-packages/libvirt.py, line 19, in moduleraise lib_eFile /home/test/.local/lib/python3.10/site-packages/libvirt.py, line 13, in moduleimport libvirtmod # type: ignore
ImportError: /lib/x86_64-linux-gnu/libvirt.so.0: version LIBVIRT_7.7.0 not found 翻看代码这里的逻辑是为了兼容cygwin的环境先尝试导入cygvirtmod如果导入失败则尝试导入libvirtmod。在导入 libvirtmod 的时候就出现了后续的错误。
进一步定位到 libvirtmod.cpython-310-x86_64-linux-gnu.so 文件它是 libvirt-python 的C扩展模块在运行时侯通过 ctypes 或直接绑定的方式与系统的 libvirt.so 动态库交互。如果 libvirt.so 的版本低于 C 扩展模块编译时的要求缺少必要符号或函数就会引发上述运行错误。
可以通过以下命令查看 libvirtmod.cpython-310-x86_64-linux-gnu.so 文件中依赖的符号表 $ strings /home/test/.local/lib/python3.10/site-packages/libvirtmod.cpython-310-x86_64-linux-gnu.so结果显示该模块依赖多处 LIBVIRT_7.x.0 和 LIBVIRT_8.0.0 的符号。进一步确认系统环境差异 Ubuntu 22.04 中的 libvirt 的版本
testM920t-N000:~$ virsh --version
8.0.0
testM920t-N000:~$ ls -lr /usr/lib/x86_64-linux-gnu/libvirt.so
lrwxrwxrwx 1 root root 12 4月 13 2024 /usr/lib/x86_64-linux-gnu/libvirt.so - libvirt.so.0
testM920t-N000:~$ ls -lr /usr/lib/x86_64-linux-gnu/libvirt.so.0
lrwxrwxrwx 1 root root 19 4月 13 2024 /usr/lib/x86_64-linux-gnu/libvirt.so.0 - libvirt.so.0.8000.0
testM920t-N000:~$ ls -lr /usr/lib/x86_64-linux-gnu/libvirt.so.0.8000.0
-rw-r--r-- 1 root root 4731576 4月 13 2024 /usr/lib/x86_64-linux-gnu/libvirt.so.0.8000.0UOS 1070 中的 libvirt 版本
$ virsh --version
5.0.0显然UOS 上的 libvirt.so 版本无法满足 libvirt-python 对 LIBVIRT_7.x.0 或 LIBVIRT_8.0.0 的要求。 升级libvirt的可能 理论上可以尝试将 UOS 的 libvirt 动态库升级到与 Ubuntu 一致的版本但升级的工作量和风险极高。以 libvirt-python 的 C 扩展模块为例其依赖的动态库数量多达 57 个
testM920t-N000:~/.pyenv/versions/3.10.14/lib/python3.10/site-packages$ ls -lr
...
-rw-rw-r-- 1 test test 6759 9月 13 11:20 libvirt_qemu.py
drwxrwxr-x 2 test test 4096 9月 13 11:20 libvirt_python-10.7.0.dist-info
-rw-rw-r-- 1 test test 373128 9月 13 11:20 libvirt.py
-rwxrwxr-x 1 test test 93352 9月 13 11:20 libvirtmod_qemu.cpython-310-x86_64-linux-gnu.so
-rwxrwxr-x 1 test test 81360 9月 13 11:20 libvirtmod_lxc.cpython-310-x86_64-linux-gnu.so
-rwxrwxr-x 1 test test 1041224 9月 13 11:20 libvirtmod.cpython-310-x86_64-linux-gnu.so
-rw-rw-r-- 1 test test 1729 9月 13 11:20 libvirt_lxc.py
-rw-rw-r-- 1 test test 16957 9月 13 11:20 libvirtaio.py
...
testM920t-N000:~/.pyenv/versions/3.10.14/lib/python3.10/site-packages$ ldd libvirtmod.cpython-310-x86_64-linux-gnu.so | wc -l
57动态库的依赖链复杂且紧密任何库的版本不匹配都会导致问题。例如以前尝试为某个功能升级库时不得不更新 glibc 小版本结果导致系统无法启动。考虑到潜在的工作量和风险放弃升级 UOS 的 libvirt 动态库转而寻找其他解决方案。 嫁接整个package
从系统本身出发当前使用的 UOS 1070 系统基于 Debian 10Buster系统版本信息如下
$ cat /etc/debian_version
10.10在 Debian Buster 的官网3中发现了它有自己维护的 python3-libvirt 包。通过以下命令可以轻松安装
sudo apt install python3-libvirt使用 apt install 方式来安装具有以下优势安装的版本与系统中的 libvirt 保持一致系统自动处理依赖关系例如安装 libvirt 动态库 (libvirt.so) 和头文件 (libvirt-dev)通过 apt 安装的包默认与系统中其他依赖保持一致减少版本冲突的可能性安装过程非常简单不需要编译二进制包直接可用无需额外配置。
安装完成后libvirt-python 被默认安装到系统自带的 Python 3.7.3 环境中。 问题转移
虽然 libvirt-python 在 Python 3.7.3 环境中可以被导入和调用但我们实际需要在 Python 3.10 环境中调用 libvirt-python。此时我尝试将系统中 Python 3.7.3 的 libvirt-python 包整体“嫁接”到 Python 3.10 的环境中以解决此问题。 定位并复制系统中的 libvirt-python 包 首先列出系统中 libvirt-python 的文件内容
$ ls -lr /usr/lib/python3/dist-packages/libvirt*
-rw-r--r-- 1 root root 3213 1月 24 2019 /usr/lib/python3/dist-packages/libvirt_qemu.py
-rw-r--r-- 1 root root 875 1月 24 2019 /usr/lib/python3/dist-packages/libvirt_python-5.0.0.egg-info
-rw-r--r-- 1 root root 331921 1月 24 2019 /usr/lib/python3/dist-packages/libvirt.py
-rw-r--r-- 1 root root 35000 1月 24 2019 /usr/lib/python3/dist-packages/libvirtmod_qemu.cpython-37m-x86_64-linux-gnu.so
-rw-r--r-- 1 root root 30808 1月 24 2019 /usr/lib/python3/dist-packages/libvirtmod_lxc.cpython-37m-x86_64-linux-gnu.so
-rw-r--r-- 1 root root 306936 1月 24 2019 /usr/lib/python3/dist-packages/libvirtmod.cpython-37m-x86_64-linux-gnu.so
-rw-r--r-- 1 root root 1738 1月 24 2019 /usr/lib/python3/dist-packages/libvirt_lxc.py
-rw-r--r-- 1 root root 15416 1月 24 2019 /usr/lib/python3/dist-packages/libvirtaio.py然后将上述文件拷贝到 Python 3.10 的 site-packages 目录
$ cp -r /usr/lib/python3/dist-packages/libvirt* /home/test/.local/lib/python3.10/site-packages/重命名 .so 文件以匹配 Python 3.10 因为 .so 文件是为 Python 3.7 编译的必须根据 Python 3.10 的命名规则进行重命名 libvirtmod_qemu.cpython-310-x86_64-linux-gnu.so
libvirtmod_lxc.cpython-310-x86_64-linux-gnu.so
libvirtmod.cpython-310-x86_64-linux-gnu.so测试 Python 3.10 环境 上述调整后在 Python 3.10 环境中成功加载了 libvirt-python。 这种方法将 Python 3.7 的 libvirt-python 包嫁接到 Python 3.10 环境中从而绕开了重编译和系统版本冲突的问题。
从调用分层的角度来看新的方案是在更高一层来解决问题反倒成为了最简单的解决方案。
小结
通过逐层分析 Python 应用运行环境中的问题找到了一种简洁且实用的解决方案。libvirt-python 作为一个依赖多层环境的 C 扩展包其可用性受限于 Python 包管理层、二进制动态库层以及系统底层的协调性。正是这种多层次的依赖关系导致版本迁移过程中容易出现不匹配问题。
在本次实践中“嫁接”方案展现了灵活性与高效性通过直接迁移包的方式成功让 Python 3.10 环境加载并正常使用 Python 3.7.3 环境中的 libvirt-python。 然而仍需注意以下几点
长期可行性由于“嫁接”方法依赖特定的环境兼容性可能无法适应未来系统更新或环境变更。可扩展性与维护成本如需进一步升级 Python 环境或 libvirt 版本可能需要重新调整迁移过程。备选方案评估若“嫁接”方法失效可以考虑直接调用 libvirt API通过绕过 Python 扩展层来解决可用性问题但这将带来更高的开发成本与复杂性。
所以当前的“嫁接”方案仅作为快速实现 MVP 的过渡性解决方案。长期来看为保证系统的稳定性和可维护性还需要探索新的解决方案。
参考 统信桌面专业版【安装第三方应用软件时报“段错误”】解决方案 libvirt-python python3-libvirt
附录
Python 应用分层依赖的完整结构
如果读者需要了解更详细的分层依赖结构可参考以下说明
应用代码层的依赖
Python 包依赖在应用代码中通过 import 语句引入所需的 Python 包(例如 import os)这是应用最直接的依赖。Python 包的依赖关系在应用的层次上定义通常列在 requirements.txt 或 pyproject.toml 文件中。包的嵌套依赖应用直接依赖的包通常会进一步依赖其他包。例如scikit-learn 依赖于 numpy 和 scipy 等。这些嵌套依赖必须全部满足应用才能正常运行。
Python环境的依赖
Python解释器所有Python代码都依赖于Python解释器解释器的版本和实现如CPython、PyPy影响应用兼容性。一些包尤其是C扩展包可能要求特定版本的Python才能正常运行。pip和虚拟环境pip作为Python包管理器用于安装、管理Python包。Python虚拟环境如venv或conda环境帮助隔离项目之间的依赖防止包版本冲突。在虚拟环境中安装依赖可以确保应用只使用当前环境中的包。
Python 包的二进制依赖
C扩展库许多Python包如numpy、PySide6包含用C/C编写的底层模块这些模块在编译后生成二进制共享库.so文件。应用依赖的包会加载这些.so文件比如PySide6.QtWidgets.so。包的共享库依赖如果某个Python包的.so文件依赖于其他共享库例如Qt库libQt5Core.so那么这些共享库也需要在系统上可用。共享库的路径和版本必须与Python包兼容否则会出现链接错误如Symbol not found。
系统级库的依赖
共享库.so依赖关系共享库的依赖链可以层层递进。例如一个Python包的.so文件可能依赖于Qt库而Qt库又依赖于低层次的库如X11或OpenGL。GNU C Library (glibc)几乎所有的Linux共享库最终都会依赖于glibc这是Linux系统的标准C库为应用提供底层系统调用和基本功能支持如内存管理、线程、I/O操作等。不同版本的glibc存在向后不兼容的情况因此一些依赖特定版本glibc的.so文件在不同Linux发行版上可能无法兼容。
内核及硬件依赖
Linux内核应用的最底层依赖是Linux内核因为所有系统调用例如内存分配、进程管理等最终会通过内核执行。现代应用很少直接依赖特定的内核版本但对于一些底层库如驱动程序需要确保内核与应用或库的依赖相符。硬件支持在需要硬件加速的场景如GPU加速中系统还依赖于特定的硬件设备和相关驱动程序。这通常是通过内核模块或厂商提供的.so文件如NVIDIA驱动实现。