Gestión de versiones de Flutter

Flutter es un framework que me está gustando bastante, es muy consistente en cuanto a las distintas versiones, se ve muy similar en todas las plataformas y Dart como lenguaje es bastante interesante y nada esotérico (por eso de que usa cosas que ya manejamos y no se dedica a reinventar la rueda).

Flutter Version Management

Tanto es así que empezamos hace unos meses un proyecto de aplicación móvil con Flutter, coincidiendo con la llegada de la versión 2.0 y las cosas empezaron a ir «demasiado deprisa». La comunidad y los mantenedores del sdk parece que se han puesto las pilas y han decidido incluir mejoras a un ritmo trepidante, cuando escribo estas líneas ya vamos por la versión 2.8.1.

Nosotros estabilizamos la app en un contenedor docker usando la versión 2.5.2 de Flutter y nos encontramos ahora que no hay manera de instalar desde cero esa versión con los sistemas que proporciona Flutter. Todos aquellos sistemas en los que hicimos un upgrade ya no los podemos utilizar para desarrollo porque, entre otras cosas, han cambiado librerías y ya no son compatibles algunas partes de nuestro código.

Pero no soy el único con ese problema. Varios de los desarrolladores de Flutter se han encontrado con la misma situación y, afortunadamente, han desarrollado una manera de poder disponer de una versión propia de flutter para cada proyecto… Mediante FVM.

Os cuento los pasos básicos para tener FVM funcionando (partiendo de que has instalado flutter en tu sistema) y cómo usarlo para cada proyecto:

1. Instalar FVM

dart pub global activate fvm

Esto te instala el paquete, pero tendrás que cambiar el entorno para poder acceder al comando fvm cada vez, en mi caso es algo como:

export PATH="$PATH":"$HOME/.pub-cache/bin"

Añadiendo esta línea al final del ~/.bashrc conseguiréis meter en el path el comando FVM

2. Instalar una versión de flutter para su uso posterior

En mi caso quería instalar la versión 2.5.2 y tuve que ejecutar esto:

fvm install 2.5.2

Puedes instalar tantas como quieras (o necesites), puedes conseguir la lista de todas las instaladas con el comando fvm list

3. Usar una versión concreta en tu proyecto

Dentro del directorio del proyecto en el que quieras usar esta versión puedes sustituir el uso del comando flutter por el comando fvm flutter que te ejecutará la versión correspondiente, para indicar qué versión quieres usar debes escribir:

fvm use 2.5.2

Esto te genera un directorio .fvm en donde se almacenarán los enlaces correspondientes, no olvides incluir en tu .gitignore el directorio .fvm/flutter_sdk

Con esto y algunas cosillas más (os dejo consultar la documentación) ya podréis desarrollar y depurar con la versión de flutter que queráis.

log4j, las vulnerabilidades, los parches y la sobre-ingeniería

Durante estos días si te dedicas mínimamente a esto de la informática y has creado algún sistema con Java habras sufrido el problema del log4jshell. Si es que no, pues te lo explico:

log4j es una librería de Java que lleva existiendo desde hace innumerables años y que es muy utilizada para registrar los eventos que tienen lugar en un sistema y poder controlar qué se registra y qué no. Pues bien, la versión 2 de esta librería incluía funcionalidades para hacer sustituciones en las cadenas que se guardan en el log y, continuando con la tradición más añeja de Java, se les ocurrió que sería buena idea que esas cadenas a sustituir pudiesen hacer llamadas a sistemas externos y recibir objetos completos. Utilizando el estandar jndi permitían incluso hacer llamadas RMI o acceder a servidores LDAP. Supongo que el programador que añadió estas funcionalidades vería su utilidad en algún momento, pero también es cierto que yo nunca he visto a nadie usarla.

