From c24b5ef618dd64d73b8ec6771d5d6e34d978cf3e Mon Sep 17 00:00:00 2001 From: Gaelle Fournier Date: Fri, 7 Jul 2023 10:54:48 +0200 Subject: [PATCH 1/4] feat(core): Add jibcli tool in camel-k image --- build/Dockerfile | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/build/Dockerfile b/build/Dockerfile index 5f52516375..931cec1fbd 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -13,6 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. +FROM alpine:latest AS jibcli +ARG JIB_CLI_VERSION=0.12.0 +ARG JIB_HOME="/opt/jib" +RUN apk --no-cache add ca-certificates \ + curl \ + unzip \ + && rm -rf /var/cache/apk/* +# replace xargs command not available in some base images +RUN set -xe \ + && curl -sSL -o jib.zip https://github.com/GoogleContainerTools/jib/releases/download/v${JIB_CLI_VERSION}-cli/jib-jre-${JIB_CLI_VERSION}.zip \ + && unzip jib.zip \ + && rm jib.zip \ + && mv jib-${JIB_CLI_VERSION} ${JIB_HOME} \ + && sed -i "s/xargs -n1/tr \' \' \'\\\n\'/g" ${JIB_HOME}/bin/jib + FROM eclipse-temurin:17-jdk as base ARG MAVEN_DEFAULT_VERSION="3.8.6" @@ -21,6 +36,8 @@ ARG MAVEN_DIST_URL="https://archive.apache.org/dist/maven/maven-3/${MAVEN_DEFAUL ARG MVNW_DIR="/usr/share/maven/mvnw/" ARG MVN_REPO="/etc/maven/m2" +ARG JIB_HOME="/opt/jib" + USER 0 # Maven configuration @@ -42,6 +59,8 @@ RUN ${MVNW_DIR}/mvnw --version | grep "Maven home:" | sed 's/Maven home: //' >> && rm $(cat ${MVNW_DIR}default)/lib/maven-slf4j-provider* ENV MAVEN_OPTS="${MAVEN_OPTS} -Dlogback.configurationFile=${MAVEN_HOME}/conf/logback.xml" +COPY --from=jibcli ${JIB_HOME} ${JIB_HOME} + ADD build/_maven_output ${MVN_REPO} ADD build/_kamelets /kamelets @@ -52,7 +71,9 @@ RUN chgrp -R 0 ${MVN_REPO} \ && chmod -R g=u /kamelets \ && chgrp -R 0 ${MAVEN_HOME} \ && chown -R 1001:0 ${MAVEN_HOME} \ - && chmod -R 775 ${MAVEN_HOME} + && chmod -R 775 ${MAVEN_HOME} \ + && chown -R 1001:0 ${JIB_HOME} \ + && chmod -R 775 ${JIB_HOME} USER 1001:0 @@ -64,4 +85,4 @@ RUN go install github.com/go-delve/delve/cmd/dlv@latest FROM base as debug -COPY --from=go /go/bin/dlv /usr/local/bin/dlv +COPY --from=go /go/bin/dlv /usr/local/bin/dlv \ No newline at end of file From 4086d732700acb8daac4fbd1c42c5441cae1c341 Mon Sep 17 00:00:00 2001 From: Gaelle Fournier Date: Mon, 3 Jul 2023 16:29:38 +0200 Subject: [PATCH 2/4] feat(core): Add Jib publish strategy using jibcli --- config/crd/bases/camel.apache.org_builds.yaml | 37 ++++ .../samples/patch-integration-platform.yaml | 4 +- .../ROOT/partials/apis/camel-k-crds.adoc | 40 ++++ helm/camel-k/crds/crd-build.yaml | 37 ++++ pkg/apis/camel/v1/build_types.go | 8 + .../camel/v1/integrationplatform_types.go | 4 + pkg/apis/camel/v1/zz_generated.deepcopy.go | 22 +++ pkg/builder/image.go | 100 +++++++++- pkg/builder/jib.go | 187 ++++++++++++++++++ pkg/builder/tasks.go | 13 ++ .../applyconfiguration/camel/v1/jibtask.go | 73 +++++++ .../camel/applyconfiguration/camel/v1/task.go | 9 + pkg/client/camel/applyconfiguration/utils.go | 2 + pkg/controller/build/build_pod.go | 2 + pkg/controller/build/monitor_routine.go | 7 + pkg/controller/catalog/initialize.go | 148 ++++++++++++++ pkg/trait/builder.go | 12 ++ pkg/trait/quarkus.go | 16 +- 18 files changed, 705 insertions(+), 16 deletions(-) create mode 100644 pkg/builder/jib.go create mode 100644 pkg/client/camel/applyconfiguration/camel/v1/jibtask.go diff --git a/config/crd/bases/camel.apache.org_builds.yaml b/config/crd/bases/camel.apache.org_builds.yaml index f7947276d4..b760243fff 100644 --- a/config/crd/bases/camel.apache.org_builds.yaml +++ b/config/crd/bases/camel.apache.org_builds.yaml @@ -648,6 +648,43 @@ spec: description: name of the task type: string type: object + jib: + description: a JibTask, for Jib strategy + properties: + baseImage: + description: base image layer + type: string + contextDir: + description: can be useful to share info with other tasks + type: string + image: + description: final image name + type: string + name: + description: name of the task + type: string + registry: + description: where to publish the final image + properties: + address: + description: the URI to access + type: string + ca: + description: the configmap which stores the Certificate + Authority + type: string + insecure: + description: if the container registry is insecure (ie, + http only) + type: boolean + organization: + description: the registry organization + type: string + secret: + description: the secret where credentials are stored + type: string + type: object + type: object kaniko: description: a KanikoTask, for Kaniko strategy properties: diff --git a/config/samples/patch-integration-platform.yaml b/config/samples/patch-integration-platform.yaml index f53bd4783d..e7ea4f540b 100644 --- a/config/samples/patch-integration-platform.yaml +++ b/config/samples/patch-integration-platform.yaml @@ -44,9 +44,9 @@ spec: # # # Build publish strategy for integrations - # ie. Buildah, Kaniko, S2I, Spectrum + # ie. Buildah, Kaniko, S2I, Spectrum, Jib # - # publishStrategy: Buildah | Kaniko | S2I | Spectrum + # publishStrategy: Buildah | Kaniko | S2I | Spectrum | Jib # # Set the camel-k runtime version # diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc index c922052faf..448ef01209 100644 --- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc +++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc @@ -385,6 +385,7 @@ a checksum (SHA1) of the content * <<#_camel_apache_org_v1_BuildahTask, BuildahTask>> * <<#_camel_apache_org_v1_BuilderTask, BuilderTask>> +* <<#_camel_apache_org_v1_JibTask, JibTask>> * <<#_camel_apache_org_v1_KanikoTask, KanikoTask>> * <<#_camel_apache_org_v1_S2iTask, S2iTask>> * <<#_camel_apache_org_v1_SpectrumTask, SpectrumTask>> @@ -3419,6 +3420,37 @@ string JSONSchemaURL represents a schema url. +[#_camel_apache_org_v1_JibTask] +=== JibTask + +*Appears on:* + +* <<#_camel_apache_org_v1_Task, Task>> + +JibTask is used to configure Jib + +[cols="2,2a",options="header"] +|=== +|Field +|Description + +|`BaseTask` + +*xref:#_camel_apache_org_v1_BaseTask[BaseTask]* +|(Members of `BaseTask` are embedded into this type.) + + + + +|`PublishTask` + +*xref:#_camel_apache_org_v1_PublishTask[PublishTask]* +|(Members of `PublishTask` are embedded into this type.) + + + + + +|=== + [#_camel_apache_org_v1_KameletCondition] === KameletCondition @@ -4268,6 +4300,7 @@ the specification *Appears on:* * <<#_camel_apache_org_v1_BuildahTask, BuildahTask>> +* <<#_camel_apache_org_v1_JibTask, JibTask>> * <<#_camel_apache_org_v1_KanikoTask, KanikoTask>> * <<#_camel_apache_org_v1_SpectrumTask, SpectrumTask>> @@ -4827,6 +4860,13 @@ a SpectrumTask, for Spectrum strategy a S2iTask, for S2I strategy +|`jib` + +*xref:#_camel_apache_org_v1_JibTask[JibTask]* +| + + +a JibTask, for Jib strategy + |`custom` + *xref:#_camel_apache_org_v1_UserTask[UserTask]* | diff --git a/helm/camel-k/crds/crd-build.yaml b/helm/camel-k/crds/crd-build.yaml index f7947276d4..b760243fff 100644 --- a/helm/camel-k/crds/crd-build.yaml +++ b/helm/camel-k/crds/crd-build.yaml @@ -648,6 +648,43 @@ spec: description: name of the task type: string type: object + jib: + description: a JibTask, for Jib strategy + properties: + baseImage: + description: base image layer + type: string + contextDir: + description: can be useful to share info with other tasks + type: string + image: + description: final image name + type: string + name: + description: name of the task + type: string + registry: + description: where to publish the final image + properties: + address: + description: the URI to access + type: string + ca: + description: the configmap which stores the Certificate + Authority + type: string + insecure: + description: if the container registry is insecure (ie, + http only) + type: boolean + organization: + description: the registry organization + type: string + secret: + description: the secret where credentials are stored + type: string + type: object + type: object kaniko: description: a KanikoTask, for Kaniko strategy properties: diff --git a/pkg/apis/camel/v1/build_types.go b/pkg/apis/camel/v1/build_types.go index e928c66c9a..5c8dcb2d5c 100644 --- a/pkg/apis/camel/v1/build_types.go +++ b/pkg/apis/camel/v1/build_types.go @@ -67,6 +67,8 @@ type Task struct { Spectrum *SpectrumTask `json:"spectrum,omitempty"` // a S2iTask, for S2I strategy S2i *S2iTask `json:"s2i,omitempty"` + // a JibTask, for Jib strategy + Jib *JibTask `json:"jib,omitempty"` // User customizable task execution @@ -154,6 +156,12 @@ type KanikoTaskCache struct { PersistentVolumeClaim string `json:"persistentVolumeClaim,omitempty"` } +// JibTask is used to configure Jib +type JibTask struct { + BaseTask `json:",inline"` + PublishTask `json:",inline"` +} + // SpectrumTask is used to configure Spectrum type SpectrumTask struct { BaseTask `json:",inline"` diff --git a/pkg/apis/camel/v1/integrationplatform_types.go b/pkg/apis/camel/v1/integrationplatform_types.go index d877373588..6fda741bf3 100644 --- a/pkg/apis/camel/v1/integrationplatform_types.go +++ b/pkg/apis/camel/v1/integrationplatform_types.go @@ -165,6 +165,9 @@ const ( // IntegrationPlatformBuildPublishStrategySpectrum uses Spectrum project (https://github.com/container-tools/spectrum) // in order to push the incremental images to the image repository. It is the default choice on vanilla Kubernetes cluster IntegrationPlatformBuildPublishStrategySpectrum IntegrationPlatformBuildPublishStrategy = "Spectrum" + // IntegrationPlatformBuildPublishStrategyJib used the JibCli tool (https://github.com/GoogleContainerTools/jib/tree/master/jib-cli) + // in order to ush the incremental images to the image repository. + IntegrationPlatformBuildPublishStrategyJib IntegrationPlatformBuildPublishStrategy = "Jib" ) // IntegrationPlatformBuildPublishStrategies the list of all available publish strategies @@ -173,6 +176,7 @@ var IntegrationPlatformBuildPublishStrategies = []IntegrationPlatformBuildPublis IntegrationPlatformBuildPublishStrategyKaniko, IntegrationPlatformBuildPublishStrategyS2I, IntegrationPlatformBuildPublishStrategySpectrum, + IntegrationPlatformBuildPublishStrategyJib, } // IntegrationPlatformPhase is the phase of an IntegrationPlatform diff --git a/pkg/apis/camel/v1/zz_generated.deepcopy.go b/pkg/apis/camel/v1/zz_generated.deepcopy.go index e7d79c4dd7..cc44ba60da 100644 --- a/pkg/apis/camel/v1/zz_generated.deepcopy.go +++ b/pkg/apis/camel/v1/zz_generated.deepcopy.go @@ -1735,6 +1735,23 @@ func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *JibTask) DeepCopyInto(out *JibTask) { + *out = *in + out.BaseTask = in.BaseTask + out.PublishTask = in.PublishTask +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JibTask. +func (in *JibTask) DeepCopy() *JibTask { + if in == nil { + return nil + } + out := new(JibTask) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Kamelet) DeepCopyInto(out *Kamelet) { *out = *in @@ -2577,6 +2594,11 @@ func (in *Task) DeepCopyInto(out *Task) { *out = new(S2iTask) **out = **in } + if in.Jib != nil { + in, out := &in.Jib, &out.Jib + *out = new(JibTask) + **out = **in + } if in.Custom != nil { in, out := &in.Custom, &out.Custom *out = new(UserTask) diff --git a/pkg/builder/image.go b/pkg/builder/image.go index 215f3e4351..fcff60d937 100644 --- a/pkg/builder/image.go +++ b/pkg/builder/image.go @@ -30,6 +30,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util" "github.com/apache/camel-k/v2/pkg/util/defaults" + "github.com/apache/camel-k/v2/pkg/util/log" ) const ( @@ -43,19 +44,23 @@ func init() { } type imageSteps struct { - IncrementalImageContext Step - NativeImageContext Step - StandardImageContext Step - ExecutableDockerfile Step - JvmDockerfile Step + IncrementalImageContext Step + NativeImageContext Step + StandardImageContext Step + ExecutableDockerfile Step + JvmDockerfile Step + ExecutableJibCliBuildfile Step + JibCliBuildfile Step } var Image = imageSteps{ - IncrementalImageContext: NewStep(ApplicationPackagePhase, incrementalImageContext), - NativeImageContext: NewStep(ApplicationPackagePhase, nativeImageContext), - StandardImageContext: NewStep(ApplicationPackagePhase, standardImageContext), - ExecutableDockerfile: NewStep(ApplicationPackagePhase+1, executableDockerfile), - JvmDockerfile: NewStep(ApplicationPackagePhase+1, jvmDockerfile), + IncrementalImageContext: NewStep(ApplicationPackagePhase, incrementalImageContext), + NativeImageContext: NewStep(ApplicationPackagePhase, nativeImageContext), + StandardImageContext: NewStep(ApplicationPackagePhase, standardImageContext), + ExecutableDockerfile: NewStep(ApplicationPackagePhase+1, executableDockerfile), + JvmDockerfile: NewStep(ApplicationPackagePhase+1, jvmDockerfile), + ExecutableJibCliBuildfile: NewStep(ApplicationPackagePhase+1, executableJibCliBuildfile), + JibCliBuildfile: NewStep(ApplicationPackagePhase+1, jibCliBuildfile), } type artifactsSelector func(ctx *builderContext) error @@ -119,6 +124,81 @@ func jvmDockerfile(ctx *builderContext) error { return nil } +func executableJibCliBuildfile(ctx *builderContext) error { + // #nosec G202 + jibcliBuildFile := []byte(`apiVersion: jib/v1alpha1 +kind: BuildFile +from: + image: ` + ctx.BaseImage + ` + platforms: + - architecture: amd64 + os: linux +workingDirectory: ` + DeploymentDir + ` +layers: + properties: + filePermissions: 775 + directoryPermissions: 775 + user: "nonroot" + group: "root" + entries: + - name: runner + files: + - src: ` + filepath.Join(ctx.Path, ContextDir) + ` + dest: ` + DeploymentDir + ` +`) + err := os.WriteFile(filepath.Join(ctx.Path, ContextDir, "jibclibuild.yaml"), jibcliBuildFile, 0o400) + if err != nil { + return err + } + log.Info(string(jibcliBuildFile)) + return nil +} + +func jibCliBuildfile(ctx *builderContext) error { + // #nosec G202 + jibcliBuildFile := []byte(`apiVersion: jib/v1alpha1 +kind: BuildFile +from: + image: ` + ctx.BaseImage + ` + platforms: + - architecture: amd64 + os: linux +workingDirectory: ` + DeploymentDir + ` +user: 1000 +layers: + entries: + - name: libboot + files: + - src: ` + filepath.Join(ctx.Path, ContextDir, "dependencies/lib/boot") + ` + dest: ` + DeploymentDir + `/dependencies/lib/boot + - name: libmain + files: + - src: ` + filepath.Join(ctx.Path, ContextDir, "dependencies/lib/main") + ` + dest: ` + DeploymentDir + `/dependencies/lib/main + - name: quarkus + files: + - src: ` + filepath.Join(ctx.Path, ContextDir, "dependencies/quarkus") + ` + dest: ` + DeploymentDir + `/dependencies/quarkus + - name: app + files: + - src: ` + filepath.Join(ctx.Path, ContextDir, "dependencies/app") + ` + dest: ` + DeploymentDir + `/dependencies/app + - name: context + files: + - src: ` + filepath.Join(ctx.Path, ContextDir) + ` + dest: ` + DeploymentDir + ` + excludes: + - "**/config.json" + - "**/google-cloud-tools-java**" + - "**/jib.yaml" +`) + err := os.WriteFile(filepath.Join(ctx.Path, ContextDir, "jib.yaml"), jibcliBuildFile, 0o400) + if err != nil { + return err + } + return nil +} + func incrementalImageContext(ctx *builderContext) error { images, err := listPublishedImages(ctx) if err != nil { diff --git a/pkg/builder/jib.go b/pkg/builder/jib.go new file mode 100644 index 0000000000..d4993b7e6e --- /dev/null +++ b/pkg/builder/jib.go @@ -0,0 +1,187 @@ +/* +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 + +import ( + "context" + "encoding/json" + "os" + "os/exec" + "path/filepath" + "strings" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/apache/camel-k/v2/pkg/client" + "github.com/apache/camel-k/v2/pkg/util" + "github.com/apache/camel-k/v2/pkg/util/log" + "go.uber.org/multierr" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type jibTask struct { + c client.Client + build *v1.Build + task *v1.JibTask +} + +type JibImage struct { + Image string `json:"image,omitempty"` + ImageID string `json:"imageId,omitempty"` + ImageDigest string `json:"imageDigest,omitempty"` + Tags []string `json:"tags,omitempty"` + ImagePushed *bool `json:"imagePushed,omitempty"` +} + +var _ Task = &jibTask{} + +var ( + logger = log.WithName("jib") + + loggerInfo = func(s string) string { logger.Info(s); return "" } + loggerError = func(s string) string { logger.Error(nil, s); return "" } +) + +func (t *jibTask) Do(ctx context.Context) v1.BuildStatus { + status := v1.BuildStatus{} + + baseImage := t.build.Status.BaseImage + if baseImage == "" { + baseImage = t.task.BaseImage + status.BaseImage = baseImage + } + + contextDir := t.task.ContextDir + if contextDir == "" { + // Use the working directory. + // This is useful when the task is executed in-container, + // so that its WorkingDir can be used to share state and + // coordinate with other tasks. + pwd, err := os.Getwd() + if err != nil { + return status.Failed(err) + } + contextDir = filepath.Join(pwd, ContextDir) + } + + exists, err := util.DirectoryExists(contextDir) + if err != nil { + return status.Failed(err) + } + empty, err := util.DirectoryEmpty(contextDir) + if err != nil { + return status.Failed(err) + } + if !exists || empty { + // this can only indicate that there are no more resources to add to the base image, + // because transitive resolution is the same even if spec differs. + log.Infof("No new image to build, reusing existing image %s", baseImage) + status.Image = baseImage + return status + } + + log.Debugf("Registry address: %s", t.task.Registry.Address) + log.Debugf("Base image: %s", baseImage) + + pushInsecure := t.task.Registry.Insecure + pullInsecure := t.task.Registry.Insecure // incremental build case + if !strings.HasPrefix(baseImage, t.task.Registry.Address) { + if pullInsecure { + log.Info("Assuming secure pull because the registry for the base image and the main registry are different") + pullInsecure = false + } + } + + registryConfigDir := "" + if t.task.Registry.Secret != "" { + registryConfigDir, err = MountJibSecret(ctx, t.c, t.build.Namespace, t.task.Registry.Secret, contextDir) + if err != nil { + return status.Failed(err) + } + } + + jibCmd := "/opt/jib/bin/jib" + jibArgs := []string{"build", + "--target=" + t.task.Image, + "--build-file=" + filepath.Join(contextDir, "jib.yaml"), + "--image-metadata-out=" + filepath.Join(contextDir, "jibimage.json")} + + if pushInsecure || pullInsecure { + jibArgs = append(jibArgs, "--allow-insecure-registries") + } + + cmd := exec.CommandContext(ctx, jibCmd, jibArgs...) + + cmd.Dir = contextDir + + env := os.Environ() + env = append(env, "HOME="+contextDir) + cmd.Env = env + + myerror := util.RunAndLog(ctx, cmd, loggerInfo, loggerError) + if myerror != nil { + log.Errorf(myerror, "jib integration image containerization did not run successfully") + return status.Failed(myerror) + } + + log.Info("jib integration image containerization did run successfully") + status.Image = t.task.Image + + // retrieve image digest + jibOutput, err := util.ReadFile(filepath.Join(contextDir, "jibimage.json")) + if err != nil { + return status.Failed(err) + } + var jibImage = JibImage{} + if err := json.Unmarshal(jibOutput, &jibImage); err != nil { + return status.Failed(err) + } + status.Digest = jibImage.ImageDigest + + if registryConfigDir != "" { + if err := os.RemoveAll(registryConfigDir); err != nil { + return status.Failed(err) + } + } + + return status +} + +func MountJibSecret(ctx context.Context, c client.Client, namespace, name string, jibContextDir string) (string, error) { + dockerConfigDir := filepath.Join(jibContextDir, ".docker") + + err := util.CreateDirectory(dockerConfigDir) + if err != nil { + return "", err + } + + secret, err := c.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + if removeErr := os.RemoveAll(dockerConfigDir); removeErr != nil { + err = multierr.Append(err, removeErr) + } + return "", err + } + + for file, content := range secret.Data { + if err := os.WriteFile(filepath.Join(dockerConfigDir, remap(file)), content, 0o600); err != nil { + if removeErr := os.Remove(filepath.Join(dockerConfigDir, remap(file))); removeErr != nil { + err = multierr.Append(err, removeErr) + } + return "", err + } + } + return dockerConfigDir, nil +} diff --git a/pkg/builder/tasks.go b/pkg/builder/tasks.go index 00e575e0ea..ce75da0352 100644 --- a/pkg/builder/tasks.go +++ b/pkg/builder/tasks.go @@ -62,6 +62,13 @@ func (b *Build) Task(task v1.Task) Task { build: b.build, task: task.S2i, } + + case task.Jib != nil: + return &jibTask{ + c: b.builder.client, + build: b.build, + task: task.Jib, + } } return &emptyTask{ @@ -138,6 +145,12 @@ func (b *Build) TaskByName(name string) Task { build: b.build, task: task.S2i, } + case task.Jib != nil && task.Jib.Name == name: + return &jibTask{ + c: b.builder.client, + build: b.build, + task: task.Jib, + } } } return &missingTask{ diff --git a/pkg/client/camel/applyconfiguration/camel/v1/jibtask.go b/pkg/client/camel/applyconfiguration/camel/v1/jibtask.go new file mode 100644 index 0000000000..1e87d42814 --- /dev/null +++ b/pkg/client/camel/applyconfiguration/camel/v1/jibtask.go @@ -0,0 +1,73 @@ +/* +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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// JibTaskApplyConfiguration represents an declarative configuration of the JibTask type for use +// with apply. +type JibTaskApplyConfiguration struct { + BaseTaskApplyConfiguration `json:",inline"` + PublishTaskApplyConfiguration `json:",inline"` +} + +// JibTaskApplyConfiguration constructs an declarative configuration of the JibTask type for use with +// apply. +func JibTask() *JibTaskApplyConfiguration { + return &JibTaskApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *JibTaskApplyConfiguration) WithName(value string) *JibTaskApplyConfiguration { + b.Name = &value + return b +} + +// WithContextDir sets the ContextDir field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ContextDir field is set to the value of the last call. +func (b *JibTaskApplyConfiguration) WithContextDir(value string) *JibTaskApplyConfiguration { + b.ContextDir = &value + return b +} + +// WithBaseImage sets the BaseImage field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the BaseImage field is set to the value of the last call. +func (b *JibTaskApplyConfiguration) WithBaseImage(value string) *JibTaskApplyConfiguration { + b.BaseImage = &value + return b +} + +// WithImage sets the Image field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Image field is set to the value of the last call. +func (b *JibTaskApplyConfiguration) WithImage(value string) *JibTaskApplyConfiguration { + b.Image = &value + return b +} + +// WithRegistry sets the Registry field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Registry field is set to the value of the last call. +func (b *JibTaskApplyConfiguration) WithRegistry(value *RegistrySpecApplyConfiguration) *JibTaskApplyConfiguration { + b.Registry = value + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/task.go b/pkg/client/camel/applyconfiguration/camel/v1/task.go index 01fd1aa5a2..a4b7912c2e 100644 --- a/pkg/client/camel/applyconfiguration/camel/v1/task.go +++ b/pkg/client/camel/applyconfiguration/camel/v1/task.go @@ -27,6 +27,7 @@ type TaskApplyConfiguration struct { Kaniko *KanikoTaskApplyConfiguration `json:"kaniko,omitempty"` Spectrum *SpectrumTaskApplyConfiguration `json:"spectrum,omitempty"` S2i *S2iTaskApplyConfiguration `json:"s2i,omitempty"` + Jib *JibTaskApplyConfiguration `json:"jib,omitempty"` Custom *UserTaskApplyConfiguration `json:"custom,omitempty"` } @@ -76,6 +77,14 @@ func (b *TaskApplyConfiguration) WithS2i(value *S2iTaskApplyConfiguration) *Task return b } +// WithJib sets the Jib field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Jib field is set to the value of the last call. +func (b *TaskApplyConfiguration) WithJib(value *JibTaskApplyConfiguration) *TaskApplyConfiguration { + b.Jib = value + return b +} + // WithCustom sets the Custom field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Custom field is set to the value of the last call. diff --git a/pkg/client/camel/applyconfiguration/utils.go b/pkg/client/camel/applyconfiguration/utils.go index 1e0497534b..3ce316c0eb 100644 --- a/pkg/client/camel/applyconfiguration/utils.go +++ b/pkg/client/camel/applyconfiguration/utils.go @@ -136,6 +136,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &camelv1.IntegrationSpecApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("IntegrationStatus"): return &camelv1.IntegrationStatusApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("JibTask"): + return &camelv1.JibTaskApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("JSON"): return &camelv1.JSONApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("JSONSchemaProp"): diff --git a/pkg/controller/build/build_pod.go b/pkg/controller/build/build_pod.go index bb5fe31a7a..686152ab3b 100644 --- a/pkg/controller/build/build_pod.go +++ b/pkg/controller/build/build_pod.go @@ -170,6 +170,8 @@ func newBuildPod(ctx context.Context, c ctrl.Reader, client client.Client, build addBuildTaskToPod(ctx, client, build, task.S2i.Name, pod) case task.Spectrum != nil: addBuildTaskToPod(ctx, client, build, task.Spectrum.Name, pod) + case task.Jib != nil: + addBuildTaskToPod(ctx, client, build, task.Jib.Name, pod) case task.Custom != nil: addCustomTaskToPod(build, task.Custom, pod) } diff --git a/pkg/controller/build/monitor_routine.go b/pkg/controller/build/monitor_routine.go index 6aa9ed696f..4712341bd9 100644 --- a/pkg/controller/build/monitor_routine.go +++ b/pkg/controller/build/monitor_routine.go @@ -148,6 +148,13 @@ tasks: break tasks } t.ContextDir = filepath.Join(buildDir, builder.ContextDir) + + } else if t := task.Jib; t != nil && t.ContextDir == "" { + if buildDir == "" { + status.Failed(fmt.Errorf("cannot determine context directory for task %s", t.Name)) + break tasks + } + t.ContextDir = filepath.Join(buildDir, builder.ContextDir) } // Execute the task diff --git a/pkg/controller/catalog/initialize.go b/pkg/controller/catalog/initialize.go index 5d1ec67f8b..0e5d93efdd 100644 --- a/pkg/controller/catalog/initialize.go +++ b/pkg/controller/catalog/initialize.go @@ -27,6 +27,7 @@ import ( "fmt" "io" "os" + "os/exec" "path/filepath" "runtime" "strings" @@ -39,6 +40,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util" "github.com/apache/camel-k/v2/pkg/util/defaults" "github.com/apache/camel-k/v2/pkg/util/kubernetes" + "github.com/apache/camel-k/v2/pkg/util/log" "github.com/apache/camel-k/v2/pkg/util/openshift" "github.com/apache/camel-k/v2/pkg/util/s2i" @@ -90,6 +92,9 @@ func (action *initializeAction) Handle(ctx context.Context, catalog *v1.CamelCat if platform.Status.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategyS2I { return initializeS2i(ctx, action.client, platform, catalog) } + if platform.Status.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategyJib { + return initializeJib(ctx, action.client, platform, catalog) + } // Default to spectrum // Make basic options for building image in the registry options, err := makeSpectrumOptions(ctx, action.client, platform.Namespace, platform.Status.Build.Registry) @@ -387,6 +392,107 @@ func initializeS2i(ctx context.Context, c client.Client, ip *v1.IntegrationPlatf return target, nil } +func initializeJib(ctx context.Context, c client.Client, ip *v1.IntegrationPlatform, catalog *v1.CamelCatalog) (*v1.CamelCatalog, error) { + target := catalog.DeepCopy() + + organization := ip.Status.Build.Registry.Organization + if organization == "" { + organization = ip.Namespace + } + imageName := fmt.Sprintf( + "%s/%s/camel-k-runtime-%s-builder:%s", + ip.Status.Build.Registry.Address, + organization, + catalog.Spec.Runtime.Provider, + strings.ToLower(catalog.Spec.Runtime.Version), + ) + + jibBuildFileName := fmt.Sprintf( + "camel-k-runtime-%s-builder-jib.yaml", + catalog.Spec.Runtime.Provider, + ) + + root := os.TempDir() + jibContextDir, err := os.MkdirTemp(root, "jib-builder") + if err != nil { + target.Status.Phase = v1.CamelCatalogPhaseError + target.Status.SetErrorCondition( + v1.CamelCatalogConditionReady, + "Builder Image", + err, + ) + return target, err + } + defer os.RemoveAll(jibContextDir) + + if ip.Status.Build.Registry.Secret != "" { + _, err = builder.MountJibSecret(ctx, c, ip.Namespace, ip.Status.Build.Registry.Secret, jibContextDir) + if err != nil { + target.Status.Phase = v1.CamelCatalogPhaseError + target.Status.SetErrorCondition( + v1.CamelCatalogConditionReady, + "Builder Image", + err, + ) + return target, err + } + } + + err = jibBuildFile(catalog, jibContextDir, jibBuildFileName) + if err != nil { + target.Status.Phase = v1.CamelCatalogPhaseError + target.Status.SetErrorCondition( + v1.CamelCatalogConditionReady, + "Builder Image", + err, + ) + return target, err + } + + jibCmd := "/opt/jib/bin/jib" + jibArgs := []string{"build", + "--target=" + imageName, + "--build-file=" + filepath.Join(jibContextDir, jibBuildFileName), + "--image-metadata-out=" + filepath.Join(jibContextDir, "jibimage.json")} + + if ip.Status.Build.Registry.Insecure { + jibArgs = append(jibArgs, "--allow-insecure-registries") + } + + cmd := exec.CommandContext(ctx, jibCmd, jibArgs...) + + cmd.Dir = jibContextDir + + env := os.Environ() + env = append(env, "HOME="+jibContextDir) + cmd.Env = env + + var loggerInfo = func(s string) string { log.Info(s); return "" } + var loggerError = func(s string) string { log.Error(nil, s); return "" } + + err = util.RunAndLog(ctx, cmd, loggerInfo, loggerError) + if err != nil { + target.Status.Phase = v1.CamelCatalogPhaseError + target.Status.SetErrorCondition( + v1.CamelCatalogConditionReady, + "Builder Image", + err, + ) + return target, err + } + + target.Status.Phase = v1.CamelCatalogPhaseReady + target.Status.SetCondition( + v1.CamelCatalogConditionReady, + corev1.ConditionTrue, + "Builder Image", + "Container image successfully built", + ) + target.Status.Image = imageName + + return target, nil +} + func imageExistsSpectrum(options spectrum.Options) bool { Log.Infof("Checking if Camel K builder container %s already exists...", options.Base) ctrImg, err := spectrum.Pull(options) @@ -578,3 +684,45 @@ func getS2iUserID(ctx context.Context, c client.Client, ip *v1.IntegrationPlatfo } return ugfidStr } +func jibBuildFile(catalog *v1.CamelCatalog, jibContextDir string, jibBuildFileName string) error { + // #nosec G202 + jibBuildFile := []byte(`apiVersion: jib/v1alpha1 +kind: BuildFile +from: + image: ` + catalog.Spec.GetQuarkusToolingImage() + ` + platforms: + - architecture: amd64 + os: linux +layers: + properties: + filePermissions: 755 + directoryPermissions: 755 + user: "1001" + group: "0" + entries: + - name: maven + files: + - src: /usr/share/maven/mvnw/ + dest: /usr/share/maven/mvnw/ + - name: jib-cli + files: + - src: /opt/jib + dest: /opt/jib + - name: kamel-cli + files: + - src: /usr/local/bin/kamel + dest: /usr/local/bin/kamel + - name: localrepo + files: + - src: ` + defaults.LocalRepository + ` + dest: ` + defaults.LocalRepository + ` +`) + + err := os.WriteFile(filepath.Join(jibContextDir, jibBuildFileName), jibBuildFile, 0o400) + if err != nil { + return err + } + + return nil + +} diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go index 2d997210e6..c291921ae8 100644 --- a/pkg/trait/builder.go +++ b/pkg/trait/builder.go @@ -107,6 +107,18 @@ func (t *builderTrait) Apply(e *Environment) error { Tag: e.IntegrationKit.ResourceVersion, }}) + case v1.IntegrationPlatformBuildPublishStrategyJib: + e.Pipeline = append(e.Pipeline, v1.Task{Jib: &v1.JibTask{ + BaseTask: v1.BaseTask{ + Name: "jib", + }, + PublishTask: v1.PublishTask{ + BaseImage: e.Platform.Status.Build.BaseImage, + Image: getImageName(e), + Registry: e.Platform.Status.Build.Registry, + }, + }}) + case v1.IntegrationPlatformBuildPublishStrategyBuildah: var platform string var found bool diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go index ae182e740b..0ea1b672ab 100644 --- a/pkg/trait/quarkus.go +++ b/pkg/trait/quarkus.go @@ -318,17 +318,25 @@ func (t *quarkusTrait) applyWhenBuildSubmitted(e *Environment) error { steps = append(steps, builder.Quarkus.PrepareProjectWithSources) } steps = append(steps, builder.Image.NativeImageContext) - // Spectrum does not rely on Dockerfile to assemble the image - if e.Platform.Status.Build.PublishStrategy != v1.IntegrationPlatformBuildPublishStrategySpectrum { + // Spectrum and Jib does not rely on Dockerfile to assemble the image + if e.Platform.Status.Build.PublishStrategy != v1.IntegrationPlatformBuildPublishStrategySpectrum && + e.Platform.Status.Build.PublishStrategy != v1.IntegrationPlatformBuildPublishStrategyJib { steps = append(steps, builder.Image.ExecutableDockerfile) } + if e.Platform.Status.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategyJib { + steps = append(steps, builder.Image.ExecutableJibCliBuildfile) + } } else { build.Maven.Properties["quarkus.package.type"] = string(traitv1.FastJarPackageType) steps = append(steps, builder.Quarkus.ComputeQuarkusDependencies, builder.Image.IncrementalImageContext) - // Spectrum does not rely on Dockerfile to assemble the image - if e.Platform.Status.Build.PublishStrategy != v1.IntegrationPlatformBuildPublishStrategySpectrum { + // Spectrum and Jib does not rely on Dockerfile to assemble the image + if e.Platform.Status.Build.PublishStrategy != v1.IntegrationPlatformBuildPublishStrategySpectrum && + e.Platform.Status.Build.PublishStrategy != v1.IntegrationPlatformBuildPublishStrategyJib { steps = append(steps, builder.Image.JvmDockerfile) } + if e.Platform.Status.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategyJib { + steps = append(steps, builder.Image.JibCliBuildfile) + } } // Sort steps by phase From 97ecc5712e29c53b73716022e65abbbd227c4b22 Mon Sep 17 00:00:00 2001 From: Gaelle Fournier Date: Fri, 7 Jul 2023 13:18:29 +0200 Subject: [PATCH 3/4] feat(core): Refatoring for jibcli usage --- pkg/builder/jib.go | 44 +++-------------- pkg/controller/catalog/initialize.go | 17 ++++--- pkg/util/jib/jibcli.go | 74 ++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 43 deletions(-) create mode 100644 pkg/util/jib/jibcli.go diff --git a/pkg/builder/jib.go b/pkg/builder/jib.go index d4993b7e6e..c223eac2e4 100644 --- a/pkg/builder/jib.go +++ b/pkg/builder/jib.go @@ -26,9 +26,8 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/client" "github.com/apache/camel-k/v2/pkg/util" + "github.com/apache/camel-k/v2/pkg/util/jib" "github.com/apache/camel-k/v2/pkg/util/log" - "go.uber.org/multierr" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type jibTask struct { @@ -106,20 +105,20 @@ func (t *jibTask) Do(ctx context.Context) v1.BuildStatus { registryConfigDir := "" if t.task.Registry.Secret != "" { - registryConfigDir, err = MountJibSecret(ctx, t.c, t.build.Namespace, t.task.Registry.Secret, contextDir) + registryConfigDir, err = jib.MountJibSecret(ctx, t.c, t.build.Namespace, t.task.Registry.Secret, contextDir) if err != nil { return status.Failed(err) } } - jibCmd := "/opt/jib/bin/jib" - jibArgs := []string{"build", - "--target=" + t.task.Image, - "--build-file=" + filepath.Join(contextDir, "jib.yaml"), - "--image-metadata-out=" + filepath.Join(contextDir, "jibimage.json")} + jibCmd := jib.JibCliCmdBinary + jibArgs := []string{jib.JibCliCmdBuild, + jib.JibCliParamTarget + t.task.Image, + jib.JibCliParamBuildFile + filepath.Join(contextDir, "jib.yaml"), + jib.JibCliParamOutput + filepath.Join(contextDir, "jibimage.json")} if pushInsecure || pullInsecure { - jibArgs = append(jibArgs, "--allow-insecure-registries") + jibArgs = append(jibArgs, jib.JibCliParamInsecureRegistry) } cmd := exec.CommandContext(ctx, jibCmd, jibArgs...) @@ -158,30 +157,3 @@ func (t *jibTask) Do(ctx context.Context) v1.BuildStatus { return status } - -func MountJibSecret(ctx context.Context, c client.Client, namespace, name string, jibContextDir string) (string, error) { - dockerConfigDir := filepath.Join(jibContextDir, ".docker") - - err := util.CreateDirectory(dockerConfigDir) - if err != nil { - return "", err - } - - secret, err := c.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{}) - if err != nil { - if removeErr := os.RemoveAll(dockerConfigDir); removeErr != nil { - err = multierr.Append(err, removeErr) - } - return "", err - } - - for file, content := range secret.Data { - if err := os.WriteFile(filepath.Join(dockerConfigDir, remap(file)), content, 0o600); err != nil { - if removeErr := os.Remove(filepath.Join(dockerConfigDir, remap(file))); removeErr != nil { - err = multierr.Append(err, removeErr) - } - return "", err - } - } - return dockerConfigDir, nil -} diff --git a/pkg/controller/catalog/initialize.go b/pkg/controller/catalog/initialize.go index 0e5d93efdd..2f27530970 100644 --- a/pkg/controller/catalog/initialize.go +++ b/pkg/controller/catalog/initialize.go @@ -39,6 +39,7 @@ import ( platformutil "github.com/apache/camel-k/v2/pkg/platform" "github.com/apache/camel-k/v2/pkg/util" "github.com/apache/camel-k/v2/pkg/util/defaults" + "github.com/apache/camel-k/v2/pkg/util/jib" "github.com/apache/camel-k/v2/pkg/util/kubernetes" "github.com/apache/camel-k/v2/pkg/util/log" "github.com/apache/camel-k/v2/pkg/util/openshift" @@ -426,7 +427,7 @@ func initializeJib(ctx context.Context, c client.Client, ip *v1.IntegrationPlatf defer os.RemoveAll(jibContextDir) if ip.Status.Build.Registry.Secret != "" { - _, err = builder.MountJibSecret(ctx, c, ip.Namespace, ip.Status.Build.Registry.Secret, jibContextDir) + _, err = jib.MountJibSecret(ctx, c, ip.Namespace, ip.Status.Build.Registry.Secret, jibContextDir) if err != nil { target.Status.Phase = v1.CamelCatalogPhaseError target.Status.SetErrorCondition( @@ -449,14 +450,14 @@ func initializeJib(ctx context.Context, c client.Client, ip *v1.IntegrationPlatf return target, err } - jibCmd := "/opt/jib/bin/jib" - jibArgs := []string{"build", - "--target=" + imageName, - "--build-file=" + filepath.Join(jibContextDir, jibBuildFileName), - "--image-metadata-out=" + filepath.Join(jibContextDir, "jibimage.json")} + jibCmd := jib.JibCliCmdBinary + jibArgs := []string{jib.JibCliCmdBuild, + jib.JibCliParamTarget + imageName, + jib.JibCliParamBuildFile + filepath.Join(jibContextDir, jibBuildFileName), + jib.JibCliParamOutput + filepath.Join(jibContextDir, "jibimage.json")} if ip.Status.Build.Registry.Insecure { - jibArgs = append(jibArgs, "--allow-insecure-registries") + jibArgs = append(jibArgs, jib.JibCliParamInsecureRegistry) } cmd := exec.CommandContext(ctx, jibCmd, jibArgs...) @@ -684,6 +685,8 @@ func getS2iUserID(ctx context.Context, c client.Client, ip *v1.IntegrationPlatfo } return ugfidStr } + +// Create the jibcli BuildConfig file. func jibBuildFile(catalog *v1.CamelCatalog, jibContextDir string, jibBuildFileName string) error { // #nosec G202 jibBuildFile := []byte(`apiVersion: jib/v1alpha1 diff --git a/pkg/util/jib/jibcli.go b/pkg/util/jib/jibcli.go new file mode 100644 index 0000000000..1e2af22516 --- /dev/null +++ b/pkg/util/jib/jibcli.go @@ -0,0 +1,74 @@ +/* +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 jib + +import ( + "context" + "os" + "path/filepath" + + "github.com/apache/camel-k/v2/pkg/client" + "github.com/apache/camel-k/v2/pkg/util" + "go.uber.org/multierr" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + JibCliCmdBinary = "/opt/jib/bin/jib" + + JibCliCmdBuild = "build" + JibCliParamBuildFile = "--build-file=" + JibCliParamTarget = "--target=" + JibCliParamOutput = "--image-metadata-out=" + JibCliParamInsecureRegistry = "--allow-insecure-registries" +) + +// Mount the secret containing the docker auth configuration into the folder ${jibContextDir}/.docker/. +func MountJibSecret(ctx context.Context, c client.Client, namespace, name string, jibContextDir string) (string, error) { + dockerConfigDir := filepath.Join(jibContextDir, ".docker") + + err := util.CreateDirectory(dockerConfigDir) + if err != nil { + return "", err + } + + secret, err := c.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + if removeErr := os.RemoveAll(dockerConfigDir); removeErr != nil { + err = multierr.Append(err, removeErr) + } + return "", err + } + + for file, content := range secret.Data { + if err := os.WriteFile(filepath.Join(dockerConfigDir, remap(file)), content, 0o600); err != nil { + if removeErr := os.Remove(filepath.Join(dockerConfigDir, remap(file))); removeErr != nil { + err = multierr.Append(err, removeErr) + } + return "", err + } + } + return dockerConfigDir, nil +} + +func remap(name string) string { + if name == ".dockerconfigjson" { + return "config.json" + } + return name +} From 1315a0b2296e8e2d7906117fc374f6ee6f52ba94 Mon Sep 17 00:00:00 2001 From: Gaelle Fournier Date: Fri, 7 Jul 2023 13:19:57 +0200 Subject: [PATCH 4/4] feat(e2e): Activate e2e for Jib publish strategy --- .github/workflows/builder.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index d301d1f614..2f38b31b69 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -74,7 +74,7 @@ jobs: strategy: fail-fast: false matrix: - publisher: ["Buildah", "Spectrum", "Kaniko"] + publisher: ["Buildah", "Spectrum", "Kaniko", "Jib"] steps: - name: Checkout code