From 0978f23343bb33a6a3b94d58822583305de6dfc1 Mon Sep 17 00:00:00 2001
From: Alexander Bachmann <a.t.bachmann@gmail.com>
Date: Fri, 13 Sep 2024 17:32:41 +0200
Subject: [PATCH] hack: use buildx to cross build images with docker

---
 hack/build-image | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/hack/build-image b/hack/build-image
index 1c8a3db..c8b0f2e 100755
--- a/hack/build-image
+++ b/hack/build-image
@@ -125,6 +125,7 @@ QUAL_FQIN = 'fqin'
 
 
 _DISCOVERED_CONTAINER_ENGINES = []
+_BUILDX_BUILDER_NAME = "samba-in-kubernetes"
 
 
 def check_kind(kind):
@@ -203,14 +204,18 @@ def container_engine(cli):
 
 def container_build(cli, target):
     """Construct and execute a command to build the target container image."""
-    args = [container_engine(cli), "build"]
-    pkgs_from = PACKAGES_FROM[target.pkg_source]
-    if pkgs_from:
-        args.append(f"--build-arg=INSTALL_PACKAGES_FROM={pkgs_from}")
-    # docker doesn't currently support alt. architectures
+    eng = container_engine(cli)
+    args = [eng, "build"]
+
     if "docker" in args[0]:
+        # if the target arch and the host_arch are not the same, we need to use buildx
         if target.arch != host_arch():
-            raise RuntimeError("Docker does not support --arch")
+            args = [eng, "buildx", "build", f"--builder={_BUILDX_BUILDER_NAME}", f"--platform=linux/{target.arch}"]
+            # Docker's default builder only supports the host architecture.
+            # Therefore, we need to create a new builder to support other
+            # architectures. Errors are suppressed to prevent issues when
+            # the builder is already available - this can be improved later.
+            run(cli, [eng, "buildx", "create", f"--name={_BUILDX_BUILDER_NAME}"], check=False)
     elif target.arch != host_arch() or FORCE_ARCH_FLAG:
         # We've noticed a few small quirks when using podman with the --arch
         # option. The main issue is that building the client image works
@@ -219,6 +224,11 @@ def container_build(cli, target):
         # --arch is not provided. So if the target arch and the host_arch
         # are the same, skip passing the extra argument.
         args.append(f"--arch={target.arch}")
+
+    pkgs_from = PACKAGES_FROM[target.pkg_source]
+    if pkgs_from:
+        args.append(f"--build-arg=INSTALL_PACKAGES_FROM={pkgs_from}")
+    
     if cli.extra_build_arg:
         args.extend(cli.extra_build_arg)
     for tname in target.all_names(baseless=cli.without_repo_bases):