Integración de Node-RED: Dar acceso a los puertos USB al contenedor Docker

Voy a reiniciar desde cero para confirmar que tengo los privilegios, porque he eliminado y repuesto tantas órdenes que prefiero volver a intentarlo.
Pero estoy casi seguro de que al principio, tomé la orden que me validaste y, por lo tanto, no hay conexión del Node serial.
Aquí está la orden:

Volveré contigo :wink:

buenas noches @pierre-gilles
Acabo de reinstalar Gladys con el comando anterior (mensaje anterior)
Aquí está el resultado:


Aquí están los permisos de los puertos:

crw-rw---- 1 root dialout 188,  0 Feb 20 18:13 /dev/ttyUSB0
lrwxrwxrwx 1 root root          7 Feb 20 18:13 /dev/tty-usb-arduino-nano -> ttyUSB0
no funciona

pero cuando doy los derechos a « otros » para el puerto USB0, con este comando:

pi@rasp3b:~ $ sudo chmod a+rw /dev/ttyUSB0

el nodo serial se conecta.
Tengo 2 pantallas en mi PC y vi que tan pronto como validé el comando chmod
el nodo serial se conectó inmediatamente y envió su mensaje para decir que el RFLINK está listo

de modo que para mí --privileged \, no da todos los derechos
y como te dije, cuando se desconecta el Rflink, los derechos del puerto USB0 se reinician.

@Psoy acabo de encontrar esto (quizás tú también): https://stackoverflow.com/questions/24225647/docker-a-way-to-give-access-to-a-host-usb-or-serial-device
Hay que bajar hasta The Safe and Proper way of accessing tty devices without *--privileged* mode
Al leer el resto parece interesante, pero no tengo nada para probar en casa, a ver qué tal funciona en tu host.
En resumen, cada vez que vuelves a conectar tu rflink, se ejecuta un script para volver a conectarlo al lugar correcto en tu host.

¡Buenas noches @mutmut!
No he visto lo que has encontrado, he trabajado con Gemini para entender por qué el nodo serial en Node Red no se conecta al puerto USB, la respuesta es « acceso denegado », por lo que he investigado los permisos de los puertos (todo lo que explico más arriba).
He leído lo que me has enviado, pero creo que es un poco ligero para modificar el docker run del que habla. Además, no sé si debo modificar el archivo /etc/udev/rules.d/99-docker-tty.rules, que ya existe en Gladys o si debo adaptarlo o crear uno nuevo?
Efectivamente parece ser una solución. Si dominas el tema, me gustaría que me dieras una plantilla para ayudarme a probarlo, si quieres!

Pero primero, sería necesario que, al abrir Node-Red desde Gladys, se den los accesos del puerto USB0 como mencioné.
:blush:

@Psoy ¿Bajo qué usuario lanzas el contenedor Gladys?

Si quieres que --privileged funcione, el usuario debe ser root.

¡Creo que no es tu caso!

¿Haces bien sudo docker run...?

Efectivamente, no estaba poniendo sudo delante de docker run :worried:.
Por lo tanto, volví a escribir el comando docker run con sudo delante, y repetí la manipulación tres veces para estar seguro, pero incluso con sudo los permisos del puerto USB0 no cambian y se mantienen igual

crw-rw---- 1 root dialout 188,  0 Feb 21 09:59 /dev/ttyUSB0
lrwxrwxrwx 1 root root          7 Feb 21 09:59 /dev/tty-usb-arduino-nano -> ttyUSB0

Solo puedo conectar el « node serial » escribiendo el comando
sudo chmod a+rw /dev/ttyUSB0

Es normal, los permisos del puerto USB0 deben permanecer así.

Los permisos aquí muestran que el usuario « root » es el propietario de este puerto USB, pero si has lanzado tu contenedor como root, deberías ser el propietario del puerto USB.

Ahora, en tu caso, solo has lanzado el contenedor Gladys, y el contenedor Node-RED fue lanzado por Gladys. Tal vez el contenedor Node-RED no se lanzó como root.

¿Puedes verificar qué usuario lanzó el contenedor Gladys y compararlo con el usuario que lanzó el contenedor Node-RED?

(Te dejo que uses Google/IA para encontrar los comandos adecuados para hacerlo :slight_smile: )

¡Sí, así es como se aprende! :wink: :joy:

De lo que acabo de probar, todos los comandos se hacen en el host, no en el docker gladys.
Primero hay que asegurarse de que tu docker Gladys y Node-red estén en funcionamiento.
Luego, para ver si funciona, puedes probar:
docker ps -qf name=node-red
et esto debería devolverte un número/id (el de tu docker node-red).
Si no es así, no continuaremos y puedes ver si los dockers están en funcionamiento con docker ps

