summaryrefslogtreecommitdiff
path: root/build_files
diff options
context:
space:
mode:
authorTranch <tranch.xiao@gmail.com>2026-07-22 17:26:46 +0800
committerGitHub <noreply@github.com>2026-07-22 17:26:46 +0800
commit677aaf3fbbe3f941c1b782980dbc0b422d937027 (patch)
tree8156006e752aa03a910281021ffb5f364927a8d6 /build_files
parent96aac6e87ac41b27383d1839687f391925080007 (diff)
parent5198f735cf5a8c9e8390c2fa2156252c79be72ab (diff)
downloadAeroCore-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-xbuild_files/build-initramfs17
-rwxr-xr-xbuild_files/build.sh12
-rwxr-xr-xbuild_files/image-info78
-rwxr-xr-xbuild_files/install-instruments.sh182
-rwxr-xr-xbuild_files/patch-bazzite-deck-identity.sh35
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"