Skip to content

Commit

Permalink
feat: default-flatpaks module
Browse files Browse the repository at this point in the history
  • Loading branch information
xynydev authored Oct 21, 2023
2 parents 835222f + 5e6bc4c commit 7104111
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 0 deletions.
78 changes: 78 additions & 0 deletions files/usr/bin/system-flatpak-setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env bash

# Script Version
VER=1
VER_FILE="/etc/ublue-os/system-flatpak-configured"
VER_RAN=$(cat $VER_FILE)

# Run script if updated
if [[ -f $VER_FILE && $VER = $VER_RAN ]]; then
echo "Flatpak setup v$VER has already ran. Exiting..."
exit 0
fi

# Opt out of and remove Fedora's flatpak repo
if grep -qz 'fedora' <<< $(flatpak remotes); then
/usr/bin/gnome-software --quit
/usr/lib/fedora-third-party/fedora-third-party-opt-out
/usr/bin/fedora-third-party disable
flatpak remote-delete fedora --force
flatpak remote-delete fedora-testing --force

# Remove flatpak apps from origin fedora
FEDORA_FLATPAKS=$(flatpak list --app --columns=application,origin | grep -w 'fedora' | awk '{print $1}')
flatpak remove --system --noninteractive ${FEDORA_FLATPAKS[@]}

# Remove flatpak runtimes from origin fedora
FEDORA_FLATPAKS=$(flatpak list --runtime --columns=application,arch,branch,origin | grep -w 'fedora' | awk '{print $1"/"$2"/"$3}')
flatpak remove --system --noninteractive ${FEDORA_FLATPAKS[@]}
fi

REPO_INFO="/etc/flatpak/system/repo-info.yml"
REPO_URL=$(yq '.repo-url' $REPO_INFO)
REPO_NAME=$(yq '.repo-name' $REPO_INFO)
REPO_TITLE=$(yq '.repo-title' $REPO_INFO)

# Set up system-wide Flatpak repository
if [[ ! $REPO_URL == "null" && ! $REPO_NAME == "null" ]]; then
echo "Adding system-wide remote $REPO_NAME from $REPO_URL"
flatpak remote-add --if-not-exists --system $REPO_NAME $REPO_URL
fi

# If configured remote is flathub, enable it here.
# Flathub is already installed on Fedora, but not enabled by default,
# so the above command won't add it again
if [[ $REPO_NAME == "flathub" ]]; then
flatpak remote-modify --system $REPO_NAME --enable
fi

# Change repository title to configured title, if not null
if [[ ! $REPO_TITLE == "null" ]]; then
echo "Setting title $REPO_TITLE for remote $REPO_NAME"
flatpak remote-modify --system $REPO_NAME --title="$REPO_TITLE"
fi

# Lists of flatpaks
FLATPAK_LIST=$(flatpak list --columns=application)
INSTALL_LIST=$(cat /etc/flatpak/system/install)
REMOVE_LIST=$(cat /etc/flatpak/system/remove)

# Install flatpaks in list
if [[ -n $INSTALL_LIST ]]; then
if ! flatpak install --system --noninteractive $REPO_NAME ${INSTALL_LIST[@]}; then
# Exit on error
exit 1
fi
fi

# Remove flatpaks in list
if [[ -n $REMOVE_LIST ]]; then
flatpak remove --system --noninteractive ${REMOVE_LIST[@]}
fi

notify-send "Flatpak Installer" "Finished installing system flatpaks" --app-name="Flatpak Installer" -u NORMAL

# Prevent future executions
echo "Writing state file"
mkdir -p /etc/ublue-os
echo $VER > $VER_FILE
60 changes: 60 additions & 0 deletions files/usr/bin/user-flatpak-setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env bash

# Script Version
VER=1
VER_FILE="$HOME/.config/ublue-os/user-flatpak-configured"
VER_RAN=$(cat $VER_FILE)

# Run script if updated
if [[ -f $VER_FILE && $VER = $VER_RAN ]]; then
echo "Flatpak setup v$VER has already ran. Exiting..."
exit 0
fi

# Remove Fedora's flatpak repo, if it exists
if grep -qz 'fedora' <<< $(flatpak remotes); then
flatpak remote-delete --user fedora --force
flatpak remote-delete --user fedora-testing --force
fi