En fin, que esto llevaba ahí un tiempo y a algún «hacker malvado» se le ocurrió probar qué pasaba si en la url que le pasaba a la cadena a loguear incluía la dirección de un servidor que él controlaba y que permitía descargarse un objeto que hacía «cosas malas» en el sistema… Y la prueba funcionó y en cuanto alguien se dió cuenta que había cadenas extrañas que empezaban por ${jndi:ldap:// y que provocaban funcionamientos anómalos se dio la voz de alarma y se creó un registro de vulnerabilidad (CVE-2021-44228) y con un exploit super-sencillo y que mostraba que había cientos de miles de sistemas afectados.

El parche a esa vulnerabilidad llegó pronto (y eso que log4j está mantenido solo por voluntarios) y mucha gente se pasó buna parte del fin de semana parcheando los sistemas (alguno tardó algo más), aunque sin tener muy claro si el sistema había sido comprometido y modificado antes, cosa que requiere otras medidas adicionales y muy costosas. A día de hoy se ha encontrado que el parche que se hizo no contempla todos los casos y se ha registrado otra vulnerabilidad (CVE-2021-45046) que requiere otro parche… Parches, que, al fin y al cabo lo único que hacen es deshabilitar esa funcionalidad que, en algún momento, a alguien, le pareció interesante.

Son incontables el número de horas que el personal de IT (desde programadores hasta técnicos de sistemas) se han dedicado a tapar este agujero (y seguro que habrá muchos agujeros sin tapar todavía). Eso se traduce en muchos millones de Euros de dinero gastado sin sentido… Y todo porque a alguién «le pareció una buena idea esa funcionalidad» y porque todo el mundo usa componentes que no conoce, en los que «confía», aunque no poga un duro para su desarrollo…

Por cierto… Hay por ahí ya los «negacionistas de los parches» que van diciendo que si los parches son malos, que no saben lo que hay dentro, que todo es parte de una conspiración y esas cositas… En fin, el ser humano es lo que tiene (o no).

ACTUALIZACIÓN 17-12-2021: Hay todavía otro parche que meter, el 2.17.0 ya que hay una cadena especial que puede dar como resultado un DDoS… A ver lo que nos dura.

Automatiza tu casa

Creí, francamente, que ya había escrito sobre el tema de la domótica en mi blog, pero revisando me he encontrado que no he escrito casi nada sobre el tema, así que comienzo ahora a desvelaros, muy poco a poco, qué es esto de la automatización y cómo puedes controlar tu casa y hacerla más inteligente con un coste ridículo (y aprendiendo un montón).

domótica

Como resumen, la domótica aglutina todo lo que podemos controlar de manera remota 8o programar localmente) en nuestro hogar. Son esas cosas que nos permiten encender la calefacción horas antes de que lleguemos de un viaje, abrir y cerrar persianas sin que estemos o apagar y encender luces cuando se detecta nuestra presencia. Dado que esto es un campo muy amplio, os recomiendo que visitéis webs más especializadas para descubrir el montón de cosas que se pueden hacer. Yo, por mi parte, iré recopilando las cosas interesantes que voy haciendo por si os sirve de algo.

Lo primero…

Para poder «jugar» un poco con la domótica necesitamos algún controlador en el que centralizar todas estas opciones. En mi caso me he decidido por home assistant, que tiene un montón de información en internet y del que disponéis de plugins y librerías para cadsi todo. La instalación es tremendamente sencilla si vamos a utilizar una raspberry pi (recomiendo que sea la 4, pero la 3 también nos serviría igualmente). La guía de instalación para raspberry pi está bastante bien y la podéis encontrar en este enlace.

El proceso consiste, básicamente, en descargarte la imagen de internet, grabar con esa imagen una tarjeta SD y si tenéis conexión por cable simplemente meter la sd en la rasperry, enchufar el cable de red y esperar a que arranque, tendréis el sistema de configuracion en la url http://homeassistant.local:8123/. Si vais a usar wifi desde el primer momento el proceso es un poco más complicado, básicamente consiste en copiar este archivo (modifica a tu gusto el SSID y contraseña) en la particion de boot del SD que acabáis de grabar (en CONFIG/network/) y llámalo my-network:

