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


13

ご存じのとおり、デフォルトでは、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デーモンがないことがわかったため、syslogデーモンをインストールしました。

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

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


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

潜在的に実行可能な厄介なハックの 1つは、start-stop-daemonやなどの実際にサービスを開始するさまざまなコマンドを一時的に置き換えるinitctlことです。他に選択肢がない場合は...

ここでの理想的な解決策は、Debianベースのシステムがこのがらくたの実行を停止することですが、それに失敗するのは、おそらくapt-get

明確でない場合は、可能であれば、テンプレートの外部でのテンプレートの管理に関連するものは何でも保持したいと思います。

回答:


23

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などのツールで使用される手法です

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

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

これはかなりきれいに見えますが、テンプレートからコンテナを作成する前に削除する必要があります。
マイケルハンプトン

1
これをありがとう。Dockerのmkimage-debootstrapスクリプトはほとんどこの問題を解決したように見えるので、私は単にDockerのmkimage-debootstrapスクリプトを取り去る必要があるかもしれません。
マイケルハンプトン

4

できるよ:

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コマンドで行います。シングルモードでは適切にインストールされない(まれな?)パッケージがあるかもしれません(ただし、ほとんどの場合、これは問題になりません)。


export RUNLEVEL=1、ここで重要なのは?何が起こるのでしょうか?
マイケルハンプトン

@MichaelHampton RUNLEVEL環境変数が現在の実行レベルを提供すると信じています。この例では、彼は単にそれを上書きしているだけなので、どのアプリケーションでも1で実行されていると見なされます。
WinkyWolly 14

元の回答に説明を追加しました。基本的にこれは@WinkyWollyが言ったことです。
デイビスNT 14

残念ながらrsyslog、この方法でインストールしようとすると完全に爆発する「まれな」パッケージの1つでした。しかし、これはまだ有用かもしれませんので、あなたは賛成票を維持することができます:)
マイケルハンプトン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.