diff --git a/elements/architecture-emulation-binaries/README.md b/elements/architecture-emulation-binaries/README.md new file mode 100644 index 000000000..c56612578 --- /dev/null +++ b/elements/architecture-emulation-binaries/README.md @@ -0,0 +1,20 @@ +This element enables execution for different architectures + +When building an image for an architecture that the host machine +can not execute, we need to chroot into the image to execute code, +and if the host architecture does not match, we need to emulate +the instructions. + +This element does the following: + + * copies the binary file into chroot /usr/bin environment. + Binary file is chosen based on host architecture and + image architecture the user is trying to build. + + If an image we are building for an architecture is not the host + architecture, install tools provided by qemu-user-static + (which needs to be installed) to allow us to run commands + inside the building image. + + This is tested on amd64/i386 architecture to build armhf and arm64 + ubuntu cloud images. diff --git a/elements/architecture-emulation-binaries/cleanup.d/01-cleanbinary b/elements/architecture-emulation-binaries/cleanup.d/01-cleanbinary new file mode 100755 index 000000000..72ec8d144 --- /dev/null +++ b/elements/architecture-emulation-binaries/cleanup.d/01-cleanbinary @@ -0,0 +1,9 @@ +#!/bin/bash + +set -eux +set -o pipefail + +if [ -x "$TMP_MOUNT_PATH/tmp/clean_up_qemu_binary" ] ; then + "$TMP_MOUNT_PATH/tmp/clean_up_qemu_binary" + rm -rf "$TMP_MOUNT_PATH/tmp/clean_up_qemu_binary" +fi diff --git a/elements/architecture-emulation-binaries/extra-data.d/01-copy-binary b/elements/architecture-emulation-binaries/extra-data.d/01-copy-binary new file mode 100755 index 000000000..e5f205081 --- /dev/null +++ b/elements/architecture-emulation-binaries/extra-data.d/01-copy-binary @@ -0,0 +1,61 @@ +#!/bin/bash + +set -eux +set -o pipefail + +function clean_up_arch_emulation { + cat <$TMP_MOUNT_PATH/tmp/clean_up_qemu_binary +#!/bin/bash + +set -eux +set -o pipefail + +sudo rm -rf "${TMP_MOUNT_PATH}${1}" +EOF + + sudo chmod +x "$TMP_MOUNT_PATH/tmp/clean_up_qemu_binary" +} + +function check_copy_file { + if [ -f "$1" ] ; then + if [ ! -f "${TMP_MOUNT_PATH}${1}" ]; then + sudo cp "$1" "$TMP_MOUNT_PATH/usr/bin" + clean_up_arch_emulation $1 + fi + else + echo "qemu binary file not found." + exit 1 + fi +} + +function copy_binary { + echo "checking for architecture compatibility..." + img_arch=$2 + if [[ "$host_arch" != "$img_arch" ]]; then + qemu_binary=$1 + check_copy_file $qemu_binary + else + echo "Emulation not required for this host/image architecture combination" + fi +} + +host_arch="$(uname -m)" + +case "$ARCH" in + "i386" | "amd64") + qemu_binary_file="/usr/bin/qemu-i386-static" + copy_binary $qemu_binary_file $ARCH + ;; + "armhf") + qemu_binary_file="/usr/bin/qemu-arm-static" + copy_binary $qemu_binary_file $ARCH + ;; + "arm64") + qemu_binary_file="/usr/bin/qemu-aarch64-static" + copy_binary $qemu_binary_file $ARCH + ;; + *) + echo "architecture not supported" + exit 1 + ;; +esac