La último ha sido unos problemas derivados de la caída del servidor donde se almacenan las capturas. Como ya vimos es un servidor remoto desde el que montamos una carpeta por sshfs. He tenido diversos problemas con dicho servidor e inoportunas caídas del servicio. Los problemas detectados son:
- Cuando se interrumpe la conexión sshfs ya no se recupera hasta que se reinicia el router. Ese reinicio lo tengo programado una vez al día a medianoche.
- Si se interrumpe la conexión el guardado de las imágenes se hace en /mnt local, con lo cual los pocos megas de espacio de almacenamiento interno del router se llenan rápidamente y dejan el OpenWrt malfuncionando. Al reiniciar el router ese espacio se libera borrando las capturas.
- En general, las capturas hechas durante el tiempo que está el sshfs caído se pierden como lágrimas en la lluvia, ya que muchas veces no se llegan a enviar por problemas derivados del llenado del almacenamiento interno.
- He ordenado un poco el código creando varias funciones, sacando al programita de los años 50 del siglo pasado.
- He creado un fichero local llamado /mnt/testigo que solo será visible si el sistema remoto no está montado por sshfs.
- Al principio pregunto si el sistema sshfs está montado y en caso negativo intento re-montarlo.
- Si no hay manera de remontarlo y no hay movimiento detectado, el fichero con la imagen *snapshot* no se almacena en la memoria interna: se borra.
- Si no hay manera de remontarlo y hay movimiento detectado, los ficheros con la secuencia son guardados en el espacio de almacenamiento interno de forma local y, cuando llegan a ser 10, empaquetados y enviados por correo, borrándose luego. El "10" es un número arbitrario que cada cual puede variar para ajustarlo a su espacio de almacenamiento
# cat /root/controlador.sh
#!/bin/ash
log() {
test $montado -eq 1 && echo "$1" >> /mnt/snapshot/log.txt
}
email() {
test $email -eq 1 && echo -e "$1" | sendmail correo.aviso@gmail.com
}
monta_sshfs() {
sshfs -o ssh_command="ssh -i /root/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" -o nonempty openwrt@192.168.0.25:/home/openwrt /mnt
}
envia_secuencia() {
if [ -e /tmp/motion.txt ]
then
#Recopila todos los ficheros de /tmp/motion/txt y los envia en un correo
ficheros=$(cat /tmp/motion.txt | tr '\n' ' ')
rm /tmp/motion.txt
log "Historia de capturas $ficheros"
zip -9 /mnt/escena.zip $ficheros
echo "Secuencia $1" > /mnt/mensaje.txt
test $email -eq 1 && mutt -s "Evento camara" correo.aviso@gmail.com -a /mnt/escena.zip < /mnt/mensaje.txt
rm /mnt/escena.zip
#Si no hay acceso al almacenamiento remoto, borramos las capturas para no llenar el disco del router.
test $montado -eq 0 && rm -rf $destino
fi
}
#Parametro 1: start, picture, end
#Parametro 2: fecha
#Parametro 3: nombre fichero (opcional)
#Obtenemos fecha y hora por si queremos poner algun filtro sobre ella y solo avisar en determinados
#momentos
time=$(date +%s)
anio=$(date +%Y @$time)
mes=$(date +%m @$time)
dia=$(date +%d @$time)
hora=$(date +%H @$time)
minuto=$(date +%M @$time)
diasemana=$(date +%u @$time) #El 1 es lunes
destino="/mnt/snapshot/$anio-$mes-$dia"
montado=1
email==0
if [ $diasemana -ge 6 -o $hora -le 7 -o $hora -ge 17 ] # sabado/domingo o cualquier dia antes de las 8:00 o despues de las 17:00
then
email=1
fi
#Si existe el fichero /mnt/testigo no se ha montado directorio remoto por sshfs,
#Intentamos montarlo y otra vez y luego preguntamos de nuevo.
#Si no se ha montado nada es que no se puede guardar nada de forma permanente ya que estamos escribiendo en la
#memoria interna del router y eso se llena rapido
test -e /mnt/testigo || monta_sshfs
if test -e /mnt/testigo
then
montado=0
#No hay almacenamiento organizado por dias, no vamos a guardar tanto tiempo el fichero.
destino="/mnt/snapshot"
fi
test -d $destino || mkdir -p $destino
case $1 in
"start")
log "Detectado inicio de movimiento $2"
email "Subject: Evento camara\r\n\r\nDetectado inicio de movimiento $2"
#El fichero motion.txt tiene dos finalidades: 1) testigo para indicar que estamos detectando movimiento
# 2) guarda los nombres de los ficheros de captura de las fotos
touch /tmp/motion.txt
;;
"picture")
fichero=$(basename $3)
log "Guardando imagen $2 : $destino/$fichero"
#Si estamos en una ráfaga de movimiento detectado, guardamos el nombre de fichero con la foto.
test -e /tmp/motion.txt && echo "$destino/$fichero" >> /tmp/motion.txt
#Se guarda el fichero en el almacenamiento destino
mv "$3" "$destino/$fichero"
#Si no está montado el almacenamiento remoto y vemos que llevamos mas de 10 imagenes en
#movimiento tenemos que borrarlas y enviarlas ya mismo, para no saturar el espacio.
if [ $montado -eq 0 ]
then
#Si estamos en una ráfaga de movimiento detectado....
if [ -e /tmp/motion.txt ]
then
lineas=$(wc -l /tmp/motion.txt | cut -d" " -f1)
test $lineas -gt 10 && envia_secuencia $2
else
#Si no lo estamos, es una captura *snapshot* regular sin interés, la borramos.
rm -f "$destino/$fichero"
fi
fi
;;
"end")
log "Detectado fin de movimiento $2"
envia_secuencia $2
;;
*) log "Evento $1"
esac
#Borra fichero "sent" creado por sendmail si existe, para liberar espacio
rm -rf /root/sent
rm -rf /sent
exit 0
Por otro lado, el fichero /etc/rc.local se modifica para crear el fichero /mnt/testigo en el arranque. # cat /etc/rc.local
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
sleep 40
#Desmontamos /mnt por si acaso
umount /mnt
#Borramos /mnt/snapshot local si tuviera algo
rm -rf /mnt/snapshot
#Creamos testigo para detectar que no se ha montado el almacen remoto
touch /mnt/testigo
#Montamos almacen remoto por sshfs
sshfs -o ssh_command="ssh -i /root/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" -o nonempty openwrt@172.19.231.4:/home/openwrt /mnt
exit 0
Bueno, pues esto quedá asi hasta el siguiente ciclo de mejoras.
No hay comentarios:
Publicar un comentario