Debianベースで破壊されたパッケージ管理を復旧する初期手順

LUGHでL4Gでパッケージ管理を使うのに、既存サイトの情報をもとにやるとうまくいかないという質問があった。
ちょっとイラっとしたので、i386でパッケージ管理が壊されている時の、dpkgやaptのリカバリ方法をまとめておく。
ファイルシステムについては、LANDISK独特の部分は考慮していない。armへの読み替えを含めて、そのへんはやる人が考えることだわ。


debootstrapを使ってsarge用のbaseシステムを作ります。

# mkdir deboot
# debootstrap --arch i386 sarge ./deboot http://archive.debian.org/debian-archive/debian/
# chroot ./deboot
# COLUMNS=150 dpkg -l | awk 'NR>5 {print $2}' | wc
    122     122    1181

というわけで、ミニマム構成では122パッケージが入っています。
この中には、依存関係も弱くて、不要なパッケージもあり、削ると100くらいにはなります。

# dpkg -L dpkg

とすると、dpkgパッケージに含まれるファイルがリストされます。
LANDISKのファームに近い状態を再現するために、これらを削除します。

rm -r /usr/share/doc/dpkg
rm -r /usr/share/locale/*
rm -r /usr/share/dpkg
rm -r /usr/share/man/
rm -r /usr/lib/dpkg
rm /usr/bin/dpkg-split
rm /usr/bin/dpkg-query
rm /usr/bin/dpkg
rm /usr/bin/dpkg-deb
rm /usr/bin/md5sum
rm /usr/sbin/update-alternatives
rm /usr/sbin/install-info
rm /usr/sbin/dpkg-divert
rm /usr/sbin/dpkg-statoverride
rm /usr/sbin/cleanup-info
rm /sbin/start-stop-daemon
rm -r /var/lib/dpkg
rm -r /etc/alternatives
rm -r /etc/dpkg

# dpkg       
bash: /usr/bin/dpkg: No such file or directory


これで、パッケージ管理は完全に崩壊しました。


dpkgパッケージをダウンロードして展開します。

# cd /home/
# wget http://archive.debian.org/debian-archive/debian/pool/main/d/dpkg/dpkg_1.10.28_i386.deb
# ar -x dpkg_1.10.28_i386.deb 


あ、ar入れておくの忘れた...
こういう時は、無理せず他で展開したdata.tar.gzをもってくることにします。
アーカイブを/から展開して上書きします。

# tar zxvf data.tar.gz -C /


dpkgコマンドが使えるようになっているのを確認します。

# dpkg --version
Debian GNU/Linux `dpkg' package management program version 1.10.28 (i386).


まだパッケージ管理は開始されていないので、この時点ではstatusは空ですから、作っておきます。

# touch /var/lib/dpkg/status


パッケージをインストールしてみましょう。

# dpkg -i dpkg_1.10.28_i386.deb 
Selecting previously deselected package dpkg.
dpkg: regarding dpkg_1.10.28_i386.deb containing dpkg, pre-dependency problem:
 dpkg pre-depends on dselect
  dselect is not installed.
dpkg: error processing dpkg_1.10.28_i386.deb (--install):
 pre-dependency problem - not installing dpkg
Errors were encountered while processing:
 dpkg_1.10.28_i386.deb

当たり前ですが、依存関係が一切満たされていないので、エラーになります。
dpkgは、dselectが依存関係に指定されているので、まずこれがエラーになって出てきますが、本来は依存しているものは芋づるでたくさんあります。
このあたりは、インストーラーでインストールすることが前提になっていて、依存関係に明示されていないものがたまにありますので、この状態での依存関係エラーは、完全に信頼できるわけではありません。


この時、statusの状況はこんな風になっています。

# cat /var/lib/dpkg/status
Package: dpkg
Status: install ok not-installed
Priority: required
Section: base


依存関係などのエラーを全て無視してインストールを強制します。

# dpkg --force-all -i dpkg_1.10.28_i386.deb 
dpkg: regarding dpkg_1.10.28_i386.deb containing dpkg, pre-dependency problem:
 dpkg pre-depends on dselect
  dselect is not installed.
dpkg: warning - ignoring pre-dependency problem !
dpkg: regarding dpkg_1.10.28_i386.deb containing dpkg, pre-dependency problem:
 dpkg pre-depends on libc6 (>= 2.3.2.ds1-21)
dpkg: warning - ignoring pre-dependency problem !
(Reading database ... 0 files and directories currently installed.)
Unpacking dpkg (from dpkg_1.10.28_i386.deb) ...
dpkg: dpkg: dependency problems, but configuring anyway as you request:
 dpkg depends on dselect; however:
  Package dselect is not installed.
 dpkg depends on libc6 (>= 2.3.2.ds1-21); however:
  Package libc6 is not installed.
Setting up dpkg (1.10.28) ...


statusはこのようになりました。

# cat /var/lib/dpkg/status
Package: dpkg
Essential: yes
Status: install ok installed
Priority: required
Section: base
Installed-Size: 5636
Origin: debian
Maintainer: Dpkg Development <debian-dpkg@lists.debian.org>
Bugs: debbugs://bugs.debian.org
Architecture: i386
Version: 1.10.28
Replaces: dpkg-doc-ja, dpkg-static, manpages-de (<= 0.4-3)
Pre-Depends: dselect, libc6 (>= 2.3.2.ds1-21)
Conflicts: sysvinit (<< 2.82-1), dpkg-iasearch (<< 0.11), dpkg-static, dpkg-dev (<< 1.10)
Conffiles:
 /etc/dpkg/origins/debian 24926c0576edec3e316fd9f6072b8118
 /etc/alternatives/README 69c4ba7f08363e998e0f2e244a04f881
Description: Package maintenance system for Debian
 This package contains the programs which handle the installation and
 removal of packages on your system.
 .
 The primary interface for the dpkg suite is the `dselect' program;
 a more low-level and less user-friendly interface is available in
 the form of the `dpkg' command.
 .
 In order to unpack and build Debian source packages you will need to
 install the developers' package `dpkg-dev' as well as this one.


パッケージは、インストールされ、管理された状態にあります。
dpkgコマンドでインストールされたパッケージの状況を確認します。

# dpkg -l
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name           Version        Description
+++-==============-==============-============================================
ii  dpkg           1.10.28        Package maintenance system for Debian

依存関係をとりあえず無視して入れていますので、データベースの整合性は取れていない状態です。これを完全にもとにもどすのはかなり手のかかる作業ですが、通常の作業に問題がない程度までには復旧しておくといいでしょう。


dpkgのPre-Dependsには、dselect, libc6 (>= 2.3.2.ds1-21)が指定されているので、これらをインストールします。

# wget http://archive.debian.org/debian-archive/debian/pool/main/g/glibc/libc6_2.3.2.ds1-22sarge6_i386.deb
# dpkg --force-all -i libc6_2.3.2.ds1-22sarge6_i386.deb 

# wget http://archive.debian.org/debian-archive/debian/pool/main/d/dpkg/dselect_1.10.28_i386.deb
# dpkg --force-all -i dselect_1.10.28_i386.deb 


statusファイルを見ると、それぞれの項目が追加されています。
追加された libc6とdselectのDepends項目を見ます。

Depends: libdb1-compat
Depends: libc6 (>= 2.3.2.ds1-21), libgcc1 (>= 1:3.4.1-3), libncurses5 (>= 5.4-1), libstdc++5 (>= 1:3.3.4-1)

libc6は入れてありますしバージョン指定も問題なさそうです。
それ以外の、4つのパッケージは入っていないので、完全性が損なわれています。これらも取得して追加します。
poolを見ても最新版が判断できないときは、http://www.debian.org/distrib/packages で検索するのが便利ですが、これはSargeではもう使えないですね(^^;。
そういう時には、Packagesを展開して探すのですが、めんどくさいのでaptにまかせたほうがいいかもしれません。
aptをインストールします。

# wget http://archive.debian.org/debian-archive/debian/pool/main/a/apt/apt_0.5.28.6_i386.deb
# dpkg --force-all -i apt_0.5.28.6_i386.deb  

リポジトリ取得先の設定は必要があればやります。

# vi /etc/apt/sources.list 
deb http://archive.debian.org/debian-archive/debian sarge main


リポジトリデータベースを更新し、依存関係の復元を行います。

# apt-get update
# apt-get -f install
Reading Package Lists... Done
Building Dependency Tree... Done
Correcting dependencies... Done
The following extra packages will be installed:
  gcc-3.3-base libdb1-compat libgcc1 libncurses5 libstdc++5
The following NEW packages will be installed:
  gcc-3.3-base libdb1-compat libgcc1 libncurses5 libstdc++5
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 0B/830kB of archives.
After unpacking 1794kB of additional disk space will be used.
Do you want to continue? [Y/n] 

管理されているものについては、依存関係の整合性が取れる状態に復元されました。

# dpkg -l
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name           Version        Description
+++-==============-==============-============================================
ii  apt            0.5.28.6       Advanced front-end for dpkg
ii  dpkg           1.10.28        Package maintenance system for Debian
ii  dselect        1.10.28        a user tool to manage Debian packages
ii  gcc-3.3-base   3.3.5-13       The GNU Compiler Collection (base package)
ii  libc6          2.3.2.ds1-22sa GNU C Library: Shared libraries and Timezone
ii  libdb1-compat  2.1.3-7        The Berkeley database routines [glibc 2.0/2.
ii  libgcc1        3.4.3-13sarge1 GCC support library
ii  libncurses5    5.4-4          Shared libraries for terminal handling
ii  libstdc++5     3.3.5-13       The GNU Standard C++ Library v3


こんな感じですが、これは、一度インストールされたDebianが部分的に破壊された状況からのリカバリを想定していますので、暗黙の前提条件については露出してきていません。スクラッチでやるときには、これ以上にたいへんです。まぁ、普通はそんな事はせずに、debootstrapしてchrootかpivot_rootしますが。

あとは、この手順で進めていくと、LANDISK関係のデフォルトファイルを上書き更新しますので、どこかの段階でWebUIからの管理システムが動作しなくなると思います。一見動作しているようでも、整合性はすでに取れていないので、意図しない動作結果になる可能性がありますので、ご注意を。