From 996651b478bc2bdcb0c41e0f59ec55218bcdd87f Mon Sep 17 00:00:00 2001
From: Michal Nasiadka <mnasiadka@gmail.com>
Date: Mon, 23 Sep 2024 16:16:42 +0200
Subject: [PATCH] kolla-build: Add support for cross-arch builds

When kolla_base_arch and ansible_facts.architecture differs
we need to run multiarch/qemu-user-static image - see [1].

[1]: https://github.com/multiarch/qemu-user-static

Co-Authored-By: Bartosz Bezak <bartosz@stackhpc.com>

Change-Id: If149418f509c687c3e5d1072cc39a80af33dec5a
---
 ansible/container-image-build.yml                   |  2 ++
 ansible/inventory/group_vars/all/kolla              |  4 ++++
 ansible/roles/kolla-build/defaults/main.yml         |  3 +++
 ansible/roles/kolla-build/tasks/main.yml            | 12 ++++++++++++
 .../kolla-build/templates/kolla/kolla-build.conf    |  3 +++
 doc/source/configuration/reference/kolla.rst        |  3 +++
 etc/kayobe/kolla.yml                                |  4 ++++
 .../notes/cross-arch-builds-5b5b7810beab4cca.yaml   | 13 +++++++++++++
 8 files changed, 44 insertions(+)
 create mode 100644 releasenotes/notes/cross-arch-builds-5b5b7810beab4cca.yaml

diff --git a/ansible/container-image-build.yml b/ansible/container-image-build.yml
index 9a667405..a29f3a08 100644
--- a/ansible/container-image-build.yml
+++ b/ansible/container-image-build.yml
@@ -10,6 +10,7 @@
     # default set of images.
     container_image_regexes: ""
     kolla_build_log_path: "/var/log/kolla-build.log"
+    platform: "{{ 'linux/arm64' if kolla_base_arch == 'aarch64' else 'linux/amd64' }}"
   tasks:
     - name: Set the container image sets to build if images regexes specified
       set_fact:
@@ -53,6 +54,7 @@
           {% if kolla_docker_registry is not none %}--registry {{ kolla_docker_registry }}{% endif %}
           {% if push_images | bool %}--push{% endif %}
           {% if nocache | bool %}--nocache{% endif %}
+          {% if kolla_base_arch != ansible_facts.architecture %}--platform {{ platform }}{% endif %}
           {{ item.regexes }} 2>&1 | tee --append {{ kolla_build_log_path }}
         executable: /bin/bash
       with_items: "{{ container_image_sets }}"
diff --git a/ansible/inventory/group_vars/all/kolla b/ansible/inventory/group_vars/all/kolla
index a6da96cf..291171ab 100644
--- a/ansible/inventory/group_vars/all/kolla
+++ b/ansible/inventory/group_vars/all/kolla
@@ -52,6 +52,10 @@ kolla_node_custom_config_path: "{{ kolla_config_path }}/config"
 ###############################################################################
 # Kolla configuration.
 
+# Kolla base container image architecture. Options are "x86_64", "aarch64".
+# Default is "{{ ansible_facts.architecture }}"
+kolla_base_arch: "{{ ansible_facts.architecture }}"
+
 # Kolla base container image distribution. Options are "centos", "debian",
 # "rocky", "ubuntu". Default is {{ os_distribution }}.
 kolla_base_distro: "{{ os_distribution }}"
diff --git a/ansible/roles/kolla-build/defaults/main.yml b/ansible/roles/kolla-build/defaults/main.yml
index b1704105..a6673be7 100644
--- a/ansible/roles/kolla-build/defaults/main.yml
+++ b/ansible/roles/kolla-build/defaults/main.yml
@@ -12,6 +12,9 @@ kolla_build_config_paths_extra: []
 # Paths to extra kolla configuration files.
 kolla_build_config_paths: "{{ kolla_build_config_paths_default + kolla_build_config_paths_extra }}"
 
+# Valid options are [ x86_64, aarch64 ]
+kolla_base_arch:
+
 # Valid options are [ centos, debian, rocky, ubuntu ]
 kolla_base_distro:
 
