From ccbc5691cb9d6d815be3f58c23e922207f6d41b1 Mon Sep 17 00:00:00 2001 From: Rob Bavey Date: Mon, 5 Oct 2020 13:38:09 -0400 Subject: [PATCH] Docker Build: Add ability to detect/set build architecture (#12303) Clean backport of #12302 This commit adds the ability for the docker build to build artifacts for multiple architectures. By default, the target architecture is inferred from the architecture of the machine the build is being run from - running the build from an aarch64 machine will build an aarch64 docker image, while building from an x86_64 machine will build an x86_64 docker image. This can be overridden by setting the environment variable DOCKER_ARCHITECTURE to either `x86_64` or `aarch64`. This commit also updates the integration tests to test against the architecture from the machine the test is being run on, and includes the target architecture in the test description. --- docker/Makefile | 10 +++++++++ docker/templates/Dockerfile.j2 | 4 ++-- qa/docker/shared_examples/image_metadata.rb | 4 ++-- qa/docker/spec/spec_helper.rb | 25 ++++++++++++++++----- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/docker/Makefile b/docker/Makefile index 7ac714e24..d2533058a 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -12,6 +12,12 @@ else VERSION_TAG := $(ELASTIC_VERSION) endif +ifdef DOCKER_ARCHITECTURE + ARCHITECTURE := $(DOCKER_ARCHITECTURE) +else + ARCHITECTURE := $(shell uname -m) +endif + IMAGE_FLAVORS ?= oss full ubi8 DEFAULT_IMAGE_FLAVOR ?= full @@ -85,6 +91,7 @@ public-dockerfiles_full: venv templates/Dockerfile.j2 docker_paths $(COPY_FILES) jinja2 \ -D created_date='$(DATE)' \ -D elastic_version='$(ELASTIC_VERSION)' \ + -D arch='${ARCHITECTURE}' \ -D version_tag='$(VERSION_TAG)' \ -D image_flavor='full' \ -D local_artifacts='false' \ @@ -98,6 +105,7 @@ public-dockerfiles_oss: venv templates/Dockerfile.j2 docker_paths $(COPY_FILES) jinja2 \ -D created_date='$(DATE)' \ -D elastic_version='$(ELASTIC_VERSION)' \ + -D arch='${ARCHITECTURE}' \ -D version_tag='$(VERSION_TAG)' \ -D image_flavor='oss' \ -D local_artifacts='false' \ @@ -111,6 +119,7 @@ public-dockerfiles_ubi8: venv templates/Dockerfile.j2 docker_paths $(COPY_FILES) jinja2 \ -D created_date='$(DATE)' \ -D elastic_version='$(ELASTIC_VERSION)' \ + -D arch='${ARCHITECTURE}' \ -D version_tag='$(VERSION_TAG)' \ -D image_flavor='ubi8' \ -D local_artifacts='false' \ @@ -166,6 +175,7 @@ dockerfile: venv templates/Dockerfile.j2 jinja2 \ -D created_date='$(DATE)' \ -D elastic_version='$(ELASTIC_VERSION)' \ + -D arch='${ARCHITECTURE}' \ -D version_tag='$(VERSION_TAG)' \ -D image_flavor='$(FLAVOR)' \ -D local_artifacts='true' \ diff --git a/docker/templates/Dockerfile.j2 b/docker/templates/Dockerfile.j2 index 4931df84a..ee48872c5 100644 --- a/docker/templates/Dockerfile.j2 +++ b/docker/templates/Dockerfile.j2 @@ -6,10 +6,10 @@ {% endif -%} {% if image_flavor == 'oss' -%} - {% set tarball = 'logstash-oss-%s-linux-x86_64.tar.gz' % elastic_version -%} + {% set tarball = 'logstash-oss-%s-linux-%s.tar.gz' % (elastic_version, arch) -%} {% set license = 'Apache 2.0' -%} {% else -%} - {% set tarball = 'logstash-%s-linux-x86_64.tar.gz' % elastic_version -%} + {% set tarball = 'logstash-%s-linux-%s.tar.gz' % (elastic_version, arch) -%} {% set license = 'Elastic License' -%} {% endif -%} diff --git a/qa/docker/shared_examples/image_metadata.rb b/qa/docker/shared_examples/image_metadata.rb index 56d1ea56d..10dccd329 100644 --- a/qa/docker/shared_examples/image_metadata.rb +++ b/qa/docker/shared_examples/image_metadata.rb @@ -9,8 +9,8 @@ shared_examples_for 'the metadata is set correctly' do |flavor| expect(@image_config['WorkingDir']).to eql '/usr/share/logstash' end - it 'should have the correct Architecture' do - expect(@image.json['Architecture']).to have_correct_architecture_for_flavor(flavor) + it "should have an architecture of #{running_architecture}" do + expect(@image.json['Architecture']).to have_correct_architecture end %w(license org.label-schema.license org.opencontainers.image.licenses).each do |label| diff --git a/qa/docker/spec/spec_helper.rb b/qa/docker/spec/spec_helper.rb index 2cc712df0..cbba2a389 100644 --- a/qa/docker/spec/spec_helper.rb +++ b/qa/docker/spec/spec_helper.rb @@ -80,10 +80,24 @@ def exec_in_container(container, command) container.exec(command.split)[0].join end -def architecture_for_flavor(flavor) - flavor.match(/aarch64/) ? 'arm64' : 'amd64' +def running_architecture + architecture = ENV['DOCKER_ARCHITECTURE'] + architecture = normalized_architecture(`uname -m`.strip) if architecture.nil? + architecture end +def normalized_architecture(cpu) + case cpu + when 'x86_64' + 'amd64' + when 'aarch64' + 'arm64' + else + cpu + end +end + + RSpec::Matchers.define :have_correct_license_label do |expected| match do |actual| values_match? license_label_for_flavor(expected), actual @@ -103,13 +117,12 @@ RSpec::Matchers.define :have_correct_license_agreement do |expected| end end -RSpec::Matchers.define :have_correct_architecture_for_flavor do |expected| +RSpec::Matchers.define :have_correct_architecture do match do |actual| - values_match? architecture_for_flavor(expected), actual - true + values_match? running_architecture, actual end failure_message do |actual| - "expected Architecture: #{actual} to be #{architecture_for_flavor(expected)}" + "expected Architecture: #{actual} to be #{running_architecture}" end end