私はD-Busを使用して互いに通信する複数のバックグラウンドプロセスを実行するDockerイメージを構築しています。私のイメージはUbuntu Bionicに基づいています。システムはすでにDebian 9でデフォルトで実行されています。
コンテナ内でD-Busを動作させるにはどうすればよいですか?インターネット検索でいくつかのアイデアを見つけましたが、インターネット上の質問のほとんどは、コンテナとホストシステム間でDバスを使用することです。一方、コンテナ内で実行されているプロセスだけをリンクするだけです。これまでの最も成功した試みは、X11関連のエントリが欠落しているというエラーメッセージで失敗しました。これは現在X11がまったくインストールされていないためです。
コンテナ内で実行して接続するD-Busサービスの例:
#!/usr/bin/env python
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
import sys
service_name = "com.testservice"
object_path = "/testservice"
interface_name = service_name
class SomeObject(dbus.service.Object):
def __init__(self, bus, object_path):
dbus.service.Object.__init__(self, bus, object_path)
@dbus.service.method(service_name, in_signature='', out_signature='')
def Exit(self):
mainloop.quit()
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
session_bus = dbus.SessionBus()
name = dbus.service.BusName(service_name, session_bus)
object = SomeObject(session_bus, object_path)
mainloop = gobject.MainLoop()
mainloop.run()
現在のサービスを開始しようとすると、次の出力が提供されます。
Traceback (most recent call last):
File "/hostwork/dbus-test.py", line 35, in <module>
session_bus = dbus.SessionBus()
File "/usr/lib/python2.7/dist-packages/dbus/_dbus.py", line 211, in __new__
mainloop=mainloop)
File "/usr/lib/python2.7/dist-packages/dbus/_dbus.py", line 100, in __new__
bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 122, in __new__
bus = cls._new_for_bus(address_or_type, mainloop=mainloop)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
答え1
私は自分で解決策を見つけました。
私はDockerfileにdbusパッケージをインストールしましたが、X11には関係ありません。また、質問で共有したPythonスクリプトの依存関係を含む、私のソフトウェアのすべての依存関係をインストールしました。
私のDockerfileには次の行があります。
COPY start.sh /usr/local/bin
RUN chmod +x /usr/local/bin/start.sh
ENTRYPOINT ["/bin/bash", "/usr/local/bin/start.sh"]
start.shの内容は次のとおりです。
#!/usr/bin/env bash
export DBUS_SESSION_BUS_ADDRESS=`dbus-daemon --fork --config-file=/usr/share/dbus-1/session.conf --print-address`
exec bash
このようにコンテナを実行すると、DBUS_SESSION_BUS_ADDRESS が適切に設定されたシェルが提供されます。バックグラウンドでテストスクリプトを実行し、次のように話すことができます。
dbus-send --print-reply --session --dest=com.testservice /testservice com.testservice.Exit
殺す。