diff --git a/build/Dockerfile.arch b/build/Dockerfile.arch new file mode 100644 index 0000000000..799e65da5c --- /dev/null +++ b/build/Dockerfile.arch @@ -0,0 +1,47 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM --platform=$BUILDPLATFORM ghcr.io/graalvm/graalvm-ce:ol8-java11-22.1.0 + +ARG MAVEN_VERSION="3.8.4" +ARG MAVEN_HOME="/usr/share/maven" +ARG SHA="a9b2d825eacf2e771ed5d6b0e01398589ac1bfa4171f36154d1b5787879605507802f699da6f7cfc80732a5282fd31b28e4cd6052338cbef0fa1358b48a5e3c8" +ARG BASE_URL="https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries" + +USER 0 + +RUN mkdir -p ${MAVEN_HOME} \ + && curl -Lso /tmp/maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \ + && echo "${SHA} /tmp/maven.tar.gz" | sha512sum -c - \ + && tar -xzC ${MAVEN_HOME} --strip-components=1 -f /tmp/maven.tar.gz \ + && rm -v /tmp/maven.tar.gz \ + && ln -s ${MAVEN_HOME}/bin/mvn /usr/bin/mvn \ + && rm ${MAVEN_HOME}/lib/maven-slf4j-provider* + +ADD build/_maven_output /tmp/artifacts/m2 +ADD build/_kamelets /kamelets +COPY build/_maven_overlay/ /usr/share/maven/lib/ +ADD build/logback.xml /usr/share/maven/conf/ + +ENV MAVEN_OPTS="${MAVEN_OPTS} -Dlogback.configurationFile=/usr/share/maven/conf/logback.xml" + +RUN chgrp -R 0 /tmp/artifacts/m2 \ + && chmod -R g=u /tmp/artifacts/m2 \ + && chgrp -R 0 /kamelets \ + && chmod -R g=u /kamelets + +USER 1000 + +ADD build/_output/bin/kamel /usr/local/bin/kamel diff --git a/config/crd/bases/camel.apache.org_builds.yaml b/config/crd/bases/camel.apache.org_builds.yaml index 6ac023fd66..7976161a86 100644 --- a/config/crd/bases/camel.apache.org_builds.yaml +++ b/config/crd/bases/camel.apache.org_builds.yaml @@ -107,6 +107,9 @@ spec: name: description: name of the task type: string + platform: + description: The platform of build image + type: string registry: description: where to publish the final image properties: diff --git a/docs/modules/ROOT/pages/configuration/multi-architecture.adoc b/docs/modules/ROOT/pages/configuration/multi-architecture.adoc new file mode 100644 index 0000000000..45c0c2e4be --- /dev/null +++ b/docs/modules/ROOT/pages/configuration/multi-architecture.adoc @@ -0,0 +1,81 @@ +[[multi-architecture-props]] += Multi Architecture + +To use kamel inside other architecture like arm64 you must build it and use Buildah as builder strategy. + +NOTE: For now only arm64 is supported as other architectures + +[[multi-architecture-build]] +== Build and Publish Kamel + +As first step it's necessary to build kamel project `https://github.com/apache/camel-k` manually and push image to own docker repository. + +I suggest to create a free docker image repository with `docker-hub` or `ghcr`. + +[source,shell] +.script/Makefile +---- +make build images-arch images-push +---- + +NOTE: The base image of kamel operator is graalvm because multi architecture quarkus-mandrel image not published yet + +[[multi-architecture-install]] +== Install Kamel + +Proceed with installation of kamel inside kubernetes cluster with the below command + +[source,shell] +---- +./kamel install --build-publish-strategy=Buildah --registry YOUR_REGISTRY --registry-auth-username YOUR_USERNAME --registry-auth-password YOUR_PASSWORD +---- + +[[multi-architecture-use]] +== Use kamel + +Build and run an integration + +[source,groovy] +.hello.groovy +---- +from('timer:tick?period=3000') + .setBody().constant('Hello world from Camel K') + .to('log:info') +---- + +Send the groovy file to kamel operator to build, publish and run it +[source,shell] +---- +kamel run hello.groovy +---- + +[[multi-architecture-configure-optional]] +== Optional Buildah Configuration + +If you want change the default architecture of buildah build strategy, you must edit integration platform manually. + +[source,shell] +---- +kubectl edit ip +---- + +This command will open the editor with the yaml of `IntegrationPlatform`, to change the architecture you can fill inside `spec.build.PublishStrategyOptions` as below +[source,yaml] +---- +spec: + build: + PublishStrategyOptions: + BuildahPlatform: linux/arm/v8 +---- + +After few seconds the yaml will be updated and that field is imported inside status + +[source,yaml] +---- +status: + build: + PublishStrategyOptions: + BuildahPlatform: linux/arm/v8 +---- + +NOTE: It's important to know buidah supports only amd64 and arm64 diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc index 445c663790..bf0e60ae6e 100644 --- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc +++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc @@ -431,6 +431,13 @@ BuildStatus defines the observed state of Build |Field |Description +|`observedGeneration` + +int64 +| + + +ObservedGeneration is the most recent generation observed for this Build. + |`phase` + *xref:#_camel_apache_org_v1_BuildPhase[BuildPhase]* | @@ -546,6 +553,13 @@ BuildahTask is used to configure Buildah +|`platform` + +string +| + + +The platform of build image + |`verbose` + bool | @@ -1425,6 +1439,13 @@ IntegrationKitStatus defines the observed state of IntegrationKit |Field |Description +|`observedGeneration` + +int64 +| + + +ObservedGeneration is the most recent generation observed for this IntegrationKit. + |`phase` + *xref:#_camel_apache_org_v1_IntegrationKitPhase[IntegrationKitPhase]* | @@ -1861,6 +1882,13 @@ IntegrationPlatformStatus defines the observed state of IntegrationPlatform +|`observedGeneration` + +int64 +| + + +ObservedGeneration is the most recent generation observed for this IntegrationPlatform. + |`phase` + *xref:#_camel_apache_org_v1_IntegrationPlatformPhase[IntegrationPlatformPhase]* | @@ -2014,6 +2042,13 @@ IntegrationStatus defines the observed state of Integration |Field |Description +|`observedGeneration` + +int64 +| + + +ObservedGeneration is the most recent generation observed for this Integration. + |`phase` + *xref:#_camel_apache_org_v1_IntegrationPhase[IntegrationPhase]* | @@ -2477,9 +2512,8 @@ NodeSelector TopologySpreadConstraints - |`securityContext` + -*https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#podsecuritycontext-v1-core[[\]Kubernetes core/v1.PodSecurityContext]* +*https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#podsecuritycontext-v1-core[Kubernetes core/v1.PodSecurityContext]* | @@ -3196,4 +3230,4 @@ Selects a key of a ConfigMap. Selects a key of a secret. -|=== +|=== \ No newline at end of file diff --git a/docs/modules/ROOT/partials/apis/kamelets-crds.adoc b/docs/modules/ROOT/partials/apis/kamelets-crds.adoc index fe8e1b828c..04aab42a9d 100644 --- a/docs/modules/ROOT/partials/apis/kamelets-crds.adoc +++ b/docs/modules/ROOT/partials/apis/kamelets-crds.adoc @@ -874,6 +874,13 @@ KameletBindingStatus specify the status of a binding |Field |Description +|`observedGeneration` + +int64 +| + + +ObservedGeneration is the most recent generation observed for this KameletBinding. + |`phase` + *xref:#_camel_apache_org_v1alpha1_KameletBindingPhase[KameletBindingPhase]* | @@ -1096,6 +1103,13 @@ KameletStatus defines the observed state of Kamelet |Field |Description +|`observedGeneration` + +int64 +| + + +ObservedGeneration is the most recent generation observed for this Kamelet. + |`phase` + *xref:#_camel_apache_org_v1alpha1_KameletPhase[KameletPhase]* | diff --git a/go.sum b/go.sum index 711cdf2a0a..520c4ff6f3 100644 --- a/go.sum +++ b/go.sum @@ -310,6 +310,7 @@ github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7 github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= +github.com/containerd/containerd v1.5.8 h1:NmkCC1/QxyZFBny8JogwLpOy2f+VEbO/f6bV2Mqtwuw= github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= diff --git a/helm/camel-k/crds/crd-build.yaml b/helm/camel-k/crds/crd-build.yaml index 6ac023fd66..7976161a86 100644 --- a/helm/camel-k/crds/crd-build.yaml +++ b/helm/camel-k/crds/crd-build.yaml @@ -107,6 +107,9 @@ spec: name: description: name of the task type: string + platform: + description: The platform of build image + type: string registry: description: where to publish the final image properties: diff --git a/pkg/apis/camel/v1/build_types.go b/pkg/apis/camel/v1/build_types.go index 880fef7821..0de3fd47c4 100644 --- a/pkg/apis/camel/v1/build_types.go +++ b/pkg/apis/camel/v1/build_types.go @@ -107,6 +107,8 @@ type PublishTask struct { type BuildahTask struct { BaseTask `json:",inline"` PublishTask `json:",inline"` + // The platform of build image + Platform string `json:"platform,omitempty"` // log more information Verbose *bool `json:"verbose,omitempty"` } diff --git a/pkg/builder/buildah.go b/pkg/builder/buildah.go new file mode 100644 index 0000000000..d900ec1fed --- /dev/null +++ b/pkg/builder/buildah.go @@ -0,0 +1,20 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builder + +const BuildahPlatform = "BuildahPlatform" diff --git a/pkg/controller/build/build_pod.go b/pkg/controller/build/build_pod.go index 00cab13aa3..1ebb74c52f 100644 --- a/pkg/controller/build/build_pod.go +++ b/pkg/controller/build/build_pod.go @@ -30,7 +30,6 @@ import ( corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - ctrl "sigs.k8s.io/controller-runtime/pkg/client" v1 "github.com/apache/camel-k/pkg/apis/camel/v1" @@ -239,16 +238,29 @@ func addBuildTaskToPod(build *v1.Build, taskName string, pod *corev1.Pod) { } func addBuildahTaskToPod(ctx context.Context, c ctrl.Reader, build *v1.Build, task *v1.BuildahTask, pod *corev1.Pod) error { - bud := []string{ + var bud []string + + bud = []string{ "buildah", "bud", "--storage-driver=vfs", + } + + if task.Platform != "" { + bud = append(bud, []string{ + "--platform", + task.Platform, + }...) + } + + bud = append(bud, []string{ + "--pull-always", "-f", "Dockerfile", "-t", task.Image, ".", - } + }...) push := []string{ "buildah", diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go index 21908ed032..9b7ea2e647 100644 --- a/pkg/trait/builder.go +++ b/pkg/trait/builder.go @@ -101,7 +101,17 @@ func (t *builderTrait) Apply(e *Environment) error { }}) case v1.IntegrationPlatformBuildPublishStrategyBuildah: + var platform string + var found bool + if platform, found = e.Platform.Status.Build.PublishStrategyOptions[builder.BuildahPlatform]; !found { + platform = "" + t.L.Infof("Attribute platform for buildah not found, default from host will be used!") + } else { + t.L.Infof("User defined %s platform, will be used from buildah!", platform) + } + e.BuildTasks = append(e.BuildTasks, v1.Task{Buildah: &v1.BuildahTask{ + Platform: platform, BaseTask: v1.BaseTask{ Name: "buildah", }, @@ -151,6 +161,7 @@ func (t *builderTrait) builderTask(e *Environment) (*v1.BuilderTask, error) { for _, repo := range e.IntegrationKit.Spec.Repositories { maven.Repositories = append(maven.Repositories, mvn.NewRepository(repo)) } + task := &v1.BuilderTask{ BaseTask: v1.BaseTask{ Name: "builder", diff --git a/pkg/util/defaults/defaults.go b/pkg/util/defaults/defaults.go index 257d8e3cea..90ca3eb159 100644 --- a/pkg/util/defaults/defaults.go +++ b/pkg/util/defaults/defaults.go @@ -29,13 +29,13 @@ const ( DefaultRuntimeVersion = "1.13.0" // BuildahVersion -- - BuildahVersion = "1.14.0" + BuildahVersion = "1.23.3" // KanikoVersion -- KanikoVersion = "0.17.1" // baseImage -- - baseImage = "adoptopenjdk/openjdk11:slim" + baseImage = "docker.io/adoptopenjdk/openjdk11:slim" // LocalRepository -- LocalRepository = "/tmp/artifacts/m2" diff --git a/script/Makefile b/script/Makefile index 635f3265c2..5b12f11b04 100644 --- a/script/Makefile +++ b/script/Makefile @@ -19,14 +19,14 @@ OPERATOR_VERSION := $(subst -SNAPSHOT,,$(VERSION)) LAST_RELEASED_IMAGE_NAME := camel-k-operator LAST_RELEASED_VERSION := 1.9.2 RUNTIME_VERSION := 1.13.0 -BUILDAH_VERSION := 1.14.0 +BUILDAH_VERSION := 1.23.3 KANIKO_VERSION := 0.17.1 INSTALL_DEFAULT_KAMELETS := true CONTROLLER_GEN_VERSION := v0.6.1 OPERATOR_SDK_VERSION := v1.14.0 KUSTOMIZE_VERSION := v4.1.2 OPM_VERSION := v1.21.0 -BASE_IMAGE := adoptopenjdk/openjdk11:slim +BASE_IMAGE := docker.io/adoptopenjdk/openjdk11:slim LOCAL_REPOSITORY := /tmp/artifacts/m2 IMAGE_NAME := docker.io/apache/camel-k @@ -334,6 +334,23 @@ else endif docker build -t $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -f build/Dockerfile . +images-arch: bundle-kamelets test maven-overlay + mkdir -p build/_maven_output + mkdir -p build/_output/bin +ifneq ($(shell uname -s 2>/dev/null || echo Unknown),Linux) + GOOS=linux go build $(GOFLAGS) -o build/_output/bin/kamel ./cmd/kamel/*.go +else + cp kamel build/_output/bin +endif + docker buildx rm --all-inactive --force + docker buildx create --append --name builder +ifeq ($(shell uname -m), x86_x64) + docker buildx build --platform=linux/amd64 -t $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -f build/Dockerfile.arch . +endif +ifeq ($(shell uname -m), aarch64) + docker buildx build --platform=linux/arm64 -t $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -f build/Dockerfile.arch . +endif + images-dev: bundle-kamelets test package-artifacts maven-overlay mkdir -p build/_maven_output mkdir -p build/_output/bin @@ -344,6 +361,23 @@ else endif docker build -t $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -f build/Dockerfile . +images-arch-dev: bundle-kamelets test package-artifacts maven-overlay + mkdir -p build/_maven_output + mkdir -p build/_output/bin +ifneq ($(shell uname -s 2>/dev/null || echo Unknown),Linux) + GOOS=linux go build $(GOFLAGS) -o build/_output/bin/kamel ./cmd/kamel/*.go +else + cp kamel build/_output/bin +endif + docker buildx rm --all-inactive --force + docker buildx create --append --name builder +ifeq ($(shell uname -m), x86_x64) + docker buildx build --platform=linux/amd64 -t $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -f build/Dockerfile.arch . +endif +ifeq ($(shell uname -m), aarch64) + docker buildx build --platform=linux/arm64 -t $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -f build/Dockerfile.arch . +endif + images-push: docker push $(CUSTOM_IMAGE):$(CUSTOM_VERSION)