python dbus

python - Conectando a dbus sobre tcp



(3)

Escribí un sencillo programa en Python para reproducir y pausar el reproductor de música Banshee. Mientras funciona en mi propia máquina, tengo problemas para hacerlo en una computadora remota, conectada al mismo enrutador (LAN). Edité el session.conf de la máquina remota, para agregar esta línea:

<listen>tcp:host=localhost,port=12434</listen>

Y aquí está mi programa:

import dbus bus_obj=dbus.bus.BusConnection("tcp:host=localhost,port=12434") proxy_object=bus_obj.get_object(''org.bansheeproject.Banshee'', ''/org/bansheeproject/Banshee/PlayerEngine'') playerengine_iface=dbus.Interface(proxy_object, dbus_interface=''org.bansheeproject.Banshee.PlayerEngine'') var=0 while (var!="3"): var=raw_input("/nPress/n1 to play/n2 to pause/n3 to exit/n") if var=="1": print "playing..." playerengine_iface.Play() elif var=="2": print "pausing" playerengine_iface.Pause()

Esto es lo que obtengo cuando trato de ejecutarlo

Traceback (most recent call last): File "dbus3.py", line 4, in <module> bus_obj=dbus.bus.BusConnection("tcp:host=localhost,port=12434") File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 125, in __new__ bus = cls._new_for_bus(address_or_type, mainloop=mainloop) dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoServer: Failed to connect to socket "localhost:12434" Connection refused

¿Qué estoy haciendo mal aquí? debo editar /usr/lib/python2.7/dist-packages/dbus/bus.py

ACTUALIZAR:

ok, aqui esta el trato cuando agrego

<listen>tcp:host=192.168.1.7,port=12434</listen>

a /etc/dbus-1/session.conf, luego reinicie, con la esperanza de que comience a escuchar en el reinicio, nunca arranca. Se atasca en la pantalla de carga y, ocasionalmente, parpadea una pantalla negra con el siguiente texto:

Pulseaudio Configured For Per-user Sessions Saned Disabled;edit/etc/default/saned

entonces, cuando voy a ctrl + alt + f1, cambie session.conf a su estado original y reinicie, se inicia correctamente.

¿De qué se trata todo eso? ¿Cómo puedo hacer que el demonio dbus escuche las conexiones tcp, sin encontrar problemas?


Hace poco necesité configurar esto y descubrí que el truco es: el orden es importante para los elementos <listen> en session.conf . Debería asegurarse de que el elemento TCP aparezca primero. Extraño, lo sé, pero cierto, al menos para mi caso. (Veo exactamente el mismo comportamiento de la pantalla en negro si invierto el orden y pongo el elemento <listen> zócalo UNIX primero.)

Además, es necesario anteponer la etiqueta TCP <listen> , pero no es suficiente. Para hacer que las conexiones remotas de D-Bus a través de TCP funcionen, debe hacer tres cosas:

  1. Agregue una etiqueta <listen> encima de UNIX, similar a esto:

    <listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen> <listen>unix:tmpdir=/tmp</listen>

  2. Agregar una línea (justo debajo de las etiquetas <listen> está bien) que dice:

    <auth>ANONYMOUS</auth>

  3. Agrega otra línea debajo de estas que dice:

    <allow_anonymous/>

La etiqueta <auth> debe agregarse además de cualquier otra etiqueta <auth> que pueda estar contenida en su session.conf . En resumen, su session.conf debe contener un fragmento de código que se parece a esto:

<listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen> <listen>unix:tmpdir=/tmp</listen> <auth>ANONYMOUS</auth> <allow_anonymous/>

Después de hacer estas tres cosas, debería poder conectarse al bus de sesión de forma remota. Así es como se ve al especificar una conexión remota en D-Feet :