REPO_INFO="/etc/flatpak/user/repo-info.yml"
REPO_URL=$(yq '.repo-url' $REPO_INFO)
REPO_NAME=$(yq '.repo-name' $REPO_INFO)
REPO_TITLE=$(yq '.repo-title' $REPO_INFO)

# Set up per-user Flatpak repository
if [[ ! $REPO_URL == "null" && ! $REPO_NAME == "null" ]]; then
echo "Adding remote $REPO_NAME from $REPO_URL"
flatpak remote-add --if-not-exists --user $REPO_NAME $REPO_URL
fi

# Change repository title to configured title, if not null
if [[ ! $REPO_TITLE == "null" ]]; then
echo "Setting title $REPO_TITLE for remote $REPO_NAME"
flatpak remote-modify --user $REPO_NAME --title="$REPO_TITLE"
fi

# Lists of flatpaks
FLATPAK_LIST=$(flatpak list --columns=application)
INSTALL_LIST=$(cat /etc/flatpak/user/install)
REMOVE_LIST=$(cat /etc/flatpak/user/remove)

# Install flatpaks in list
if [[ -n $INSTALL_LIST ]]; then
if ! flatpak install --user --noninteractive $REPO_NAME ${INSTALL_LIST[@]}; then
# Exit on error
exit 1
fi
fi

# Remove flatpaks in list
if [[ -n $REMOVE_LIST ]]; then
flatpak remove --user --noninteractive $flatpak ${REMOVE_LIST[@]}
fi

notify-send "Flatpak Installer" "Finished installing user flatpaks" --app-name="Flatpak Installer" -u NORMAL

# Prevent future executions
echo "Writing state file"
mkdir -p $HOME/.config/ublue-os/
echo $VER > $VER_FILE
14 changes: 14 additions & 0 deletions files/usr/lib/systemd/system/system-flatpak-setup.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[Unit]
Description=Manage system flatpaks
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/system-flatpak-setup
Restart=on-failure
RestartSec=30
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
13 changes: 13 additions & 0 deletions files/usr/lib/systemd/user/user-flatpak-setup.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Configure Flatpaks for current user
Requires=xdg-desktop-autostart.target

[Service]
Type=simple
ExecStart=/usr/bin/user-flatpak-setup
Restart=on-failure
RestartSec=30
StartLimitInterval=0

[Install]
WantedBy=default.target
40 changes: 40 additions & 0 deletions modules/default-flatpaks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# `default-flatpaks` module for startingpoint

The `default-flatpaks` module can be used to install flatpaks from a configurable remote on first boot. This module first removes the Fedora Flatpaks remote and Flatpaks that come pre-installed in Fedora. A Flatpak remote is configured the first time the module is used, and subsequent usages of the module will install flatpaks to the same remote. If no Flatpak remote is specified, the module will default to using Flathub.

Flatpaks can either be installed system-wide or per-user, though per-user flatpaks will be installed for every user on a system. Previously-installed flatpaks can also be removed.

The module uses the following scripts to handle flatpak setup:

- `/usr/bin/system-flatpak-setup`
- `/usr/bin/user-flatpak-setup`

The scripts are run on first boot and login by these services:

- `/usr/lib/systemd/system/system-flatpak-setup.service`
- `/usr/lib/systemd/user/user-flatpak-setup-service`

`system-flatpak-setup` checks the flatpak repo information and install/remove lists created by the module. It also checks for the existence of `/etc/ublue-os/system-flatpak-configured` before running. `user-flatpak-setup` functions the same for user flatpaks, but checks for `$HOME/.config/ublue-os/user-flatpak-configured` instead.

Flatpak setup can be run again by removing `/etc/ublue-os/system-flatpak-configured` for system-wide flatpaks, or `$HOME/.config/ublue-os/user-flatpak-configured` for user flatpaks.

This module stores the Flatpak remote configuration and Flatpak install/remove lists in `/etc/flatpak/`. There are two subdirectories, `user` and `system` corresponding with the install level of the Flatpaks and repositories. Each directory has text files containing the IDs of flatpaks to `install` and `remove`, plus a `repo-info.yml` containing the details of the Flatpak repository.

## Example configuration

```yaml
- type: default-flatpaks
system:
# If no repo information is specified, Flathub will be used by default
repo-url: https://dl.flathub.org/repo/flathub.flatpakrepo
repo-name: flathub
repo-title: "Flathub (system-wide)" # Optional; this sets the remote's user-facing name in graphical frontends like GNOME Software
install:
- org.gnome.Loupe
remove:
- org.gnome.eog
# A flatpak repo can also be added without having to install flatpaks,
# as long as one of the repo- fields is present
user:
repo-name: flathub
```
86 changes: 86 additions & 0 deletions modules/default-flatpaks/default-flatpaks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env bash

