Handle flatpak from Salt

Introduction

Manage flatpak from salt. This guide requires to have some Salt knowledge.

A few months ago, I had most of my setup managed by salt, but then I got lazy and with the introduction of flatpak I didn’t even look at using salt to handle it. Here is a simple method that “just” works, which:

  • setup flathub
  • install flatpak programs
  • register flatpak programs in Qubes applications provided by the template
  • make sure they will be updated

Setup (Fedora)

In a Salt state file, add this:

{% set flatpak_packages = [
    "org.libreoffice.Libreoffice",
    "org.mozilla.firefox",
    "org.videolan.VLC"
] %}

flatpak_setup:
  cmd.script:
    - source: salt://scripts/flatpak-setup.sh
    - template: jinja
    - context:
        flatpak_packages: {{ ' '.join(flatpak_packages) }}


/etc/qubes/post-install.d/05-flatpak-update.sh:
  file.managed:
    - user: root
    - group: wheel
    - mode: 555
    - contents: |
        #!/bin/sh
        if [ $(qubesdb-read /type) = "TemplateVM" ]
        then
          all_proxy=http://127.0.0.1:8082 flatpak upgrade -y --noninteractive
        fi

And in /srv/user_salt/scripts/flatpak-setup.sh:

#!/bin/sh
export all_proxy=http://127.0.0.1:8082/

flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo

# list programs that should be installed
flatpak install -y --noninteractive flathub {{ flatpak_packages }}

# make flatpak programs available in menus
find /var/lib/flatpak/exports/share/applications/ -type l -name "*.desktop" -exec ln -s {} /usr/share/applications/ \;

# delete dead links, in case a flatpak program was deleted
find /usr/share/applications/ -xtype l -delete

/etc/qubes/post-install.d/10-qubes-core-agent-appmenus.sh
2 Likes

Pesonally, I prefer to use flatpak in user space as described in below post.

1 Like

different use case :slight_smile:

I see. I am not sure what you are referring to. The solution I referenced in previous post works to install apps from flatpak. It can be achieved using saltstak too.

I think it’s about this use case:

2 Likes

Beautiful script! It is possible to generalize it by feeding package names (and other stuff) with jinja. In .sls:

{% set flatpak_packages = [
    "org.libreoffice.Libreoffice",
    "org.mozilla.firefox",
    "org.videolan.VLC"
] %}

flatpak_setup:
  cmd.script:
    - source: salt://scripts/flatpak-setup.sh
    - template: jinja
    - context:
        flatpak_packages: {{ ' '.join(flatpak_packages) }}

And in the script itself:

...
flatpak install -y --noninteractive flathub {{ flatpak_packages }}
...

Thanks! I’ve updated the top post to include your improvements.

It should be possible to handle user installed flatpak from salt as well, but this requires some changes:

  • the script should be run with the proper user
  • paths should be updated to use ~/.local/share/applications/

But I’m not sure how to deploy an auto update of the flatpak. Maybe in user .bashrc ? what do you think?

So far I have installed flatpak apps only on one AppVM. Unless there is a security benefit in installing flatpak apps in TemplateVM compared to installing it in AppVM, I think the use case is uncommon.

I use the same programs in multiple appvms, so they are installed in my templates.

1 Like

BTW how exactly does the verification of flatpaks work? Is there any way this could be nicely integrated into the dom0 updater ?

I am hesitant to allow http connections in a template.
Currently I only use a dvm-flatpak template qube and install specific software in single qubes if I need persistent data.

you already use http connections from the template to install packages :thinking:

I need to find how it works, I stumbled upon a script checking if apt/dnf had an update and report to dom0 there is an update for the according template, but I wasn’t able to find it again. Help needed :pray: With this, it should be trivial to use AppVMs to check for flatpak updates

… Just remebered that there is an issue with permission changes when a flatpak updates. This might be dangerous unattended

I don’t really understand how much you open the template for potential attacks with:

export all_proxy=http://127.0.0.1:8082/
or
https_proxy=http://127.0.0.1:8082/

You are not obligated to implement the auto update. Regular packages don’t even handle permissions and nobody care, but if you want to review your flatpak updates just don’t implement the auto update :wink:

the templates already use the http proxy to download updates, this piece of code only tell the shell to use the proxy. I don’t think there is a real world risk using it for that situation.

/lib/systemd/system/qubes-update-check.service
1 Like

I mean for some Qubes users the sandbox might be really important.
A clunky workaround might be to provide an optional global override file that disables EVERY permission by default.

This might not account for everything ( I am not sure if it’s possible to disable that a flatpak adds any file paths manually instead of host=all or home=all )

I would hope that with this:

[Context]
sockets=!session-bus;!system-bus;
filesystems=!home;!host;

[Session Bus Policy]
org.freedesktop.Flatpak=none

The most dangerous stuff would be disabled and not even possible to add manually file paths etc…

Even thought it might be a fools errand to make the sandbox secure on x11…

Yeah might be better to wait until the flatpak guys implement a better way to handle the permissions

I’ll try to make a script that look for flatpak updates, then in the template, run a dry run to check a permission change, in that case it would abort and display a popup about this problem, otherwise the update process would continue smoothly. Seems a good enhancement without sacrificing security?

I plan to write salt states for both the user and global setup.

1 Like

This post is more notes for future myself, I got interesting findings but no time yet to implement it.

This is doable but boring, someone made it in PHP Dakusan’s Domain > Posts > Checking permissions before updating Flatpaks

Basically, the current permissions are stored in a metadata file, the path is different between a system or user installation, and between a runtime or application (although I’m not even sure we should care about runtimes because I don’t think they have permissions?).

Then, using flatpak remote-info --show-metadata flathub $app you can retrieve the metadata to compare with the local file.

It’s possible to check for new updates with flatpak remote-ls --updates | grep ., if the command returns 0 then there is something to update.

very nice idea.

I think something like

diff old.permission new.permission | magic | echo "PAUSE permissions for the following programs changed, please confirm: $PROGRAMS" 

would be enough.

the upgrade process is not manual. My idea would be abort the automatic update with a clear message to the user that they will have to handle it manually due to a permission change.

1 Like

Yeah forgot about that.

Short blogpost from the archwiki about the permission changes:
https://ejona.ersoft.org/archive/2024/03/02/flatpak-perms-upgrade/