Create a script and instructions to create an aarch64 sysroot via qemu (#35420)

* Prepare making a sysroot via qemu, so we do not need a raspberry pi ready (even though this is MUCH slower)

* Update gitignore

* Rename file for clearer naming

* Start adding some documentation on sysroot generation

* Restyle and update the image to 22.04 since this is what we use today

* Restyle

* vm is a common word

* Add helper info for mkpasswd existence

* More help messages

* More help and have auto-install because it is convenient

* Restyle

* More convenient text and help

* More updates for friendlyness

* Fix cloudinit schema

* Allocate more virtual CPUs as some things run slightly faster (a bit over 10% faster boot for me)

* Created a script to upload the cipd package

* Script cleanup and readme update

* User friendly progress and output

* Updated gitignore and script for nicer content

* Script cleanup for symlinks (goes from 7GB to 1.1GB)

* More updates to the rsync execution options

* Single rsync invokation, so that safe symlinks works better

* Restyle

* Update tag to be unique, since I was missing a symlink before and that seemed more broken

* Update integrations/docker/images/stage-1/chip-build-crosscompile/start-sysroot-vm.sh

Co-authored-by: Kiel Oleson <kielo@apple.com>

* Restyle

* Update start-sysroot-vm.sh

Update text about very weak password.

---------

Co-authored-by: Andrei Litvin <andreilitvin@google.com>
Co-authored-by: Kiel Oleson <kielo@apple.com>
diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt
index 9cb24bc..c84d403 100644
--- a/.github/.wordlist.txt
+++ b/.github/.wordlist.txt
@@ -1532,6 +1532,7 @@
 visualstudio
 vlatest
 VLEDs
+vm
 vn
 vnc
 vous
diff --git a/integrations/docker/images/stage-1/chip-build-crosscompile/.gitignore b/integrations/docker/images/stage-1/chip-build-crosscompile/.gitignore
index 37e0c7a..e4e6d2a 100644
--- a/integrations/docker/images/stage-1/chip-build-crosscompile/.gitignore
+++ b/integrations/docker/images/stage-1/chip-build-crosscompile/.gitignore
@@ -1,3 +1,10 @@
 .cipd
+cidata.iso
+cipd.yaml
 ensure_file.txt
+meta-data
+sysrootsrv.img
 ubuntu-21.04-aarch64-sysroot.tar.xz
+ubuntu-24.04-aarch64-sysroot
+ubuntu-24.04-server-cloudimg-arm64.img
+user-data
diff --git a/integrations/docker/images/stage-1/chip-build-crosscompile/README.md b/integrations/docker/images/stage-1/chip-build-crosscompile/README.md
index d27fc2f..4d97a7c 100644
--- a/integrations/docker/images/stage-1/chip-build-crosscompile/README.md
+++ b/integrations/docker/images/stage-1/chip-build-crosscompile/README.md
@@ -3,11 +3,55 @@
 This image adds cross-compilation support files (a suitable sysroot) on top of
 the regular linux chip-build image.
 
-The build assumes a file named `ubuntu-21.04-aarch64-sysroot.tar.xz` exists in
+The build assumes a file named `ubuntu-22.04-aarch64-sysroot.tar.xz` exists in
 the current directory. This can generally be manually built using an existing
 Raspberry Pi device (or equivalent qemu) and a convenience copy was created in
 CIPD
 
+#### Creating a Sysroot (qemu virtual emulator)
+
+NOTE: this approach is slower due to emulation usage, however has the advantage
+of not requiring separate hardware.
+
+Ensure `qemu` and `virt-install` prerequisites are met:
+
+```
+apt-get install qemu-system-arm virtinst libvirt-daemon
+```
+
+Start up the sysroot virtual machine. This will be named `sysrootsrv`:
+
+```
+./start-sysroot-vm.sh
+```
+
+Connect to a console to monitor progress. The VM is configured to pre-install
+packages based on CHIP BUILDING.md documentation plus any additional packages.
+
+```
+virsh console sysrootsrv
+```
+
+Once installation completed, you can also login as `ubuntu/1234` or use
+`ssh ubuntu@localhost -p 5555`
+
+The current image is based on Ubuntu 24.04, so you can create an image via:
+
+```
+rsync -avL -e 'ssh -p 5555' ubuntu@localhost:/lib ubuntu-24.04-aarch64-sysroot
+rsync -avL -e 'ssh -p 5555' ubuntu@localhost:/usr/lib ubuntu-24.04-aarch64-sysroot/usr
+rsync -avL -e 'ssh -p 5555' ubuntu@localhost:/usr/include ubuntu-24.04-aarch64-sysroot/usr
+```
+
+At this point you have a sysroot in `ubuntu-24.04-aarch64-sysroot`
+
+To create/upload a CIPD package tagged with the current date, a script is
+provided:
+
+```
+upload-cipd-package.sh
+```
+
 #### Creating a Sysroot
 
 Start with a fresh Raspberry PI image:
@@ -15,16 +59,16 @@
 -   Use the Raspberry pi imager from https://www.raspberrypi.org/software/
 -   Follow installation instructions from the CHIP BUILDING.md document.
     Generally this includes:
-    -   Use Ubuntu 21.04 server 64 bit server image
+    -   Use Ubuntu 22.04 server 64 bit server image
     -   Install required compile dependencies via `apt-get`. You may skip
         installing git and python3 dependencies to save some image size
 
 Generate a sysroot. You can do this locally (slow due to SD performance):
 
 ```
-rsync -avL /lib ubuntu-21.04-aarch64-sysroot/
-rsync -avL /usr/lib ubuntu-21.04-aarch64-sysroot/usr
-rsync -avL /usr/include ubuntu-21.04-aarch64-sysroot/usr
+rsync -avL /lib ubuntu-22.04-aarch64-sysroot/
+rsync -avL /usr/lib ubuntu-22.04-aarch64-sysroot/usr
+rsync -avL /usr/include ubuntu-22.04-aarch64-sysroot/usr
 ```
 
 or you can copy directly to your host machine via
@@ -33,9 +77,9 @@
 export PI="ip-of-raspberry-pi"
 ssh-copy-id ubuntu@$PI
 
-rsync -avL ubuntu@$PI:/lib ubuntu-21.04-aarch64-sysroot
-rsync -avL ubuntu@$PI:/usr/lib ubuntu-21.04-aarch64-sysroot/usr
-rsync -avL ubuntu@$PI:/include/lib ubuntu-21.04-aarch64-sysroot/usr
+rsync -avL ubuntu@$PI:/lib ubuntu-22.04-aarch64-sysroot
+rsync -avL ubuntu@$PI:/usr/lib ubuntu-22.04-aarch64-sysroot/usr
+rsync -avL ubuntu@$PI:/usr/include ubuntu-22.04-aarch64-sysroot/usr
 ```
 
 NOTE: in the future, if creating a 32-bit image (not covered by this docker
@@ -47,7 +91,7 @@
 Once the sysroot is on the host machine, create the corresponding `tar.xz` file:
 
 ```
-tar cvfJ ubuntu-21.04-aarch64-sysroot.tar.xz ubuntu-21.04-aarch64-sysroot
+tar cvfJ ubuntu-22.04-aarch64-sysroot.tar.xz ubuntu-22.04-aarch64-sysroot
 ```
 
 #### CIPD image
@@ -55,12 +99,12 @@
 CIPD image is provided as a convenience to avoid the need to spend time
 rebuilding a sysroot. It is located at:
 
-https://chrome-infra-packages.appspot.com/p/experimental/matter/sysroot/ubuntu-21.04-aarch64/+/
+https://chrome-infra-packages.appspot.com/p/experimental/matter/sysroot/ubuntu-22.04-aarch64/+/
 
 and can be downloaded using the `cipd` script from
 [depot_tools](https://dev.chromium.org/developers/how-tos/depottools):
 
 ```
-echo 'experimental/matter/sysroot/ubuntu-21.04-aarch64 latest' > ensure_file.txt
+echo 'experimental/matter/sysroot/ubuntu-22.04-aarch64 latest' > ensure_file.txt
 cipd ensure -ensure-file ensure_file.txt -root ./
 ```
diff --git a/integrations/docker/images/stage-1/chip-build-crosscompile/start-sysroot-vm.sh b/integrations/docker/images/stage-1/chip-build-crosscompile/start-sysroot-vm.sh
new file mode 100755
index 0000000..fb56c43
--- /dev/null
+++ b/integrations/docker/images/stage-1/chip-build-crosscompile/start-sysroot-vm.sh
@@ -0,0 +1,217 @@
+#!/usr/bin/env bash
+
+# This script is intended to build a SYSROOT that can be used as a base to cross-compile
+# CHIP for aarch64 (i.e. that runs on a RaspberryPi) from a amd64 linux machine
+
+set -e
+
+start_console=1
+
+while getopts "hin" opt; do
+    case $opt in
+        h)
+            echo "Usage: $0 [-h] [-i]"
+            echo "    -h    Displays this help message"
+            echo "    -i    Attempt to 'sudo apt-get install' required packages"
+            echo "    -n    Do not start a console after vm is created"
+            exit 0
+            ;;
+        i)
+            echo "Installing required packages ..."
+            sudo apt-get install \
+                genisoimage \
+                libvirt-daemon \
+                qemu-system-arm \
+                qemu-utils \
+                virtinst \
+                whois \
+                ;
+            ;;
+        n)
+            echo "Console will not be started after virtual machine startup."
+            start_console=0
+            ;;
+    esac
+done
+
+if ! which qemu-system-aarch64 >/dev/null; then
+    echo "Cannot find 'qemu-system-aarch64'. Did you 'sudo apt-get install qemu-system-arm' ?"
+    exit 1
+fi
+
+if ! which virt-install >/dev/null; then
+    echo "Cannot find 'virt-install'. Did you 'sudo apt-get install virtinst' ?"
+    exit 1
+fi
+
+if ! [ -f /usr/sbin/libvirtd ]; then
+    echo "Cannot find 'virt-install'. Did you 'sudo apt-get install libvirt-daemon' ?"
+    exit 1
+fi
+
+if ! which mkpasswd >/dev/null; then
+    echo "Cannot find 'mkpasswd'. Did you 'sudo apt-get install whois' ?"
+    exit 1
+fi
+
+if ! which qemu-img >/dev/null; then
+    echo "Cannot find 'qemu-img'. Did you 'sudo apt-get install qemu-utis' ?"
+    exit 1
+fi
+
+if ! which genisoimage >/dev/null; then
+    echo "Cannot find 'genisoimage'. Did you 'sudo apt-get install genisoimage' ?"
+    exit 1
+fi
+
+CLOUD_IMAGE_URL="https://cloud-images.ubuntu.com/releases/24.04/release-20240821/ubuntu-24.04-server-cloudimg-arm64.img"
+CLOUD_IMAGE_FILE=$(basename "$CLOUD_IMAGE_URL")
+
+if ! [ -f "$CLOUD_IMAGE_FILE" ]; then
+    echo "Image $CLOUD_IMAGE_FILE does not exist. Downloading ..."
+    wget "$CLOUD_IMAGE_URL"
+else
+    echo "Using existing $CLOUD_IMAGE_FILE ..."
+fi
+
+rm -f sysrootsrv.img
+qemu-img create -b "$CLOUD_IMAGE_FILE" -f qcow2 -F qcow2 sysrootsrv.img 10G
+
+# local user allowed to SSH in to the host directly without a password
+SSH_KEY=$(cat ~/.ssh/id_rsa.pub)
+
+# set a login password.
+# NOTE: this is a VERY WEAK password, however this should be ok because
+#       this is a local and temporary virtual machine that is NOT accessible
+#       anywhere except through the redirected port 5555 on localhost or
+#       via "virsh console" (which is the primary purpose for it: debugging)
+#
+# This is NOT meant as a persistent vm and should be deleted after use.
+PASSWORD_HASH=$(mkpasswd 1234)
+
+# Create cloud init files
+cat >user-data <<TEXTEND
+#cloud-config
+
+users:
+  - default
+  - name: ubuntu
+    shell: /bin/bash
+    ssh_authorized_keys:
+      - $SSH_KEY
+    sudo: "ALL=(ALL) NOPASSWD:ALL"
+    groups: sudo,admin,users
+    shell: /bin/bash
+    lock_passwd: false
+    passwd: $PASSWORD_HASH
+
+hostname: sysrootsrv
+
+package_update: true
+package_upgrade: true
+packages:
+  - g++
+  - gcc
+  - libavahi-client-dev
+  - libcairo2-dev
+  - libdbus-1-dev
+  - libgirepository1.0-dev
+  - libglib2.0-dev
+  - libreadline-dev
+  - libsdl2-dev
+  - libssl-dev
+  - ninja-build
+  - pkg-config
+  - unzip
+
+runcmd:
+  # Ubuntu cloud-init merges with a locked ubuntu, so the "lock_passwd" option does
+  # not actually work. Unlock it here to make console work
+  - [ passwd, --unlock, ubuntu ]
+  # A marker saying that initial install is done. Installing all the packages above is VERY slow
+  - [ echo, Initial installation DONE ]
+
+TEXTEND
+
+truncate -s 0 meta-data
+echo 'instance-id: sysrootsrv' >>meta-data
+echo 'local-hostname: sysrootsrv' >>meta-data
+
+genisoimage -output cidata.iso -V cidata -r -J user-data meta-data
+
+# NOTE: direct qemu-system-aarch64 can also be used, however that requires
+#       having QEMU_EFI.fd available (and location for that varies). Using
+#       virt-install uses extra packages/complexity however also allows
+#       the use of virsh for some operations.
+#
+#    truncate -s 64m varstore.img
+#    truncate -s 64m efi.img
+#    dd if=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd of=efi.img conv=notrunc
+#
+#    # QEMU console exit is `CTRL + a, x`
+#    qemu-system-aarch64                                   \
+#     -m 8192                                              \
+#     -M virt                                              \
+#     -cpu max                                             \
+#     -nographic                                           \
+#     -drive if=pflash,format=raw,file=efi.img,readonly=on \
+#     -drive if=pflash,format=raw,file=varstore.img        \
+#     -drive if=none,file=sysrootsrv.img,id=hd0            \
+#     -device virtio-blk-device,drive=hd0                  \
+#     -cdrom cidata.iso                                    \
+#     -netdev user,id=netdev0,hostfwd=tcp::5555-:22        \
+#     -device virtio-net-pci,netdev=netdev0                \
+#     ; # last line
+
+# EXAMPLE COMMANDS:
+#
+# View generated image:
+#   virsh dumpxml sysrootsrv
+#
+# Get a console and login (exit with `CTRL + ]`)
+#   virsh console sysrootsrv
+#
+# Delete:
+#   virsh destroy sysrootsrv && virsh undefine --nvram sysrootsrv
+virt-install \
+    --name sysrootsrv \
+    --memory 8192 \
+    --arch aarch64 \
+    --vcpus 8 \
+    --import \
+    --disk path=sysrootsrv.img,format=qcow2 \
+    --disk path=cidata.iso,device=cdrom \
+    --os-variant=ubuntu24.04 \
+    --network=user \
+    --xml "xpath.delete=./devices/input[@bus = 'usb']" \
+    --noautoconsole \
+    ;# last-line
+
+# Allow ssh via:
+#   ssh ubuntu@localhost -p 5555
+virsh qemu-monitor-command --hmp sysrootsrv 'hostfwd_add ::5555-:22'
+
+echo -e "\e[32mDONE\e[0m"
+echo ""
+echo "To delete the VM use:"
+echo ""
+echo "  virsh destroy sysrootsrv && virsh undefine --nvram sysrootsrv"
+echo ""
+echo "VM will auto-install packages via cloud-init. "
+echo "Look out for a message of 'Initial installation DONE' in the console. "
+echo ""
+
+if [ "$start_console" -eq 1 ]; then
+    echo "Delaying console start to have final message visible."
+    echo "Don't worry, vm startup takes a while anyway..."
+    sleep 10
+    echo "Starting console ..."
+    virsh console sysrootsrv
+else
+    echo "Console is not auto-started."
+    echo "To monitor VM startup/status you can open a console using: "
+    echo ""
+    echo "  virsh console sysrootsrv"
+    echo ""
+    echo "And you can exit that console using 'CTRL + ]'"
+fi
diff --git a/integrations/docker/images/stage-1/chip-build-crosscompile/upload-cidp-package.sh b/integrations/docker/images/stage-1/chip-build-crosscompile/upload-cidp-package.sh
new file mode 100755
index 0000000..eb668bb
--- /dev/null
+++ b/integrations/docker/images/stage-1/chip-build-crosscompile/upload-cidp-package.sh
@@ -0,0 +1,61 @@
+#!/usr/bin/env bash
+
+# This script is intended to be run post-install (NOTE: install takes a LONG time)
+# of start-sysroot-vm.
+
+set -e
+
+OUTPUT_DIR=ubuntu-24.04-aarch64-sysroot
+PACKAGE=experimental/matter/sysroot/ubuntu-24.04-aarch64
+
+echo "Copying a sysroot in $OUTPUT_DIR"
+mkdir -p "$OUTPUT_DIR"
+
+RSYNC_RSH="ssh -p 5555"
+
+echo "COPYING from VM (ubuntu@localhost on port 5555) ..."
+rsync \
+    --archive \
+    --human-readable \
+    --links \
+    --delete-during \
+    --delete-excluded \
+    --safe-links \
+    --info=progress2 \
+    --info=name0 \
+    --exclude='lib/aarch64-linux-gnu/dri' \
+    --exclude='lib/firmware' \
+    --exclude='lib/git-core' \
+    --exclude='lib/modules' \
+    --exclude='lib/ssl/private' \
+    --exclude='lib/systemd' \
+    ubuntu@localhost:/usr/include \
+    ubuntu@localhost:/usr/lib \
+    "$OUTPUT_DIR/usr"
+
+# Ubuntu 24.04 lib is just a symlink
+rm -f "$OUTPUT_DIR/lib"
+ln -s usr/lib "$OUTPUT_DIR/lib"
+
+echo "Creating cipd definition"
+cat >cipd.yaml <<TEXTEND
+package: $PACKAGE
+description: AArch64 sysroot for cross-compiling matter SDK examples
+install_mode: copy
+data:
+  - dir: "$OUTPUT_DIR"
+TEXTEND
+
+TODAY=$(date '+%Y.%m.%d')
+PACKAGE_VERSION="build-$TODAY"
+
+# NOTE: sufficient permissions are required to be able to upload this.
+#       Login is a prerequisite:
+#
+#    cipd auth-login
+#
+echo "Uploading package tagged '$PACKAGE_VERSION' to $PACKAGE ..."
+cipd create -pkg-def=cipd.yaml -tag "version:$PACKAGE_VERSION"
+
+echo "Updating version to latest"
+cipd set-ref "$PACKAGE" -version "version:$PACKAGE_VERSION" -ref latest