# Tell build process to exit if there are any errors.
set -oue pipefail

cp -r "$BLING_DIRECTORY"/files/usr/bin/system-flatpak-setup /usr/bin/system-flatpak-setup
cp -r "$BLING_DIRECTORY"/files/usr/bin/user-flatpak-setup /usr/bin/user-flatpak-setup
cp -r "$BLING_DIRECTORY"/files/usr/lib/systemd/system/system-flatpak-setup.service /usr/lib/systemd/system/system-flatpak-setup.service
cp -r "$BLING_DIRECTORY"/files/usr/lib/systemd/user/user-flatpak-setup.service /usr/lib/systemd/user/user-flatpak-setup.service

configure_flatpak_repo () {
CONFIG_FILE=$1
INSTALL_LEVEL=$2
REPO_INFO="/usr/etc/flatpak/$INSTALL_LEVEL/repo-info.yml"
# If REPO_INFO already exists, don't re-create it
if [[ ! -f $REPO_INFO ]]; then
echo "Configuring $INSTALL_LEVEL repo in $REPO_INFO"
REPO_URL=$(echo "$CONFIG_FILE" | yq -I=0 ".$INSTALL_LEVEL.repo-url")
REPO_NAME=$(echo "$CONFIG_FILE" | yq -I=0 ".$INSTALL_LEVEL.repo-name")
REPO_TITLE=$(echo "$CONFIG_FILE" | yq -I=0 ".$INSTALL_LEVEL.repo-title")

# Use Flathub as default repo
if [[ $REPO_URL == "null" ]]; then
REPO_URL=https://dl.flathub.org/repo/flathub.flatpakrepo
fi

# If repo-name isn't configured, use flathub as fallback
# Checked separately from URL to allow custom naming
if [[ $REPO_NAME == "null" ]]; then
REPO_NAME="flathub"
fi

touch $REPO_INFO
# EOF breaks if the contents are indented,
# so the below lines are intentionally un-indented
cat > $REPO_INFO <<EOF
repo-url: "$REPO_URL"
repo-name: "$REPO_NAME"
repo-title: "$REPO_TITLE"
EOF
fi
}

configure_lists () {
CONFIG_FILE=$1
INSTALL_LEVEL=$2
INSTALL_LIST="/usr/etc/flatpak/$INSTALL_LEVEL/install"
REMOVE_LIST="/usr/etc/flatpak/$INSTALL_LEVEL/remove"
get_yaml_array INSTALL ".$INSTALL_LEVEL.install[]" "$CONFIG_FILE"
get_yaml_array REMOVE ".$INSTALL_LEVEL.remove[]" "$CONFIG_FILE"

echo "Creating $INSTALL_LEVEL Flatpak install list at $INSTALL_LIST"
if [[ ${#INSTALL[@]} -gt 0 ]]; then
touch $INSTALL_LIST
for flatpak in "${INSTALL[@]}"; do
echo "Adding to $INSTALL_LEVEL flatpak installs: $(printf ${flatpak})"
echo $flatpak >> $INSTALL_LIST
done
fi

echo "Creating $INSTALL_LEVEL Flatpak removals list $REMOVE_LIST"
if [[ ${#REMOVE[@]} -gt 0 ]]; then
touch $REMOVE_LIST
for flatpak in "${REMOVE[@]}"; do
echo "Adding to $INSTALL_LEVEL flatpak removals: $(printf ${flatpak})"
echo $flatpak >> $REMOVE_LIST
done
fi
}

echo "Enabling flatpaks module"
mkdir -p /usr/etc/flatpak/{system,user}

# Check that `system` is present before configuring
if [[ ! $(echo "$1" | yq -I=0 ".system") == "null" ]]; then
systemctl enable -f system-flatpak-setup.service
configure_flatpak_repo "$1" "system"
configure_lists "$1" "system"
fi

# Check that `user` is present before configuring
if [[ ! $(echo "$1" | yq -I=0 ".user") == "null" ]]; then
systemctl enable -f --global user-flatpak-setup.service
configure_flatpak_repo "$1" "user"
configure_lists "$1" "user"
fi

0 comments on commit 7104111

Please sign in to comment.