Por lo tanto, en el host, puedes crear (con tu editor de archivos favorito):
sudo nano /etc/udev/rules.d/99-docker-tty.rules
Luego copias/pegas:

ACTION=="add", SUBSYSTEM=="tty", RUN+="/usr/local/bin/docker_tty.sh 'added' '%E{DEVNAME}' '%M' '%m'"
ACTION=="remove", SUBSYSTEM=="tty", RUN+="/usr/local/bin/docker_tty.sh 'removed' '%E{DEVNAME}' '%M' '%m'"

Si es nano, haces ctrl+X y Y (o O) y Enter para guardar y salir.
Luego, para aplicar las reglas:

sudo udevadm control --reload

Finalmente, hay que crear el script que montará y desmontará automáticamente el dispositivo en el puerto usb:
sudo nano /usr/local/bin/docker_tty.sh
et pegas:

#!/usr/bin/env bash  
                                                           
echo "Usb event: $1 $2 $3 $4" >> /tmp/docker_tty.log        
if [ ! -z "$(docker ps -qf name=node-red)" ]                                     
then                                                                            
if [ "$1" == "added" ]                                                          
    then                                                                        
        docker exec -u 0 env_dev mknod $2 c $3 $4                               
        docker exec -u 0 env_dev chmod -R 777 $2                                
        echo "Adding $2 to docker" >> /tmp/docker_tty.log                
    else                                                                        
        docker exec -u 0 env_dev rm $2                                          
        echo "Removing $2 from docker" >> /tmp/docker_tty.log            
    fi                                                                          
fi 

Se otorgan los permisos de ejecución a este script:
sudo chmod +x /usr/local/bin/docker_tty.sh
Y ahí puedes ver qué pasa al conectar tu dispositivo usb (especialmente en /tmp/docker_tty.log).

Si nada funciona, hay un comando que hay que pasar, pero no sé exactamente qué hace (tengo mis límites :wink: ):
docker run --device-cgroup-rule='c 188:* rmw' -itd --name my_container ubuntu
Y eso es lo que mi enlace indica hacer en primer lugar. Creo que se lanza una ubuntu con un contenedor que se llamará my_container y se le pasa un argumento. Sin embargo, no sé si hay que lanzar este comando en el docker gladys o en el docker node-red, y sabiendo que el docker node-red se lanzará, no sé si funciona …
En resumen, puede atascarse en este punto.

Dime de todos modos si los primeros tests son concluyentes.

EDIT: después, estaría tentado de decirte que no pases por Gladys para crear/lanza el docker node-red, sino que te crees uno aparte y ahí podrás pasar el comando raro en ese docker.

Buenas noches @pierre-gilles @mutmut
¿Podrían confirmarme que el nombre de la imagen del contenedor de gladys-node-red es nodered/node-red:3.1?

CONTAINER ID   IMAGE                                       COMMAND                  CREATED         STATUS                   PORTS                                       NAMES
702448e6dba6   nodered/node-red:3.1                        "./entrypoint.sh"        5 minutes ago   Up 5 minutes (healthy)   0.0.0.0:1881->1880/tcp, :::1881->1880/tcp   gladys-node-red
e000d717481c   gladysassistant/gladys:node-red-usb-ports   "docker-entrypoint.s…"   7 minutes ago   Up 7 minutes                                                         gladys
c12621b8b474   containrrr/watchtower                       "/watchtower --clean…"   4 weeks ago     Up 9 minutes (healthy)   8080/tcp                                    watchtower

Primero, debo inicializar los permisos (con CHMOD) porque al iniciar no son correctos
Acabo de probar varias veces desconectando y volviendo a conectar el rflink, pero no funciona, no se reconecta solo.
Te pongo los logs de /tmp/docker_tty.log

pi@rasp3b:/tmp $ sudo nano docker_tty.log
  GNU nano 5.4                                                            docker_tty.log
