#!/bin/bash # Initialize flags KEEP_CONTINUE=false USE_REAL_ROOT_MANUALLY=false # Parse arguments ARGS=() while [[ $# -gt 0 ]]; do case "$1" in --keep-continue) KEEP_CONTINUE=true shift ;; --use-real-root-manually) USE_REAL_ROOT_MANUALLY=true shift ;; --version) echo -e "\n'prepare-fake-ota.sh'\nProgram rewritten originally by phmqXPD.\nThis is not copyrighted, which mean it's still free of charge, free to edit/pubish.\nVersion: beta0.1 (d19-m05-y2025)" shift exit 0 ;; *) ARGS+=("$1") shift ;; esac done # Validate arguments if [[ ${#ARGS[@]} -ne 2 ]]; then echo "❌ Error: Exactly two arguments required!" echo "" echo "Usage:" echo " bash $(basename "$0") [--keep-continue | --use-real-root-manually] [--version]" echo "" echo "Example:" echo " bash $(basename "$0") [--keep-continue | --use-real-root-manually] device-codename-usermerge.tar.xz build_output" exit 1 fi DEVICE_TARBALL="${ARGS[0]}" OUTPUT="${ARGS[1]}" UBUNTU_COMMAND="${OUTPUT}/ubuntu_command" HERE="$(pwd)" # Check if device tarball exists if [[ ! -f "$DEVICE_TARBALL" ]]; then echo "❌ Error: Device tarball '$DEVICE_TARBALL' not found!" exit 1 fi # Unified privilege handling RUN_AS_FAKEROOT=false RUN_AS_SUDO=false if $USE_REAL_ROOT_MANUALLY; then if [[ $EUID -ne 0 ]]; then echo "❌ Error: --use-real-root-manually requires root privileges!" echo "Run with: sudo bash $(basename "$0") --use-real-root-manually ${ARGS[*]}" exit 1 fi echo "📝 Running as real root (--use-real-root-manually)" echo "📥 Downloading files:" echo " + image-signing.tar.xz" echo " + image-signing.tar.xz.asc" echo " + image-master.tar.xz" echo " + image-master.tar.xz.asc" echo " + ubuntu-touch-android9plus-rootfs-arm64.tar.gz (may take long)" echo "Note: If using real root, the progress won't be showed." elif $KEEP_CONTINUE; then if [[ $EUID -ne 0 ]]; then if command -v fakeroot >/dev/null 2>&1 && fakeroot echo "test" >/dev/null 2>&1; then RUN_AS_FAKEROOT=true echo "📝 Using fakeroot for simulated root privileges (with --keep-continue)" else echo "⚠️ fakeroot not available, falling back to sudo (--keep-continue)" RUN_AS_SUDO=true fi else echo "📝 Already running as root with --keep-continue, proceeding" fi else if command -v fakeroot >/dev/null 2>&1 && fakeroot echo "test" >/dev/null 2>&1; then RUN_AS_FAKEROOT=true echo "📝 Using fakeroot for simulated root privileges (default)" else echo "❌ Error: fakeroot is not installed or not functioning correctly." echo "Fakeroot is required to simulate root privileges for file operations." echo "Install it with: sudo apt install fakeroot" echo "" echo "💡 Options to proceed:" echo " - Install fakeroot and retry: sudo apt install fakeroot" echo " - Use --keep-continue to fall back to sudo" echo " - Use --use-real-root-manually if running as root" exit 1 fi fi # Execute with sudo if needed if $RUN_AS_SUDO; then echo "Executing with sudo..." exec sudo "$0" --keep-continue "${ARGS[@]}" fi # Execute with fakeroot if needed if $RUN_AS_FAKEROOT && [[ $EUID -ne 0 ]]; then echo "Executing with fakeroot..." exec fakeroot -- "$0" "${ARGS[@]}" fi # At this point, we're running with appropriate privileges # Source deviceinfo if [[ ! -f "${HERE}/deviceinfo" ]]; then echo "❌ Error: deviceinfo file not found in current directory!" exit 1 fi source "${HERE}/deviceinfo" # URLs and configuration URL='https://system-image.ubports.com' ROOTFS_URL=${ROOTFS_URL:-'https://ci.ubports.com/job/focal-hybris-rootfs-arm64/job/master/lastSuccessfulBuild/artifact/ubuntu-touch-android9plus-rootfs-arm64.tar.gz'} OTA_CHANNEL=${OTA_CHANNEL:-'20.04/arm64/android9plus/devel'} # Determine device generic URL based on Android version case "${deviceinfo_bootimg_os_version}" in 9) DEVICE_GENERIC_URL='https://ci.ubports.com/job/UBportsCommunityPortsJenkinsCI/job/ubports%252Fporting%252Fcommunity-ports%252Fjenkins-ci%252Fgeneric_arm64/job/main/lastSuccessfulBuild/artifact/halium_halium_arm64.tar.xz' ;; 10) DEVICE_GENERIC_URL='https://ci.ubports.com/job/UBportsCommunityPortsJenkinsCI/job/ubports%252Fporting%252Fcommunity-ports%252Fjenkins-ci%252Fgeneric_arm64/job/halium-10.0/lastSuccessfulBuild/artifact/halium_halium_arm64.tar.xz' ;; 11) DEVICE_GENERIC_URL='https://ci.ubports.com/job/UBportsCommunityPortsJenkinsCI/job/ubports%252Fporting%252Fcommunity-ports%252Fjenkins-ci%252Fgeneric_arm64/job/halium-11.0/lastSuccessfulBuild/artifact/halium_halium_arm64.tar.xz' ;; 12) DEVICE_GENERIC_URL='https://ci.ubports.com/job/UBportsCommunityPortsJenkinsCI/job/ubports%252Fporting%252Fcommunity-ports%252Fjenkins-ci%252Fgeneric_arm64/job/halium-12.0/lastSuccessfulBuild/artifact/halium_halium_arm64.tar.xz' ;; 13) DEVICE_GENERIC_URL='https://ci.ubports.com/job/UBportsCommunityPortsJenkinsCI/job/ubports%252Fporting%252Fcommunity-ports%252Fjenkins-ci%252Fgeneric_arm64/job/halium-13.0/lastSuccessfulBuild/artifact/halium_halium_arm64.tar.xz' ;; *) echo "❌ Error: Unsupported Android version: ${deviceinfo_bootimg_os_version}" exit 1 ;; esac # Create output directories mkdir -p "$OUTPUT" "$OUTPUT/backup_otafiles" || { echo "❌ Error: Failed to create output directories!" exit 1 } # Cleanup on interrupt cleanup() { echo "🛑 Interrupt received, cleaning up..." rm -rf "$OUTPUT"/* exit 1 } trap cleanup SIGINT # Helper to download file + .asc (optional) download_file_and_asc() { local url="$1" dest="$2" local file file=$(basename "$url") if ! wget --no-hsts --no-hpkp -q "$url" -O "$dest/$file"; then echo "❌ Error: Failed to download $url" exit 1 fi if ! wget --no-hsts --no-hpkp -q "$url.asc" -O "$dest/$file.asc"; then echo "⚠️ Warning: Failed to download $url.asc" touch "$dest/$file.asc" fi } # Download keyrings download_file_and_asc "${URL}/gpg/image-signing.tar.xz" "$OUTPUT" download_file_and_asc "${URL}/gpg/image-master.tar.xz" "$OUTPUT" # Create ubuntu_command file cat << EOF > "$UBUNTU_COMMAND" format system load_keyring image-master.tar.xz image-master.tar.xz.asc load_keyring image-signing.tar.xz image-signing.tar.xz.asc mount system EOF # Download and process rootfs file=$(basename "$ROOTFS_URL") download_file_and_asc "$ROOTFS_URL" "$OUTPUT" mkdir -p "$OUTPUT/rootfs/system" || { echo "❌ Error: Failed to create rootfs directory!" exit 1 } echo "📦 Extracting official rootfs..." if ! tar xpzf "$OUTPUT/$file" --numeric-owner -C "$OUTPUT/rootfs/system" 2>/dev/null; then echo "⚠️ Failed to extract $file" fallback_file=$(find "$OUTPUT" -name 'device-ubports-*android9*' | head -n1) if [[ -n "$fallback_file" && -f "$fallback_file" ]]; then echo "📥 Fallback: using $fallback_file as rootfs.tar.xz" cp "$fallback_file" "$OUTPUT/rootfs.tar.xz" rm -rf "$OUTPUT/rootfs" echo "update rootfs.tar.xz rootfs.tar.xz.asc" >> "$UBUNTU_COMMAND" else echo "❌ Error: No valid fallback rootfs tarball found!" exit 1 fi else echo "✅ Rootfs extracted successfully" echo "Working... Download will be start after finish working..." echo "📥 Downloading queues:" echo " + halium_halium_arm64.tar.xz (may take long)" mkdir -p "$OUTPUT/rootfs/system/etc/init" "$OUTPUT/rootfs/system/etc/default" cat > "$OUTPUT/rootfs/system/etc/init/ssh.override" << EOF2 start on startup exec /usr/sbin/sshd -D -o PasswordAuthentication=yes -o PermitEmptyPasswords=yes EOF2 cat > "$OUTPUT/rootfs/system/etc/init/usb-tethering.conf" << EOF2 start on startup exec /bin/bash /usr/bin/usb-tethering EOF2 cat > "$OUTPUT/rootfs/system/etc/default/adbd" << EOF2 ADBD_SECURE=0 EOF2 cd "$OUTPUT/rootfs" || exit 1 XZ_OPT=-1 tar cJf "../rootfs.tar.xz" --owner=root --group=root system cd - >/dev/null rm -rf "$OUTPUT/rootfs" echo "update rootfs.tar.xz rootfs.tar.xz.asc" >> "$UBUNTU_COMMAND" fi # Backup files cp -r "$OUTPUT"/* "$OUTPUT/backup_otafiles" 2>/dev/null # Reverted Halium download method echo "📥 Downloading Halium image (may take long)..." file=$(basename "$DEVICE_GENERIC_URL") if ! wget --no-hsts --no-hpkp --show-progress "$DEVICE_GENERIC_URL" -O "$OUTPUT/$file"; then echo "❌ Error: Failed to download Halium image from $DEVICE_GENERIC_URL" exit 1 fi touch "$OUTPUT/$file.asc" echo "update $file $file.asc" >> "$UBUNTU_COMMAND" # Process device tarball file=$(basename "$DEVICE_TARBALL") cp "$DEVICE_TARBALL" "$OUTPUT" || { echo "❌ Error: Failed to copy device tarball!" exit 1 } touch "$OUTPUT/$file.asc" echo "update $file $file.asc" >> "$UBUNTU_COMMAND" # Create version configuration mkdir -p "$OUTPUT/version/system/etc/system-image/config.d" cat << EOF > "$OUTPUT/version/system/etc/system-image/channel.ini" [service] base: system-image.ubports.com http_port: 80 https_port: 443 channel: $OTA_CHANNEL device: ${deviceinfo_codename} EOF ln -sf ../channel.ini "$OUTPUT/version/system/etc/system-image/config.d/01_channel.ini" ln -sf ../client.ini "$OUTPUT/version/system/etc/system-image/config.d/00_default.ini" cd "$OUTPUT/version" || exit 1 tar cJf "../version.tar.xz" --owner=root --group=root system cd - >/dev/null rm -rf "$OUTPUT/version" touch "$OUTPUT/version.tar.xz.asc" echo "update version.tar.xz version.tar.xz.asc" >> "$UBUNTU_COMMAND" echo 'unmount system' >> "$UBUNTU_COMMAND" echo "" echo "🎉 Done! Output generated in: $OUTPUT"