particle-os-modules/modules/default-flatpaks/v1/system-flatpak-setup
fiftydinar 128de83a78
chore(default-flatpaks): Don't quit Gnome Software if it's not installed & adjust fedora-third-party messaging
If `fedora-third-party` package is removed, then there's no need to disable the Fedora 3rd party repos through `fedora-third-party` CLI.
2025-05-16 13:24:56 +02:00

286 lines
14 KiB
Bash
Executable file

#!/usr/bin/env bash
# Check for available internet connection before proceeding (network-online.target doesn't work for some network connections)
# Check it 3 times in 2 second interval, to avoid until loop
# Used when adding remotes & when installing flatpaks
check_internet_connection() {
local max_attempts=3
local sleep_time=2
local attempt=1
while (( attempt <= max_attempts )); do
if curl --silent --head --fail "https://fedoraproject.org/static/hotspot.txt" > /dev/null; then
return 0
else
echo "Internet connection is not available. Waiting..."
sleep ${sleep_time}
(( attempt++ ))
fi
done
return 1
}
REPO_INFO="/usr/share/bluebuild/default-flatpaks/system/repo-info.json"
REPO_URL=$(jq -r 'try .["repo-url"]' $REPO_INFO)
REPO_NAME=$(jq -r 'try .["repo-name"]' $REPO_INFO)
REPO_TITLE=$(jq -r 'try .["repo-title"]' $REPO_INFO)
# Opt out of and remove Fedora's system flatpak repos
FLATPAK_SYSTEM_REMOTES=($(flatpak --system remotes))
fedora_system=false
fedora_testing_system=false
for system_remote in "${FLATPAK_SYSTEM_REMOTES[@]}"; do
if [[ "${system_remote}" == "fedora" ]]; then
fedora_system=true
elif [[ "${system_remote}" == "fedora-testing" ]]; then
fedora_testing_system=true
fi
done
if rpm -q fedora-third-party &>/dev/null; then
if [[ ! "$(fedora-third-party query)" == *"disabled." ]]; then
echo "Disabling Fedora third-party repos..."
if command -v gnome-software &> /dev/null; then
/usr/bin/gnome-software --quit
fi
/usr/lib/fedora-third-party/fedora-third-party-opt-out
/usr/bin/fedora-third-party disable
else
echo "Fedora third-party repos are already disabled"
fi
else
echo "There is no need to opt-out from Fedora 3rd party repos, because 'fedora-third-party' package is already removed."
fi
# Remove fedora system remote, unless fedora remote is strictly specified
if [[ ! "${REPO_URL}" == "oci+https://registry.fedoraproject.org" ]]; then
if "${fedora_system}"; then
echo "Removing system flatpak remote 'fedora'"
flatpak remote-delete --system fedora --force
else
echo "System flatpak remote 'fedora' is already removed"
fi
else
echo "Not removing the system flatpak remote 'fedora', as it's specified for use in config"
fi
if "${fedora_testing_system}"; then
echo "Removing system flatpak remote 'fedora-testing'"
flatpak remote-delete --system fedora-testing --force
else
echo "System flatpak remote 'fedora-testing' is already removed"
fi
# Remove flatpak apps from system origin fedora, unless fedora remote is strictly specified
if [[ ! "${REPO_URL}" == "oci+https://registry.fedoraproject.org" ]]; then
FEDORA_FLATPAKS_APP=($(flatpak list --system --app --columns=application,origin | awk '$2 == "fedora" {print $1}'))
if [[ ${#FEDORA_FLATPAKS_APP[@]} -gt 0 ]]; then
echo "Removing system flatpak apps from 'fedora' remote"
flatpak remove --system --noninteractive "${FEDORA_FLATPAKS_APP[@]}"
else
echo "System flatpak apps from 'fedora' remote are already removed"
fi
else
echo "Not automatically removing all flatpak apps from system remote 'fedora', as it's specified for use in config"
fi
# Remove flatpak runtimes from system origin fedora, unless fedora remote is strictly specified
if [[ ! "${REPO_URL}" == "oci+https://registry.fedoraproject.org" ]]; then
FEDORA_FLATPAKS_RUNTIME=($(flatpak list --system --runtime --columns=application,arch,branch,origin | awk '$4 == "fedora" {print $1"/"$2"/"$3}'))
if [[ ${#FEDORA_FLATPAKS_RUNTIME[@]} -gt 0 ]]; then
echo "Removing system flatpak runtimes from 'fedora' remote"
flatpak remove --system --noninteractive "${FEDORA_FLATPAKS_RUNTIME[@]}"
else
echo "System flatpak runtimes from 'fedora' remote are already removed"
fi
else
echo "Not automatically removing all flatpak runtimes from system remote 'fedora', as it's specified for use in config"
fi
# Remove flatpak apps from system origin fedora-testing
FEDORA_TESTING_FLATPAKS_APP=($(flatpak list --system --app --columns=application,origin | awk '$2 == "fedora-testing" {print $1}'))
if [[ ${#FEDORA_TESTING_FLATPAKS_APP[@]} -gt 0 ]]; then
echo "Removing system flatpak apps from 'fedora-testing' remote"
flatpak remove --system --noninteractive "${FEDORA_TESTING_FLATPAKS_APP[@]}"
else
echo "System flatpak apps from 'fedora-testing' remote are already removed"
fi
# Remove flatpak runtimes from system origin fedora-testing
FEDORA_TESTING_FLATPAKS_RUNTIME=($(flatpak list --system --runtime --columns=application,arch,branch,origin | awk '$4 == "fedora-testing" {print $1"/"$2"/"$3}'))
if [[ ${#FEDORA_TESTING_FLATPAKS_RUNTIME[@]} -gt 0 ]]; then
echo "Removing system flatpak runtimes from 'fedora-testing' remote"
flatpak remove --system --noninteractive "${FEDORA_TESTING_FLATPAKS_RUNTIME[@]}"
else
echo "System flatpak runtimes from 'fedora-testing' remote are already removed"
fi
# General conditions for not running the unnecessary flatpak setup
# Currently, we don't modify remote title if it's already modified
# Flatpak add remote is ran for some reason, even with --if-not-exists flag, apparently, it modifies the URL
# We cannot compare repo URLs properly
# Flatpak outputs repo URL, while we have flatpakref URL, which is not the same
no_title_modify=false
readarray -t CURRENT_REPO_INFO < <(flatpak remotes --system --columns=name,url,title)
for index in "${CURRENT_REPO_INFO[@]}"; do
CURRENT_REPO_NAMES+=("$(echo "${index}" | awk '{print $1}')")
CURRENT_REPO_TITLES+=("$(echo "${index}" | awk '{ for(i=3;i<NF;i++) printf "%s ", $i; print $NF }')")
for name in "${CURRENT_REPO_NAMES[@]}"; do
for title in "${CURRENT_REPO_TITLES[@]}"; do
if [[ "${name}" == "${REPO_NAME}" ]] && [[ "${title}" == "${REPO_TITLE}" ]]; then
no_title_modify=true
fi
done
done
done
# Set up system-wide Flatpak repository
if [[ $REPO_URL != "null" && $REPO_NAME != "null" ]]; then
if check_internet_connection; then
echo "Adding system-wide remote $REPO_NAME from $REPO_URL if it doesn't exist (requires internet)"
flatpak remote-add --if-not-exists --system "$REPO_NAME" "$REPO_URL"
else
echo "NOTE: Skipping the addition of system-wide remote, because there is no internet connection"
fi
fi
# If configured remote is flathub, enable it here.
# Flathub is already installed in Fedora, but not enabled by default,
# so the above command won't add it again
if [[ $REPO_NAME == "flathub" ]]; then
echo "Enabling specified 'flathub' remote, that is already installed, but disabled in Fedora"
flatpak remote-modify --system "$REPO_NAME" --enable
fi
# Change repository title to configured title, if not null & if not already changed
if [[ $REPO_TITLE != "null" ]] && ! ${no_title_modify}; then
echo "Setting title $REPO_TITLE for system remote $REPO_NAME"
flatpak remote-modify --system "$REPO_NAME" --title="$REPO_TITLE"
elif [[ $REPO_TITLE != "null" ]] && ${no_title_modify}; then
echo "Custom flatpak system remote title is already set"
fi
# Notifications config
NOTIFICATIONS_FILE="/usr/share/bluebuild/default-flatpaks/notifications"
USER_NOTIFICATIONS_FILE="/etc/bluebuild/default-flatpaks/notifications"
# Ignore words starting with # symbol, whitelines & duplicate entries for notifications config
MAINTAINER_NOTIFICATIONS=$(cat "$NOTIFICATIONS_FILE" | grep -v -E '^#|^$' | awk '!seen[$0]++')
USER_NOTIFICATIONS=$(cat "$USER_NOTIFICATIONS_FILE" | grep -v -E '^#|^$' | awk '!seen[$0]++')
# If user modified notifications config, utilize user's configuration, otherwise maintainer's
if [[ -n $USER_NOTIFICATIONS ]]; then
NOTIFICATIONS="$USER_NOTIFICATIONS"
else
NOTIFICATIONS="$MAINTAINER_NOTIFICATIONS"
fi
# Installed flatpaks
FLATPAK_LIST=$(flatpak list --system --app --columns=application)
# Flatpak list files
INSTALL_LIST_FILE="/usr/share/bluebuild/default-flatpaks/system/install"
REMOVE_LIST_FILE="/usr/share/bluebuild/default-flatpaks/system/remove"
USER_INSTALL_LIST_FILE="/etc/bluebuild/default-flatpaks/system/install"
USER_REMOVE_LIST_FILE="/etc/bluebuild/default-flatpaks/system/remove"
# Prefer user's install + remove list over maintainer's, in case when same flatpak ID is present in maintainer's install list + user's remove list & vice-versa
# Also ignores words starting with # symbol, whitelines & duplicate entries
MAINTAINER_INSTALL_LIST=$(comm -23 <(sort "$INSTALL_LIST_FILE") <(sort "$USER_REMOVE_LIST_FILE") | grep -v -E '^#|^$' | awk '!seen[$0]++')
MAINTAINER_REMOVE_LIST=$(comm -23 <(sort "$REMOVE_LIST_FILE") <(sort "$USER_INSTALL_LIST_FILE") | grep -v -E '^#|^$' | awk '!seen[$0]++')
# Combine maintainer & user list. Ignore words starting with # symbol, whitelines & duplicate entries
COMBINED_INSTALL_LIST=$(cat <(echo "$MAINTAINER_INSTALL_LIST") "$USER_INSTALL_LIST_FILE" | grep -v -E '^#|^$' | awk '!seen[$0]++')
COMBINED_REMOVE_LIST=$(cat <(echo "$MAINTAINER_REMOVE_LIST") "$USER_REMOVE_LIST_FILE" | grep -v -E '^#|^$' | awk '!seen[$0]++')
# Loginctl has different command for parsing json since v256 (F41), so handle that scenario here
LOGINCTL_VERSION=$(loginctl --version | awk 'NR==1 {print $2}')
function notify-send-pre-install {
if [[ ${LOGINCTL_VERSION} -ge 256 ]]; then
user_name=$(loginctl list-users -j | jq -r '.[] | select(.state == "active") | .user')
uid=$(loginctl list-users -j | jq -r '.[] | select(.state == "active") | .uid')
else
user_name=$(loginctl list-users --output=json | jq -r '.[] | select(.state == "active") | .user')
uid=$(loginctl list-users --output=json | jq -r '.[] | select(.state == "active") | .uid')
fi
xdg_runtime_path="/run/user/$uid"
sudo -u "$user_name" DBUS_SESSION_BUS_ADDRESS=unix:path="$xdg_runtime_path"/bus notify-send "Flatpak Installer" "Started install of system flatpaks" --app-name="Flatpak Installer" -u NORMAL
}
function notify-send-install {
if [[ ${LOGINCTL_VERSION} -ge 256 ]]; then
user_name=$(loginctl list-users -j | jq -r '.[] | select(.state == "active") | .user')
uid=$(loginctl list-users -j | jq -r '.[] | select(.state == "active") | .uid')
else
user_name=$(loginctl list-users --output=json | jq -r '.[] | select(.state == "active") | .user')
uid=$(loginctl list-users --output=json | jq -r '.[] | select(.state == "active") | .uid')
fi
xdg_runtime_path="/run/user/$uid"
sudo -u "$user_name" DBUS_SESSION_BUS_ADDRESS=unix:path="$xdg_runtime_path"/bus notify-send "Flatpak Installer" "Finished install of system flatpaks:\n$INSTALL_LIST" --app-name="Flatpak Installer" -u NORMAL
}
function notify-send-pre-uninstall {
if [[ ${LOGINCTL_VERSION} -ge 256 ]]; then
user_name=$(loginctl list-users -j | jq -r '.[] | select(.state == "active") | .user')
uid=$(loginctl list-users -j | jq -r '.[] | select(.state == "active") | .uid')
else
user_name=$(loginctl list-users --output=json | jq -r '.[] | select(.state == "active") | .user')
uid=$(loginctl list-users --output=json | jq -r '.[] | select(.state == "active") | .uid')
fi
xdg_runtime_path="/run/user/$uid"
sudo -u "$user_name" DBUS_SESSION_BUS_ADDRESS=unix:path="$xdg_runtime_path"/bus notify-send "Flatpak Installer" "Started uninstall of some system flatpaks" --app-name="Flatpak Installer" -u NORMAL
}
function notify-send-uninstall {
if [[ ${LOGINCTL_VERSION} -ge 256 ]]; then
user_name=$(loginctl list-users -j | jq -r '.[] | select(.state == "active") | .user')
uid=$(loginctl list-users -j | jq -r '.[] | select(.state == "active") | .uid')
else
user_name=$(loginctl list-users --output=json | jq -r '.[] | select(.state == "active") | .user')
uid=$(loginctl list-users --output=json | jq -r '.[] | select(.state == "active") | .uid')
fi
xdg_runtime_path="/run/user/$uid"
sudo -u "$user_name" DBUS_SESSION_BUS_ADDRESS=unix:path="$xdg_runtime_path"/bus notify-send "Flatpak Installer" "Finished uninstall of system flatpaks:\n$REMOVE_LIST" --app-name="Flatpak Installer" -u NORMAL
}
# Remove flatpaks in list
if [[ -f $REMOVE_LIST_FILE ]] || [[ -f $USER_REMOVE_LIST_FILE ]]; then
REMOVE_LIST=$(comm -12 <(echo "$COMBINED_REMOVE_LIST" | sort) <(echo "$FLATPAK_LIST" | sort))
if [[ -n $REMOVE_LIST ]] && [[ ! $NOTIFICATIONS == "true" ]]; then
echo "Removing system flatpaks from config list"
flatpak uninstall --system --noninteractive ${REMOVE_LIST[@]}
elif [[ -n $REMOVE_LIST ]] && [[ $NOTIFICATIONS == "true" ]]; then
echo "Removing system flatpaks from config list"
notify-send-pre-uninstall
flatpak uninstall --system --noninteractive ${REMOVE_LIST[@]}
notify-send-uninstall
fi
fi
# Install flatpaks in list
if [[ -f $INSTALL_LIST_FILE ]] || [[ -f $USER_INSTALL_LIST_FILE ]]; then
if [[ -n $FLATPAK_LIST ]]; then
INSTALL_LIST=$(comm -23 <(echo "$COMBINED_INSTALL_LIST" | sort) <(echo "$FLATPAK_LIST" | sort))
else
INSTALL_LIST="$COMBINED_INSTALL_LIST"
fi
if [[ -n $INSTALL_LIST ]] && [[ ! $NOTIFICATIONS == "true" ]]; then
if check_internet_connection; then
echo "Installing system flatpaks from config list (requires internet)"
flatpak install --system --noninteractive "$REPO_NAME" ${INSTALL_LIST[@]}
else
echo "ERROR: Installation of system flatpaks was not performed, because there was no internet connection"
exit 1
fi
elif [[ -n $INSTALL_LIST ]] && [[ $NOTIFICATIONS == "true" ]]; then
if check_internet_connection; then
echo "Installing system flatpaks from config list (requires internet)"
notify-send-pre-install
flatpak install --system --noninteractive "$REPO_NAME" ${INSTALL_LIST[@]}
notify-send-install
else
echo "ERROR: Installation of system flatpaks was not performed, because there was no internet connection"
exit 1
fi
fi
fi