summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTranch <tranch.xiao@gmail.com>2026-08-26 17:26:02 +0800
committerGitHub <noreply@github.com>2026-08-26 17:26:02 +0800
commit455dddfcc4f4a8bdf9f2761b52434a43c878dc21 (patch)
tree1b2f3e2356053558381673e9a1b73c4c9c92afb1
parent0cc466a5285bed432f5b706667ab185eb1a69a21 (diff)
parentc42b55f8accfea46263890323f2aedd2142fd515 (diff)
downloadAeroCore-OS-455dddfcc4f4a8bdf9f2761b52434a43c878dc21.tar.gz
AeroCore-OS-455dddfcc4f4a8bdf9f2761b52434a43c878dc21.zip
Merge pull request #23 from AeroCore-IO/fix/f44-payload-branding
Fix/f44 payload branding
-rw-r--r--.github/workflows/build-installer-iso.yml20
-rw-r--r--Containerfile2
-rwxr-xr-xbuild_files/build.sh33
-rwxr-xr-xbuild_files/image-info29
-rw-r--r--installer/Containerfile2
-rwxr-xr-xinstaller/build.sh18
-rwxr-xr-xinstaller/configure-target-gpt-root.sh1
-rwxr-xr-xjust_scripts/build-installer-iso.sh29
8 files changed, 129 insertions, 5 deletions
diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml
index da3ef10..2402dfe 100644
--- a/.github/workflows/build-installer-iso.yml
+++ b/.github/workflows/build-installer-iso.yml
@@ -68,6 +68,26 @@ jobs:
run: |
sudo podman pull "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
+ - name: Verify AeroCore install image identity
+ run: |
+ sudo podman run --rm --entrypoint /usr/bin/bash \
+ "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" -ceu '
+ system_release_target=$(readlink -f /etc/system-release)
+ if od -An -v -tx1 "$system_release_target" | awk '\''{ for (i = 1; i <= NF; i++) if ($i == "00") found = 1 } END { exit(found ? 0 : 1) }'\''; then
+ echo "NUL byte in ${system_release_target}" >&2
+ exit 1
+ fi
+ case "$(<"$system_release_target")" in
+ "AeroCore OS release $(rpm -E %fedora) ("*) ;;
+ *)
+ echo "Unexpected system-release: $(<"$system_release_target")" >&2
+ exit 1
+ ;;
+ esac
+ jq -e '\''.["image-name"] == "aerocore-os" and .["image-vendor"] == "aerocore-io"'\'' \
+ /usr/share/ublue-os/image-info.json >/dev/null
+ '
+
- name: Build installer ISO payload
run: |
mkdir -p output
diff --git a/Containerfile b/Containerfile
index be9737e..71bf132 100644
--- a/Containerfile
+++ b/Containerfile
@@ -9,7 +9,7 @@ COPY system_files /system_files
FROM ${BASE_IMAGE}
ARG BASE_IMAGE
ARG IMAGE_NAME="aerocore-os"
-ARG IMAGE_VENDOR="AeroCore-IO"
+ARG IMAGE_VENDOR="aerocore-io"
ARG IMAGE_BRANCH="stable"
ARG VERSION_TAG="latest"
ARG VERSION_PRETTY="latest"
diff --git a/build_files/build.sh b/build_files/build.sh
index 5618d20..dd58852 100755
--- a/build_files/build.sh
+++ b/build_files/build.sh
@@ -14,6 +14,39 @@ esac
# Copy the contents of system_files/ of the git repo to /
cp -avf "/ctx/system_files"/. /
+# 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
+ cp -f "${AEROCORE_DISTRIBUTOR_LOGO}" "${AEROCORE_ICON_DIR}/${icon_name}"
+done
+
+# 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/*/places; do
+ [[ -d "${icon_dir}" ]] || continue
+ source_icon="${icon_dir}/bazzite-logo-icon.png"
+ if [[ -f "${source_icon}" ]]; then
+ cp -f "${source_icon}" "${icon_dir}/start-here.png"
+ cp -f "${source_icon}" "${icon_dir}/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
diff --git a/build_files/image-info b/build_files/image-info
index bd66383..ae4406a 100755
--- a/build_files/image-info
+++ b/build_files/image-info
@@ -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,20 @@ 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.
+# Write through that link and verify the final bytes: bootupd uses this value as
+# the efibootmgr label, where even a trailing NUL makes Anaconda fail before
+# any %post installer hook can run.
+SYSTEM_RELEASE="/etc/system-release"
+SYSTEM_RELEASE_TARGET="$(readlink -f "$SYSTEM_RELEASE")"
+EXPECTED_SYSTEM_RELEASE="$IMAGE_PRETTY_NAME release $FEDORA_VERSION (Deck)"
+printf '%s\n' "$EXPECTED_SYSTEM_RELEASE" > "$SYSTEM_RELEASE"
+
+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/installer/Containerfile b/installer/Containerfile
index 32b327e..a7f1d3b 100644
--- a/installer/Containerfile
+++ b/installer/Containerfile
@@ -2,7 +2,7 @@
# The image installed to disk is supplied separately as INSTALL_IMAGE_PAYLOAD.
ARG BASE_IMAGE=ghcr.io/ublue-os/bazzite:stable
-ARG IMAGE_VENDOR=AeroCore-IO
+ARG IMAGE_VENDOR=aerocore-io
ARG IMAGE_NAME=aerocore-os
ARG INSTALL_IMAGE_PAYLOAD=ghcr.io/${IMAGE_VENDOR}/${IMAGE_NAME}:stable
ARG INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci
diff --git a/installer/build.sh b/installer/build.sh
index 937d324..e027bd6 100755
--- a/installer/build.sh
+++ b/installer/build.sh
@@ -158,6 +158,24 @@ fi
/usr/libexec/aerocore-configure-target-gpt-root \${target_root}
%end
+# Do not let stale Fedora boot files from an earlier installation collide with
+# the bootc payload being installed. This matches the upstream Bazzite
+# installer behavior; other vendor EFI directories are left untouched.
+%pre-install --erroronfail --log=/tmp/aerocore-efi-cleanup.log
+set -eux
+efi_root=
+for root in /mnt/sysroot /mnt/sysimage /var/mnt/sysroot /var/mnt/sysimage; do
+ if mountpoint -q \${root}/boot/efi; then
+ efi_root=\${root}/boot/efi
+ break
+ fi
+done
+if [ x\${efi_root} = x ]; then
+ echo No mounted EFI system partition found for cleanup >&2
+ exit 1
+fi
+rm -rf \${efi_root}/EFI/fedora
+%end
ostreecontainer --url=${INSTALL_IMAGE_PAYLOAD} --transport=containers-storage --no-signature-verification
# The local containers-storage deployment is intentionally unverified because
diff --git a/installer/configure-target-gpt-root.sh b/installer/configure-target-gpt-root.sh
index 470821e..6c1a2d1 100755
--- a/installer/configure-target-gpt-root.sh
+++ b/installer/configure-target-gpt-root.sh
@@ -17,7 +17,6 @@ if [[ ! "${source_device}" =~ ^/dev/ ]]; then
source_maj_min="$(findmnt -no MAJ:MIN --target "${target_root}")"
source_device="$(lsblk -nrpo NAME,MAJ:MIN | awk -v wanted="${source_maj_min}" '$2 == wanted { print $1; exit }')"
fi
-
case "${source_device}" in
/dev/*[0-9]) ;;
*)
diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh
index fb1f6c0..5d40a05 100755
--- a/just_scripts/build-installer-iso.sh
+++ b/just_scripts/build-installer-iso.sh
@@ -16,7 +16,10 @@ source_image="${image_name}:${image_tag}"
# origin instead of persisting the temporary localhost name. OSTREE_IMAGE_REF
# is intentionally tagless, matching the image-info contract.
image_basename="${image_name##*/}"
-ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://ghcr.io/${REPO_ORGANIZATION:-AeroCore-IO}/${image_basename}}"
+registry_organization="${REPO_ORGANIZATION:-aerocore-io}"
+registry_organization="${registry_organization,,}"
+ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://ghcr.io/${registry_organization}/${image_basename}}"
+ostree_image_ref="${ostree_image_ref,,}"
install_image_ref="${ostree_image_ref#ostree-image-signed:docker://}"
install_image_ref="${install_image_ref#ostree-unverified-registry:docker://}"
install_image_ref="${install_image_ref#docker://}"
@@ -79,8 +82,32 @@ ensure_rootful_image() {
rm -rf "${copy_tmp}"
}
+validate_install_payload() {
+ # Run on the build host rather than from installer/Containerfile. Nested
+ # Podman has no /dev/fuse in the build sandbox, while this check needs to
+ # mount the payload rootfs to inspect the bootupd label source.
+ "${podman_cmd[@]}" run --rm --network none --entrypoint /usr/bin/bash \
+ "${source_image}" -ceu '
+ system_release_target=$(readlink -f /etc/system-release)
+ if od -An -v -tx1 "$system_release_target" | awk '\''{ for (i = 1; i <= NF; i++) if ($i == "00") found = 1 } END { exit(found ? 0 : 1) }'\''; then
+ echo "Install payload has a NUL byte in ${system_release_target}" >&2
+ exit 1
+ fi
+ case "$(<"$system_release_target")" in
+ "AeroCore OS release $(rpm -E %fedora) ("*) ;;
+ *)
+ echo "Unexpected system-release: $(<"$system_release_target")" >&2
+ exit 1
+ ;;
+ esac
+ jq -e '\''.["image-name"] == "aerocore-os" and .["image-vendor"] == "aerocore-io"'\'' \
+ /usr/share/ublue-os/image-info.json >/dev/null
+ '
+}
+
mkdir -p "${output_dir}"
ensure_rootful_image
+validate_install_payload
"${podman_cmd[@]}" tag "${source_image}" "${payload}"
"${podman_cmd[@]}" save --format oci-archive --output "${payload_archive}" "${payload}"