web-dev-qa-db-ja.com

関連するサービスを開始せずにパッケージをインストールするにはどうすればよいですか?

ご存知のとおり、デフォルトでは、DebianまたはUbuntuベースのシステムにパッケージをインストールするときに、パッケージにサービスが含まれている場合、パッケージをインストールすると、そのサービスが有効になり、自動的に開始されます。

これは私にとって問題です。

LXCコンテナーを構築するためのテンプレートを管理する必要があることに気づきました。いくつかのコンテナがあり、それぞれがDebianまたはUbuntuのリリースに対応しています。 (Red Hatベースのコンテナーもありますが、ここでは関係ありません。)

/var/lib/libvirt/filesystems/debian6_template
/var/lib/libvirt/filesystems/debian7_template
/var/lib/libvirt/filesystems/ubuntu1004_template
/var/lib/libvirt/filesystems/ubuntu1204_template

テンプレートにパッケージがないか、他の変更が必要な場合があるので、テンプレートにchrootしてパッケージをインストールします。残念ながら、それを行うと、パッケージのサービスのいくつかのコピーが実行されてしまいます!

例として、テンプレートにsyslogデーモンがないことがわかったので、それをインストールしました。

for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
    chroot $template apt-get install rsyslog
done

そして、すぐにrsyslogの4つのコピーが実行されてしまいました。 exim4の2つのコピーは言うまでもありません。おっとっと!


Chrootで実行しているときにサービスを開始することは想定されていませんが、ここでは明らかに発生していません。

実際にサービスを開始するさまざまなコマンド(start-stop-daemoninitctlなど)を一時的に置き換えるために、実行可能な可能性がある1つの 厄介なハック 呼び出しが必要ですする。他に選択肢がないなら...

ここでの理想的な解決策は、Debianベースのシステムがこのがらくたをやめることをやめることですが、失敗した場合、おそらくapt-getのあいまいな、または文書化されていないコマンドラインオプションです。

はっきりしない場合は、可能であれば、テンプレートの管理の外側の管理に関連するものはすべて残しておきたいと思います。

13
Michael Hampton

Debianの場合、これは policy-rc.d で実行できます。これが 1つの説明 です。

パッケージのメンテナースクリプトは、invoke-rc.d、update-rc.d、およびLSB initスクリプトヘッダーを介してinitシステムとのみインターフェースすることになっています... invoke-rc.dは、アクションを実行する前に、 /usr/sbin/policy-rc.dは実行可能で、それぞれのサービス名と現在のランレベル番号をコマンドラインで呼び出し、終了コードに従って動作します。たとえば、101の戻り値は、計画されたアクションが実行されないようにします。これには、パッケージのインストール時のサービスの自動開始およびパッケージの削除時のサービスの停止が含まれ、パッケージのアップグレード中のstop-upgrade-restartの儀式を減らして、古いバージョンのサービスを実行したままにする可能性があるアップグレードを実行するだけにします。

サービスを開始したくないので、policy-rc.dスクリプトは簡単にできます

#!/bin/sh
exit 101

これは、pbuilderやDockerの mkimage-debootstrap などのツールで使用される手法です。

残念ながら、この手法 buntuでは機能しません chroots。 upstart initシステムと統合するパッケージは、インストール時にinvoke-rc.dの代わりに/ usr/sbin/initctlを呼び出し、initctlはpolicy-rc.dを調べません。 pstartの作者によると 回避策は、/ sbin/initctlをchrootの/ bin/trueへのシンボリックリンクに置き換えることです。これはmkimage-debootstrapでも確認できます。

dpkg-divert --local --rename --add /sbin/initctl
ln -sf /bin/true sbin/initctl
23
sciurus

できるよ:

export RUNLEVEL=1
for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
    chroot $template apt-get install rsyslog
done
exit

私はchrootでテストしていませんが、動作するはずです。最初はRUNLEVEL環境変数を設定するため、apt-get 開始されない任意のサービスによって開始されたプロセスは、システムがシングルモードで実行されていると「考える」ためです。環境は将来のコマンドに影響を与える可能性がある方法で変更されるため、変更された環境が不要になったときにシェルを終了する必要があります。これはexitコマンドによって実行されます最後に。ありますあるかもしれませんシングルモードで正しくインストールされない(まれな)パッケージがあります(ただし、これはほとんどの場合問題にはなりません)。

4
DavisNT