[connection]
id=my-network
uuid=72111c67-4a5d-4d5c-925e-f8ee26efb3c3
type=802-11-wireless

[802-11-wireless]
mode=infrastructure
ssid=MI_SSID
# Uncomment below if your SSID is not broadcasted
#hidden=true

[802-11-wireless-security]
auth-alg=open
key-mgmt=wpa-psk
psk=MI_CONTRASEÑA_WIFI

[ipv4]
method=auto

[ipv6]
addr-gen-mode=stable-privacy
method=auto

En fin, una vez que tengáis home assistant instalado toca poner los datos tuyos y los del domicilio donde vas a instalarlo y el sistema se encargará de buscar por red las integraciones a las que pueda acceder directamente.

En siguientes entradas veremos aspectos interesantes sobre cómo configurarlo para tener acceso a dispositivos zigbee, a detectar presencia propia o a hacer automatizaciones… Por ahora intentad tener el controlador preparado e id buscando dispositivos para hacer de vuestra casa una casa inteligente.

Big Sur + iphone en mi ubuntu

Continuando con lo que escribí en la anterior entrada, el siguiente objetivo es múltiple: conseguir la última versión de mac os (Big Sur) y poder utilizar un teléfono físico con la máquina virtual para poder generar la versión final de las aplicaciones para ios.

Utilizar sosumi en ubuntu es muy sencillo y relativamente poco complicado, pero al intentar actualizar a BigSur siempre daba el mismo problema… Se descargaba la actualización, comanzaba a ejecutarla y tras el primer reinicio… nada… Seguimos en Catalina. Tras varios intentos infructuosos decidí seguir otro camino. Decidí seguir esta entrada y crear un usb bootable para instalar Big Sur desde cero. Eso lo conseguí añadiendo el dispositivo usb al archivo launch con esta línea:

-device usb-host,vendorid=0x0951,productid=0x16ae

El vendorid y productid lo podemos sacar con un comando lsusb:

Bus 003 Device 072: ID 0951:16ae Kingston Technology DT microDuo 3C

Con esta línea en el archivo launch conseguimos que la máquina macos reconozca el usb cuando lo pinchemos y nos permita formatearlo e instalarle el instalador de BigSur. Arrancando la máquina con este usb pinchado nos permitiría ejecutar una instalación limpia de Big Sur (en teoría)… Pero la teoría y la práctica en la práctica no coinciden y no conseguí que funcionase la instalación desde el usb con sosumi, así que, guardando mi dispositivo USB por si las moscas (spoiler alert, si que lo vamos a necesitar) busqué otras formas de ejecutar macos en mi ubuntu. El siguiente en la lista y que me ha dado buenos resultados está en esta url:

https://github.com/kholia/OSX-KVM

Siguiendo las instrucciones de instalación se consigue más o menos de manera sencilla lo mismo que con sosumi, resumiendo, esto es lo que hay que hacer:

echo 1 | sudo tee /sys/module/kvm/parameters/ignore_msrs
sudo apt-get install qemu uml-utilities virt-manager git \
    wget libguestfs-tools p7zip-full -y
git clone --depth 1 https://github.com/kholia/OSX-KVM.git
cd OSX-KVM

Llegados a este punto deberíamos poder bajarnos de la web de apple el instalador del sistema que queremos, siguiendo las instrucciones a mi no me ha funcionado y terminaba instalándose catalina cada vez… Así que recuperando mi USB de instalación de BigSur decidí arriesgarme y utilizar la imagen que creé para arrancar, para ello copié el archivo BaseSystem.dmg que se encuentra en el directorio BaseSystem del USB creado al directorio y lo convertí con el comando:

qemu-img convert BaseSystem.dmg -O raw BaseSystem.img

Lo siguiente es crear un disco duro con el tamaño que nos interese (yo lo creé de 128G para no quedarme corto) con:

qemu-img create -f qcow2 mac_hdd_ng.img 128G

