저는 D-Bus를 사용하여 서로 통신하는 여러 백그라운드 프로세스를 실행하는 Docker 이미지를 구축하고 있습니다. 내 이미지는 Ubuntu Bionic을 기반으로 합니다. 시스템은 이미 Debian 9에서 기본적으로 실행됩니다.
컨테이너 내부에서 D-Bus가 작동하도록 하려면 어떻게 해야 합니까? 인터넷 검색을 통해 몇 가지 아이디어를 찾았지만 인터넷에 있는 대부분의 질문은 컨테이너와 호스트 시스템 사이에 D-Bus를 사용하는 것에 관한 것입니다. 반면 컨테이너 내부에서 실행되는 프로세스만 연결하면 됩니다. 지금까지 가장 성공적인 시도는 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
죽여.