Tenga en cuenta que, si también desea conectarse al bus del sistema, necesita hacer cambios similares a /etc/dbus-1/system.conf , pero especificar un puerto TCP diferente , por ejemplo 55557. (Por extraño que parezca, el elemento El orden parece no importar en este caso.

El único comportamiento extraño que he notado en esta configuración es que la ejecución de aplicaciones de escritorio con sudo (por ejemplo, sudo gvim ) tiende a generar errores o falla completamente diciendo "No hay ningún demonio D-BUS en ejecución". Pero esto es algo que necesito hacer tan raramente que apenas importa.

Si desea enviar a una máquina remota mediante dbus-send , necesita configurar DBUS_SESSION_BUS_ADDRESS consecuencia, por ejemplo, a algo como:

export DBUS_SESSION_BUS_ADDRESS=tcp:host=localhost,bind=*,port=55556,family=ipv4

Esto funciona incluso si el bus al que desea enviar es en realidad el bus del sistema de la máquina remota, siempre que la configuración coincida con la etiqueta TCP <listen> en /etc/dbus-1/system.conf en el destino. (Gracias a Martin Vidner por este consejo. Hasta que encontré su respuesta a esta pregunta , no creía que dbus-send compatible con la operación remota).

ACTUALIZACIÓN : Si está usando systemd (y desea acceder al bus del sistema), es posible que también necesite agregar una línea que diga ListenStream=55557 a /lib/systemd/system/dbus.socket , de esta manera:

[Socket] ListenStream=/var/run/dbus/system_bus_socket ListenStream=55557 # <-- Add this line

ACTUALIZACIÓN2 : Gracias a @altagir por señalar que las versiones recientes de D-Bus habilitarán la mediación de AppArmor en los sistemas donde esté disponible, por lo que es posible que también deba agregar <apparmor mode="disabled"/> a session.conf / system.conf para que estas instrucciones funcionen.


Otra gracias @Shorin, y otra FYI, tuve que hacer algo como esto para hacer que mi trabajo funcione:

<listen>tcp:host=localhost,bind=0.0.0.0,port=55884</listen>

Tenga en cuenta que el bind=0.0.0.0 - el bind=* no funcionó para mí, y dejé fuera la parte family=ipv4 . Estoy en Ubuntu 12.04. Usé netstat en la máquina remota para confirmar que dbus estaba escuchando en el puerto y telnet desde el local para confirmar que el puerto estaba abierto.

netstat -plntu | grep 55884 tcp 0 0 0.0.0.0:55884 0.0.0.0:* LISTEN 707/dbus-daemon

Tienes que ver algo como 0 0.0.0.0:55884 y no algo como 0 127.0.0.1:55884 .


desde dbus 1.6.12 (por ejemplo, kubuntu 13.10), su conexión también será rechazada a menos que agregue a su archivo de configuración de dbus (ya sea / etc / dbus-1 / mybus .conf o la interfaz que requiera acceso remoto, es decir, system.d / my. interfaz.conf )

<apparmor mode="disabled"/>

ACTUALIZACIÓN: después de esforzarse por crear un perfil de apparmor que permita que el servicio se conecte con el dbus-daemon personalizado, parece que la conexión siempre se rechaza debido a un error en DBUS ... Así que por ahora DEBEMOS deshabilitar apparmor siempre que use tcp =. .. Corrección de errores dirigida a 14.04

Abrí un error en bugs.launchpad.net siguiendo la discusión here con Tyler Hicks:

El código de mediación de AppArmor solo tiene la capacidad de verificar las etiquetas de pares en los sockets de dominio UNIX. Es muy probable que vea un error al obtener la etiqueta y luego rechazar la conexión.

Nota: el indicador de deshabilitación no es reconocido por dbus <1.6.12, por lo que necesita empaquetar diferentes versiones de mydaemon.conf dependiendo de systen), de lo contrario, dbus-daemon fallará al iniciarse si no hay un armador ... lo usé por ahora en mis CMakeLists.txt:

IF(EXISTS "/usr/sbin/apparmor_status") install(FILES dbus_daemon-apparmordisabled.conf RENAME dbus_daemon.conf DESTINATION /etc/dbus-1/ ) ELSE (EXISTS "/usr/sbin/apparmor_status") install(FILES dbus_daemon.conf DESTINATION /etc/dbus-1/ ) ENDIF(EXISTS "/usr/sbin/apparmor_status")