diff --git a/ansible/roles/kolla-build/tasks/main.yml b/ansible/roles/kolla-build/tasks/main.yml
index de812854..6c62441a 100644
--- a/ansible/roles/kolla-build/tasks/main.yml
+++ b/ansible/roles/kolla-build/tasks/main.yml
@@ -36,3 +36,15 @@
     src: template-override.j2.j2
     dest: "{{ kolla_build_config_path }}/template-override.j2"
     mode: "0644"
+
+- name: Run multiarch/qemu-user-static image to support cross-arch build
+  community.general.docker_container:
+    command: "--reset -p yes"
+    cleanup: true
+    detach: false
+    image: "multiarch/qemu-user-static:7.2.0-1"
+    name: "qemu_user_static"
+    privileged: true
+    state: "started"
+    network_mode: "host"
+  when: ansible_facts.architecture != kolla_base_arch
diff --git a/ansible/roles/kolla-build/templates/kolla/kolla-build.conf b/ansible/roles/kolla-build/templates/kolla/kolla-build.conf
index 762f86c4..4e84cec0 100644
--- a/ansible/roles/kolla-build/templates/kolla/kolla-build.conf
+++ b/ansible/roles/kolla-build/templates/kolla/kolla-build.conf
@@ -6,6 +6,9 @@ base={{ kolla_base_distro }}
 # Base container image tag.
 base_tag={{ kolla_base_tag }}
 
+# Base container image architecture.
+base_arch={{ kolla_base_arch }}
+
 # Docker namespace to use for Kolla images.
 namespace={{ kolla_docker_namespace }}
 
diff --git a/doc/source/configuration/reference/kolla.rst b/doc/source/configuration/reference/kolla.rst
index 651407f6..76b6bc93 100644
--- a/doc/source/configuration/reference/kolla.rst
+++ b/doc/source/configuration/reference/kolla.rst
@@ -72,6 +72,9 @@ The following variables are global, affecting all container images. They are
 used to generate the Kolla configuration file, ``kolla-build.conf``, and also
 affect :ref:`Kolla Ansible configuration <configuration-kolla-ansible-global>`.
 
+``kolla_base_arch``
+    Kolla base container image architecture. Options are ``x86_64``,
+    ``aarch64``. Default is ``{{ ansible_facts.architecture }}``.
 ``kolla_base_distro``
     Kolla base container image distribution. Options are ``centos``,
     ``debian``, ``rocky`` or ``ubuntu``. Default is ``{{ os_distribution }}``.
diff --git a/etc/kayobe/kolla.yml b/etc/kayobe/kolla.yml
index c75ca9c2..ada15c49 100644
--- a/etc/kayobe/kolla.yml
+++ b/etc/kayobe/kolla.yml
@@ -66,6 +66,10 @@
 ###############################################################################
 # Kolla configuration.
 
+# Kolla base container image architecture. Options are "x86_64", "aarch64".
+# Default is "{{ ansible_facts.architecture }}"
+#kolla_base_arch:
+
 # Kolla base container image distribution. Options are "centos", "debian",
 # "rocky", "ubuntu". Default is {{ os_distribution }}.
 #kolla_base_distro:
diff --git a/releasenotes/notes/cross-arch-builds-5b5b7810beab4cca.yaml b/releasenotes/notes/cross-arch-builds-5b5b7810beab4cca.yaml
new file mode 100644
index 00000000..db361c5c
--- /dev/null
+++ b/releasenotes/notes/cross-arch-builds-5b5b7810beab4cca.yaml
@@ -0,0 +1,13 @@
+---
+features:
+  - |
+    The `kolla_base_arch` variable has been introduced, allowing users
+    to specify the architecture for base container images. This supports
+    cross-architecture builds, enabling the building of images for
+    architectures different from the host machine (e.g., building
+    `aarch64` images on an `x86_64` machine).
+
+    By default, `kolla_base_arch` is set to the detected architecture
+    (`{{ ansible_facts.architecture }}`). However, when `kolla_base_arch`
+    differs from the host architecture, the `multiarch/qemu-user-static`
+    image is used to facilitate cross-arch builds.
-- 
GitLab