Usar snap sin Snapd
No me gusta snap
Muchos ya lo sabeis, no me gusta el formato de snap por sus vulnerabilidades o por la monstruosidad de tamaño que ocupan las aplicaciones empaquetadas en este formato, prefiero siempre aplicaciones nativas en la paquetería de la distribución, en mi caso .deb
ya que utilizo Debian.
Ubuntu te rastrea
Sin embargo, me gusta trastear con todo y como hay veces que porque a algún desarrollador no le apetece generar su software para el formato de cada distribución, me he propuesto ejecutar aplicaciones snap pero sin utilizar el servicio de snapd.
La razón principal por la que me niego a usar snapd
como gestor de paquetes snap es por el seguimiento por parte de Ubuntu de los equipos que descargan y usan los paquetes snap.
Descargando los paquetes snap sin snapd
El primer problema es que para descargar cualquier programa de la Snap Store
tienes que usar el instalador de paquetes Snap.
Puedes usar wget-snap para descargar desde línea de comando ficheros snap, pero hay que instarlo como paquete snap.... jajaja.
Sin embargo la Snap Store
dispone de una API que es la que utiliza el gestor de paquetes de snap para localizar y descargar cada aplicación empaquetada de esta forma, así que vamos a usarla para localizar la URL de descarga del fichero .snap
La url de la API es: http://api.snapcraft.io/v2/snaps/info
A esta url hay que indicarle el nombre de la aplicación y además enviarle una cabecera
para poder obtener toda la información necesaria de cada paquete snap.
Para el ejemplo vamos a localizar la aplicación Skype
a la que Microsoft a dejado de dar soporte en el formato nativo para las distribuciones y sólo existe ya como paquete .snap
Para mostrar toda la información, que nos devolverá en formato JSON
, vamos a usar la aplicación curl
y el programa jq
para transformar el resultado y verlo de forma más cómoda y usarla el resultado despues desde la terminal.
# Actualizamos
sudo apt update
# Instalamos jq
sudo apt -y install jq
Preguntamos a la API mediante curl
:
# Definimos el nombre de la aplicacion snap a localizar
SNAP=skype
# Preguntamos por la info del paquete snap a la API
curl --silent -H 'Snap-Device-Series: 16' http://api.snapcraft.io/v2/snaps/info/$SNAP|jq
El JSON que nos devuelve es así:
De todos estos valores tan sólo nos interesa localizar dos cosas:
- La Arquitectura:
amd64
,i386
óarm
- La URL de descarga
Modificamos nuestra consulta y mediante grep
extraemos estos dos campos:
SNAP=skype
curl --silent -H 'Snap-Device-Series: 16' http://api.snapcraft.io/v2/snaps/info/$SNAP|jq|grep -E "architecture|url"
Perfecto ya sólo nos faltaría por filtar por nuestra arquitectura y obtener la URL de descarga:
ARQUITECTURA=amd64
curl --silent -H 'Snap-Device-Series: 16' http://api.snapcraft.io/v2/snaps/info/$SNAP|jq|grep -E "architecture|url"|grep $ARQUITECTURA -A1|grep '"url"'|awk '{print $2}'|sed 's/"//g'
https://api.snapcraft.io/api/v1/snaps/download/QRDEfjn4WJYnm0FzDKwqqRZZI77awQEV_351.snap
https://api.snapcraft.io/api/v1/snaps/download/QRDEfjn4WJYnm0FzDKwqqRZZI77awQEV_352.snap
Sin embargo podemos comprobar que pueden existir más de una versión activa, así que vamos a extraer unicamente la URL de la última versión:
curl --silent -H 'Snap-Device-Series: 16' http://api.snapcraft.io/v2/snaps/info/$SNAP|jq|grep -E "architecture|url"|grep $ARQUITECTURA -A1|grep '"url"'|awk '{print $2}'|sed 's/"//g'|awk -F '_' '{print $2" "$1"_"$2}'|sort -k1 -n|tail -1|awk '{print $2}'
https://api.snapcraft.io/api/v1/snaps/download/QRDEfjn4WJYnm0FzDKwqqRZZI77awQEV_352.snap
Con esta URL ya podemos descargar el fichero .snap
usando por ejemplo wget:
wget -q https://api.snapcraft.io/api/v1/snaps/download/QRDEfjn4WJYnm0FzDKwqqRZZI77awQEV_352.snap
El proceso lo podemos mejorar con un script que realice toda la tarea y además nos renombre el fichero descargado fijando en el nombre la versión del fichero snap. Podeis descargarlo del siguiente enlace:
Tras descargarlo sólo teneis que ponerle permisos de ejecución: chmod +x download_snap_amd64.sh
Y para usarlo: .download_snap_amd64.sh aplicacion
indicando el nombre de la aplicación que querais descargar:
./download_snap_amd64.sh skype
Descargando: skype
Ultima versión disponible: 352.snap
Espere ...
Se ha descargado: skype_352.snap
Extraer el contenido del fichero snap
Los fichero snap
usan para su empaquetado el formato squashfs
Squashfs es un sistema de archivos comprimido de solo lectura para Linux. SquashFS comprime archivos, inodos y directorios, y soporta tamaños de bloque de hasta 1024 KB para mayor compresión.
Puede usar zlib, lz4, lzo, o xz para la compresión de datos.
Para poder extraer el contenido necesitaremos la utilidad unsquashfs
, para ello necesitamos instalar el paquete que lo contiene:
sudo apt -y install squashfs-tools
Ya estamos preparados para extraer su contenido y ejecutar los ficheros que contiene:
# Extraer contenido de fichero snap (squashfs)
unsquashfs skype_352.snap
Parallel unsquashfs: Using 4 processors
14028 inodes (10700 blocks) to write
[=================================================-] 24728/24728 100%
created 7661 files
created 1184 directories
created 6367 symlinks
created 0 devices
created 0 fifos
created 0 sockets
created 0 hardlinks
Una vez que termine con la extracción verás que en esa misma ruta se ha creado un directorio con el nombre squashfs-root
Si vas a descargar y extraer muchos ficheros snap
debes renombrar cada directorio squashfs-root
al nombre de la aplicación para no sobrescribir cada uno, por ejemplo: mv squasfs-root skype
Localizando el binario/ejecutable del snap
Dependiendo de como se haya generado el fichero snap
puede que dentro del directorio recien extraido encuentres un fichero snapcraft.yaml
En éste fichero estará la ruta del ejecutable, en command:
podemos obtenerlo directamente con un grep
:
grep -i 'command:' snapcraft.yaml
command: $SNAP/usr/share/skypeforlinux/skypeforlinux
En nuestro caso simplemente eliminariamos $SNAP
y lo sustituimos por la ruta en la que estamos actualmente o simplemente por un punto .
# Iniciar skype indicando ruta absoluta
$(pwd)/usr/share/skypeforlinux/skypeforlinux
# Iniciar skype desde la ruta actual
./usr/share/skypeforlinux/skypeforlinux
Y ya tenemos ejecutandose una aplicacion snap
sin necesidad de usar los servicios y tracking
de Ubuntu.
En los casos en los que no exista el fichero .yaml
localizaremos el fichero .desktop
de la ruta usr/share
y de ahí podemos extrear la ruta del ejecutable que aparece en Exec=
o localizaremos el ejecutable de otras formas.
Por ejemplo para la aplicación Brave
en formato snap, nos devuelve una ruta de un ejecutable que "realmente" no está ahí:
# Localizar ruta del ejecutable en fichero .desktop
find ./usr/share -iname "*desktop" -exec grep -i "exec" {} \;|awk '{print $1}'|sed 's/Exec=/./g'
./usr/bin/brave-browser-stable
Sin embargo si usamos el comando find
para localizar brave
nos aparecerá en otra ruta, que es la que deberemos usar para lanzar Brave:
./opt/brave.com/brave/brave
Ajuste de Librerías del fichero snap
A pesar de que la aplicación se ejecute, podemos mejorar su funcionamiento si definimos que utilice sus propias librería internas mediante la variable LD_LIBRARY_PATH
Podemos localizar todas las rutas en las que existan librerías, ficheros .so
:
find . -iname "*so" -exec dirname $(pwd)/{} \;|sort -u|xargs |sed 's/ /:/g'
Si unimos el ajuste de LD_LIBRARY_PATH
con la llamada de la aplicación en una única línea la aplicación usará sus librerías internas:
# Skype
LD_LIBRARY_PATH=$(find . -iname "*so" -exec dirname $(pwd)/{} \;|sort -u|xargs |sed 's/ /:/g') $(pwd)/usr/share/skypeforlinux/skypeforlinux
# Brave en formato snap (extraido en /tmp/)
LD_LIBRARY_PATH=/tmp/brave/opt/brave.com/brave:/tmp/brave/usr/lib/x86_64-linux-gnu /tmp/brave/opt/brave.com/brave/brave
Limpieza y esplendor
Una vez que ya no queramos usar el paquete snap, simplemente borraremos el directorio y además revisaremos y borraremos los ficheros de configuración y caché que haya dejado la aplicación en nuestro equipo:
# Ruta de configuraciones del usuario
ls -latr ~/.config/
# Ruta de caché del usuario
ls -latr ~/.cache/