Usb event: added /dev/tty14 4 14
Usb event: added /dev/tty15 4 15
Usb event: added /dev/tty16 4 16
Usb event: added /dev/tty17 4 17
Usb event: added /dev/tty18 4 18
Usb event: added /dev/tty20 4 20
Usb event: added /dev/tty2 4 2
Usb event: added /dev/tty22 4 22
Usb event: added /dev/tty24 4 24
Usb event: added /dev/tty19 4 19
Usb event: added /dev/tty21 4 21
Usb event: added /dev/tty23 4 23
Usb event: added /dev/tty25 4 25
Usb event: added /dev/tty26 4 26
Usb event: added /dev/tty27 4 27
Usb event: added /dev/tty29 4 29
Usb event: added /dev/tty28 4 28
Usb event: added /dev/tty3 4 3
Usb event: added /dev/tty30 4 30
Usb event: added /dev/tty31 4 31
Usb event: added /dev/tty32 4 32
Usb event: added /dev/tty33 4 33
Usb event: added /dev/tty34 4 34
Usb event: added /dev/tty35 4 35
Usb event: added /dev/tty36 4 36
Usb event: added /dev/tty37 4 37
Usb event: added /dev/tty38 4 38
Usb event: added /dev/tty39 4 39
Usb event: added /dev/tty4 4 4
Usb event: added /dev/tty40 4 40
Usb event: added /dev/tty41 4 41
Usb event: added /dev/tty42 4 42
Usb event: added /dev/tty43 4 43
Usb event: added /dev/tty44 4 44
Usb event: added /dev/tty45 4 45
Usb event: added /dev/tty46 4 46
Usb event: added /dev/tty47 4 47
Usb event: added /dev/tty48 4 48
Usb event: added /dev/tty49 4 49
Usb event: added /dev/tty5 4 5
Usb event: added /dev/tty50 4 50
Usb event: added /dev/tty51 4 51
Usb event: added /dev/tty52 4 52
Usb event: added /dev/tty53 4 53
Usb event: added /dev/tty54 4 54
Usb event: added /dev/tty55 4 55
Usb event: added /dev/tty56 4 56
Usb event: added /dev/tty57 4 57
Usb event: added /dev/tty58 4 58
Usb event: added /dev/tty59 4 59
Usb event: added /dev/tty6 4 6
Usb event: added /dev/tty60 4 60
Usb event: added /dev/tty61 4 61
Usb event: added /dev/tty62 4 62
Usb event: added /dev/tty63 4 63
Usb event: added /dev/tty7 4 7

No veo ningún puerto ttyUSB, ¿te suena?
He desconectado varias veces mi Rflink.

He intentado pasar este comando --device-cgroup-rule='c 188:* rmw' en el docker run, pero sigue sin dar permisos a los puertos usb.

Luego he integrado este comando --device=/dev/ttyUSB0 \ en el
docker run y ahí sí da permisos al puerto USB y el node serial se conecta bien.
Sin embargo, sigue igual cuando se desconecta el rflink, el puerto USB pierde sus permisos y vuelve a crw-rw---- 1 root dialout 188, 0 Feb 21 22:52 /dev/ttyUSB0 en lugar de crw-rw-rw- 1 root dialout 188, 0 Feb 21 22:52 /dev/ttyUSB0

Sí, es correcto.

Entonces, habría que añadir tu chmod en el script que mantiene las variables, y si no funciona, reemplazando el chmod a+rw $2 por chmod a+rw /dev/ttyUSB0 de forma fija:

#!/usr/bin/env bash  
                                                           
echo "Usb event: $1 $2 $3 $4" >> /tmp/docker_tty.log        
if [ ! -z "$(docker ps -qf name=gladys-node-red)" ]                                     
then                                                                            
if [ "$1" == "added" ]                                                          
    then
        chmod a+rw $2                                                                         
        docker exec -u 0 gladys-node-red mknod $2 c $3 $4                               
        docker exec -u 0 gladys-node-red chmod -R 777 $2                                
        echo "Adding $2 to docker" >> /tmp/docker_tty.log                
    else                                                                        
        docker exec -u 0 gladys-node-red rm $2                                          
        echo "Removing $2 from docker" >> /tmp/docker_tty.log            
    fi                                                                          
fi 

EDIT : oops, olvidé cambiar env_dev por gladys-node-red en el script, no debía funcionar bien :confused:

¡Hola @mutmut!
¿Qué representan $1 $2 $3 $4?

al mirar el script que escribe en tmp, diría:
Usb event: added /dev/tty40 4 40
$1 = added (o removed)
$2 = /dev/tty40
$3 = 4
$4 = 40
Pero no tengo ni idea de qué representan $3 y $4.

Deberíamos ver /dev/ttyUSB al ejecutar un lsusb, pero no aparecerá en el registro del script (además, será un enlace simbólico, si no me equivoco).

para mí el enlace simbólico es esto

 /dev/tty-usb-arduino-nano 

que apunta a /dev/ttyUSB0

¡Genial, funciona! Voy a hacer algunas pruebas esta noche, pero parece que al desconectar y volver a conectar el Rflink, se desconecta y se reconecta :clap:

¿Esta solución se va a añadir a Gladys?

Desinstalé gladys y node _red y los volví a instalar, pero no eliminé los 2 archivos creados. Después del reinicio, el rflink se reconecta correctamente.
Entonces, yo lo probé en un Raspberry 3B+, ¿funcionará esta solución en un mini PC?

¡Buena noticia!

Para el script, lo he recuperado para Debian en PC, así que si funciona en tu Raspberry Pi, no hay razón para que no funcione.