From c888b2c5d54ceda2191fc6bafb2a1274f228f814 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Tue, 27 Jan 2026 23:41:17 +0800 Subject: [PATCH 1/2] Add gigabyte-ampere-cuttlefish-installer subdirectory gigabyte-ampere-cuttlefish-installer generates the iso installer for Gigabyte Ampere server. Signed-off-by: Ying-Chun Liu (PaulLiu) --- .../addpreseed.sh | 88 +++++ .../preseed/after_install_1.sh | 126 +++++++ .../preseed/preseed.cfg | 318 ++++++++++++++++++ .../tests/installer-iso-extract-partitions.sh | 62 ++++ .../tests/installer-iso-install-edk2.expect | 70 ++++ .../tests/installer-iso-install.expect | 210 ++++++++++++ .../tests/installer-iso-run-qemu-edk2.sh | 55 +++ .../tests/installer-iso-run-qemu.sh | 58 ++++ .../multidisk/installer-create-empty-disk2.sh | 17 + .../installer-create-preinstalled-disk2.sh | 74 ++++ .../installer-create-preinstalled-disk5.sh | 97 ++++++ ...taller-iso-extract-partitions-multidisk.sh | 103 ++++++ .../tests/test-after-install-script-kernel.sh | 10 + .../tests/test-cuttlefish-time.sh | 5 + .../tests/test-inside-pbuilder.sh | 39 +++ .../tests/test-install-metapackage-deb.sh | 26 ++ .../utils/download-ci-cf.sh | 16 + .../utils/install-build-depends.py | 75 +++++ .../utils/install_repo_package.sh | 17 + 19 files changed, 1466 insertions(+) create mode 100755 gigabyte-ampere-cuttlefish-installer/addpreseed.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/preseed/after_install_1.sh create mode 100644 gigabyte-ampere-cuttlefish-installer/preseed/preseed.cfg create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/installer-iso-extract-partitions.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/installer-iso-install-edk2.expect create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/installer-iso-install.expect create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/installer-iso-run-qemu-edk2.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/installer-iso-run-qemu.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-empty-disk2.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-preinstalled-disk2.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-preinstalled-disk5.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-iso-extract-partitions-multidisk.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/test-after-install-script-kernel.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/test-cuttlefish-time.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/test-inside-pbuilder.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/tests/test-install-metapackage-deb.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/utils/download-ci-cf.sh create mode 100755 gigabyte-ampere-cuttlefish-installer/utils/install-build-depends.py create mode 100755 gigabyte-ampere-cuttlefish-installer/utils/install_repo_package.sh diff --git a/gigabyte-ampere-cuttlefish-installer/addpreseed.sh b/gigabyte-ampere-cuttlefish-installer/addpreseed.sh new file mode 100755 index 00000000000..c0bc88a2cb1 --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/addpreseed.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +BASEDIR=$(dirname $(realpath "$0")) + +orig_iso=mini.iso +auto_extract_efi=1 +efi_img=efi.img + +new_files=iso_unpacked_and_modified +new_iso=preseed-mini.iso + +PRESEEDFILE=$(realpath "${BASEDIR}"/preseed/preseed.cfg) +AFTERINSTALLSCRIPT=$(realpath "${BASEDIR}"/preseed/after_install_1.sh) + +part_img_ready=1 +if test "$auto_extract_efi" = 1; then + start_block=$(/sbin/fdisk -l "$orig_iso" | fgrep "$orig_iso"2 | \ + awk '{print $2}') + block_count=$(/sbin/fdisk -l "$orig_iso" | fgrep "$orig_iso"2 | \ + awk '{print $4}') + if test "$start_block" -gt 0 -a "$block_count" -gt 0 2>/dev/null + then + dd if="$orig_iso" bs=512 skip="$start_block" count="$block_count" \ + of="$efi_img" + else + echo "Cannot read plausible start block and block count from fdisk" >&2 + part_img_ready=0 + fi +fi + +# add preseed +mkdir ${new_files} +bsdtar -C ${new_files} -xf "$orig_iso" +cd ${new_files} +cp -f "${PRESEEDFILE}" preseed.cfg +cp -f "${AFTERINSTALLSCRIPT}" after_install_1.sh +chmod a+rx after_install_1.sh + +# add preseed to console based installer +chmod ug+w initrd.gz +gzip -d -f initrd.gz +echo preseed.cfg | cpio -H newc -o -A -F initrd +echo after_install_1.sh | cpio -H newc -o -A -F initrd +gzip -9 initrd +chmod a-w initrd.gz +# add preseed to GTK based installer +chmod ug+w gtk +cd gtk +chmod ug+w initrd.gz +gzip -d -f initrd.gz +cp -f ../preseed.cfg . +cp -f ../after_install_1.sh . +echo preseed.cfg | cpio -H newc -o -A -F initrd +echo after_install_1.sh | cpio -H newc -o -A -F initrd +gzip -9 initrd +chmod a-w initrd.gz +rm -f preseed.cfg after_install_1.sh +cd .. +chmod a-w gtk +# modify Graphical installer to use tty1 +chmod ug+w boot +chmod ug+w boot/grub +chmod ug+w boot/grub/grub.cfg +sed -i '0,/menuentry/{s#menuentry#menuentry '\''Ampere Install'\'' {\n set background_color=black\n linux /linux --- quiet console=tty1\n initrd /gtk/initrd.gz\n}\nmenuentry#}' boot/grub/grub.cfg +sed -i '0,/insmod gzio/{s#insmod gzio#set timeout=120\n\ninsmod gzio#}' boot/grub/grub.cfg +chmod a-w boot/grub/grub.cfg +chmod a-w boot/grub +chmod a-w boot +cd .. + +rm -f "${new_iso}" + +# Create the new ISO image if not partition extraction failed +test "$part_img_ready" = 1 && \ +xorriso -as mkisofs \ + -r -V 'Debian arm64 n' \ + -o "$new_iso" \ + -J -joliet-long -cache-inodes \ + -e boot/grub/efi.img \ + -no-emul-boot \ + -append_partition 2 0xef "$efi_img" \ + -partition_cyl_align all \ + "$new_files" + +# clean +rm -f efi.img +chmod ug+w -R "${new_files}" +rm -rf "${new_files}" diff --git a/gigabyte-ampere-cuttlefish-installer/preseed/after_install_1.sh b/gigabyte-ampere-cuttlefish-installer/preseed/after_install_1.sh new file mode 100755 index 00000000000..5846242c6db --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/preseed/after_install_1.sh @@ -0,0 +1,126 @@ +#!/bin/sh + +apt-get update + +# Install necessary packages +apt-get install -y debconf-utils +apt-get install -y ca-certificates +apt-get install -y wget +apt-get install -y git +apt-get install -y python3 +apt-get install -y p7zip-full unzip +apt-get install -y iptables ebtables +apt-get install -y curl +apt-get install -y lsb-release +apt-get install -y gpg +apt-get install -y jq + +# Adjust user groups +adduser vsoc-01 kvm +adduser vsoc-01 render +adduser vsoc-01 video + +# Detect distribution +DEBIAN_DISTRIBUTION="$(lsb_release -c -s)" +DEBIAN_ARCH="$(dpkg --print-architecture)" + +apt -o Apt::Get::Assume-Yes=true -o APT::Color=0 -o DPkgPM::Progress-Fancy=0 \ + update + +# Install kernel +DEBIAN_DISTRIBUTION="$(lsb_release -c -s)" +#apt-get install -y '^linux-image-6.1.*aosp14-linaro.*' '^linux-headers-6.1.*aosp14-linaro.*' +has_backports=$(apt-cache policy | grep "${DEBIAN_DISTRIBUTION}-backports") +if [ x"$has_backports" != x"" ]; then + apt install -y -t "${DEBIAN_DISTRIBUTION}-backports" linux-headers-arm64 + apt install -y -t "${DEBIAN_DISTRIBUTION}-backports" linux-image-arm64 +fi + +# Install nVidia or AMD GPU driver +nvidia_gpu=$(lspci | grep -i nvidia) +amd_gpu=$(lspci | grep VGA | grep AMD) +if [ x"$amd_gpu" != x"" ]; then + # # Install amd firmware + # if [ x"$has_backports" != x"" ]; then + # apt-get install -y -t ${DEBIAN_DISTRIBUTION}-backports firmware-amd-graphics + # else + # apt-get install -y firmware-amd-graphics + # fi + # sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"/GRUB_CMDLINE_LINUX_DEFAULT=\"\1 amdgpu.runpm=0 amdgpu.dc=0\"/' /etc/default/grub + # dpkg-reconfigure -fnoninteractive grub-efi-arm64 + echo "AMD GPU detected — skipping GPU driver installation." +elif [ x"$nvidia_gpu" != x"" ]; then + # Install nvidia driver + if [ x"$has_backports" != x"" ]; then + DEBIAN_FRONTEND=noninteractive apt-get install -y -t "${DEBIAN_DISTRIBUTION}-backports" -q --force-yes nvidia-kernel-dkms + DEBIAN_FRONTEND=noninteractive apt-get install -y -t "${DEBIAN_DISTRIBUTION}-backports" -q --force-yes nvidia-driver + DEBIAN_FRONTEND=noninteractive apt-get install -y -t "${DEBIAN_DISTRIBUTION}-backports" -q --force-yes firmware-misc-nonfree + else + DEBIAN_FRONTEND=noninteractive apt-get install -y -q --force-yes nvidia-open-kernel-dkms + DEBIAN_FRONTEND=noninteractive apt-get install -y -q --force-yes nvidia-driver + DEBIAN_FRONTEND=noninteractive apt-get install -y -q --force-yes firmware-misc-nonfree + fi +fi +# End of Install kernel + +# Install android cuttlefish packages +curl -fsSL --retry 7 --retry-all-errors https://us-apt.pkg.dev/doc/repo-signing-key.gpg -o /etc/apt/trusted.gpg.d/artifact-registry.asc +chmod a+r /etc/apt/trusted.gpg.d/artifact-registry.asc +echo "deb https://us-apt.pkg.dev/projects/android-cuttlefish-artifacts android-cuttlefish main" \ + | tee -a /etc/apt/sources.list.d/artifact-registry.list +apt-get update +apt-get install -y cuttlefish-base cuttlefish-user cuttlefish-orchestration -t android-cuttlefish +adduser vsoc-01 cvdnetwork + +# Install gigabyte package +apt -o Apt::Get::Assume-Yes=true -o APT::Color=0 -o DPkgPM::Progress-Fancy=0 -o Acquire::Retries=5 install cuttlefish-integration-gigabyte-arm64 + +# Extra tools +cd /root +git clone https://github.com/matthuisman/gdrivedl.git +cd - + +# Use iptables-legacy +update-alternatives --set iptables /usr/sbin/iptables-legacy + +# Install network manager +apt-get install -y network-manager + +# Network-manager workaround +rm -f '/etc/NetworkManager/system-connections/Wired connection 1' + +# Install Docker container +# Add Docker's official GPG key: +apt-get update +curl -fsSL --retry 7 --retry-all-errors https://download.docker.com/linux/debian/gpg -o /etc/apt/trusted.gpg.d/docker.asc +chmod a+r /etc/apt/trusted.gpg.d/docker.asc + +# Add the repository to Apt sources: +echo \ + "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + tee /etc/apt/sources.list.d/docker.list > /dev/null +apt-get update +DEBIAN_FRONTEND=noninteractive apt-get install -y -q docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +usermod -aG docker vsoc-01 + +# Inastall nvidia-container-toolkit +curl -fsSL --retry 7 --retry-all-errors https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /etc/apt/trusted.gpg.d/nvidia-container-toolkit-keyring.gpg \ +&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ + tee /etc/apt/sources.list.d/nvidia-container-toolkit.list +apt-get update +DEBIAN_FRONTEND=noninteractive apt-get install -y -q --force-yes nvidia-container-toolkit + +# Install container image +DEBIAN_FRONTEND=noninteractive apt-get install -y -q --force-yes skopeo +ORCHESTRATION_IMAGE="us-docker.pkg.dev/android-cuttlefish-artifacts/cuttlefish-orchestration/cuttlefish-orchestration" +STABLE_DIGEST=$(skopeo inspect docker://${ORCHESTRATION_IMAGE}:stable --format '{{.Digest}}') +CANDIDATES=$(skopeo list-tags docker://${ORCHESTRATION_IMAGE} | jq -r '.Tags[] | select(test("^[0-9]+\\.[0-9]+\\.[0-9]+$"))' | sort -V -r) +ORCHESTRATION_TAG="" +for CANDIDATE in $CANDIDATES; do + DIGEST=$(skopeo inspect docker://${ORCHESTRATION_IMAGE}:${CANDIDATE} --format '{{.Digest}}') + if [ "$DIGEST" = "$STABLE_DIGEST" ]; then + ORCHESTRATION_TAG=${CANDIDATE} + break + fi +done +docker pull ${ORCHESTRATION_IMAGE}:${ORCHESTRATION_TAG} diff --git a/gigabyte-ampere-cuttlefish-installer/preseed/preseed.cfg b/gigabyte-ampere-cuttlefish-installer/preseed/preseed.cfg new file mode 100644 index 00000000000..b42e110fb75 --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/preseed/preseed.cfg @@ -0,0 +1,318 @@ +#_preseed_V1 +#### Contents of the preconfiguration file (for trixie) +### Localization +# Preseeding only locale sets language, country and locale. +d-i debian-installer/locale string en_US.UTF-8 + +# Keyboard selection. +d-i keyboard-configuration/xkb-keymap select us +# d-i keyboard-configuration/toggle select No toggling + +# netcfg will choose an interface that has link if possible. This makes it +# skip displaying a list if there is more than one interface. +d-i netcfg/choose_interface select auto + +# Any hostname and domain names assigned from dhcp take precedence over +# values set here. However, setting the values still prevents the questions +# from being shown, even if values come from dhcp. +d-i netcfg/get_hostname string debian-1 +d-i netcfg/get_domain string + +# Mirror protocol: +d-i mirror/country string manual +d-i mirror/http/hostname string deb.debian.org +d-i mirror/http/directory string /debian +d-i mirror/http/proxy string + +# Skip creation of a root account (normal user account will be able to +# use sudo). +d-i passwd/root-login boolean false + +# To create a normal user account. +d-i passwd/user-fullname string vsoc 01 +d-i passwd/username string vsoc-01 +# Normal user's password, either in clear text +d-i passwd/user-password password cuttlefish +d-i passwd/user-password-again password cuttlefish + +# Controls whether or not the hardware clock is set to UTC. +d-i clock-setup/utc boolean true + +# You may set this to any valid setting for $TZ; see the contents of +# /usr/share/zoneinfo/ for valid values. +d-i time/zone string US/Eastern + +# Controls whether to use NTP to set the clock during the install +d-i clock-setup/ntp boolean true + +# Choose disk +d-i partman/early_command string \ + VGNAME="$(debconf-get partman-auto-lvm/new_vg_name)"; \ + NUMOFPARTITIONS=$(list-devices partition | wc -l); \ + COUNTER=0; \ + while [ "$COUNTER" -lt "$NUMOFPARTITIONS" ]; do \ + COUNTER=$((COUNTER+1)); \ + if [ "$COUNTER" -eq 1 ]; then \ + PARTITION1=$(list-devices partition|head -n1); \ + else \ + PARTITION1=$(list-devices partition|head -n$COUNTER|tail -1); \ + fi; \ + if blkid "${PARTITION1}" | grep 'LABEL="Debian arm64' | grep 'TYPE="iso9660"'; then \ + INSTALLER_PARTITION=${PARTITION1}; \ + break; \ + elif blkid "${PARTITION1}" | grep 'LABEL="ISOIMAGE"' | grep 'TYPE="iso9660"'; then \ + INSTALLER_PARTITION=${PARTITION1}; \ + break; \ + elif blkid "${PARTITION1}" | grep 'PARTLABEL="debdilnr"'; then \ + INSTALLER_PARTITION=${PARTITION1}; \ + break; \ + fi; \ + done; \ + NUMOFDISKS=$(list-devices disk | wc -l); \ + COUNTER=0; \ + while [ "$COUNTER" -lt "$NUMOFDISKS" ]; do \ + COUNTER=$((COUNTER+1)); \ + if [ "$COUNTER" -eq 1 ]; then \ + DISK1=$(list-devices disk|head -n1); \ + else \ + DISK1=$(list-devices disk|head -n$COUNTER|tail -1); \ + fi; \ + if [[ x"${INSTALLER_PARTITION}" == x"${DISK1}*" ]]; then \ + INSTALLER_DISK=${DISK1}; \ + break; \ + fi; \ + done; \ + NUMOFLV=$(lvdisplay -C -o lv_path --readonly | wc -l); \ + LVS=$(lvdisplay -C -o lv_path --readonly); \ + for LV1 in ${LVS}; do \ + if [ x"${LV1}" = x"Path" ]; then \ + continue; \ + fi; \ + lvremove "${LV1}" -f -y; \ + done; \ + NUMOFVG=$(vgdisplay -C -o vg_name --readonly | wc -l); \ + VGS=$(vgdisplay -C -o vg_name --readonly); \ + for VG1 in ${VGS}; do \ + if [ x"${VG1}" = x"VG" ]; then \ + continue; \ + fi; \ + vgremove "${VG1}" -f -y; \ + done; \ + NUMOFPV=$(pvdisplay -C -o pv_name --readonly | wc -l); \ + PVS=$(pvdisplay -C -o pv_name --readonly); \ + for PV1 in ${PVS}; do \ + if [ x"${PV1}" = x"PV" ]; then \ + continue; \ + fi; \ + if [[ x"${PV1}" == x"${INSTALLER_DISK}*" ]]; then \ + continue; \ + fi; \ + pvremove "${PV1}" -f -y; \ + done; \ + NUMOFDISKS=$(list-devices disk | wc -l); \ + for DISK2 in "/dev/nvme0n1" "/dev/sda" "/dev/vda"; do \ + if [ x"${DISK2}" = x"${INSTALLER_DISK}" ]; then \ + continue; \ + fi; \ + COUNTER=0; \ + FOUNDFLAG=0; \ + while [ "$COUNTER" -lt "$NUMOFDISKS" ]; do \ + COUNTER=$((COUNTER+1)); \ + if [ "$COUNTER" -eq 1 ]; then \ + DISK1=$(list-devices disk|head -n1); \ + else \ + DISK1=$(list-devices disk|head -n$COUNTER|tail -1); \ + fi; \ + if [ x"${DISK1}" = x"${DISK2}" ]; then \ + FOUNDFLAG=1; \ + break; \ + fi; \ + done; \ + if [ "${FOUNDFLAG}" -eq 1 ]; then \ + MAIN_DISK="${DISK2}"; \ + break; \ + fi; \ + done; \ + COUNTER=0; \ + if [ x"$MAIN_DISK" != x ]; then \ + FINAL_DISKS="$MAIN_DISK"; \ + fi; \ + if [ x"$MAIN_DISK" != x ]; then \ + RECIPE_PART1="$(debconf-get partman-auto/expert_recipe_linaro_lvm_nopv)"; \ + FINAL_RECIPE="${RECIPE_PART1} 4096 8192 1000000000 \$default_filesystem \$defaultignore{ } \$primary{ } method{ lvm } device{ ${MAIN_DISK} } vg_name{ ${VGNAME} } ."; \ + fi; \ + if [ x"$MAIN_DISK" != x ]; then \ + COUNTER=0; \ + while [ "$COUNTER" -lt "$NUMOFDISKS" ]; do \ + COUNTER=$((COUNTER+1)); \ + if [ "$COUNTER" -eq 1 ]; then \ + DISK1=$(list-devices disk|head -n1); \ + else \ + DISK1=$(list-devices disk|head -n$COUNTER|tail -1); \ + fi; \ + if [ x"$DISK1" = x"$MAIN_DISK" ]; then \ + continue; \ + elif [ x"$DISK1" = x"$INSTALLER_DISK" ]; then \ + continue; \ + elif [[ x"$DISK1" == x"/dev/nvme*" ]]; then \ + FINAL_DISKS="${FINAL_DISKS} ${DISK1}"; \ + FINAL_RECIPE="${FINAL_RECIPE} 128 8192 1000000000 \$default_filesystem \$defaultignore{ } \$primary{ } method{ lvm } device{ ${DISK1} } vg_name{ ${VGNAME} } ."; \ + elif [[ x"$DISK1" == x"/dev/vd*" ]]; then \ + FINAL_DISKS="${FINAL_DISKS} ${DISK1}"; \ + FINAL_RECIPE="${FINAL_RECIPE} 128 8192 1000000000 \$default_filesystem \$defaultignore{ } \$primary{ } method{ lvm } device{ ${DISK1} } vg_name{ ${VGNAME} } ."; \ + fi; \ + done; \ + fi; \ + if [ x"$FINAL_DISKS" != x ]; then \ + debconf-set partman-auto/disk "$FINAL_DISKS"; \ + fi; \ + if [ x"$FINAL_RECIPE" != x ]; then \ + debconf-set partman-auto/expert_recipe "${FINAL_RECIPE}"; \ + fi; + +# Set the disk to install. If not set, select Guided -> select device. +#d-i partman-auto/disk string /dev/vda +d-i partman-auto/method string lvm +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-lvm/device_remove_lvm_span boolean true +d-i partman-md/device_remove_md boolean true +d-i partman-auto/purge_lvm_from_device boolean true +d-i partman-auto-lvm/new_vg_name string vglinarogigamprootfs +d-i partman/alignment string "optimal" +d-i partman-auto-lvm/guided_size string max +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true + +d-i partman-auto/expert_recipe_linaro_lvm_nopv string \ + linaroefiroot :: \ + 128 256 512 fat32 \ + $iflabel{ gpt } \ + $primary{ } \ + $reusemethod{ } \ + method{ efi } format{ } \ + label { esp } \ + . \ + 256 2048 4096 ext4 \ + $primary{ } \ + $bootable{ } \ + method{ format } \ + format{ } \ + use_filesystem{ } \ + filesystem{ ext4 } \ + mountpoint{ /boot } \ + . \ + 4096 8192 -1 ext4 \ + $lvmok{} \ + lv_name{ lvlinarogigamprootfs } \ + in_vg{ vglinarogigamprootfs } \ + method{ format } format{ } \ + use_filesystem{ } \ + filesystem{ ext4 } \ + mountpoint{ / } \ + . + +d-i partman-auto/expert_recipe_linaro_root string \ + linaroefiroot :: \ + 128 256 512 fat32 \ + $iflabel{ gpt } \ + $reusemethod{ } \ + method{ efi } format{ } \ + . \ + 4096 8192 1000000000 ext4 \ + method{ format } format{ } \ + use_filesystem{ } \ + filesystem{ ext4 } \ + mountpoint{ / } \ + . + +d-i partman-auto/expert_recipe_linaro_home_format string \ + linaroefiroot :: \ + 128 256 512 fat32 \ + $iflabel{ gpt } \ + $reusemethod{ } \ + method{ efi } format{ } \ + . \ + 8192 71680 143360 ext4 \ + method{ format } format{ } \ + use_filesystem{ } \ + filesystem{ ext4 } \ + mountpoint{ / } \ + . \ + 4096 71680 1000000000 ext4 \ + method{ format } format{ } \ + use_filesystem{ } \ + filesystem{ ext4 } \ + mountpoint{ /home } \ + . + +d-i partman-auto/expert_recipe_linaro_home string \ + linaroefiroot :: \ + 128 256 512 fat32 \ + $iflabel{ gpt } \ + $reusemethod{ } \ + method{ efi } format{ } \ + . \ + 8192 71680 143360 ext4 \ + method{ format } format{ } \ + use_filesystem{ } \ + filesystem{ ext4 } \ + mountpoint{ / } \ + . \ + 4096 71680 1000000000 ext4 \ + method{ keep } \ + use_filesystem{ } \ + filesystem{ ext4 } \ + mountpoint{ /home } \ + . + +# +d-i partman-auto/choose_recipe select linaroefiroot +d-i partman-basicfilesystems/no_swap boolean false + +# Don't punt for no-method filesystems. Another undocumented option. +d-i partman-basicmethods/method_only boolean false + +# This makes partman automatically partition without confirmation, provided +# that you told it what to do using one of the methods above. +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +# Force UEFI booting ('BIOS compatibility' will be lost). Default: false. +d-i partman-efi/non_efi_system boolean true + +# Ensure the partition table is GPT - this is required for EFI +d-i partman-partitioning/choose_label select gpt +d-i partman-partitioning/default_label string gpt + +# Choose, if you want to scan additional installation media +# (default: false). +d-i apt-setup/cdrom/set-first boolean false +# Backport selection +d-i apt-setup/services-select multiselect backports +# You can choose to install non-free firmware. +d-i apt-setup/non-free-firmware boolean true +# You can choose to install non-free and contrib software. +d-i apt-setup/non-free boolean true +d-i apt-setup/contrib boolean true + +tasksel tasksel/first multiselect standard, ssh-server + +popularity-contest popularity-contest/participate boolean false + +grub-efi-arm64 grub2/linux_cmdline_default string quiet amdgpu.runpm=0 amdgpu.dc=0 + +# This is fairly safe to set, it makes grub install automatically to the UEFI +# partition/boot record if no other operating system is detected on the machine. +d-i grub-installer/only_debian boolean true +d-i grub-installer/force-efi-extra-removable boolean true +d-i grub-installer/update-nvram boolean false + +# Avoid that last message about the install being complete. +d-i finish-install/reboot_in_progress note + +d-i preseed/late_command string \ + cp -f /after_install_1.sh /target/root; \ + in-target /bin/sh /root/after_install_1.sh; + diff --git a/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-extract-partitions.sh b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-extract-partitions.sh new file mode 100755 index 00000000000..8edca4f231e --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-extract-partitions.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +extract_image() { + disk1e="$1" + part1e="$2" + out1e="$3" + + partition_start=$(partx -g -o START -s -n "${part1e}" "${disk1e}" | xargs) + partition_end=$(partx -g -o END -s -n "${part1e}" "${disk1e}" | xargs) + partition_num_sectors=$((${partition_end} - ${partition_start} + 1)) + partition_offset=$((${partition_start} * 512)) + partition_size=$((${partition_num_sectors} * 512)) + + dd if="${disk1e}" of="${out1e}" bs=512 skip="${partition_start}" \ + count="${partition_num_sectors}" +} + +disk="uboot_qemu_disk1.img" + +NUMOFPARTITIONS=$(partx -g "${disk}" | wc -l) + +if [ ${NUMOFPARTITIONS} -ne 3 ]; then + echo "Number of partitions incorrect: ${NUMOFPARTITIONS}" + partx "${disk}" + exit 1 +fi + +rootfs_partition_tempfile="rootfs.img" +lvm_partition_tempfile="lvm.img" +lvm_partition="3" +boot_partition_tempfile="boot.img" +boot_partition="2" + +extract_image "${disk}" "${boot_partition}" "${boot_partition_tempfile}" +extract_image "${disk}" "${lvm_partition}" "${lvm_partition_tempfile}" +/usr/sbin/e2fsck -p -f "${boot_partition_tempfile}" || true + +LOOPDEV="$(sudo losetup -f)" +sudo losetup -r "${LOOPDEV}" "${lvm_partition_tempfile}" +sleep 10 +sudo pvdisplay --readonly --devices "${LOOPDEV}" +sudo vgdisplay --readonly --devices "${LOOPDEV}" +sudo lvdisplay --readonly --devices "${LOOPDEV}" +rootfs_lv_path=$(sudo lvdisplay -C -o "lv_path" --readonly --devices "${LOOPDEV}" | tail -1 | xargs) +rootfs_dev_path=$(sudo lvdisplay -C -o "lv_dm_path" --readonly --devices "${LOOPDEV}" | tail -1 | xargs) +sudo lvchange -ay "${rootfs_lv_path}" --devices "${LOOPDEV}" --verbose +sleep 10 +#sudo dd if="${rootfs_lv_path}" of="${rootfs_partition_tempfile}" bs=512 +guestfish <<_EOF_ +add-ro ${lvm_partition_tempfile} +run +pvs-full +vgs-full +lvs-full +list-filesystems +download ${rootfs_lv_path} ${rootfs_partition_tempfile} +_EOF_ +sudo e2fsck -p -f "${rootfs_partition_tempfile}" || true +sudo lvchange -an "${rootfs_lv_path}" --devices "${LOOPDEV}" --verbose +sleep 10 +sudo losetup -d "${LOOPDEV}" +sleep 10 diff --git a/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-install-edk2.expect b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-install-edk2.expect new file mode 100755 index 00000000000..1d9b6a45ecf --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-install-edk2.expect @@ -0,0 +1,70 @@ +#!/usr/bin/expect -- + +if {$argc < 2} { + set filename1 test_filename1 + set content1 Eimoh5be +} else { + set filename1 [lindex $argv 0] + set content1 [lindex $argv 1] +} + +set timeout 120 +log_file -noappend installer-iso-serial-console.log + +spawn ./installer-iso-run-qemu-edk2.sh +set qemu_pid $spawn_id + +# grub select serial console based install +set timeout 3 + +expect { + # select "Install" + -re "\\*(Install)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +# after installation +set timeout -1 + +expect { + "login:" { sleep 1; send -- "vsoc-01\r" } + -re "Dependency failed for (.*)ttyAMA0" { + send_user "\nttyAMA0 failed, exit earlier.\n" + sleep 60 + spawn sshpass -p cuttlefish ssh -o "StrictHostKeyChecking no" -o "UserKnownHostsFile /dev/null" -p 33322 vsoc-01@localhost "while ! systemctl is-active dev-ttyAMA0.device; do sleep 10; done; echo cuttlefish | sudo -S -k systemctl start serial-getty@ttyAMA0.service" + wait $spawn_id + exp_continue + } + timeout { exit 1 } +} + +set timeout 120 + +expect { + "Password:" { sleep 1; send -- "cuttlefish\r" } + timeout { exit 1 } +} + +expect { + -re "(\\$) $" { send -- "echo $content1 > $filename1 ; sync\r" } + timeout { exit 1 } +} + +expect { + -re "(\\$) $" { send -- "sudo su\r" } + timeout { exit 1 } +} + +expect { + "password for vsoc-01" { sleep 1; send -- "cuttlefish\r" } + timeout { exit 1 } +} + +set timeout 300 + +expect { + -re "(#) $" { send -- "shutdown -h 1\r" } + timeout { exit 1 } +} + +interact diff --git a/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-install.expect b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-install.expect new file mode 100755 index 00000000000..47704dae26a --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-install.expect @@ -0,0 +1,210 @@ +#!/usr/bin/expect -- + +if {$argc < 2} { + set filename1 test_filename1 + set content1 Eimoh5be +} else { + set filename1 [lindex $argv 0] + set content1 [lindex $argv 1] +} + +set timeout 120 +log_file -noappend installer-iso-serial-console.log + +spawn ./installer-iso-run-qemu.sh +set qemu_pid $spawn_id + +expect { + "Hit any key to stop" { send -- "\r" } + timeout { exit 1 } +} + +set send_human {.4 .4 .2 .5 100} + +expect { + "=>" { send -- "true\r" } + timeout { exit 1 } +} + +expect { + "=>" { send -- "virtio info\r" } + timeout { exit 1 } +} + +expect { + # get the last virtio device + -re "Device (\[0-9\]+):" { set lastvirtiodev $expect_out(1,string); exp_continue } + "=>" { send -- "echo I think the last virtio device is ${lastvirtiodev}\r" } + timeout { exit 1 } +} + +expect { + "=>" { send -- "eficonfig\r" } + timeout { exit 1 } +} + +# eficonfig to add debian installer as boot option +set timeout 5 + +expect { + # ANSI: ESC[7m color invert, ESC[0K erase the line to EOL + -re "\x1b.7m\x1b.\[0-9\]+K(Add Boot Option)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]+K(Description:)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + "Enter description:" { sleep 1; send -- "d-i\r" } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]K(File:)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]K(Select File)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]K(virtio ${lastvirtiodev}:2)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]K(efi.)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]K(boot.)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]K(bootaa64.efi)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]K(Save)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]K(Change Boot Order)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + # unselect all virtio devices + -re "\x1b.7m\x1b.\[0-9\]K(\\\[\\*\\\]\\s+virtio.*)\x1b.0m" { sleep 1; send -- " "; exp_continue } + -re "\x1b.7m(\\\[\\*\\\]\\s+virtio.*)\x1b.0m" { sleep 1; send -- " "; exp_continue } + # select d-i if not selected + -re "\x1b.7m(\\\[\\s\\\]\\s+d-i)\x1b.0m" { sleep 1; send -- " "; exp_continue } + -re "\x1b.7m(\\\[\\*\\\]\\s+d-i)\x1b.0m" { sleep 1; exp_continue } + # Save + -re "\x1b.7m\x1b.\[0-9\]K(Save)\x1b.0m" { sleep 1; send -- "\r" } + -re "\x1b.7m(Save)\x1b.0m" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + -re "\x1b.7m\x1b.\[0-9\]K(Quit)" { sleep 1; send -- "\r" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +set timeout 120 + +expect { + "=>" { send -- "bootefi bootmgr\r" } + timeout { exit 1 } +} + +# grub select serial console based install +set timeout 3 + +expect { + # select "Install" + -re "\\*(Install)" { sleep 1; send -- "e" } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + # locate linux line + # ANSI: ESC[y;xH move the cursor + -re "\x1b\\\[(\[0-9\]+;\[0-9\]+)H\\s*(linux\\s)" { set linuxlocation $expect_out(1,string) } + timeout { exit 1 } +} + +expect { + # move cursor to linux line + # ANSI: ESC[?25l turn off the cursor. ESC[?25h turn on the cursor + -re "\x1b.\\\?25l\x1b\\\[${linuxlocation}H\x1b.\\\?25h" { } + timeout { send -- "\x1b\[B"; exp_continue } +} + +expect { + # move cursor to end of line + timeout { send -- "\x05" } +} + +expect { + timeout { send " DEBIAN_FRONTEND=text" } +} + +expect { + # ctrl-x + timeout { send -- "\x18" } +} + +# after installation +set timeout -1 + +expect { + "login:" { sleep 1; send -- "vsoc-01\r" } + -re "Dependency failed for (.*)ttyAMA0" { + send_user "\nttyAMA0 failed, exit earlier.\n" + sleep 60 + spawn sshpass -p cuttlefish ssh -o "StrictHostKeyChecking no" -o "UserKnownHostsFile /dev/null" -p 33322 vsoc-01@localhost "while ! systemctl is-active dev-ttyAMA0.device; do sleep 10; done; echo cuttlefish | sudo -S -k systemctl start serial-getty@ttyAMA0.service" + wait $spawn_id + exp_continue + } + timeout { exit 1 } +} + +set timeout 120 + +expect { + "Password:" { sleep 1; send -- "cuttlefish\r" } + timeout { exit 1 } +} + +expect { + -re "(\\$) $" { send -- "echo $content1 > $filename1 ; sync\r" } + timeout { exit 1 } +} + +expect { + -re "(\\$) $" { send -- "sudo su\r" } + timeout { exit 1 } +} + +expect { + "password for vsoc-01" { sleep 1; send -- "cuttlefish\r" } + timeout { exit 1 } +} + +set timeout 300 + +expect { + -re "(#) $" { send -- "shutdown -h 1\r" } + timeout { exit 1 } +} + +interact diff --git a/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-run-qemu-edk2.sh b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-run-qemu-edk2.sh new file mode 100755 index 00000000000..a2ccf5e94c6 --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-run-qemu-edk2.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +SELFPID=$$ +renice 5 -p "$SELFPID" +#ionice -c 3 -p "$SELFPID" + +tmpdisk1="edk2_qemu_disk1.img" +edk2vars="/usr/share/AAVMF/AAVMF_VARS.fd" +edk2code="/usr/share/AAVMF/AAVMF_CODE.fd" +tmpflash="AAVMF_VARS.fd" +edk2bios="/usr/share/qemu-efi-aarch64/QEMU_EFI.fd" +debiancd=preseed-mini*.iso + +debiancd=$(realpath ${debiancd}) + +# We need to backup the debiancd file because qemu doesn't treat +# it as a read-only CD. So the program might be able to change it. + +debiancdtmp=$(mktemp -p $(dirname "${debiancd}")) +cp -f "${debiancd}" "${debiancdtmp}" + +if [ ! -e "${tmpdisk1}" ]; then + truncate -s 20G "${tmpdisk1}" +fi + +# create Flash image for storing EDK2 variables. +if [ ! -e "${tmpflash}" ]; then + cp -f "${edk2vars}" "${tmpflash}" +fi + +COUNTER=0 +DISKS="" +for DISK1 in edk2_qemu_disk*.img; do + DISKS="$DISKS -drive file=${DISK1},format=raw,if=none,aio=threads,id=drive-virtio-disk${COUNTER} -device virtio-blk-pci,drive=drive-virtio-disk${COUNTER},iommu_platform=true,disable-legacy=on" + COUNTER=$((COUNTER+1)) +done + +qemu-system-aarch64 -machine virt \ + -cpu cortex-a57 \ + -nographic \ + -netdev user,id=net0,hostfwd=tcp::35555-:5555,hostfwd=tcp::33322-:22 \ + -device virtio-net-pci,mac=50:54:00:00:00:56,netdev=net0,id=net0-dev \ + -object rng-builtin,id=objrng0 \ + -device virtio-rng-pci-non-transitional,rng=objrng0,id=rng0,max-bytes=1024,period=2000 \ + -drive if=pflash,format=raw,readonly=on,file="${edk2code}" \ + -drive if=pflash,format=raw,file="${tmpflash}" \ + -drive if=virtio,format=raw,file="${debiancdtmp}" \ + ${DISKS} \ + -object cryptodev-backend-builtin,id=cryptodev0 \ + -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \ + -device virtio-iommu-pci \ + -device virtio-gpu-pci \ + -m 1G + +rm -f "${debiancdtmp}" diff --git a/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-run-qemu.sh b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-run-qemu.sh new file mode 100755 index 00000000000..d091fdd20e4 --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/installer-iso-run-qemu.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +SELFPID=$$ +renice 5 -p "$SELFPID" +#ionice -c 3 -p "$SELFPID" + +TEST_DISK_SIZE_DEFAULT=20G +if [ x"${TEST_DISK_SIZE}" = x ]; then + TEST_DISK_SIZE="${TEST_DISK_SIZE_DEFAULT}" +fi + +tmpdisk1="uboot_qemu_disk1.img" +tmpflash="uboot_qemu_flash.img" +uboot="/usr/lib/u-boot/qemu_arm64/u-boot.bin" +debiancd=preseed-mini*.iso + +debiancd=$(realpath ${debiancd}) + +# We need to backup the debiancd file because qemu doesn't treat +# it as a read-only CD. So the program might be able to change it. + +debiancdtmp=$(mktemp -p $(dirname "${debiancd}")) +cp -f "${debiancd}" "${debiancdtmp}" + +if [ ! -e "${tmpdisk1}" ]; then + truncate -s "${TEST_DISK_SIZE}" "${tmpdisk1}" +fi + +# create Flash image for storing U-boot variables. +if [ ! -e "${tmpflash}" ]; then + qemu-img create -f raw "${tmpflash}" 64M +fi + +COUNTER=0 +DISKS="" +for DISK1 in uboot_qemu_disk*.img; do + DISKS="$DISKS -drive file=${DISK1},format=raw,if=none,aio=threads,id=drive-virtio-disk${COUNTER} -device virtio-blk-pci,drive=drive-virtio-disk${COUNTER},iommu_platform=true,disable-legacy=on" + COUNTER=$((COUNTER+1)) +done + +qemu-system-aarch64 -machine virt \ + -cpu cortex-a57 \ + -nographic \ + -netdev user,id=net0,hostfwd=tcp::35555-:5555,hostfwd=tcp::33322-:22 \ + -device virtio-net-pci,mac=50:54:00:00:00:56,netdev=net0,id=net0-dev \ + -object rng-builtin,id=objrng0 \ + -device virtio-rng-pci-non-transitional,rng=objrng0,id=rng0,max-bytes=1024,period=2000 \ + -drive if=virtio,format=raw,file="${debiancdtmp}" \ + ${DISKS} \ + -drive if=pflash,format=raw,index=1,file="${tmpflash}" \ + -object cryptodev-backend-builtin,id=cryptodev0 \ + -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \ + -device virtio-iommu-pci \ + -device virtio-gpu-pci \ + -m 1G \ + -bios "${uboot}" + +rm -f "${debiancdtmp}" diff --git a/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-empty-disk2.sh b/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-empty-disk2.sh new file mode 100755 index 00000000000..23ec6f05703 --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-empty-disk2.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +SELFPID=$$ +renice 5 -p "$SELFPID" + +# This test creates 2 disks. Each of them are 5G. + +tmpdisk1="uboot_qemu_disk1.img" +tmpdisk2="uboot_qemu_disk2.img" + +if [ ! -e "${tmpdisk1}" ]; then + truncate -s 5G "${tmpdisk1}" +fi + +if [ ! -e "${tmpdisk2}" ]; then + truncate -s 5G "${tmpdisk2}" +fi diff --git a/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-preinstalled-disk2.sh b/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-preinstalled-disk2.sh new file mode 100755 index 00000000000..af101e00f5d --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-preinstalled-disk2.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +SELFPID=$$ +renice 5 -p "$SELFPID" +#ionice -c 3 -p "$SELFPID" + +# This test creates 2 disks. Each of them are 5G. The 2nd disk +# contains a PV already. Simulate something is installed previously. + +tmpdisk1="uboot_qemu_disk1.img" +tmpdisk2="uboot_qemu_disk2.img" + +if [ ! -e "${tmpdisk1}" ]; then + truncate -s 5G "${tmpdisk1}" +fi + +if [ ! -e "${tmpdisk2}" ]; then + truncate -s 5G "${tmpdisk2}" +fi + +# partition disk1 +/usr/sbin/sgdisk \ + "-n:1:5M:0" "-t:1:8e00" "-c:1:ubu2lvm" \ + "-A:1:set:0" "${tmpdisk1}" + +# partition disk2 +/usr/sbin/sgdisk \ + "-n:1:18M:+32M" "-t:1:ef00" "-c:1:ubuesp" \ + "-A:1:set:0" "${tmpdisk2}" + +/usr/sbin/sgdisk \ + "-n:2:50M:+50M" "-t:2:8305" "-c:2:ububoot" \ + "-A:2:set:2" "${tmpdisk2}" + +/usr/sbin/sgdisk \ + "-n:3:100M:0" "-t:3:8e00" "-c:3:ubulvm" \ + "-A:3:set:0" "${tmpdisk2}" + +system_partition=1 +system_partition_start=$(partx -g -o START -s -n "${system_partition}" "${tmpdisk2}" | xargs) +system_partition_end=$(partx -g -o END -s -n "${system_partition}" "${tmpdisk2}" | xargs) +system_partition_num_sectors=$((${system_partition_end} - ${system_partition_start} + 1)) +system_partition_num_vfat_blocks=$((${system_partition_num_sectors} / 2)) +/usr/sbin/mkfs.vfat -n SYSTEM -F 16 --offset=${system_partition_start} "${tmpdisk2}" ${system_partition_num_vfat_blocks} + +boot_partition=2 +boot_partition_start=$(partx -g -o START -s -n "${boot_partition}" "${tmpdisk2}" | xargs) +boot_partition_end=$(partx -g -o END -s -n "${boot_partition}" "${tmpdisk2}" | xargs) +boot_partition_num_sectors=$((${boot_partition_end} - ${boot_partition_start} + 1)) +boot_partition_offset=$((${boot_partition_start} * 512)) +boot_partition_size=$((${boot_partition_num_sectors} * 512)) + +/usr/sbin/mke2fs -E offset=${boot_partition_offset} ${tmpdisk2} 50m +/usr/sbin/e2fsck -fy "${tmpdisk2}"?offset=${boot_partition_offset} || true + +guestfish <<_EOF_ +add ${tmpdisk1} +add ${tmpdisk2} +run +list-devices +list-partitions +pvcreate /dev/sda1 +pvcreate /dev/sdb3 +pvs-full +vgcreate ubu-vg "/dev/sdb3 /dev/sda1" +vgs-full +lvcreate-free ubu-lv ubu-vg 100 +lvs-full +vg-activate-all true +list-filesystems +mke2fs /dev/ubu-vg/ubu-lv +e2fsck-f /dev/ubu-vg/ubu-lv +list-filesystems +_EOF_ diff --git a/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-preinstalled-disk5.sh b/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-preinstalled-disk5.sh new file mode 100755 index 00000000000..1f35f8e6c3b --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-create-preinstalled-disk5.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +SELFPID=$$ +renice 5 -p "$SELFPID" +#ionice -c 3 -p "$SELFPID" + +# This test creates 5 disks. Each of them are 2G. The 2nd disk +# contains a PV already. Simulate something is installed previously. + +tmpdisk0="uboot_qemu_disk0.img" +tmpdisk1="uboot_qemu_disk1.img" +tmpdisk2="uboot_qemu_disk2.img" +tmpdisk3="uboot_qemu_disk3.img" +tmpdisk4="uboot_qemu_disk4.img" + +if [ ! -e "${tmpdisk0}" ]; then + truncate -s 2G "${tmpdisk0}" +fi + +if [ ! -e "${tmpdisk1}" ]; then + truncate -s 2G "${tmpdisk1}" +fi + +if [ ! -e "${tmpdisk2}" ]; then + truncate -s 2G "${tmpdisk2}" +fi + +if [ ! -e "${tmpdisk3}" ]; then + truncate -s 2G "${tmpdisk3}" +fi + +if [ ! -e "${tmpdisk4}" ]; then + truncate -s 2G "${tmpdisk4}" +fi + +# partition disk4 +/usr/sbin/sgdisk \ + "-n:1:18M:+32M" "-t:1:ef00" "-c:1:ubuesp" \ + "-A:1:set:0" "${tmpdisk4}" + +/usr/sbin/sgdisk \ + "-n:2:50M:+50M" "-t:2:8305" "-c:2:ububoot" \ + "-A:2:set:2" "${tmpdisk4}" + +/usr/sbin/sgdisk \ + "-n:3:100M:0" "-t:3:8e00" "-c:3:ubulvm" \ + "-A:3:set:0" "${tmpdisk4}" + +system_partition=1 +system_partition_start=$(partx -g -o START -s -n "${system_partition}" "${tmpdisk4}" | xargs) +system_partition_end=$(partx -g -o END -s -n "${system_partition}" "${tmpdisk4}" | xargs) +system_partition_num_sectors=$((${system_partition_end} - ${system_partition_start} + 1)) +system_partition_num_vfat_blocks=$((${system_partition_num_sectors} / 2)) +/usr/sbin/mkfs.vfat -n SYSTEM -F 16 --offset=${system_partition_start} "${tmpdisk4}" ${system_partition_num_vfat_blocks} + +boot_partition=2 +boot_partition_start=$(partx -g -o START -s -n "${boot_partition}" "${tmpdisk4}" | xargs) +boot_partition_end=$(partx -g -o END -s -n "${boot_partition}" "${tmpdisk4}" | xargs) +boot_partition_num_sectors=$((${boot_partition_end} - ${boot_partition_start} + 1)) +boot_partition_offset=$((${boot_partition_start} * 512)) +boot_partition_size=$((${boot_partition_num_sectors} * 512)) + +/usr/sbin/mke2fs -E offset=${boot_partition_offset} ${tmpdisk4} 50m +/usr/sbin/e2fsck -fy "${tmpdisk4}"?offset=${boot_partition_offset} || true + +guestfish <<_EOF_ +add ${tmpdisk0} +add ${tmpdisk1} +add ${tmpdisk2} +add ${tmpdisk3} +add ${tmpdisk4} +run +list-devices +list-partitions +pvcreate /dev/sda +pvcreate /dev/sdb +pvcreate /dev/sdc +pvcreate /dev/sdd +pvcreate /dev/sde3 +pvs-full +vgcreate ubu-vg "/dev/sde3" +vgs-full +lvcreate-free ubu-lv ubu-vg 100 +lvs-full +vg-activate-all true +mke2fs /dev/ubu-vg/ubu-lv +e2fsck-f /dev/ubu-vg/ubu-lv +list-filesystems +vgcreate home-vg "/dev/sda /dev/sdb /dev/sdc /dev/sdd" +vgs-full +lvcreate-free home-lv home-vg 100 +lvs-full +vg-activate-all true +mke2fs /dev/home-vg/home-lv +e2fsck-f /dev/home-vg/home-lv +list-filesystems +_EOF_ diff --git a/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-iso-extract-partitions-multidisk.sh b/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-iso-extract-partitions-multidisk.sh new file mode 100755 index 00000000000..20beb06e895 --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/multidisk/installer-iso-extract-partitions-multidisk.sh @@ -0,0 +1,103 @@ +#!/bin/bash + +extract_image() { + disk1e="$1" + part1e="$2" + out1e="$3" + + partition_start=$(partx -g -o START -s -n "${part1e}" "${disk1e}" | xargs) + partition_end=$(partx -g -o END -s -n "${part1e}" "${disk1e}" | xargs) + partition_num_sectors=$((${partition_end} - ${partition_start} + 1)) + partition_offset=$((${partition_start} * 512)) + partition_size=$((${partition_num_sectors} * 512)) + + dd if="${disk1e}" of="${out1e}" bs=512 skip="${partition_start}" \ + count="${partition_num_sectors}" +} + +diskmain=$(ls uboot_qemu_disk*.img | head -1) + +NUMOFPARTITIONS=$(partx -g "${diskmain}" | wc -l) + +if [ ${NUMOFPARTITIONS} -ne 3 ]; then + echo "Number of partitions incorrect: ${NUMOFPARTITIONS}" + partx "${diskmain}" + exit 1 +fi + +for DISK1 in uboot_qemu_disk*.img; do + if [ x"${DISK1}" = x"${diskmain}" ]; then + continue + fi + NUMOFPARTITIONS1=$(partx -g "${DISK1}" | wc -l) + if [ ${NUMOFPARTITIONS1} -ne 1 ]; then + echo "Number of partitions incorrect for ${DISK1}: ${NUMOFPARTITIONS1}" + partx "${DISK1}" + exit 1 + fi +done + +rootfs_partition_tempfile="rootfs.img" +lvm_partition_tempfile="lvm"$(echo "${diskmain}" | sed 's/uboot_qemu_disk\(.*\)\.img/\1/')".img" +lvm_partition="3" +boot_partition_tempfile="boot.img" +boot_partition="2" + +extract_image "${diskmain}" "${boot_partition}" "${boot_partition_tempfile}" +extract_image "${diskmain}" "${lvm_partition}" "${lvm_partition_tempfile}" +/usr/sbin/e2fsck -p -f "${boot_partition_tempfile}" || true + +for DISK1 in uboot_qemu_disk*.img; do + if [ x"${DISK1}" = x"${diskmain}" ]; then + continue + fi + NUM1=$(echo "${DISK1}" | sed 's/uboot_qemu_disk\(.*\)\.img/\1/') + extract_image "${DISK1}" 1 "lvm${NUM1}.img" +done + +sudo true + +LOOPDEVS="" +LOOPDEVSPV="" +for LVM1 in lvm*.img; do + LOOPDEV="$(sudo losetup -f)" + LOOPDEVS="${LOOPDEVS} ${LOOPDEV}" + LOOPDEVSPV="${LOOPDEVSPV} --devices ${LOOPDEV}" + sudo losetup -r "${LOOPDEV}" "${LVM1}" + sleep 10 +done + +echo "Test pvdisplay on each PV. Should printout a warning." +for LOOPDEV in ${LOOPDEVS}; do + sudo pvdisplay --readonly --devices "${LOOPDEV}" +done + +echo "Test pvdisplay on all PV. Should be OK." +sudo pvdisplay --readonly ${LOOPDEVSPV} +sudo vgdisplay --readonly ${LOOPDEVSPV} +sudo lvdisplay --readonly ${LOOPDEVSPV} +rootfs_lv_path=$(sudo lvdisplay -C -o "lv_path" --readonly ${LOOPDEVSPV} | tail -1 | xargs) +rootfs_dev_path=$(sudo lvdisplay -C -o "lv_dm_path" --readonly ${LOOPDEVSPV} | tail -1 | xargs) +sudo lvchange -ay "${rootfs_lv_path}" ${LOOPDEVSPV} --verbose +sleep 10 +#sudo dd if="${rootfs_lv_path}" of="${rootfs_partition_tempfile}" bs=512 +touch guestfish_commands.txt +for LVM1 in lvm*.img; do + echo "add-ro ${LVM1}" >> guestfish_commands.txt +done +cat >> guestfish_commands.txt <<_EOF_ +run +pvs-full +vgs-full +lvs-full +list-filesystems +download ${rootfs_lv_path} ${rootfs_partition_tempfile} +_EOF_ +guestfish < guestfish_commands.txt +sudo e2fsck -p -f "${rootfs_partition_tempfile}" || true +sudo lvchange -an "${rootfs_lv_path}" ${LOOPDEVSPV} --verbose +sleep 10 +for LOOPDEV in ${LOOPDEVS}; do + sudo losetup -d "${LOOPDEV}" + sleep 10 +done diff --git a/gigabyte-ampere-cuttlefish-installer/tests/test-after-install-script-kernel.sh b/gigabyte-ampere-cuttlefish-installer/tests/test-after-install-script-kernel.sh new file mode 100755 index 00000000000..18afd5687cb --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/test-after-install-script-kernel.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +awk '/# Install kernel/,/# End of Install kernel/' preseed/after_install_1.sh > after_install_1_kernel.sh + +if [ x"${EMULATE_NVIDIA_GPU}" != x"" ]; then + sed -i 's/^nvidia_gpu=.*/nvidia_gpu="nVidia"/' after_install_1_kernel.sh +fi +if [ x"${EMULATE_AMD_GPU}" != x"" ]; then + sed -i 's/^amd_gpu=.*/amd_gpu="VGA_AMD"/' after_install_1_kernel.sh +fi diff --git a/gigabyte-ampere-cuttlefish-installer/tests/test-cuttlefish-time.sh b/gigabyte-ampere-cuttlefish-installer/tests/test-cuttlefish-time.sh new file mode 100755 index 00000000000..274eeaada4d --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/test-cuttlefish-time.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +time HOME=$PWD ./bin/launch_cvd --daemon + +HOME=$PWD ./bin/stop_cvd diff --git a/gigabyte-ampere-cuttlefish-installer/tests/test-inside-pbuilder.sh b/gigabyte-ampere-cuttlefish-installer/tests/test-inside-pbuilder.sh new file mode 100755 index 00000000000..1168f2659ba --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/test-inside-pbuilder.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +# This script runs test scripts and artifacts inside pbuilder environment. +# Please use pbuilder-dist to create the environment first. + +set -e + +DISTRIBUTION="$1" +shift +ARCH="$1" +shift +SCRIPT1="$1" +shift + +TDIR=$(mktemp -d) + +cp -f "${SCRIPT1}" "${TDIR}" + +while [ $# -gt 0 ]; do + cp "$1" "${TDIR}" + shift +done + +SCRIPT1NAME=$(basename "${SCRIPT1}") + +cat < "${TDIR}"/start1.sh +#!/bin/sh + +set -e + +cd "${TDIR}" + +exec "${TDIR}/${SCRIPT1NAME}" + +EOF + +chmod a+x "${TDIR}"/start1.sh + +pbuilder-dist "${DISTRIBUTION}" "${ARCH}" execute --bindmounts "${TDIR}" "${TDIR}/start1.sh" diff --git a/gigabyte-ampere-cuttlefish-installer/tests/test-install-metapackage-deb.sh b/gigabyte-ampere-cuttlefish-installer/tests/test-install-metapackage-deb.sh new file mode 100755 index 00000000000..fab1343009f --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/tests/test-install-metapackage-deb.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +set -e + +apt-get install -y sudo +apt-get install -y debconf-utils +echo "tzdata tzdata/Areas select Etc" | debconf-set-selections -v +echo "tzdata tzdata/Zones/Etc select UTC" | debconf-set-selections -v +DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata +dpkg-reconfigure --frontend noninteractive tzdata + +apt -o Apt::Get::Assume-Yes=true -o APT::Color=0 -o DPkgPM::Progress-Fancy=0 install git devscripts config-package-dev debhelper-compat golang curl +apt-get install -y p7zip-full + +7z x meta_gigamp_packages.7z + +apt -o Apt::Get::Assume-Yes=true -o APT::Color=0 -o DPkgPM::Progress-Fancy=0 install ./*.deb + +test -e /etc/security/limits.d/95-linaro-gigamp-nofile.conf +ulimit -n + +grep time1.google.com /etc/ntpsec/ntp.conf + +apt -o Apt::Get::Assume-Yes=true -o APT::Color=0 -o DPkgPM::Progress-Fancy=0 purge metapackage-linaro-gigamp + +test $(grep time1.google.com /etc/ntpsec/ntp.conf | wc -l) -eq 0 diff --git a/gigabyte-ampere-cuttlefish-installer/utils/download-ci-cf.sh b/gigabyte-ampere-cuttlefish-installer/utils/download-ci-cf.sh new file mode 100755 index 00000000000..16350d9e2f5 --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/utils/download-ci-cf.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Download Cuttlefish + +set -o errexit + +URL=https://ci.android.com/builds/latest/branches/aosp-main-throttled/targets/aosp_cf_arm64_only_phone-trunk_staging-userdebug/view/BUILD_INFO +RURL=$(curl -Ls -o /dev/null -w %{url_effective} ${URL}) +echo $RURL + +FILENAME=$(wget -nv -O - ${RURL%/view/BUILD_INFO}/ | grep aosp_cf_arm64_only_phone-img- | sed 's/.*\(aosp_cf_arm64_only_phone-img-[0-9]*[.]zip\).*/\1/g') + +wget -nv -c ${RURL%/view/BUILD_INFO}/raw/${FILENAME} +wget -nv -c ${RURL%/view/BUILD_INFO}/raw/cvd-host_package.tar.gz + +exit 0 diff --git a/gigabyte-ampere-cuttlefish-installer/utils/install-build-depends.py b/gigabyte-ampere-cuttlefish-installer/utils/install-build-depends.py new file mode 100755 index 00000000000..f03fc382919 --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/utils/install-build-depends.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +import re +import subprocess + +def parse_debian_control(filename): + data = {} + current_section = None + with open(filename, 'r') as f: + key = "" + for line in f: + if not line or line.startswith('#'): + continue + if line.startswith(' ') or line.startswith('\t'): + line = line.strip() + data[key] = data[key] + line + else: + data1 = line.split(':', 1) + if (len(data1) == 2): + key = data1[0].strip() + value = data1[1].strip() + data[key] = value + return data + +def get_arch(): + arch = None + try: + arch = subprocess.check_output( + ['dpkg', '--print-architecture'], + encoding='utf-8' + ).strip() + except: + pass + return arch + +if __name__ == '__main__': + config = parse_debian_control("debian/control") + apt_command = ["apt", "-o", "Apt::Get::Assume-Yes=true", "-o", "APT::Color=0", "-o", "DPkgPM::Progress-Fancy=0", "install"] + + for i in ['Build-Depends', 'Build-Depends-Arch', 'Build-Depends-Indep']: + if (not (i in config)): + continue + packages = config[i] + packages = packages.split(",") + for package in packages: + # package (version) <...> + m1 = re.match(r"([^(\s]*)\s*([(][^)]*[)])\s*(?:<(?:.*)>)?", package); + # package (version) [arch] <...> + m2 = re.match(r"([^[(\s]*)\s*(?:[(][^)]*[)])?\s*\[(.*)\]\s*(?:<(?:.*)>)?", package); + # package <...> + m3 = re.match(r"([^[(\s]*)\s*(?:[(][^)]*[)])?\s*(?:<(?:.*)>)?", package); + if (m1): + print("Install %s"%(m1.group(1))) + apt_command_1 = apt_command[:] + apt_command_1.append(m1.group(1)) + subprocess.run(apt_command_1) + elif (m2): + if (get_arch() in m2.group(2).split()): + print("Install %s for %s"%(m2.group(1), m2.group(2))) + apt_command_1 = apt_command[:] + apt_command_1.append(m2.group(1)) + subprocess.run(apt_command_1) + else: + print("Not install %s because architecture not match (%s)."%(m2.group(1), m2.group(2))) + elif (m3): + print("Install %s"%(m3.group(1))) + apt_command_1 = apt_command[:] + apt_command_1.append(m3.group(1)) + subprocess.run(apt_command_1) + else: + print("Install %s"%(package)) + apt_command_1 = apt_command[:] + apt_command_1.append(package) + subprocess.run(apt_command_1) + pass diff --git a/gigabyte-ampere-cuttlefish-installer/utils/install_repo_package.sh b/gigabyte-ampere-cuttlefish-installer/utils/install_repo_package.sh new file mode 100755 index 00000000000..d32c913753f --- /dev/null +++ b/gigabyte-ampere-cuttlefish-installer/utils/install_repo_package.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# This script is for CodeLinaro CI. To install repo package in Debian +# image. + +# To run this script you need to install build-essential, devscripts, +# ubuntu-dev-tools, equivs, and fakeroot packages first. + +mkdir -p repo_debian_package_build_space +cd repo_debian_package_build_space +pull-debian-source repo +cd repo-* +mk-build-deps --install --root-cmd sudo --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control +debuild --no-sign +cd .. +sudo apt -o Apt::Get::Assume-Yes=true -o APT::Color=0 -o DPkgPM::Progress-Fancy=0 install ./*.deb +cd .. From fc35bfed6b5099c32dc33bfbb95538ed8dfd78c8 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Tue, 27 Jan 2026 23:42:06 +0800 Subject: [PATCH 2/2] Add workflows for gigabyte-ampere-cuttlefish-installer Signed-off-by: Ying-Chun Liu (PaulLiu) --- .../gigabyte-ampere-cuttlefish-installer.yaml | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 .github/workflows/gigabyte-ampere-cuttlefish-installer.yaml diff --git a/.github/workflows/gigabyte-ampere-cuttlefish-installer.yaml b/.github/workflows/gigabyte-ampere-cuttlefish-installer.yaml new file mode 100644 index 00000000000..8f26f98b415 --- /dev/null +++ b/.github/workflows/gigabyte-ampere-cuttlefish-installer.yaml @@ -0,0 +1,92 @@ +name: Workflow for Gigabyte Ampere Server Cuttlefish Installer + +on: [push] + +jobs: + build-iso: + runs-on: ubuntu-22.04 + container: + image: debian@sha256:9258a75a7e4323c9e5562b361effc84ee747920116d8adfc98a465a5cdc9150e # debian:bookworm-20250407 (amd64) + env: + DEBIAN_ISO_URL: "https://deb.debian.org/debian/dists/bookworm/main/installer-arm64/current/images/netboot/mini.iso" + CI_PROJECT_NAME: ${{ github.event.repository.name }} + CI_PIPELINE_ID: ${{ github.run_id }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setting up build environment + run: | + apt-get update + apt-get upgrade -y + apt-get install -y sudo + apt-get install -y wget libarchive-tools + apt-get install -y xorriso + apt-get install -y cpio xz-utils + apt-get install -y fdisk + - name: Build the iso image + run: | + cd gigabyte-ampere-cuttlefish-installer + sed -i "2i CI_PROJECT_NAME=${CI_PROJECT_NAME}" preseed/after_install_1.sh + sed -i "3i CI_PIPELINE_ID=${CI_PIPELINE_ID}" preseed/after_install_1.sh + wget -nv -c ${DEBIAN_ISO_URL} + ./addpreseed.sh + xz -9e preseed-mini.iso + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: gigabyte-ampere-cuttlefish-installer-artifacts + path: gigabyte-ampere-cuttlefish-installer/preseed-mini.iso.xz + + test-iso: + needs: build-iso + runs-on: ubuntu-22.04 + container: + image: debian:trixie # debian:trixie (amd64) + env: + TEST_DISK_SIZE: "10G" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: gigabyte-ampere-cuttlefish-installer-artifacts + - name: Prepare test environment + run: | + apt-get update + apt-get upgrade -y + apt-get install -y sudo + apt-get install -y debconf-utils + echo "tzdata tzdata/Areas select Etc" | debconf-set-selections -v + echo "tzdata tzdata/Zones/Etc select UTC" | debconf-set-selections -v + DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata + dpkg-reconfigure --frontend noninteractive tzdata + echo "pbuilder pbuilder/mirrorsite string http://deb.debian.org/debian/" | debconf-set-selections -v + DEBIAN_FRONTEND=noninteractive apt-get install -y pbuilder + dpkg-reconfigure --frontend noninteractive pbuilder + apt-get install -y util-linux util-linux-extra + apt-get install -y xz-utils + apt-get install -y qemu-system-arm + apt-get install -y expect + apt-get install -y e2tools e2fsprogs + apt-get install -y guestfish + apt-get install -y lvm2 + apt-get install -y ubuntu-dev-tools + apt-get install -y sshpass + apt-get install -y u-boot-qemu + - name: Run test + run: | + cd gigabyte-ampere-cuttlefish-installer + mv ../preseed-mini.iso.xz . + xz -d preseed-mini.iso.xz + chmod a-w preseed-mini.iso + cp -f tests/installer-iso-* . + ./installer-iso-install.expect successful_install sheeFei2 + ./installer-iso-extract-partitions.sh + e2cp rootfs.img:/home/vsoc-01/successful_install successful_install + echo sheeFei2 > successful_install_compare + cmp successful_install successful_install_compare + e2cp boot.img:/$(e2ls boot.img:/vmlinuz-* | tail -1) . + test -e vmlinuz- + e2ls -l rootfs.img:/usr/bin/cvd_host_orchestrator | grep cvd_host_orchestrator | grep root + test '!' -e home.img