Y ya podemos arrancar el sistema y hacer lo mismo que hicimos con sosumi, entrar en el gestor de discos, formatear el disco inicial y luego seleccionar la opción de reinstalación del sistema operativo… Va a tardar un rato largo pero, al final, tendrás un Big sur operativo ejecutando el comando:

./OpenCore-Boot.sh

Y como veo que este post me está quedando un poco largo, dejaremos el tema de pinchar un iphone a nuestra máquina virtual para un post posterior… Porque la cosa tiene miga (no, no es tan sencillo como lo de la memoria USB de antes).

Por ahora podéis experimentar con el sistema y veréis que tenéis algo más de control que con sosumi a cambio de tener un poco más de cuidado con lo que hacéis… Ah! y como bonus, que sepas que puedes hacer un backup de la máquina virtual simplemente copiando el directorio OSX-KVM y podrás restaurar la máquina a ese mismo estado (incluso llevártela a otro ordenador) sin ningún problema.

Mac os en mi Ubuntu

Llevo varios años desarrollando aplicaciones móviles, la última nomorepass, y me encuentro siempre en la tesitura de tener que compilar la aplicación en un mac nativo. Supongo que eso es un peaje que Apple pide por «dejarte» usar ios, pero es que gastarse unos cuantos miles de euros solo para compilar una aplicación es bastante aberrante.

CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 82

Hace unos años me compré un macbook pro de 15″ que me ha dado buen servicio hasta hace cosa de tres años en que falló el chip gráfico de nvidia y el servicio técnico me cambió la placa entera (700 Euros) y me querían cobrar otros 400 si se me ocurría reclamar mi placa vieja… Negociazo redondo para apple cuando cambie un chip y le endose la misma placa a otro ingenuo… En fin, que se me han quitado las ganas de comprar un apple y el que tenemos en la oficina es un poco «lento» y tarda una eternidad en compilar un simple proyecto (más con cada actualización del sistema operativo). Por esto he estado intentando de todas las maneras posibles poder hacer esa compilación en una máquina profesional de verdad que corriese linux.. He intentado hackintosh, he intentado virtualbox, etc… Hasta que hace poco encontré que se puede instalar una versión de mac en qemu… Una versión genuina, sin modificar… Y dicho y hecho…

Forma sencilla

La forma más sencilla de instalar mac os (Catalina) en un Ubuntu es instalar el paquete snap sosumi. Os recomiendo mucho que echéis un vistazo a este video, ya que explica todo con cierta profundidad. Básicamente esto es lo que necesité hacer:

sudo snap install sosumi

Una vez instalado (es rápido), se puede ejecutar incluso desde el lanzador de aplicaciones buscando sosumi. La primera vez que se lanza te mostrará la pantalla de recuperación y deberás abrir el programa Disk Utility para dar formato al disco virtual (inicialmente le da una capacidad limitada, pero puedes ampliarlo antes de hacer este paso):

En Disk Utility selecciona el primer disco y dale formato con la opción Erase… Ponle el nombre que quieras (por ejemplo MacHD) y debería quedar algo así:

Luego, cierra la aplicación y ves a la opción de Reinstalar macOS… Y listo para instalar

Aceptas la licencia y seleccionas el disco para instalar y eso es todo… Tendrás una máquina con macOS catalina lista para ejecutar.

Hay algunas cosillas interesantes a hacer como cambiar la resolución de la pantalla, para eso os recomiendo que sigáis este procedimiento, o aumentar la memoria o los cores que se hace editando el archivo ~/snap/sosumi/common/launch y teniendo cuidado en no poner cosas disparatadas.

El mayor problema que me he encontrado con este método es que no he conseguido actualizarlo a la nueva versión Big Sur, por lo que su utilidad queda un poco limitada. Sin embargo, he encontrado un método (un poco rebuscado, eso si) para instalar BigSur en qemu y poder utilizar mi máquina linux para compilar con xcode… Pero eso si, os lo contaré cuando lo tenga un poco más pulido