# Usabilidad Cómo se trabaja con esto en el día a día. No la instalación —eso está en [ansible/README.md](../02_device_lab/ansible/README.md)— sino **cómo se usa una vez montado**, y qué decisiones de diseño hacen que sea llevadero o insufrible. --- ## Un solo punto de control 45 dispositivos son ingobernables si hay que entrar a cada blade. Por eso **todo pasa por el coordinador**: ``` tú coordinador 45 Android ┌────┐ ssh ┌──────────────────┐ adb ┌───┬───┬───┐ │ │ ──────────► │ fleet · adb │ ─────────► │ · │ · │ · │ └────┘ │ devices.txt │ └───┴───┴───┘ └──────────────────┘ ``` `devices.txt` lo genera Ansible a partir del inventario y de la RAM real de cada blade. Nunca se edita a mano: si cambia la flota, se relanza `playbooks/coordinator.yml` y se regenera. --- ## Órdenes ```bash fleet connect # conecta adb a toda la flota fleet list # qué hay conectado, y cuántos faltan fleet install app.apk # instala en todos fleet shell '' # ejecuta en todos fleet ip # IP de cada Android fleet reboot # reinicia todo ``` Todas son **idempotentes o inocuas**. `connect` se puede lanzar mil veces. Ninguna borra nada. La única destructiva del proyecto es `playbooks/destroy.yml`, y exige `-e confirmar=si`. ### Por qué `fleet list` dice "declarados" y "conectados" ``` declarados: 45 · conectados: 43 ``` Esa resta es el diagnóstico más útil del sistema. Si no cuadra, hay dos contenedores caídos y se sabe al instante, sin mirar 15 blades. El siguiente paso es `playbooks/status.yml`, que dice en qué nodo. --- ## Flujos de trabajo reales ### Probar una APK nueva en toda la flota ```bash ansible-playbook playbooks/apk.yml -e apk_local_path=~/oasis-0.9.1.apk ``` Un solo comando desde el portátil: copia el APK al coordinador, conecta la flota e instala en los 45. Sale un recuento de `ok` / `FALLO` por dispositivo. ### El caso de los dos APKs que se tienen que ver Es el que motivó el proyecto. Con `redroid_network_mode: macvlan`: ```bash fleet ip # cada Android con su IP real de LAN fleet install oasis-A.apk # ...o instalar distinto en cada mitad adb -s 10.0.0.20:5555 install oasis-B.apk ``` Los dos se ven como **pares de red de verdad**, no a través de traducciones. Es lo más cerca de "dos móviles en la misma wifi" sin tener dos móviles. ### Mirar una instancia concreta ```bash scrcpy -s 10.0.0.20:5555 ``` Ventana con la pantalla del Android, ratón y teclado. Para depurar algo visual no hay nada mejor. ### Comprobar una propiedad en toda la flota ```bash fleet shell 'getprop ro.build.version.release' fleet shell 'pm list packages | grep oasis' ``` --- ## Decisiones de diseño | Decisión | Por qué | |---|---| | **Preflight de solo lectura** | Se puede lanzar contra hardware ajeno sin miedo. Contesta "¿qué hay aquí y sirve?" sin tocar nada | | **Instancias automáticas por RAM** | No hay que calcular ni mantener un número por blade. Se amplía la RAM y el siguiente despliegue se ajusta solo | | **`fleet` en el PATH** | `fleet list`, no `/opt/granja/fleet.sh list` | | **Playbooks pequeños y con nombre obvio** | `preflight`, `provision`, `devices`, `apk`, `status`, `destroy`. Se adivina cuál usar | | **Todo relanzable** | `site.yml` es idempotente. Ante la duda, se relanza | | **Errores que dicen qué hacer** | El fallo de binder no dice "error": dice que el módulo estaba en uso, que la config persistente ya está escrita y que basta reiniciar ese blade | | **`destroy.yml` conserva los datos** | Borrar `/data` exige un segundo flag. Lo destructivo nunca es el camino por defecto | --- ## Problemas conocidos Ordenados por probabilidad. Están documentados porque son inevitables, no porque sean fallos. ### 1 · Binder, la primera vez **Síntoma**: el playbook falla con "faltan devices binder tras el modprobe". **Causa**: el módulo ya estaba cargado y en uso, así que no se pudo recargar con los parámetros nuevos. **Solución**: la configuración persistente ya quedó escrita. Reinicia ese blade y relanza. Pasa una sola vez por máquina. ### 2 · macvlan: el anfitrión no ve a sus propios contenedores **Síntoma**: adb desde un blade no encuentra los Android de ese mismo blade. **Causa**: limitación del driver macvlan, no un error de configuración. **Solución**: no es un problema en este diseño — el coordinador es un blade **distinto** y desde fuera sí se llega. Por eso `apk.yml` se ejecuta siempre desde el coordinador. Si algún día montas adb en un nodo de carga, es esto. ### 3 · El primer arranque de redroid tarda **Síntoma**: `fleet connect` falla justo después de `site.yml`. **Causa**: un Android recién creado tarda en levantar por primera vez, sobre todo con render por software y 45 a la vez. **Solución**: esperar y reintentar. `fleet connect` es inocuo y se puede repetir. --- ## Ergonomía del hardware Cosas que no son software pero deciden si esto se usa o se abandona: **El ruido manda.** 70–85 dB significa que no se puede estar en la misma habitación sin protección. Todo el trabajo tiene que ser remoto — de ahí que no haya nada en el diseño que exija tocar el chasis en marcha. **El LCD frontal es el mejor amigo en el arranque.** Configura la red de la CMC con su asistente, sin cable serie ni portátil enganchado. Es el camino corto la primera vez. **Encender por ventanas cambia el hábito.** Si el chasis no está siempre en marcha (y no debería, ver [costes.md](costes.md)), el flujo pasa a ser: encender → esperar arranque → `fleet connect` → trabajar → apagar. Merece la pena tener eso en un script y no en la cabeza. --- ## Pendiente - **GADS** — UI web con la flota, vista de pantallas y Appium integrado. Es el salto de calidad cuando se pasa de una decena de dispositivos. No está automatizado a propósito: montar un despliegue de Node sin poder probarlo sería complejidad sin verificar - **Script de encendido/apagado por ventanas** contra la CMC vía RACADM - **`fleet watch`** — un panel de estado que se refresque solo - **Registro de auditoría en `fleet`** — hoy no deja rastro de quién hizo qué (hallazgo S10 en [seguridad.md](seguridad.md))