summaryrefslogtreecommitdiff
path: root/installer
diff options
context:
space:
mode:
authortranch <tranch.xiao@gmail.com>2026-09-13 19:18:04 +0800
committertranch <tranch.xiao@gmail.com>2026-09-13 19:18:04 +0800
commit796c6c8a70c92d4675df7c2ec2d25ecda139d723 (patch)
tree06c6d3e7788d7b2ad5ddd0565e2651c0c8d9d151 /installer
parentab070aec5f1d760a2539e14cb19da61593bded15 (diff)
parentd734f2c746632772b794143762f2fcea78e62011 (diff)
downloadAeroCore-OS-796c6c8a70c92d4675df7c2ec2d25ecda139d723.tar.gz
AeroCore-OS-796c6c8a70c92d4675df7c2ec2d25ecda139d723.zip
Merge testing into main for 44.x stable release44.20260913
Diffstat (limited to 'installer')
-rw-r--r--installer/Containerfile2
-rwxr-xr-xinstaller/build.sh67
-rwxr-xr-xinstaller/configure-target-gpt-root.sh39
-rw-r--r--installer/system_files/overrides/etc/anaconda/profile.d/aerocore.conf36
4 files changed, 139 insertions, 5 deletions
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 4535113..34c55b7 100755
--- a/installer/build.sh
+++ b/installer/build.sh
@@ -9,6 +9,11 @@ INSTALL_IMAGE_PAYLOAD_ARCHIVE=${INSTALL_IMAGE_PAYLOAD_ARCHIVE:-}
INSTALL_IMAGE_TAG=${INSTALL_IMAGE_TAG:?}
OSTREE_IMAGE_REF=${OSTREE_IMAGE_REF:?}
ostree_origin_ref="${OSTREE_IMAGE_REF}:${INSTALL_IMAGE_TAG}"
+live_version_id="$(awk -F= '$1 == "VERSION_ID" { gsub(/\"/, "", $2); print $2; exit }' /usr/lib/os-release)"
+
+# The live image may ship /root as a symlink. Ensure its target exists before
+# systemd-tmpfiles and other early-boot services process root-owned paths.
+mkdir -p "$(realpath /root)"
# The installer is a live KDE environment. Keep the installed system payload
# separate: it is the AeroCore image, while BASE_IMAGE provides the live UI.
@@ -22,6 +27,7 @@ dnf --setopt=excludepkgs= install -y \
libblockdev-lvm \
dracut-live \
livesys-scripts \
+ gdisk \
grub2-efi-x64 \
grub2-efi-x64-cdboot
@@ -32,15 +38,26 @@ dnf --setopt=excludepkgs= reinstall -y \
grub2-efi-x64-cdboot
# Fedora 43's anaconda-webui bundle embeds a Cockpit password helper from
-# before cockpit-project/cockpit@900c13f. Restore that upstream fix so a weak
-# pwscore result is returned as score 0 instead of rejecting the WebUI promise.
-"${SCRIPT_DIR}/patch-anaconda-webui.sh"
+# before cockpit-project/cockpit@900c13f. Fedora 44 already carries the fix;
+# retain the workaround only for explicitly requested Fedora 43 live images.
+if [[ "${live_version_id}" == "43" ]]; then
+ "${SCRIPT_DIR}/patch-anaconda-webui.sh"
+fi
# Apply the same AeroCore overlay to the live session where possible.
if [[ -d /src/system_files ]]; then
cp -a /src/system_files/. /
fi
+# The live base can already contain this About System asset as a symlink.
+# Replace the link itself so the installer UI also renders AeroCore branding.
+if [[ -f /src/system_files/usr/share/pixmaps/system-logo-white.png ]]; then
+ rm -f /usr/share/pixmaps/system-logo-white.png
+ install -Dm0644 \
+ /src/system_files/usr/share/pixmaps/system-logo-white.png \
+ /usr/share/pixmaps/system-logo-white.png
+fi
+
BRANDING_DIR="${SCRIPT_DIR}/branding"
if [[ -d "${BRANDING_DIR}" ]]; then
mkdir -p /usr/share/anaconda/pixmaps
@@ -59,6 +76,10 @@ install -Dm0755 \
"${SCRIPT_DIR}/configure-target-grub.sh" \
/usr/libexec/aerocore-configure-target-grub
+install -Dm0755 \
+ "${SCRIPT_DIR}/configure-target-gpt-root.sh" \
+ /usr/libexec/aerocore-configure-target-gpt-root
+
# Plasma's live-session launcher defaults to start-here, and Fedora keeps
# LOGO=fedora-logo-icon in the base live environment.
for size in 16x16 22x22 24x24 32x32 36x36 48x48 64x64 96x96 128x128 256x256; do
@@ -78,10 +99,10 @@ if [[ -f /usr/share/icons/hicolor/scalable/places/distributor-logo.svg ]]; then
/usr/share/icons/hicolor/scalable/places/start-here.svg
fi
-live_version_id="$(awk -F= '$1 == "VERSION_ID" { gsub(/\"/, "", $2); print $2; exit }' /usr/lib/os-release)"
live_product_name="AeroCore OS"
sed -i "s/^NAME=.*/NAME=\"${live_product_name}\"/" /usr/lib/os-release
sed -i "s/^PRETTY_NAME=.*/PRETTY_NAME=\"${live_product_name} ${live_version_id} (Kinoite)\"/" /usr/lib/os-release
+sed -i 's/^ID=.*/ID=aerocore/' /usr/lib/os-release
sed -i "s/^LOGO=.*/LOGO=distributor-logo/" /usr/lib/os-release
printf '%s release %s (Kinoite)\n' "${live_product_name}" "${live_version_id}" > /etc/system-release
@@ -130,6 +151,44 @@ mount --bind \${target_tmp} /var/tmp
df -h /var/tmp \${target_tmp}
%end
+# bootc relies on systemd's GPT auto-root discovery on the first boot. Anaconda
+# can leave the installed root partition with the generic Linux filesystem
+# type, which makes /dev/gpt-auto-root unavailable even though the filesystem
+# itself is healthy. Normalize the type before ostreecontainer deployment.
+%pre-install --erroronfail --log=/tmp/aerocore-gpt-root.log
+set -eux
+target_root=
+for root in /mnt/sysroot /mnt/sysimage /var/mnt/sysroot /var/mnt/sysimage; do
+ if mountpoint -q \${root}; then
+ target_root=\${root}
+ break
+ fi
+done
+if [ x\${target_root} = x ]; then
+ echo No mounted target system found for GPT root configuration >&2
+ exit 1
+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
new file mode 100755
index 0000000..6c1a2d1
--- /dev/null
+++ b/installer/configure-target-gpt-root.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+target_root=${1:?usage: configure-target-gpt-root.sh TARGET_ROOT}
+
+source_device="$(findmnt --nofsroot -no SOURCE --target "${target_root}")"
+# For a Btrfs subvolume, findmnt decorates the backing device with the
+# subvolume path (for example, /dev/vda3[/root]). lsblk and the partition
+# validation below require the undecorated block-device path.
+source_device="${source_device%%\[*}"
+# Anaconda can bind-mount the target at /mnt/sysroot. In that case findmnt's
+# human-readable SOURCE is "root", even though the mounted filesystem still
+# has the real target partition's device number. Resolve that number through
+# lsblk before requiring a partition-backed source.
+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]) ;;
+ *)
+ echo "Could not resolve a partition-backed target root: ${source_device}" >&2
+ exit 1
+ ;;
+esac
+
+parent_device="$(lsblk -no PKNAME "${source_device}")"
+partition_number="$(lsblk -no PARTN "${source_device}")"
+if [[ -z "${parent_device}" || -z "${partition_number}" ]]; then
+ echo "Could not resolve parent disk and partition number for ${source_device}" >&2
+ exit 1
+fi
+
+disk="/dev/${parent_device}"
+root_type_guid="4f68bce3-e8cd-4db1-96e7-fbcaf984b709"
+echo "Setting ${source_device} (partition ${partition_number} on ${disk}) to GPT root-x86-64 type ${root_type_guid}"
+sgdisk --typecode="${partition_number}:${root_type_guid}" "${disk}"
+partprobe "${disk}" || true
diff --git a/installer/system_files/overrides/etc/anaconda/profile.d/aerocore.conf b/installer/system_files/overrides/etc/anaconda/profile.d/aerocore.conf
new file mode 100644
index 0000000..0dd8f41
--- /dev/null
+++ b/installer/system_files/overrides/etc/anaconda/profile.d/aerocore.conf
@@ -0,0 +1,36 @@
+# Anaconda configuration for the AeroCore live installer.
+#
+# This deliberately does not inherit the Fedora KDE profile: that profile
+# hides the accounts screen, which would leave an interactive bootc install
+# without a user account. Keep the account page available so the installer
+# creates the user's requested login during installation.
+
+[Profile]
+profile_id = aerocore
+
+[Profile Detection]
+os_id = aerocore
+
+[Network]
+default_on_boot = FIRST_WIRED_WITH_LINK
+
+[Bootloader]
+efi_dir = fedora
+menu_auto_hide = True
+
+[Storage]
+default_scheme = BTRFS
+btrfs_compression = zstd:1
+default_partitioning =
+ / (min 1 GiB, max 70 GiB)
+ /home (min 500 MiB, free 50 GiB)
+ /var (btrfs)
+
+[User Interface]
+# Leave anaconda-screen-accounts visible. The user account is configured in
+# the WebUI rather than via an unused Lorax template.
+hidden_webui_pages =
+ network
+
+[Localization]
+use_geolocation = False