diff options
Diffstat (limited to 'build_files')
| -rwxr-xr-x | build_files/build.sh | 99 | ||||
| -rwxr-xr-x | build_files/image-info | 33 | ||||
| -rwxr-xr-x | build_files/patch-bazzite-deck-identity.sh | 58 | ||||
| -rwxr-xr-x | build_files/patch-bazzite-rollback-helper.sh | 52 |
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" |
