Maintaining updated AppImages across multiple AppVMs derived from the same template can be laborious. I wrote this guide to show my approach to managing AppImage updates, for AppImages stored in a Template VM (for example, when the same AppImage needs to be used across different AppVMs based on the same template).
Store AppImages in the TemplateVM (e.g., /opt/Application/Application.AppImage
), making them available to all derived AppVMs. Since TemplateVMs should not have internet access, we'll create a dedicated "updates" AppVM to download the latest AppImages.
Create a new AppVM named "updates" that will handle downloading the latest AppImages.
Save this script in your updates AppVM:
#!/bin/bash
DOWNLOAD_DIR="/home/user/Downloads"
# Anytype
curl -s https://api.github.com/repos/anyproto/anytype-ts/releases/latest \
| grep "browser_download_url.*.AppImage" \
| cut -d : -f 2,3 \
| tr -d \" \
| wget -qi - -P "$DOWNLOAD_DIR"
# Bitwarden
curl -L "https://vault.bitwarden.com/download/?app=desktop&platform=linux&variant=appimage" -o "$DOWNLOAD_DIR/Bitwarden.AppImage"
# Cryptomator
curl -s https://api.github.com/repos/cryptomator/cryptomator/releases/latest \
| grep "browser_download_url.*x86_64.AppImage" \
| grep -v "\.asc\|\.zsync" \
| cut -d : -f 2,3 \
| tr -d \" \
| wget -qi - -P "$DOWNLOAD_DIR"
#KeepassXC
curl -s https://api.github.com/repos/keepassxreboot/keepassxc/releases/latest \
| grep -E "browser_download_url.*keepassxc.*-x86_64\.AppImage" \
| grep -v "\.asc\|\.zsync" \
| grep -v "\.sig\|\.DIGEST" \
| cut -d : -f 2,3 \
| tr -d \" \
| wget -qi - -P "$DOWNLOAD_DIR"
# Notesnook
wget -O "$DOWNLOAD_DIR/Notesnook.AppImage" https://github.com/streetwriters/notesnook/releases/latest/download/notesnook_linux_x86_64.AppImage
# Tutanota
wget https://app.tuta.com/desktop/tutanota-desktop-linux.AppImage -P "$DOWNLOAD_DIR"
echo "All downloads completed."
Make the script executable with chmod +x script-name.sh
.
Save this script in your TemplateVM. This example focuses on Anytype. You'll need to adapt it for each AppImage you're managing.
#!/bin/bash
sudo rm /opt/Anytype/Anytype.AppImage
sudo find /home/user/QubesIncoming -name "*.AppImage" -exec mv -t /home/user/QubesIncoming {} +
chmod +x /home/user/QubesIncoming/Anytype*.AppImage
sudo mv /home/user/QubesIncoming/Anytype*.AppImage /opt/Anytype/Anytype.AppImage
Create a script in dom0 that coordinates the entire update process:
#!/bin/bash
qvm-run updates /path/to/script.sh
qvm-run --pass-io updates tar -cvf downloads.tar Downloads
qvm-run --pass-io updates 'cat /home/user/downloads.tar' | qvm-run --pass-io template-vm 'cat > /home/user/QubesIncoming/downloads.tar'
qvm-run --pass-io template-vm tar -xf /home/user/QubesIncoming/downloads.tar -C /home/user/QubesIncoming
qvm-run updates rm -rf ~/Downloads/*
qvm-shutdown updates
qvm-run template-vm /path/to/update/script/application1.sh
qvm-run template-vm /path/to/update/script/application2.sh
#Add more as needed
qvm-shutdown template-vm
Replace template-vm
with the name of your TemplateVM, and the script locations as needed.
To update all AppImages in your TemplateVM:
To add a new AppImage to the update process:
This approach has some security implications to consider:
For high-security environments, this might not be a good idea.
I hope this guide is of any help. Please let me know if it can be improved, or if there are better ways to handle updates of AppImages stored in Template VMs.