生成完整包管理状态的记录

生成完整包管理状态的记录

我即将进行一些系统更改,我想记录当前良好的系统状态。有没有方便的方法来记录这些?我想跟踪以下信息

  • 当前安装的软件包及其版本
  • 哪些软件包固定在哪个版本
  • /etc/apt/sources.list它们是从哪个源安装的
  • 它们是直接安装的还是作为不同包的依赖项自动安装的
  • “未知的未知数”:即我不知道应该跟踪的东西,但在试图弄清楚为什么某些事情不起作用时可能很重要

简而言之,我希望尽可能多地保留 aptitude 数据库。最好的方法是什么?如果生成的记录易于阅读,那就太好了,尽管这并非必不可少。如果可以通过 SCM 工具轻松进行版本控制,那就更好了git

有一个超级用户问题这部分回答了这个问题,但它只提供了当前安装的软件包的列表。

更新

根据@ptman 的回答,我确定以下内容:

  • @ptman 的最后一个建议是,备份/etc/apt/var/lib/...,将完成部分工作aptitude-create-state-bundle
  • apt-cache policy似乎只是提供优先级信息,所以我需要更全面的东西;aptitude-create-state-bundle似乎是票。但是,如果能有某种方法来分析包以获取诸如 提供的信息,那将很有用apt-cache policy

我已经启动了一个 git repo(使用setgitperms.perlhook util),其中包含提取的内容aptitude-create-state-bundle,例如

sudo aptitude-create-state-bundle --force-gzip /dev/stdout | sudo tar xzv

在运行之前创建目录内容git add . && git add -u .。由于要压缩和解压缩所有内容,因此速度有点慢,我可能会将其更改为仅使用选项获取文件列表--print-inputs,然后将这些文件复制或硬链接到 git 存储库中。

这种方法效果很好:运行后git gc --aggressive,我最终得到一个 .git 目录,其大小是原始 tarball 的 2/3。这是在第二次提交后完成的,该提交记录了安装后的状态puppet及其依赖项。只需查看 diff 即可轻松查看更改的内容,这是一种在执行操作时找出aptitude实际操作的好方法。我认为有某种方法可以在 apt 本身中放置钩子(类似于 etckeeper),因此我最终可能会使用该功能在每次 apt 操作时更新 repo。

一个小问题是,即使启用了 setgitperms 钩子,该系统也不会记录时间戳。因此,我在预提交钩子中添加了第二个命令,以将长目录列表转储到.lsrepo 根目录中的文件中:

find * | xargs -d \\n ls -ld >.ls

我不确定这是否真的有必要,我这样做只是为了以aptitude-run-state-bundle某种相关方式使用时间戳。有人知道这是真的吗?即使这样,这似乎也不太可能是必要的,因为签出文件的时间戳将始终至少与这些文件提交时的原始时间戳一样新。

我将继续这样做,至少直到我有机会弄清楚它的puppet作用是什么以及如何使用它。

更新 2

我一直在使用这个系统,但它似乎变得有点笨重,因为 .git repo 增长得相当快。经过 12 次提交后,.git 目录(使用 压缩后git gc --aggressive)的大小已从初始大小(IIRC)15-20 MB 增长到大约 60 MB。

看起来,大部分文件大小似乎是由于两个大型 (~15MB) 二进制文件之间的差异造成的,我想知道这些文件是否对于保存系统打包状态是必需的。这些文件是:

var/cache/apt/pkgcache.bin
var/cache/apt/srcpkgcache.bin

如果 tarball 中没有这些文件,是否可以使用该 repo 进行恢复aptitude-run-state-bundle?是否可以将当前系统版本添加到 tarball 中,以便可以使用该 tarball aptitude-run-state-bundle(当然,假设当前系统版本没有损坏)?

答案1

查看以下工具:

dpkg --get-selections
aptitude-create-state-bundle
dpkg -l
dpkg -l |tail -n +6 | awk '{ print $2 }' | xargs apt-cache policy

备份/etc/apt/var/lib/{apt,dpkg,aptitude}

答案2

使用木偶。使用该工具,您可以查询系统并列出其当前状态。然后可以使用该列表克隆系统。它就像 buildout,只是服务器不同。

相关内容