From 3ee1a82d8761902a75e075ccbcd8e9e02a226051 Mon Sep 17 00:00:00 2001 From: Tadas Sutkaitis Date: Thu, 20 Jul 2023 23:44:37 +0200 Subject: [PATCH] add: cross-compile support The main goal is to be able to build ARM images on standard x86 hardware. Add simple functions supported by python-py and podman-py to enable creation of container images on emulated architectures. Change-Id: I1526b460f6e271c2ec63ab3a3b1dc348d742e96d --- doc/source/admin/image-building.rst | 22 +++++++++++++++++++ kolla/common/config.py | 8 +++++++ kolla/image/tasks.py | 1 + kolla/tests/test_build.py | 13 ++++++----- ...-image-cross-compile-3b1dc348d742e96d.yaml | 5 +++++ 5 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/support-image-cross-compile-3b1dc348d742e96d.yaml diff --git a/doc/source/admin/image-building.rst b/doc/source/admin/image-building.rst index f0c0e84c11..81e04f4015 100644 --- a/doc/source/admin/image-building.rst +++ b/doc/source/admin/image-building.rst @@ -526,6 +526,28 @@ variables that will be picked up from the user env: Also these variables could be overwritten using ``--build-args``, which have precedence. +Cross-compiling +--------------- + +It is possible to cross-compile container images in order to, e.g., build +``aarch64`` images on a ``x86_64`` machine. + +To build ``ARM`` images on ``x86_64`` platform, pass the ``--base-arch`` and +``--platform`` arguments: + +.. code-block:: console + + kolla-build --platform linux/arm64 --base-arch aarch64 + +.. note:: + + To make this work on x86_64 platform you can use tools like: `qemu-user-static + `_ or `binfmt + `_. + + To make this work on Apple Silicon you can use Docker Desktop or Podman + Desktop to build ``x86_64`` or native ``ARM`` images. + Known issues ============ diff --git a/kolla/common/config.py b/kolla/common/config.py index 03616fe87a..af5dab963d 100644 --- a/kolla/common/config.py +++ b/kolla/common/config.py @@ -138,6 +138,10 @@ _PROFILE_OPTS = [ hostarch = os.uname()[4] +# NOTE: Apple Silicon reports as arm64 which is aarch64 +if hostarch == "arm64": + hostarch = "aarch64" + _CLI_OPTS = [ cfg.StrOpt('base', short='b', default='rocky', choices=BASE_OS_DISTRO, @@ -174,6 +178,10 @@ _CLI_OPTS = [ help='The network mode for Docker build. Example: host'), cfg.BoolOpt('cache', default=True, help='Use the container engine cache when building'), + cfg.StrOpt('platform', default=None, + help=('The platform to use for a cross-compile build. Should ' + 'be set in conjunction with "--base-arch" argument. ' + 'Example: "--platform linux/arm64 --base-arch aarch64"')), cfg.MultiOpt('profile', types.String(), short='p', help=('Build a pre-defined set of images, see [profiles]' ' section in config. The default profiles are:' diff --git a/kolla/image/tasks.py b/kolla/image/tasks.py index c6cde6bbe6..5babce5602 100644 --- a/kolla/image/tasks.py +++ b/kolla/image/tasks.py @@ -400,6 +400,7 @@ class BuildTask(EngineTask): network_mode=self.conf.network_mode, pull=pull, forcerm=self.forcerm, + platform=self.conf.platform, buildargs=buildargs, **kwargs)[1]: if self.conf.engine == engine.Engine.PODMAN.value: diff --git a/kolla/tests/test_build.py b/kolla/tests/test_build.py index 1aa0b3a9dd..d4611d5ae1 100644 --- a/kolla/tests/test_build.py +++ b/kolla/tests/test_build.py @@ -168,7 +168,7 @@ class TasksTest(base.TestCase): mock_client().images.build.assert_called_once_with( path=self.image.path, tag=self.image.canonical_name, network_mode='host', nocache=False, rm=True, pull=True, - forcerm=True, buildargs=None, **self.build_kwargs) + forcerm=True, platform=None, buildargs=None, **self.build_kwargs) self.assertTrue(builder.success) @@ -185,7 +185,7 @@ class TasksTest(base.TestCase): mock_client().images.build.assert_called_once_with( path=self.image.path, tag=self.image.canonical_name, network_mode='bridge', nocache=False, rm=True, pull=True, - forcerm=True, buildargs=None, **self.build_kwargs) + forcerm=True, platform=None, buildargs=None, **self.build_kwargs) self.assertTrue(builder.success) @@ -205,7 +205,8 @@ class TasksTest(base.TestCase): mock_client().images.build.assert_called_once_with( path=self.image.path, tag=self.image.canonical_name, network_mode='host', nocache=False, rm=True, pull=True, - forcerm=True, buildargs=build_args, **self.build_kwargs) + forcerm=True, platform=None, buildargs=build_args, + **self.build_kwargs) self.assertTrue(builder.success) @@ -224,7 +225,8 @@ class TasksTest(base.TestCase): mock_client().images.build.assert_called_once_with( path=self.image.path, tag=self.image.canonical_name, network_mode='host', nocache=False, rm=True, pull=True, - forcerm=True, buildargs=build_args, **self.build_kwargs) + forcerm=True, platform=None, buildargs=build_args, + **self.build_kwargs) self.assertTrue(builder.success) @@ -245,7 +247,8 @@ class TasksTest(base.TestCase): mock_client().images.build.assert_called_once_with( path=self.image.path, tag=self.image.canonical_name, network_mode='host', nocache=False, rm=True, pull=True, - forcerm=True, buildargs=build_args, **self.build_kwargs) + forcerm=True, platform=None, buildargs=build_args, + **self.build_kwargs) self.assertTrue(builder.success) diff --git a/releasenotes/notes/support-image-cross-compile-3b1dc348d742e96d.yaml b/releasenotes/notes/support-image-cross-compile-3b1dc348d742e96d.yaml new file mode 100644 index 0000000000..76e12ee53a --- /dev/null +++ b/releasenotes/notes/support-image-cross-compile-3b1dc348d742e96d.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Add support for cross-compile. Enable creation of container images + on emulated architectures.