summaryrefslogtreecommitdiff
path: root/build_files
diff options
context:
space:
mode:
Diffstat (limited to 'build_files')
-rwxr-xr-xbuild_files/build.sh99
-rwxr-xr-xbuild_files/image-info33
-rwxr-xr-xbuild_files/patch-bazzite-deck-identity.sh58
-rwxr-xr-xbuild_files/patch-bazzite-rollback-helper.sh52
4 files changed, 236 insertions, 6 deletions
diff --git a/build_files/build.sh b/build_files/build.sh
index 5618d20..40b9efd 100755
--- a/build_files/build.sh
+++ b/build_files/build.sh
@@ -14,6 +14,104 @@ esac
# Copy the contents of system_files/ of the git repo to /
cp -avf "/ctx/system_files"/. /
+# Bazzite's Kinoite/Plasma desktop shortcut used to start a privileged
+# return-to-gamemode.service. Current Bazzite invokes the user-session entry
+# point directly; keep the shortcut correct when the base image still ships
+# the legacy Exec= line.
+RETURN_TO_GAMING_DESKTOP="/etc/skel/Desktop/Return.desktop"
+if [[ -f "${RETURN_TO_GAMING_DESKTOP}" ]]; then
+ sed -i 's|^Exec=.*|Exec=/usr/bin/return-to-gamemode|' "${RETURN_TO_GAMING_DESKTOP}"
+fi
+
+# ujust loads explicit imports, not every fragment in the just/ directory.
+# Preserve upstream recipes and register our overlay after copying its files.
+AEROCORE_DECKY_IMPORT='import "/usr/share/ublue-os/just/92-aerocore-decky-mirror.just"'
+if ! grep -Fxq "${AEROCORE_DECKY_IMPORT}" /usr/share/ublue-os/justfile; then
+ printf '\n%s\n' "${AEROCORE_DECKY_IMPORT}" >> /usr/share/ublue-os/justfile
+fi
+# Fail the image build if the public entry point cannot resolve the recipe.
+ujust --show setup-decky-mirror >/dev/null
+
+install_regular_file() {
+ local source_file="$1"
+ local destination_file="$2"
+
+ # Several Bazzite branding paths are symlinks. cp follows an existing
+ # destination symlink, which leaves the name Plasma resolves untouched.
+ # Replace the link itself so the final immutable image owns this exact path.
+ rm -f -- "${destination_file}"
+ install -Dm0644 -- "${source_file}" "${destination_file}"
+}
+
+# KDE's Deck presets use distributor-logo-steamdeck.svg for the Kickoff
+# launcher. In the Bazzite base image that name (and the related aliases)
+# may already exist as links to the upstream distributor-logo.svg. Install
+# the AeroCore asset explicitly after the general overlay so the final image
+# cannot silently retain the upstream Bazzite logo.
+AEROCORE_DISTRIBUTOR_LOGO="/ctx/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo.svg"
+AEROCORE_ICON_DIR="/usr/share/icons/hicolor/scalable/places"
+mkdir -p "${AEROCORE_ICON_DIR}"
+for icon_name in \
+ distributor-logo.svg \
+ distributor-logo-steamdeck.svg \
+ bazzite-logo.svg \
+ start-here.svg; do
+ install_regular_file "${AEROCORE_DISTRIBUTOR_LOGO}" "${AEROCORE_ICON_DIR}/${icon_name}"
+done
+
+# Use a downstream-specific, non-upstream icon name for Plasma's launcher.
+install_regular_file \
+ "/ctx/system_files/usr/share/pixmaps/bazzite-logo-le.svg" \
+ "/usr/share/icons/hicolor/scalable/apps/aerocore-logo.svg"
+
+# KDE's About System KCM loads this path from kcm-about-distrorc. The base
+# image may provide it as a symlink, so replace the directory entry itself or
+# the KCM can continue rendering the upstream Bazzite logo.
+install_regular_file \
+ "/ctx/system_files/usr/share/pixmaps/system-logo-white.png" \
+ "/usr/share/pixmaps/system-logo-white.png"
+
+# Game Mode's Vapor splash asset is an upstream symlink on current Bazzite
+# images, while VGUI is a regular file. Replace both exact paths explicitly.
+for look_and_feel in com.valve.vapor.desktop com.valve.vgui.desktop; do
+ install_regular_file \
+ "/ctx/system_files/usr/share/plasma/look-and-feel/${look_and_feel}/contents/splash/images/bazzite_logo.svgz" \
+ "/usr/share/plasma/look-and-feel/${look_and_feel}/contents/splash/images/bazzite_logo.svgz"
+done
+
+# Steam's Game Mode transitions load these four assets directly. They are
+# symlinks in some upstream layers, so replace their directory entries just
+# like the Plasma splash assets above.
+for animation in \
+ bazzite.webm \
+ bazzite-oled.webm \
+ bazzite-suspend.webm \
+ bazzite-suspend-oled.webm; do
+ install_regular_file \
+ "/ctx/system_files/usr/share/ublue-os/bazzite/${animation}" \
+ "/usr/share/ublue-os/bazzite/${animation}"
+done
+
+gtk-update-icon-cache -f /usr/share/icons/hicolor || true
+
+# The Plasma launcher resolves the standard start-here name from both scalable
+# and per-size places directories. Populate every existing Bazzite icon size
+# in the installed payload, not only in the live installer image.
+for icon_dir in /usr/share/icons/hicolor/*; do
+ [[ -d "${icon_dir}" ]] || continue
+ source_icon="${icon_dir}/bazzite-logo-icon.png"
+ if [[ -f "${source_icon}" ]]; then
+ mkdir -p "${icon_dir}/apps" "${icon_dir}/places"
+ cp -f "${source_icon}" "${icon_dir}/places/start-here.png"
+ cp -f "${source_icon}" "${icon_dir}/apps/fedora-logo-icon.png"
+ fi
+done
+
+if ! cmp -s "${AEROCORE_DISTRIBUTOR_LOGO}" "${AEROCORE_ICON_DIR}/distributor-logo.svg"; then
+ echo "AeroCore distributor logo was not installed into the image" >&2
+ exit 1
+fi
+
# Default HDMI-CEC to putting the TV into standby when the system sleeps.
# `ujust toggle-cec-sleep enable` changes this same setting at runtime. Keep
# the default in the base image's config so users do not need to run the
@@ -58,3 +156,4 @@ find /etc/environment.d /etc/skel/.config/environment.d -name 99-aerocore-mirror
/ctx/install-instruments.sh
/ctx/patch-bazzite-deck-identity.sh
+/ctx/patch-bazzite-rollback-helper.sh
diff --git a/build_files/image-info b/build_files/image-info
index bd66383..71ab60f 100755
--- a/build_files/image-info
+++ b/build_files/image-info
@@ -31,7 +31,7 @@ cat > "$IMAGE_INFO" <<EOF
"image-name": "$IMAGE_NAME",
"image-vendor": "$IMAGE_VENDOR",
"image-ref": "$IMAGE_REF",
- "image-tag": "stable",
+ "image-tag": "$IMAGE_BRANCH_NORMALIZED",
"image-branch": "$IMAGE_BRANCH_NORMALIZED",
"base-image-name": "$BASE_IMAGE_NAME",
"fedora-version": "$FEDORA_VERSION",
@@ -40,6 +40,20 @@ cat > "$IMAGE_INFO" <<EOF
}
EOF
+# Fail the image build if the metadata file was not rewritten with the
+# downstream identity. A base Bazzite image can otherwise leave a plausible
+# looking build with image-info.json still claiming bazzite-deck.
+if [[ "$IMAGE_NAME" != "aerocore-os" || "$IMAGE_VENDOR" != "aerocore-io" ]]; then
+ echo "Unexpected AeroCore image identity: ${IMAGE_VENDOR}/${IMAGE_NAME}" >&2
+ exit 1
+fi
+
+jq -e \
+ --arg image_name "$IMAGE_NAME" \
+ --arg image_vendor "$IMAGE_VENDOR" \
+ '.["image-name"] == $image_name and .["image-vendor"] == $image_vendor and .["image-ref"] != null' \
+ "$IMAGE_INFO" >/dev/null
+
# Keep the display name consistent across desktop settings and os-release.
sed -i "s/^VARIANT_ID=.*/VARIANT_ID=$IMAGE_ID/" /usr/lib/os-release
sed -i "s/^PRETTY_NAME=.*/PRETTY_NAME=\"$IMAGE_PRETTY_NAME\"/" /usr/lib/os-release
@@ -56,7 +70,22 @@ sed -i "s/^ANSI_COLOR=.*/ANSI_COLOR=\"$LOGO_COLOR\"/" /usr/lib/os-release
sed -i "/^REDHAT_BUGZILLA_PRODUCT=/d; /^REDHAT_BUGZILLA_PRODUCT_VERSION=/d; /^REDHAT_SUPPORT_PRODUCT=/d; /^REDHAT_SUPPORT_PRODUCT_VERSION=/d" /usr/lib/os-release
sed -i "s|^VERSION_CODENAME=.*|VERSION_CODENAME=\"Deck\"|" /usr/lib/os-release
-echo "$IMAGE_PRETTY_NAME release $FEDORA_VERSION (Deck)" > /etc/system-release
+# /etc/system-release is normally a symlink to the RPM-owned fedora-release.
+# Keep that relationship, but replace the target inode explicitly. This
+# avoids relying on an in-place write through an RPM-owned symlink, which can
+# be lost while the bootc/ostree image is assembled, leaving Anaconda to read
+# the upstream file (which may contain a trailing NUL).
+SYSTEM_RELEASE="/etc/system-release"
+SYSTEM_RELEASE_TARGET="$(readlink -f "$SYSTEM_RELEASE")"
+EXPECTED_SYSTEM_RELEASE="$IMAGE_PRETTY_NAME release $FEDORA_VERSION (Deck)"
+rm -f -- "$SYSTEM_RELEASE_TARGET"
+printf '%s\n' "$EXPECTED_SYSTEM_RELEASE" > "$SYSTEM_RELEASE_TARGET"
+
+if ! cmp -s <(printf '%s\n' "$EXPECTED_SYSTEM_RELEASE") "$SYSTEM_RELEASE_TARGET"; then
+ echo "Failed to write a clean AeroCore system-release to ${SYSTEM_RELEASE_TARGET}" >&2
+ od -An -v -tx1 "$SYSTEM_RELEASE_TARGET" >&2
+ exit 1
+fi
if grep -q '^BUILD_ID=' /usr/lib/os-release; then
sed -i "s/^BUILD_ID=.*/BUILD_ID=\"$VERSION_PRETTY\"/" /usr/lib/os-release
diff --git a/build_files/patch-bazzite-deck-identity.sh b/build_files/patch-bazzite-deck-identity.sh
index ea561e4..d3ee860 100755
--- a/build_files/patch-bazzite-deck-identity.sh
+++ b/build_files/patch-bazzite-deck-identity.sh
@@ -110,6 +110,54 @@ patch_steam_state_migration() {
fi
}
+patch_desktop_branding_migration() {
+ local file="$1"
+ local marker='AeroCore desktop branding migration'
+ local condition='pkexec /usr/libexec/bazzite-privileged-user-setup "$USER"'
+ local patched_file
+
+ if [[ ! -f "$file" ]]; then
+ echo "Unable to locate expected Bazzite user setup file: $file" >&2
+ exit 1
+ fi
+
+ if grep -Fq "$marker" "$file"; then
+ return 0
+ fi
+
+ if [[ "$(grep -Foc "$condition" "$file" || true)" -ne 1 ]]; then
+ echo "Unable to locate the Bazzite privileged user setup call in $file" >&2
+ exit 1
+ fi
+
+ patched_file="$(mktemp)"
+ awk -v condition="$condition" '
+ !inserted && $0 == condition {
+ print
+ print ""
+ print " # AeroCore desktop branding migration"
+ print " # The image contains the correct defaults. This only repairs values"
+ print " # persisted by an older Bazzite/AeroCore deployment."
+ print " if [[ -f /etc/xdg/kcm-about-distrorc ]] && grep -Fxq \"Name=Bazzite\" /etc/xdg/kcm-about-distrorc; then"
+ print " pkexec /usr/libexec/aerocore-desktop-branding-privileged"
+ print " fi"
+ print " /usr/libexec/aerocore-desktop-branding"
+ inserted=1
+ next
+ }
+ { print }
+ END { if (!inserted) exit 1 }
+ ' "$file" > "$patched_file"
+
+ cp "$patched_file" "$file"
+ rm -f "$patched_file"
+
+ if ! grep -Fq "$marker" "$file"; then
+ echo "Failed to add the AeroCore desktop branding migration to $file" >&2
+ exit 1
+ fi
+}
+
# Keep AeroCore's public image-name, while restoring the Deck capability checks
# used by Bazzite's runtime scripts. These are literal source lines; variable
# expansion must happen later, when the scripts run on the installed system.
@@ -125,8 +173,8 @@ patch_condition \
# shellcheck disable=SC2016
patch_condition \
"${1:-$(target_path /usr/libexec/bazzite-hardware-setup)}" \
- 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME =~ "ally" ]]; then' \
- 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME =~ "ally" || $IMAGE_NAME == aerocore-os ]]; then' \
+ 'if [[ $IMAGE_NAME =~ "deck" ]]; then' \
+ 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME == aerocore-os ]]; then' \
1
# bazzite-steam gates the Steam bootstrap archive and -steamdeck flag on the
@@ -144,6 +192,8 @@ patch_steam_state_migration "$(target_path /usr/bin/bazzite-steam)"
# shellcheck disable=SC2016
patch_condition \
"$(target_path /usr/libexec/bazzite-user-setup)" \
- 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME =~ "ally" ]]; then' \
- 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME =~ "ally" || $IMAGE_NAME == aerocore-os ]]; then' \
+ 'if [[ $IMAGE_NAME =~ "deck" ]]; then' \
+ 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME == aerocore-os ]]; then' \
3
+
+patch_desktop_branding_migration "$(target_path /usr/libexec/bazzite-user-setup)"
diff --git a/build_files/patch-bazzite-rollback-helper.sh b/build_files/patch-bazzite-rollback-helper.sh
new file mode 100755
index 0000000..6d565b0
--- /dev/null
+++ b/build_files/patch-bazzite-rollback-helper.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/bash
+
+set -euo pipefail
+
+file=/usr/bin/bazzite-rollback-helper
+
+if [[ ! -f "$file" ]]; then
+ echo "Unable to locate Bazzite rollback helper: $file" >&2
+ exit 1
+fi
+
+if grep -Fq 'current_image_prefix()' "$file"; then
+ exit 0
+fi
+
+patched_file=$(mktemp)
+awk '
+ /^signing_scheme\(\) \{/ {
+ print "signing_scheme() {"
+ print " local current=$(rpm-ostree status -b --json | jq -r '\''.deployments | map(select(.booted == true)) | first | .[\"container-image-reference\"] // empty'\'')"
+ print " local scheme=\"ostree-unverified-registry\""
+ print " [[ \"$current\" == *\"ostree-image-signed\"* ]] && scheme=\"ostree-image-signed\""
+ print " echo \"$scheme:docker://\""
+ print "}"
+ print ""
+ print "current_image_prefix() {"
+ print " local current"
+ print " current=$(rpm-ostree status -b --json | jq -r '\''.deployments | map(select(.booted == true)) | first | .[\"container-image-reference\"] // empty'\'')"
+ print " if [[ -z \"$current\" ]]; then"
+ print " echo \"Unable to determine the current booted image reference.\" >&2"
+ print " return 1"
+ print " fi"
+ print " current=\"${current#ostree-image-signed:}\""
+ print " current=\"${current#ostree-unverified-registry:}\""
+ print " current=\"${current#docker://}\""
+ print " echo \"${current%/*}\""
+ print "}"
+ skip=1
+ next
+ }
+ skip && /^warn_if_de_mismatch\(\) \{/ { skip=0; print; next }
+ skip { next }
+ {
+ gsub("ostree-image-signed:docker://[^\"]+/", "$(signing_scheme)$(current_image_prefix)/")
+ gsub("\\$\\(signing_scheme\\)/\\$\\(current_image_prefix\\)/", "$(signing_scheme)$(current_image_prefix)/")
+ gsub("\\$\\(signing_scheme\\)/", "$(signing_scheme)")
+ print
+ }
+' "$file" > "$patched_file"
+
+install -m 0755 "$patched_file" "$file"
+rm -f "$patched_file"