diff options
| author | Tranch <tranch.xiao@gmail.com> | 2026-07-22 17:26:46 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-22 17:26:46 +0800 |
| commit | 677aaf3fbbe3f941c1b782980dbc0b422d937027 (patch) | |
| tree | 8156006e752aa03a910281021ffb5f364927a8d6 /build_files | |
| parent | 96aac6e87ac41b27383d1839687f391925080007 (diff) | |
| parent | 5198f735cf5a8c9e8390c2fa2156252c79be72ab (diff) | |
| download | AeroCore-OS-677aaf3fbbe3f941c1b782980dbc0b422d937027.tar.gz AeroCore-OS-677aaf3fbbe3f941c1b782980dbc0b422d937027.zip | |
Merge pull request #2 from AeroCore-IO/testing
Complete AeroCore OS metadata migration and live installer integration
Diffstat (limited to 'build_files')
| -rwxr-xr-x | build_files/build-initramfs | 17 | ||||
| -rwxr-xr-x | build_files/build.sh | 12 | ||||
| -rwxr-xr-x | build_files/image-info | 78 | ||||
| -rwxr-xr-x | build_files/install-instruments.sh | 182 | ||||
| -rwxr-xr-x | build_files/patch-bazzite-deck-identity.sh | 35 |
5 files changed, 324 insertions, 0 deletions
diff --git a/build_files/build-initramfs b/build_files/build-initramfs new file mode 100755 index 0000000..9eec951 --- /dev/null +++ b/build_files/build-initramfs @@ -0,0 +1,17 @@ +#!/usr/bin/bash + +set -eoux pipefail + +echo "::group::Executing build-initramfs" +trap 'echo "::endgroup::"' EXIT + +if [[ "${KERNEL_FLAVOR:-}" == "surface" ]]; then + KERNEL_SUFFIX="surface" +else + KERNEL_SUFFIX="" +fi + +QUALIFIED_KERNEL="$(dnf5 repoquery --installed --queryformat='%{evr}.%{arch}' "kernel${KERNEL_SUFFIX:+-${KERNEL_SUFFIX}}")" +/usr/bin/dracut --no-hostonly --kver "$QUALIFIED_KERNEL" --reproducible --zstd -v --add ostree --add fido2 -f "/usr/lib/modules/$QUALIFIED_KERNEL/initramfs.img" + +chmod 0600 /usr/lib/modules/"$QUALIFIED_KERNEL"/initramfs.img diff --git a/build_files/build.sh b/build_files/build.sh index f1709da..03adff0 100755 --- a/build_files/build.sh +++ b/build_files/build.sh @@ -2,6 +2,15 @@ set -ouex pipefail +case "${BASE_IMAGE:-}" in + ghcr.io/ublue-os/bazzite-deck:* | ghcr.io/ublue-os/bazzite-deck@*) + ;; + *) + echo "AeroCore OS only supports bazzite-deck BASE_IMAGE values for HTPC game-mode builds: ${BASE_IMAGE:-<unset>}" >&2 + exit 1 + ;; +esac + # Copy the contents of system_files/ of the git repo to / cp -avf "/ctx/system_files"/. / @@ -32,3 +41,6 @@ if [[ -n "${HOMEBREW_API_DOMAIN:-}" ]]; then fi find /etc/environment.d /etc/skel/.config/environment.d -name 99-aerocore-mirrors.conf -type f -exec chmod 0644 {} + 2>/dev/null || true + +/ctx/install-instruments.sh +/ctx/patch-bazzite-deck-identity.sh diff --git a/build_files/image-info b/build_files/image-info new file mode 100755 index 0000000..a52d666 --- /dev/null +++ b/build_files/image-info @@ -0,0 +1,78 @@ +#!/usr/bin/bash + +set -eoux pipefail + +IMAGE_PRETTY_NAME="AeroCore OS" +IMAGE_ID="aerocore" +IMAGE_LIKE="fedora" +HOME_URL="https://os.aerocore.com.cn" +DOCUMENTATION_URL="https://docs.os.aerocore.com.cn" +SUPPORT_URL="https://os.aerocore.com.cn/support" +BUG_SUPPORT_URL="https://github.com/AeroCore-IO/AeroCore-OS/issues/" +LOGO_ICON="distributor-logo" +LOGO_COLOR="0;38;2;12;109;129" + +IMAGE_INFO="/usr/share/ublue-os/image-info.json" +OSTREE_REGISTRY="${OSTREE_REGISTRY:-docker://ghcr.io}" +OSTREE_NAMESPACE="${OSTREE_NAMESPACE:-$IMAGE_VENDOR}" +IMAGE_REF="${OSTREE_IMAGE_REF:-ostree-image-signed:${OSTREE_REGISTRY%/}/$OSTREE_NAMESPACE/$IMAGE_NAME}" +IMAGE_BRANCH_NORMALIZED="$IMAGE_BRANCH" +BASE_IMAGE_NAME=$(jq -er '."base-image-name"' < "$IMAGE_INFO") + +if [[ $IMAGE_BRANCH_NORMALIZED == "main" ]]; then + IMAGE_BRANCH_NORMALIZED="stable" +fi + +FEDORA_VERSION=$(rpm -E %fedora) + +mkdir -p "$(dirname "$IMAGE_INFO")" +cat > "$IMAGE_INFO" <<EOF +{ + "image-name": "$IMAGE_NAME", + "image-vendor": "$IMAGE_VENDOR", + "image-ref": "$IMAGE_REF", + "image-tag": "stable", + "image-branch": "$IMAGE_BRANCH_NORMALIZED", + "base-image-name": "$BASE_IMAGE_NAME", + "fedora-version": "$FEDORA_VERSION", + "version": "$VERSION_TAG", + "version-pretty": "$VERSION_PRETTY" +} +EOF + +# 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 +sed -i "s/^NAME=.*/NAME=\"$IMAGE_PRETTY_NAME\"/" /usr/lib/os-release +sed -i "s|^HOME_URL=.*|HOME_URL=\"$HOME_URL\"|" /usr/lib/os-release +sed -i "s|^DOCUMENTATION_URL=.*|DOCUMENTATION_URL=\"$DOCUMENTATION_URL\"|" /usr/lib/os-release +sed -i "s|^SUPPORT_URL=.*|SUPPORT_URL=\"$SUPPORT_URL\"|" /usr/lib/os-release +sed -i "s|^BUG_REPORT_URL=.*|BUG_REPORT_URL=\"$BUG_SUPPORT_URL\"|" /usr/lib/os-release +sed -i "s|^CPE_NAME=.*|CPE_NAME=\"cpe:/o:universal-blue:$IMAGE_ID\"|" /usr/lib/os-release +sed -i "s/^DEFAULT_HOSTNAME=.*/DEFAULT_HOSTNAME=\"$IMAGE_ID\"/" /usr/lib/os-release +sed -i "s/^ID=fedora/ID=$IMAGE_ID\nID_LIKE=\"$IMAGE_LIKE\"/" /usr/lib/os-release +sed -i "s/^LOGO=.*/LOGO=$LOGO_ICON/" /usr/lib/os-release +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 + +if grep -q '^BUILD_ID=' /usr/lib/os-release; then + sed -i "s/^BUILD_ID=.*/BUILD_ID=\"$VERSION_PRETTY\"/" /usr/lib/os-release +else + echo "BUILD_ID=\"$VERSION_PRETTY\"" >> /usr/lib/os-release +fi + +if grep -q '^BOOTLOADER_NAME=' /usr/lib/os-release; then + sed -i "s/^BOOTLOADER_NAME=.*/BOOTLOADER_NAME=\"$IMAGE_PRETTY_NAME $VERSION_PRETTY\"/" /usr/lib/os-release +else + echo "BOOTLOADER_NAME=\"$IMAGE_PRETTY_NAME $VERSION_PRETTY\"" >> /usr/lib/os-release +fi + +# Keep hibernation images tied to this exact image version. +if grep -q '^IMAGE_ID=' /usr/lib/os-release; then + sed -i "s/^IMAGE_ID=.*/IMAGE_ID=\"$IMAGE_NAME-$VERSION_TAG\"/" /usr/lib/os-release +else + echo "IMAGE_ID=\"$IMAGE_NAME-$VERSION_TAG\"" >> /usr/lib/os-release +fi diff --git a/build_files/install-instruments.sh b/build_files/install-instruments.sh new file mode 100755 index 0000000..f85bd3b --- /dev/null +++ b/build_files/install-instruments.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env bash + +set -euo pipefail + +: "${INSTRUMENTS_ENABLED:=true}" +: "${INSTRUMENTS_RELEASE_REPOSITORY:=AeroCore-IO/booster-installer}" +: "${INSTRUMENTS_VERSION:=latest}" +: "${INSTRUMENTS_RELEASE_API_BASE:=https://api.github.com}" +: "${INSTRUMENTS_SEED_ROOT:=/usr/share/aerocore-booster-release}" + +if [[ "${INSTRUMENTS_ENABLED}" != "true" ]]; then + echo "AeroCore Booster image integration is disabled" + exit 0 +fi + +case "$(uname -m)" in + x86_64 | amd64) + asset_suffix="_linux-x86_64.tar.gz" + ;; + *) + echo "Unsupported AeroCore Booster image architecture: $(uname -m)" >&2 + exit 1 + ;; +esac + +for command in curl jq sha256sum tar; do + command -v "$command" >/dev/null 2>&1 || { + echo "Required command is unavailable: $command" >&2 + exit 1 + } +done + +workdir="$(mktemp -d)" +trap 'rm -rf "$workdir"' EXIT + +github_curl() { + local args=( + --fail + --location + --retry 3 + --retry-delay 2 + --retry-max-time 60 + --silent + --show-error + ) + + if [[ -s /run/secrets/GITHUB_TOKEN ]]; then + args+=(--header "Authorization: Bearer $(</run/secrets/GITHUB_TOKEN)") + fi + + curl "${args[@]}" "$@" +} + +if [[ "${INSTRUMENTS_VERSION}" == "latest" ]]; then + release_endpoint="releases/latest" +else + release_endpoint="releases/tags/${INSTRUMENTS_VERSION}" +fi + +release_json="$workdir/release.json" +github_curl \ + "${INSTRUMENTS_RELEASE_API_BASE%/}/repos/${INSTRUMENTS_RELEASE_REPOSITORY}/${release_endpoint}" \ + --output "$release_json" + +release_tag="$(jq -er '.tag_name' "$release_json")" +mapfile -t payload_assets < <( + jq -er --arg suffix "$asset_suffix" ' + .assets[] + | select( + (.name | startswith("AeroCore-Booster-v")) + or (.name | startswith("instruments-ng_v")) + ) + | select(.name | endswith($suffix)) + | [.name, .browser_download_url] + | @tsv + ' "$release_json" +) + +if [[ "${#payload_assets[@]}" -ne 1 ]]; then + echo "Expected one x86_64 Booster tarball in release $release_tag, found ${#payload_assets[@]}" >&2 + exit 1 +fi + +IFS=$'\t' read -r asset_name asset_url <<<"${payload_assets[0]}" +checksum_name="${asset_name}.sha256" +checksum_url="$( + jq -er --arg name "$checksum_name" \ + '.assets[] | select(.name == $name) | .browser_download_url' \ + "$release_json" +)" + +archive="$workdir/$asset_name" +checksum_file="$workdir/$checksum_name" +github_curl "$asset_url" --output "$archive" +github_curl "$checksum_url" --output "$checksum_file" + +expected_checksum="$(awk 'NR == 1 { print $1 }' "$checksum_file")" +actual_checksum="$(sha256sum "$archive" | awk '{ print $1 }')" +if [[ ! "$expected_checksum" =~ ^[[:xdigit:]]{64}$ ]] || + [[ "${actual_checksum,,}" != "${expected_checksum,,}" ]]; then + echo "Checksum verification failed for $asset_name" >&2 + exit 1 +fi + +while IFS= read -r entry; do + case "$entry" in + /* | ../* | */../* | */..) + echo "Unsafe path in release archive: $entry" >&2 + exit 1 + ;; + esac +done < <(tar -tzf "$archive") + +extract_dir="$workdir/extracted" +install -d "$extract_dir" +tar --extract --gzip --file "$archive" --directory "$extract_dir" \ + --no-same-owner + +if [[ -d "$extract_dir/aerocore-booster-release" ]]; then + payload="$extract_dir/aerocore-booster-release" +elif [[ -d "$extract_dir/instruments-ng-release" ]]; then + payload="$extract_dir/instruments-ng-release" +else + echo "Release archive does not contain a supported payload root" >&2 + exit 1 +fi + +required_paths=( + install.sh + appimage/AppRun + appimage/AppRun.wrapped + sidecar/hhd-input-helper.cjs + sidecar/vendor/hhd-input-helper/instruments_hhd_input/__init__.py + runtime/avionics + runtime/cabin + runtime/wing + runtime/node/bin/node + python-wheelhouse + pkg/systemd/ac-avionics.service + pkg/systemd/ac-cabin.service + pkg/systemd/ac-wing.service + pkg/systemd/ac-instruments.service + scripts/check-runtime-health.cjs + manifest.yaml +) + +for path in "${required_paths[@]}"; do + if [[ ! -e "$payload/$path" ]]; then + echo "Required path is missing from Booster release: $path" >&2 + exit 1 + fi +done + +if [[ ! -f "$payload/pkg/aerocore-booster.sh" && + ! -f "$payload/pkg/instruments-ng.sh" ]]; then + echo "Booster launcher is missing from the release payload" >&2 + exit 1 +fi + +# Remove the first implementation's image-owned runtime when upgrading an +# existing AeroCore OS image. The release seed itself remains immutable. +rm -rf /usr/lib/aerocore-booster +rm -f /usr/bin/aerocore-booster +for unit in ac-avionics.service ac-cabin.service ac-wing.service \ + ac-instruments.service; do + rm -f "/usr/lib/systemd/system/$unit" +done + +rm -rf "$INSTRUMENTS_SEED_ROOT" +install -d -m 0755 "$INSTRUMENTS_SEED_ROOT" +cp -a "$payload/." "$INSTRUMENTS_SEED_ROOT/" + +cat >"$INSTRUMENTS_SEED_ROOT/image-release" <<EOF +RELEASE_TAG=$release_tag +ASSET_NAME=$asset_name +SHA256=$actual_checksum +EOF +chmod 0644 "$INSTRUMENTS_SEED_ROOT/image-release" + +systemctl enable aerocore-instruments-setup.service + +echo "Seeded AeroCore Booster $release_tag from $asset_name" diff --git a/build_files/patch-bazzite-deck-identity.sh b/build_files/patch-bazzite-deck-identity.sh new file mode 100755 index 0000000..078b76c --- /dev/null +++ b/build_files/patch-bazzite-deck-identity.sh @@ -0,0 +1,35 @@ +#!/usr/bin/bash + +set -euo pipefail + +hardware_setup="${1:-/usr/libexec/bazzite-hardware-setup}" +# These are literal source lines; variable expansion must happen at boot time. +# shellcheck disable=SC2016 +old_condition='if [[ "$IMAGE_NAME" != *deck* && "$IMAGE_NAME" != *dx* ]]; then' +# shellcheck disable=SC2016 +new_condition='if [[ "$IMAGE_NAME" != aerocore-os && "$IMAGE_NAME" != *deck* && "$IMAGE_NAME" != *dx* ]]; then' + +if grep -Fqx "$new_condition" "$hardware_setup"; then + exit 0 +fi + +if [[ "$(grep -Fxc "$old_condition" "$hardware_setup")" -ne 1 ]]; then + echo "Unable to locate the Bazzite Deck image check in $hardware_setup" >&2 + exit 1 +fi + +patched_file=$(mktemp) +trap 'rm -f "$patched_file"' EXIT + +awk \ + -v old_condition="$old_condition" \ + -v new_condition="$new_condition" \ + '$0 == old_condition { + print new_condition + next + } + { print }' "$hardware_setup" > "$patched_file" + +cp "$patched_file" "$hardware_setup" + +grep -Fqx "$new_condition" "$hardware_setup" |
