Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: default-flatpaks module #57

Merged
merged 33 commits into from
Oct 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
781b65d
feat: Add flatpaks module
zelikos Oct 1, 2023
4ea12c1
docs: Add README for flatpaks module
zelikos Oct 1, 2023
feef5dc
chore: Add requisite files for flatpak module
zelikos Oct 2, 2023
d91804c
refactor: Move module files into bling files directory
zelikos Oct 2, 2023
35df5c3
chore: Rename module to default-flatpaks
zelikos Oct 2, 2023
6ad9056
refactor: Use subdirs instead of filename prefixes
zelikos Oct 2, 2023
634cf88
fix: Don't rm -f on Flatpak lists before creating
zelikos Oct 3, 2023
874afef
feat(default-flatpaks): Make repo configurable
zelikos Oct 3, 2023
eff377b
docs: Explain per-user installs and how to re-run setup
zelikos Oct 3, 2023
a170c42
docs: Show repo configuration in example
zelikos Oct 3, 2023
d0e1434
docs: Mention that Fedora Flatpaks remote is removed
zelikos Oct 3, 2023
98a71af
docs: Show that flatpak remotes can be added without installing flatp…
zelikos Oct 3, 2023
7424ce8
fix: Check that flatpak repo is configured before trying to add
zelikos Oct 3, 2023
d186aac
fix: Remove fedora-testing remote too
zelikos Oct 4, 2023
3250cdc
docs: Explain flatpak module files and how they work
zelikos Oct 4, 2023
ec1389e
feat: Add output for flatpak remote configuration steps
zelikos Oct 4, 2023
5ed4c73
refactor: Use functions for flatpak config steps
zelikos Oct 5, 2023
edbbd0b
fix: Use location argument in configure_lists output
zelikos Oct 5, 2023
a774b67
docs: explain default-flatpaks /etc/flatpak/ structure
xynydev Oct 14, 2023
a5eb8a2
chore: Remove link to endlish-oesque issue
zelikos Oct 14, 2023
b007774
refactor: Install/remove flatpaks all at once, instead of one at a time
zelikos Oct 14, 2023
121cbe2
fix: Restart flatpaks setup on install failure
zelikos Oct 14, 2023
e0efeab
fix(default-flatpaks): Explicitly remove Fedora flatpaks
zelikos Oct 14, 2023
0c52920
fix(default-flatpaks): Quit gnome-software before removing Fedora rem…
zelikos Oct 14, 2023
11fe7ce
style: Fix indentation in -flatpak-setup scripts to match
zelikos Oct 14, 2023
c02b399
fix(default-flatpaks): Check if repo-info already exists before creating
zelikos Oct 14, 2023
30931ed
fix: Use Flathub as default remote for default-flatpaks
zelikos Oct 14, 2023
a4b8151
docs: Clarify default-flatpaks remote configuration
zelikos Oct 14, 2023
8251083
style: Improve readability of default-flatpaks functions
zelikos Oct 14, 2023
8bc41e6
fix(default-flatpaks): Check that system/user configuration is present
zelikos Oct 14, 2023
11dd657
feat(default-flatpaks): Send notification after successful flatpak setup
zelikos Oct 14, 2023
1c203cb
fix(default-flatpaks): Only enable system/user services if respective…
zelikos Oct 14, 2023
5e6bc4c
docs(default-flatpaks): put essential function first
xynydev Oct 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
zelikos marked this conversation as resolved.
Show resolved Hide resolved
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