Debian软件包管理系统是一个高度组织化和规范化的系统,本教程将深入探讨Debian 软件包管理的内部工作原理,包括档案库元数据、顶层“Release”文件及真实性、档案库层的“Release”文件以及获取用于软件包的元数据等方面的内容。
一、档案库元数据
每个发行版的元数据文件都保存在 Debian 镜像站的 “dist/codename” 下面,例如 “http://deb.debian.org/debian/”。档案库的结构可以通过网络浏览器来浏览。其中有 6 种关键的元数据。
Debian 档案库元数据的内容:
文件 | 位置 | 内容 |
---|---|---|
Release |
发行版的顶层 | 档案库描述和完整性信息 |
Release.gpg |
发行版的顶层 | “Release ” 文件的签名文件,使用档案库密钥签名 |
Contents-architecture |
发行版的顶层 | 列出在相关架构中所有软件包的全部文件 |
Release |
每个发行版/区域/架构组合的顶部 | 归档描述使用 apt_preferences ( 5 ) 的规则 |
Packages |
每个发行版/区域/二进制架构组合的顶部 | 连接 debian/control 获得二进制包 |
Sources |
每个 发行版/区域/源代码 组合的顶部 | 连接 debian/control 获取源代码包 |
为了减少网络流量,在最近的档案库中,这些元数据存储为压缩了的差分文件。
二、顶层Release文件
顶层“Release”文件用于签署 secure APT 系统下的归档文件。每个 Debian 档案库的网址都有一个这样的 “Release” 文件,例如 “http://deb.debian.org/debian/dists/unstable/Release”,内容如下。
Origin: Debian Label: Debian Suite: unstable Codename: sid Date: Sat, 14 May 2011 08:20:50 UTC Valid-Until: Sat, 21 May 2011 08:20:50 UTC Architectures: alpha amd64 armel hppa hurd-i386 i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 sparc Components: main contrib non-free Description: Debian x.y Unstable - Not Released MD5Sum: bdc8fa4b3f5e4a715dd0d56d176fc789 18876880 Contents-alpha.gz 9469a03c94b85e010d116aeeab9614c0 19441880 Contents-amd64.gz 3d68e206d7faa3aded660dc0996054fe 19203165 Contents-armel.gz ...
顶层文件 “Release” 的完整性,是由叫 secure apt 的加密架构来验证,在 apt-secure(8)中进行描述:
- 加密签名文件 “Release.gpg” 是由顶层授权文件 “Release” 和加密的 Debian 档案库公钥创建;
- 公开的 Debian 档案库公钥能够通过安装 debian-archive-keyring 软件包来安装到本地;
- secure APT 系统自动验证下载的顶层文件 “Release” 的完整性。加密验证过程用到了”Release.gpg”文件和本地安装的 Debian 档案库公钥;
- 所有 “Packages” 和 “Sources” 文件的完整性是由在顶层 “Release” 文件里的 MD5sum 值来验证。所有软件包文件的完整性由 “Packages” 和 “Sources” 文件里的 MD5sum 值来验证;
- 因加密签名验证比计算 MD5sum 值消耗更多的 CPU,使用 MD5sum 值来验证每一个软件包,使用加密签名来验证顶层的 “Release” 文件,这种方式提供 较好安全性的同时,也有比较好的性能。
如果源列表条目特别指定了 “signed-by” 选项,它下载的顶层”Release”文件使用这个指定的公钥来验证。这在当源列表包含有非 Debian 档案库时有用。
当然,你能够使用 gpg 手工验证”Release” 的完整性,使用 “Release.gpg” 文件和在 ftp-master.debian.org 上公布的 Debian 档案库公钥。
三、档案库层的Release文件
档案库层的“Release”文件将用作 apt_preferences(5) 的规则。归档层次的 “Release” 文件,其全部归档位置在 源列表 中指定,如以下的 “http://deb.debian.org/debian/dists/unstable/main/binary-amd64/Release” 或 “http://deb.debian.org/debian/dists/sid/main/binary-amd64/Release”。
Archive: unstable Origin: Debian Label: Debian Component: main Architecture: amd64
注意:系列名称(“stable”,”testing”,”unstable”, …) 用于 Debian archive ,而代号(“trusty”, “xenial”, “artful”, …) 用于 Ubuntu archive。
对于部分档案库,比如说 experimental 和 bookworm-backports, 它们包含的软件包不会被自动安装,这是因为有额外的行,例如在 “http://deb.debian.org/debian/dists/experimental/main/binary-amd64/Release” 里面有如下额外的一行。
Archive: experimental Origin: Debian Label: Debian NotAutomatic: yes Component: main Architecture: amd64
普通的档案库没有 “NotAutomatic: yes”, 默认的 Pin-Priority 值是 500, 而对于有 “NotAutomatic: yes”的特殊档案库, 默认的 Pin-Priority 值是 1。
四、获取元数据
当使用 APT 工具时,如 aptitude, apt-get, synaptic, apt-file, auto-apt,我们需要更新包含 Debian 档案库信息元数据的本地拷贝。这些本地拷贝的文件名称,和在 源列表文件里面的 distribution, area, architecture 相应名称一致。
- “/var/lib/apt/lists/deb.debian.org_debian_dists_distribution_Release”
- “/var/lib/apt/lists/deb.debian.org_debian_dists_distribution_Release.gpg”
- “/var/lib/apt/lists/deb.debian.org_debian_dists_distribution_area_binary-architecture_Packages”
- “/var/lib/apt/lists/deb.debian.org_debian_dists_distribution_area_source_Sources”
- “/var/cache/apt/apt-file/deb.debian.org_debian_dists_distribution_Contents-architecture.gz” (apt-file)
前 4 种类型的文件是所有相关的 APT 命令共享的,并且可以通过 “apt-get update” 或 “aptitude update” 在命令行中进行更新。如果在源列表中有相应的 “deb” 行,则 “软件包” 元数据会进行更新。如果在 源列表中有相应的 “deb-src” 行,则 “源代码” 元数据会进行更新。
“Packages” 和 “Sources” 的元数据文件包含有“Filename:”字段,指向二进制和源代码包文件的位置。目前,这些软件包都统一放在”pool/”目录树下,这样可以改善跨版本发布的传输。
“软件包”元数据的本地副本可以使用 aptitude 来进行交互式的搜索。专门的搜索命令 grep-dctrl(1) 可以搜索“软件包”和“源代码”元数据的本地副本。
“Contents-architecture”元数据的本地拷贝,能够被”apt-file update”更新,它的位置和其它 4 个不同。参见 apt-file(1). (auto-apt 的 “Contents-architecture.gz”文件的本地拷贝默认也使用不同的位置。)
五、APT软件包状态
除了远程获取元数据,lenny 之后的 APT 工具还会将它在本地产生的安装状态信息保存在 “/var/lib/apt/extended_states” 中,APT 会使用它们来追踪自动安装的所有软件包。
六、aptitude软件包状态
除了远程获取元数据,aptitude 命令还会将它在本地产生的安装状态信息保存在 “/var/lib/aptitude/pkgstates” 中,这些信息只能被 aptitude 使用。
七、软件包本地副本
所有通过 APT 机制远程获取的软件包都被保存在 “/var/cache/apt/archives” 中,直到它们被清除。
aptitude 的这个缓存文件清理策略,能够在”Options” → “Preferences”下设置,也可以通过它的菜单,”Actions”下的”Clean package cache” 或 “Clean obsolete files” 来执行强制清理。
八、Debian软件包文件名称
Debian 软件包文件有特定的名称结构。
Debian 软件包的名称结构:
软件包类型 | 名称结构 |
---|---|
二进制软件包(亦称 deb ) |
package-name_upstream-version-debian.revision_architecture.deb |
用于 debian-installer 的二进制软件包(亦称 udeb ) |
package-name_upstream-version-debian.revision_architecture.udeb |
源代码软件包(上游源代码) | package-name_upstream-version-debian.revision.orig.tar.gz |
1.0 源代码软件包(Debian 改变) |
package-name_upstream-version-debian.revision.diff.gz |
3.0 (quilt 补丁管理工具) 源代码软件包(Debian 改变) |
package-name_upstream-version-debian.revision.debian.tar.gz |
源代码软件包(说明) | package-name_upstream-version-debian.revision.dsc |
软件包名称中每一个组件可以使用的字符:
名称组件 | 可用的字符(正则表达式) | 存在状态 |
---|---|---|
package-name |
[a-z0-9][-a-z0-9.+]+ |
必需 |
epoch: |
[0-9]+: |
可选 |
upstream-version |
[-a-zA-Z0-9.+:]+ |
必需 |
debian.revision |
[a-zA-Z0-9.+~]+ |
可选 |
可以用 dpkg(1)提供的命令检查软件包版本, 例如., “dpkg –compare-versions 7.0 gt 7.~pre1 ; echo $?” .
debian-installer (d-i) 使用 udeb 作为它的二进制软件包的文件扩展名,而非普通的 deb。一个 udeb 软件包是从 deb 软件包中剥离了一些不必要的内容(例如文档),从而节省空间同时也放宽软件包政策的要求。deb 和 udeb 软件包会共享相同的软件包结构。“u” 表示微小。
九、dpkg命令
dpkg(1) 是 Debian 软件包管理中最底层的工具。它非常强大,必须小心使用。
当安装名为 “package_name” 的软件包时,dpkg 会按照下列的顺序处理它。
1、解包 deb 文件(等同于 “ar -x”)
2、使用 debconf(1) 执行 “package_name.preinst”
3、将软件包安装到系统中(等同于 “tar -x”)
4、使用 debconf(1) 执行 “package_name.postinst”
debconf 系统提供带有 I18N 和 L10N (第 8 章 国际化和本地化)支持的标准化用户交互。
dpkg 创建的重要文件:
文件 | 内容说明 |
---|---|
/var/lib/dpkg/info/package_name.conffiles |
列出配置文件。(使用者可修改的) |
/var/lib/dpkg/info/package_name.list |
列出软件包安装的所有文件和目录 |
/var/lib/dpkg/info/package_name.md5sums |
列出软件包安装的文件的 MD5 哈希值 |
/var/lib/dpkg/info/package_name.preinst |
软件包安装之前运行的软件包脚本 |
/var/lib/dpkg/info/package_name.postinst |
软件包安装之后运行的软件包脚本 |
/var/lib/dpkg/info/package_name.prerm |
软件包移除之前运行的软件包脚本 |
/var/lib/dpkg/info/package_name.postrm |
软件包移除之后运行的软件包脚本 |
/var/lib/dpkg/info/package_name.config |
用于 debconf 系统的软件包脚本 |
/var/lib/dpkg/alternatives/package_name |
update-alternatives 命令使用的替代信息 |
/var/lib/dpkg/available |
所有软件包的可用性信息 |
/var/lib/dpkg/diversions |
dpkg (1) 使用的文件移动信息,由 dpkg-divert (8) 设置 |
/var/lib/dpkg/statoverride |
dpkg (1) 使用的文件状态改变信息,由 dpkg-statoverride (8) 设置 |
/var/lib/dpkg/status |
所有软件包的状态信息 |
/var/lib/dpkg/status-old |
“var/lib/dpkg/status ” 文件的第一代备份 |
/var/backups/dpkg.status* |
第二代备份,以及“var/lib/dpkg/status ”文件更旧的备份 |
“status” 文件也被例如 dpkg(1)、“dselect update” 和 “apt-get -u dselect-upgrade” 等工具使用。
专门的搜索命令 grep-dctrl(1) 可以搜索 “status” 和 “available” 元数据的本地副本。在debian 安装器环境下, udpkg 命令用于打开udeb 软件包,udpkg 命令是 dpkg 命令的一个精简版本.
十、update-alternatives命令
Debian 系统使用 update-alternatives(1) 让用户可以不受干扰地安装多种重叠的程序。例如,如果同时安装了 vim 和 nvi 软件包,你可以使 vi 命令选择运行 vim。
$ ls -l $(type -p vi) lrwxrwxrwx 1 root root 20 2007-03-24 19:05 /usr/bin/vi -> /etc/alternatives/vi $ sudo update-alternatives --display vi ... $ sudo update-alternatives --config vi Selection Command ---------------------------------------------- 1 /usr/bin/vim *+ 2 /usr/bin/nvi Enter to keep the default[*], or type selection number: 1
Debian 选择系统在 “/etc/alternatives/” 目录里通过符号链接来维持它的选择。选择进程使用”/var/lib/dpkg/alternatives/”目录里面的相应文件。
十一、dpkg-statoverride命令
当安装一个软件包时,由 dpkg-statoverride(8) 命令提供的 状态修改,是告诉dpkg(1) 对 文件 使用不同的属主或权限的一个方法。如果使用了 “–update” 选项,并且文件存在,则该文件会被立即设置为新的属主和模式。
注意:
- 系统管理员使用 chmod 或 chown 命令直接修改某个软件包文件的属主或权限,在下次软件包升级时,将会被重置;
- 在此使用了文件 一词,但事实上也可用于dpkg 所处理的任何文件系统对象,包括目录,设备等。
十二、dpkg-divert命令
dpkg-divert(8) 命令提供的文件转移功能,是强制 dpkg(1) 不将文件安装到其默认位置,而是安装到被转移 的位置。dpkg-divert 专用于软件包维护脚本。不建议系统管理员随意使用它。