This is an automated email from the ASF dual-hosted git repository. pcongiusti pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit dbea42fb03cd0a4c180be3d5c285060af5bd2573 Author: Pasquale Congiusti <[email protected]> AuthorDate: Wed Jan 10 17:23:39 2024 +0100 feat(pipeline): publishing user task Assuming the last task of a pipeline is a publishing task and if it provides the digest of a published image, then, the build execution succeed --- config/crd/bases/camel.apache.org_builds.yaml | 3 + .../bases/camel.apache.org_integrationkits.yaml | 10 +-- .../camel.apache.org_integrationplatforms.yaml | 20 ++--- .../crd/bases/camel.apache.org_integrations.yaml | 10 +-- .../bases/camel.apache.org_kameletbindings.yaml | 9 +-- config/crd/bases/camel.apache.org_pipes.yaml | 9 +-- docs/modules/ROOT/partials/apis/camel-k-crds.adoc | 11 ++- docs/modules/traits/pages/builder.adoc | 4 +- helm/camel-k/crds/crd-build.yaml | 3 + helm/camel-k/crds/crd-integration-kit.yaml | 10 +-- helm/camel-k/crds/crd-integration-platform.yaml | 20 ++--- helm/camel-k/crds/crd-integration.yaml | 10 +-- helm/camel-k/crds/crd-kamelet-binding.yaml | 9 +-- helm/camel-k/crds/crd-pipe.yaml | 9 +-- pkg/apis/camel/v1/build_types.go | 2 + .../camel/applyconfiguration/camel/v1/usertask.go | 9 +++ pkg/controller/build/build_pod.go | 1 + pkg/controller/build/monitor_pod.go | 94 +++++++++++++++++----- pkg/resources/resources.go | 45 +++++++---- pkg/trait/builder.go | 75 +++++++++++++---- pkg/trait/builder_test.go | 53 +++++++----- pkg/util/test/client.go | 2 + resources/traits.yaml | 8 +- 23 files changed, 293 insertions(+), 133 deletions(-) diff --git a/config/crd/bases/camel.apache.org_builds.yaml b/config/crd/bases/camel.apache.org_builds.yaml index cb486ef73..02965a6bc 100644 --- a/config/crd/bases/camel.apache.org_builds.yaml +++ b/config/crd/bases/camel.apache.org_builds.yaml @@ -818,6 +818,9 @@ spec: name: description: name of the task type: string + publishingImage: + description: the desired image build name + type: string type: object jib: description: a JibTask, for Jib strategy diff --git a/config/crd/bases/camel.apache.org_integrationkits.yaml b/config/crd/bases/camel.apache.org_integrationkits.yaml index 3d4714344..6ec3bd07d 100644 --- a/config/crd/bases/camel.apache.org_integrationkits.yaml +++ b/config/crd/bases/camel.apache.org_integrationkits.yaml @@ -285,11 +285,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using `pod` - strategy), sorted by the order of execution in a csv format, - ie, `<taskName1>,<taskName2>,...`. Mind that you must include - also the operator tasks (`builder`, `quarkus-native`, `package`, - `jib`, `spectrum`, `s2i`) if you need to execute them. + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the specific diff --git a/config/crd/bases/camel.apache.org_integrationplatforms.yaml b/config/crd/bases/camel.apache.org_integrationplatforms.yaml index 240fb4143..9a7c238c9 100644 --- a/config/crd/bases/camel.apache.org_integrationplatforms.yaml +++ b/config/crd/bases/camel.apache.org_integrationplatforms.yaml @@ -590,11 +590,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using `pod` - strategy), sorted by the order of execution in a csv format, - ie, `<taskName1>,<taskName2>,...`. Mind that you must include - also the operator tasks (`builder`, `quarkus-native`, `package`, - `jib`, `spectrum`, `s2i`) if you need to execute them. + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the specific @@ -2480,11 +2480,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using `pod` - strategy), sorted by the order of execution in a csv format, - ie, `<taskName1>,<taskName2>,...`. Mind that you must include - also the operator tasks (`builder`, `quarkus-native`, `package`, - `jib`, `spectrum`, `s2i`) if you need to execute them. + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the specific diff --git a/config/crd/bases/camel.apache.org_integrations.yaml b/config/crd/bases/camel.apache.org_integrations.yaml index fa9fd5c0c..f0018b106 100644 --- a/config/crd/bases/camel.apache.org_integrations.yaml +++ b/config/crd/bases/camel.apache.org_integrations.yaml @@ -6503,11 +6503,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using `pod` - strategy), sorted by the order of execution in a csv format, - ie, `<taskName1>,<taskName2>,...`. Mind that you must include - also the operator tasks (`builder`, `quarkus-native`, `package`, - `jib`, `spectrum`, `s2i`) if you need to execute them. + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the specific diff --git a/config/crd/bases/camel.apache.org_kameletbindings.yaml b/config/crd/bases/camel.apache.org_kameletbindings.yaml index ad82cf8c1..cc0b8e10e 100644 --- a/config/crd/bases/camel.apache.org_kameletbindings.yaml +++ b/config/crd/bases/camel.apache.org_kameletbindings.yaml @@ -6787,12 +6787,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using - `pod` strategy), sorted by the order of execution in - a csv format, ie, `<taskName1>,<taskName2>,...`. Mind - that you must include also the operator tasks (`builder`, + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. + Mind that you must include also the operator tasks (`builder`, `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) - if you need to execute them. + if you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the diff --git a/config/crd/bases/camel.apache.org_pipes.yaml b/config/crd/bases/camel.apache.org_pipes.yaml index d018e4349..35e8fdc8c 100644 --- a/config/crd/bases/camel.apache.org_pipes.yaml +++ b/config/crd/bases/camel.apache.org_pipes.yaml @@ -6785,12 +6785,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using - `pod` strategy), sorted by the order of execution in - a csv format, ie, `<taskName1>,<taskName2>,...`. Mind - that you must include also the operator tasks (`builder`, + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. + Mind that you must include also the operator tasks (`builder`, `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) - if you need to execute them. + if you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc index 29cc535a7..f2ec00ef0 100644 --- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc +++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc @@ -5674,6 +5674,13 @@ Deprecated: use ContainerCommands the command to execute +|`publishingImage` + +string +| + + +the desired image build name + |=== @@ -5892,9 +5899,9 @@ string | -A list of tasks (available only when using `pod` strategy), sorted by the order of execution in a csv format, ie, `<taskName1>,<taskName2>,...`. +A list of tasks sorted by the order of execution in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind that you must include also the operator tasks (`builder`, `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) -if you need to execute them. +if you need to execute them. Useful only wih `pod` strategy. |`tasksRequestCPU` + []string diff --git a/docs/modules/traits/pages/builder.adoc b/docs/modules/traits/pages/builder.adoc index 6330dea1e..8560b38f9 100755 --- a/docs/modules/traits/pages/builder.adoc +++ b/docs/modules/traits/pages/builder.adoc @@ -84,9 +84,9 @@ Syntax: [configmap\|secret]:name[/key], where name represents the resource name, | builder.tasks-filter | string -| A list of tasks (available only when using `pod` strategy), sorted by the order of execution in a csv format, ie, `<taskName1>,<taskName2>,...`. +| A list of tasks sorted by the order of execution in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind that you must include also the operator tasks (`builder`, `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) -if you need to execute them. +if you need to execute them. Useful only wih `pod` strategy. | builder.tasks-request-cpu | []string diff --git a/helm/camel-k/crds/crd-build.yaml b/helm/camel-k/crds/crd-build.yaml index cb486ef73..02965a6bc 100644 --- a/helm/camel-k/crds/crd-build.yaml +++ b/helm/camel-k/crds/crd-build.yaml @@ -818,6 +818,9 @@ spec: name: description: name of the task type: string + publishingImage: + description: the desired image build name + type: string type: object jib: description: a JibTask, for Jib strategy diff --git a/helm/camel-k/crds/crd-integration-kit.yaml b/helm/camel-k/crds/crd-integration-kit.yaml index 3d4714344..6ec3bd07d 100644 --- a/helm/camel-k/crds/crd-integration-kit.yaml +++ b/helm/camel-k/crds/crd-integration-kit.yaml @@ -285,11 +285,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using `pod` - strategy), sorted by the order of execution in a csv format, - ie, `<taskName1>,<taskName2>,...`. Mind that you must include - also the operator tasks (`builder`, `quarkus-native`, `package`, - `jib`, `spectrum`, `s2i`) if you need to execute them. + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the specific diff --git a/helm/camel-k/crds/crd-integration-platform.yaml b/helm/camel-k/crds/crd-integration-platform.yaml index 240fb4143..9a7c238c9 100644 --- a/helm/camel-k/crds/crd-integration-platform.yaml +++ b/helm/camel-k/crds/crd-integration-platform.yaml @@ -590,11 +590,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using `pod` - strategy), sorted by the order of execution in a csv format, - ie, `<taskName1>,<taskName2>,...`. Mind that you must include - also the operator tasks (`builder`, `quarkus-native`, `package`, - `jib`, `spectrum`, `s2i`) if you need to execute them. + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the specific @@ -2480,11 +2480,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using `pod` - strategy), sorted by the order of execution in a csv format, - ie, `<taskName1>,<taskName2>,...`. Mind that you must include - also the operator tasks (`builder`, `quarkus-native`, `package`, - `jib`, `spectrum`, `s2i`) if you need to execute them. + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the specific diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml index fa9fd5c0c..f0018b106 100644 --- a/helm/camel-k/crds/crd-integration.yaml +++ b/helm/camel-k/crds/crd-integration.yaml @@ -6503,11 +6503,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using `pod` - strategy), sorted by the order of execution in a csv format, - ie, `<taskName1>,<taskName2>,...`. Mind that you must include - also the operator tasks (`builder`, `quarkus-native`, `package`, - `jib`, `spectrum`, `s2i`) if you need to execute them. + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the specific diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml index ad82cf8c1..cc0b8e10e 100644 --- a/helm/camel-k/crds/crd-kamelet-binding.yaml +++ b/helm/camel-k/crds/crd-kamelet-binding.yaml @@ -6787,12 +6787,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using - `pod` strategy), sorted by the order of execution in - a csv format, ie, `<taskName1>,<taskName2>,...`. Mind - that you must include also the operator tasks (`builder`, + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. + Mind that you must include also the operator tasks (`builder`, `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) - if you need to execute them. + if you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the diff --git a/helm/camel-k/crds/crd-pipe.yaml b/helm/camel-k/crds/crd-pipe.yaml index d018e4349..35e8fdc8c 100644 --- a/helm/camel-k/crds/crd-pipe.yaml +++ b/helm/camel-k/crds/crd-pipe.yaml @@ -6785,12 +6785,11 @@ spec: type: string type: array tasksFilter: - description: A list of tasks (available only when using - `pod` strategy), sorted by the order of execution in - a csv format, ie, `<taskName1>,<taskName2>,...`. Mind - that you must include also the operator tasks (`builder`, + description: A list of tasks sorted by the order of execution + in a csv format, ie, `<taskName1>,<taskName2>,...`. + Mind that you must include also the operator tasks (`builder`, `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) - if you need to execute them. + if you need to execute them. Useful only wih `pod` strategy. type: string tasksLimitCPU: description: A list of limit cpu configuration for the diff --git a/pkg/apis/camel/v1/build_types.go b/pkg/apis/camel/v1/build_types.go index 5e2a99681..076cf0426 100644 --- a/pkg/apis/camel/v1/build_types.go +++ b/pkg/apis/camel/v1/build_types.go @@ -192,6 +192,8 @@ type UserTask struct { ContainerCommand string `json:"command,omitempty"` // the command to execute ContainerCommands []string `json:"commands,omitempty"` + // the desired image build name + PublishingImage string `json:"publishingImage,omitempty"` } // BuildStatus defines the observed state of Build. diff --git a/pkg/client/camel/applyconfiguration/camel/v1/usertask.go b/pkg/client/camel/applyconfiguration/camel/v1/usertask.go index f4fc11c89..7a85991d1 100644 --- a/pkg/client/camel/applyconfiguration/camel/v1/usertask.go +++ b/pkg/client/camel/applyconfiguration/camel/v1/usertask.go @@ -26,6 +26,7 @@ type UserTaskApplyConfiguration struct { ContainerImage *string `json:"image,omitempty"` ContainerCommand *string `json:"command,omitempty"` ContainerCommands []string `json:"commands,omitempty"` + PublishingImage *string `json:"publishingImage,omitempty"` } // UserTaskApplyConfiguration constructs an declarative configuration of the UserTask type for use with @@ -75,3 +76,11 @@ func (b *UserTaskApplyConfiguration) WithContainerCommands(values ...string) *Us } return b } + +// WithPublishingImage sets the PublishingImage 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 PublishingImage field is set to the value of the last call. +func (b *UserTaskApplyConfiguration) WithPublishingImage(value string) *UserTaskApplyConfiguration { + b.PublishingImage = &value + return b +} diff --git a/pkg/controller/build/build_pod.go b/pkg/controller/build/build_pod.go index 5396573a7..4914e771d 100644 --- a/pkg/controller/build/build_pod.go +++ b/pkg/controller/build/build_pod.go @@ -572,6 +572,7 @@ func addCustomTaskToPod(build *v1.Build, task *v1.UserTask, pod *corev1.Pod) { WorkingDir: filepath.Join(builderDir, build.Name), Env: proxyFromEnvironment(), } + container.Env = append(container.Env, corev1.EnvVar{Name: "INTEGRATION_KIT_IMAGE", Value: task.PublishingImage}) configureResources(task.Name, build, &container) addContainerToPod(build, container, pod) diff --git a/pkg/controller/build/monitor_pod.go b/pkg/controller/build/monitor_pod.go index 31fe5c540..0fcf60a72 100644 --- a/pkg/controller/build/monitor_pod.go +++ b/pkg/controller/build/monitor_pod.go @@ -146,24 +146,20 @@ func (action *monitorPodAction) Handle(ctx context.Context, build *v1.Build) (*v // Account for the Build metrics observeBuildResult(build, build.Status.Phase, buildCreator, duration) - for _, task := range build.Spec.Tasks { - if t := task.Buildah; t != nil { - build.Status.Image = t.Image - - break - } else if t := task.Kaniko; t != nil { - build.Status.Image = t.Image - - break - } - } - // Reconcile image digest from build container status if available - for _, container := range pod.Status.ContainerStatuses { - if container.Name == "buildah" { - build.Status.Digest = container.State.Terminated.Message - - break - } + build.Status.Image = publishTaskImageName(build.Spec.Tasks) + build.Status.Digest = publishTaskDigest(build.Spec.Tasks, pod.Status.ContainerStatuses) + if build.Status.Digest == "" { + // Likely to happen for users provided publishing tasks and not providing the digest image among statuses + build.Status.Phase = v1.BuildPhaseError + build.Status.SetCondition( + "ImageDigestAvailable", + corev1.ConditionFalse, + "ImageDigestAvailable", + fmt.Sprintf( + "%s publishing task completed but no digest is available in container status. Make sure that the process successfully push the image to the registry and write its digest to /dev/termination-log", + publishTaskName(build.Spec.Tasks), + ), + ) } case corev1.PodFailed: @@ -341,3 +337,65 @@ func (action *monitorPodAction) setConditionsFromTerminationMessages(ctx context } } + +// we expect that the last task is any of the supported publishing task +// or a custom user task +func publishTask(tasks []v1.Task) *v1.Task { + if len(tasks) > 0 { + return &tasks[len(tasks)-1] + + } + + return nil +} + +func publishTaskImageName(tasks []v1.Task) string { + t := publishTask(tasks) + if t == nil { + return "" + } + if t.Custom != nil { + return t.Custom.PublishingImage + } else if t.Spectrum != nil { + return t.Spectrum.Image + } else if t.Jib != nil { + return t.Jib.Image + } else if t.Buildah != nil { + return t.Buildah.Image + } else if t.Kaniko != nil { + return t.Kaniko.Image + } + + return "" +} + +func publishTaskName(tasks []v1.Task) string { + t := publishTask(tasks) + if t == nil { + return "" + } + if t.Custom != nil { + return t.Custom.Name + } else if t.Spectrum != nil { + return t.Spectrum.Name + } else if t.Jib != nil { + return t.Jib.Name + } else if t.Buildah != nil { + return t.Buildah.Name + } else if t.Kaniko != nil { + return t.Kaniko.Name + } + + return "" +} + +func publishTaskDigest(tasks []v1.Task, cntStates []corev1.ContainerStatus) string { + taskName := publishTaskName(tasks) + // Reconcile image digest from build container status if available + for _, container := range cntStates { + if container.Name == taskName { + return container.State.Terminated.Message + } + } + return "" +} diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go index 536db4af3..04bba969b 100644 --- a/pkg/resources/resources.go +++ b/pkg/resources/resources.go @@ -117,9 +117,9 @@ var assets = func() http.FileSystem { "/crd/bases/camel.apache.org_builds.yaml": &vfsgen۰CompressedFileInfo{ name: "camel.apache.org_builds.yaml", modTime: time.Time{}, - uncompressedSize: 95394, + uncompressedSize: 95542, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6b\x73\x1b\x37\x96\xe8\x77\xfd\x8a\x53\xf1\x07\xcb\x55\x22\x35\xe3\xc9\xce\x66\x75\x6b\xeb\x96\x56\x4e\x66\x35\x4e\x6c\xaf\x29\x7b\x32\xb5\xb5\x55\x02\xbb\x0f\x49\x84\xdd\x40\x5f\x00\x2d\x9a\xb9\x75\xff\xfb\x2d\xbc\xfa\x21\xb2\xbb\x01\x8a\xb4\x9d\x72\xe3\x4b\x62\xaa\x01\x9c\x83\xc7\x79\xe1\x3c\x9e\xc1\xe4\x78\xed\xec\x19\xfc\x4c\x13\x64\x12\x53\x50\x1c\xd4\x0a\xe1\xba\x20\xc9\x0a\x61\xc6\x17\x6a\x43\x04\xc2\x [...] + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6b\x73\x1b\x37\x96\xe8\x77\xfd\x8a\x53\xf1\x07\xcb\x55\x22\x35\xe3\x64\x67\xb3\xba\xb5\x75\x4b\x2b\x27\xb3\x1a\x27\xb6\xd7\x94\x3d\x99\xda\xda\x2a\x81\xdd\x87\x24\xc2\x6e\xa0\x2f\x80\x16\xcd\xdc\xba\xff\xfd\x16\x5e\xfd\x10\xd9\xdd\x00\x45\xda\x9e\x72\xe3\x4b\x62\xaa\x01\x9c\x83\xc7\x79\xe1\x3c\x9e\xc1\xe4\x78\xed\xec\x19\xfc\x42\x13\x64\x12\x53\x50\x1c\xd4\x0a\xe1\xba\x20\xc9\x0a\x61\xc6\x17\x6a\x43\x04\xc2\x [...] }, "/crd/bases/camel.apache.org_camelcatalogs.yaml": &vfsgen۰CompressedFileInfo{ name: "camel.apache.org_camelcatalogs.yaml", @@ -131,30 +131,30 @@ var assets = func() http.FileSystem { "/crd/bases/camel.apache.org_integrationkits.yaml": &vfsgen۰CompressedFileInfo{ name: "camel.apache.org_integrationkits.yaml", modTime: time.Time{}, - uncompressedSize: 25734, + uncompressedSize: 26227, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3c\x5d\x6f\x1b\xb7\xb2\xef\xfa\x15\x83\xf8\x21\x36\x20\xc9\xed\xb9\x45\x71\xa1\xd3\x5b\xc0\x75\x92\x1e\x9f\x38\x89\xaf\xe5\xb4\x38\x38\x2d\x20\x6a\x77\x24\x31\xda\x25\xb7\x24\x57\xb6\xee\xc7\x7f\xbf\xe0\x90\xdc\x0f\x69\x77\xb5\x96\xe3\xde\xf4\xa0\x7a\x49\xbc\x24\x87\xc3\x99\xe1\x7c\x92\x3c\x81\xd1\xe7\xfb\x0d\x4e\xe0\x9a\x47\x28\x34\xc6\x60\x24\x98\x15\xc2\x45\xc6\xa2\x15\xc2\x54\x2e\xcc\x3d\x53\x08\x6f\x64\x2e\x [...] + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3c\x5d\x6f\xe3\xb6\xb2\xef\xfe\x15\x83\xcd\xc3\x26\x80\xed\xb4\xbd\x45\x71\xe1\xd3\xbb\x40\x9a\xdd\xed\xc9\xd9\xec\x6e\x6e\x9c\x6d\x71\x70\x7a\x00\xd3\xd2\xd8\xe6\x5a\x22\x55\x92\x72\xe2\xfb\xf1\xdf\x2f\x38\x24\xf5\x61\x4b\xb2\xe2\x6c\x7a\xdb\x83\xea\x25\xb1\x44\x0e\x87\x33\xc3\xf9\xe2\x90\x27\x30\xfa\x72\xcf\xe0\x04\xae\x79\x84\x42\x63\x0c\x46\x82\x59\x21\x5c\x64\x2c\x5a\x21\x4c\xe5\xc2\xdc\x33\x85\xf0\x56\xe6\x [...] }, "/crd/bases/camel.apache.org_integrationplatforms.yaml": &vfsgen۰CompressedFileInfo{ name: "camel.apache.org_integrationplatforms.yaml", modTime: time.Time{}, - uncompressedSize: 202778, + uncompressedSize: 203764, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6b\x73\xe3\x36\xb2\xe8\xf7\xfc\x0a\x94\x53\xa7\xc6\x93\xb2\xa4\x99\xdd\x93\x6c\x8e\xcf\xe6\xdc\xeb\x78\x26\x89\x33\x0f\xfb\xda\x9e\xd9\xb3\x95\xa4\x22\x88\x6c\x49\x88\x49\x80\x0b\x80\xb2\x95\xda\x1f\x7f\x0b\x0d\x80\x0f\x49\x04\xa9\x87\x1f\x93\x48\xa9\xda\x1d\x4b\x24\xd0\x68\x34\xfa\x85\x7e\x7c\x4e\x7a\xbb\xfb\x7c\xf6\x39\x79\xcb\x22\xe0\x0a\x62\xa2\x05\xd1\x53\x20\x27\x19\x8d\xa6\x40\xae\xc4\x58\xdf\x52\x09\x [...] + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xfb\x73\xdb\xb6\xb2\xf0\xef\xfd\x2b\x30\xee\xdc\xb1\xd3\xd1\x23\xe9\xb9\x7d\x5c\xdf\xd3\xf3\x7d\xae\x93\xb6\x6e\xe2\xd8\x9f\xed\xe4\xdc\x33\x6d\xa7\x82\xc8\x95\x84\x98\x04\x78\x01\x50\xb6\x3a\xe7\x8f\xff\x06\x0b\x80\xa4\x1e\x04\xa9\x87\x63\xa7\x95\x3a\xd3\xd8\x16\x09\x2c\x16\x8b\x7d\x61\x1f\x9f\x93\xee\xee\x3e\x9f\x7d\x4e\xde\xb0\x08\xb8\x82\x98\x68\x41\xf4\x04\xc8\x49\x46\xa3\x09\x90\x6b\x31\xd2\x77\x54\x02\x [...] }, "/crd/bases/camel.apache.org_integrations.yaml": &vfsgen۰CompressedFileInfo{ name: "camel.apache.org_integrations.yaml", modTime: time.Time{}, - uncompressedSize: 519809, + uncompressedSize: 520302, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\x96\x30\x8c\xff\x9f\x4f\x81\xb2\x53\x8f\xa4\x8d\x48\xd9\x99\xd9\xa9\x1d\xff\xa6\x9e\x94\x56\x96\x13\xfd\x62\xcb\x2a\x49\x49\x9e\x94\x93\x4d\xc0\x6e\x90\xc4\xa3\x6e\xa0\x17\x40\x53\xe2\xbc\x7e\xbf\xfb\x5b\x38\x00\xfa\xc2\x5b\x1f\xb4\x44\xc7\x99\x6d\x4c\x55\xc6\x14\xd9\xa7\x71\x39\x38\xf7\xcb\x73\x32\x7a\xba\xf1\xc5\x73\xf2\x96\x27\x4c\x68\x96\x12\x23\x89\x99\x33\x72\x5a\xd0\x64\xce\xc8\x8d\x9c\x [...] + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\x96\x30\x8c\xff\x9f\x4f\x81\xb2\x53\x8f\xa4\x8d\x48\xd9\x99\xd9\xa9\x1d\xff\xa6\x9e\x94\x56\x96\x13\xfd\x62\xcb\x2a\x49\x49\x9e\x94\x93\x4d\xc0\x6e\x90\xc4\xa3\x6e\xa0\x17\x40\x53\xe2\xbc\x7e\xbf\xfb\x5b\x38\x00\xfa\xc2\x5b\x1f\xb4\x44\xc7\x99\x6d\x4c\x55\xc6\x14\xd9\xa7\x71\x39\x38\xf7\xcb\x73\x32\x7a\xba\xf1\xc5\x73\xf2\x96\x27\x4c\x68\x96\x12\x23\x89\x99\x33\x72\x5a\xd0\x64\xce\xc8\x8d\x9c\x [...] }, "/crd/bases/camel.apache.org_kameletbindings.yaml": &vfsgen۰CompressedFileInfo{ name: "camel.apache.org_kameletbindings.yaml", modTime: time.Time{}, - uncompressedSize: 601461, + uncompressedSize: 601982, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x73\x1b\x37\xb6\x30\x0a\x7f\xf7\xaf\x40\xd9\xa9\x47\xd2\x0e\x49\xd9\x99\x99\xd4\x8c\xdf\xa9\x9d\xd2\xc8\x72\xa2\x37\xb6\xcc\xb2\x94\xe4\x49\x39\xd9\x09\xd8\x0d\x92\xd8\xea\x06\x7a\x00\x34\x25\xe6\xf8\xfc\xf7\x53\x58\x00\xfa\xc2\x9b\xb0\x9a\x92\xc6\x9e\x69\x4c\x55\xc6\xa4\xd8\xab\x71\x59\x58\xf7\xcb\x33\x32\xbc\xbf\xf1\xe4\x19\x79\xc3\x13\x26\x34\x4b\x89\x91\xc4\xcc\x19\x39\x29\x68\x32\x67\xe4\x52\x4e\xcd\x [...] + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x73\x1b\x37\xb6\x30\x0a\x7f\xf7\xaf\x40\xd9\xa9\x47\xd2\x0e\x49\xd9\x99\x99\xd4\x8c\xdf\xa9\x9d\xd2\xc8\x72\xa2\x37\xb6\xcc\xb2\x94\xe4\x49\x39\xd9\x09\xd8\x0d\x92\xd8\xea\x06\x7a\x00\x34\x25\xe6\xf8\xfc\xf7\x53\x58\x00\xfa\xc2\x9b\xb0\x9a\x92\xc6\x9e\x69\x4c\x55\xc6\xa4\xd8\xab\x71\x59\x58\xf7\xcb\x33\x32\xbc\xbf\xf1\xe4\x19\x79\xc3\x13\x26\x34\x4b\x89\x91\xc4\xcc\x19\x39\x29\x68\x32\x67\xe4\x52\x4e\xcd\x [...] }, "/crd/bases/camel.apache.org_kamelets.yaml": &vfsgen۰CompressedFileInfo{ name: "camel.apache.org_kamelets.yaml", @@ -166,14 +166,26 @@ var assets = func() http.FileSystem { "/crd/bases/camel.apache.org_pipes.yaml": &vfsgen۰CompressedFileInfo{ name: "camel.apache.org_pipes.yaml", modTime: time.Time{}, - uncompressedSize: 568839, + uncompressedSize: 569360, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\xb6\x28\x8a\xff\x9f\x4f\x81\x92\x53\x47\xd2\x8e\x48\xd9\x99\x99\xd4\x1e\xff\xa6\x4e\x4a\x5b\x96\x13\xfd\x62\xcb\x2c\x49\x49\x4e\xca\xc9\x4e\xc0\x6e\x90\xc4\x51\x37\xd0\x1b\x40\x53\x62\xae\xef\x77\xbf\x85\x05\xa0\x1f\x7c\x09\xab\x29\x69\xe4\x99\xc6\x54\x65\x4c\x8a\xbd\x1a\x8f\x85\xf5\x7e\xbc\x20\x83\x87\x1b\x5f\xbc\x20\xef\x78\xc2\x84\x66\x29\x31\x92\x98\x19\x23\x27\x05\x4d\x66\x8c\x5c\xc9\x89\x [...] + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\xb6\x28\x8a\xff\x9f\x4f\x81\x92\x53\x47\xd2\x8e\x48\xd9\x99\x99\xd4\x1e\xff\xa6\x4e\x4a\x5b\x96\x13\xfd\x62\xcb\x2c\x49\x49\x4e\xca\xc9\x4e\xc0\x6e\x90\xc4\x51\x37\xd0\x1b\x40\x53\x62\xae\xef\x77\xbf\x85\x05\xa0\x1f\x7c\x09\xab\x29\x69\xe4\x99\xc6\x54\x65\x4c\x8a\xbd\x1a\x8f\x85\xf5\x7e\xbc\x20\x83\x87\x1b\x5f\xbc\x20\xef\x78\xc2\x84\x66\x29\x31\x92\x98\x19\x23\x27\x05\x4d\x66\x8c\x5c\xc9\x89\x [...] }, "/manager": &vfsgen۰DirInfo{ name: "manager", modTime: time.Time{}, }, + "/manager/bundle": &vfsgen۰DirInfo{ + name: "bundle", + modTime: time.Time{}, + }, + "/manager/bundle/manifests": &vfsgen۰DirInfo{ + name: "manifests", + modTime: time.Time{}, + }, + "/manager/bundle/metadata": &vfsgen۰DirInfo{ + name: "metadata", + modTime: time.Time{}, + }, "/manager/operator-deployment.yaml": &vfsgen۰CompressedFileInfo{ name: "operator-deployment.yaml", modTime: time.Time{}, @@ -753,9 +765,9 @@ var assets = func() http.FileSystem { "/traits.yaml": &vfsgen۰CompressedFileInfo{ name: "traits.yaml", modTime: time.Time{}, - uncompressedSize: 73382, + uncompressedSize: 73737, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x6b\x73\x1c\xb9\x91\x00\xf8\x5d\xbf\x02\xd1\x73\x1b\x24\x75\xfd\xa0\xc6\x6b\xef\x2c\xd7\xf2\x1e\x47\xa3\xb1\x69\xbd\x78\x22\x67\xbc\x0e\x9d\xc2\x8d\xae\x42\x77\x43\xac\x06\x6a\x00\x14\xa9\x9e\xdb\xfb\xef\x17\xc8\x4c\x3c\xaa\xba\x9a\xdd\x94\x48\xd9\xda\xf5\x6e\x84\x47\x24\x0b\x40\x22\x91\x48\xe4\x3b\xbf\x61\xa3\xfb\xfb\xbf\x47\xdf\xb0\x97\xb2\x10\xca\x8a\x92\x39\xcd\xdc\x52\xb0\xd3\x9a\x17\x4b\xc1\x2e\xf4\xdc\x [...] + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\xfb\x73\x1c\xb9\x91\x30\xf8\xbb\xfe\x0a\x44\xcf\x7d\x41\x52\xd7\x0f\x4a\xfe\xec\x9d\xe5\x5a\xb3\xc7\xd1\x68\x6c\x7a\xf4\xe0\x89\x9c\xf1\xe7\xd0\x29\xdc\xe8\x2a\x74\x37\xc4\x6a\xa0\x06\x40\x91\xea\xb9\xbd\xff\xfd\x02\x99\x89\x47\x55\x57\xb3\x9b\x12\x29\x5b\xdf\x7a\x37\xc2\x23\x92\x05\x20\x91\x48\x24\xf2\x9d\xdf\xb0\xd1\xfd\xfd\xdf\xa3\x6f\xd8\x4b\x59\x08\x65\x45\xc9\x9c\x66\x6e\x29\xd8\x69\xcd\x8b\xa5\x60\x17\x [...] }, } fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ @@ -800,6 +812,7 @@ var assets = func() http.FileSystem { fs["/crd/bases/camel.apache.org_pipes.yaml"].(os.FileInfo), } fs["/manager"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ + fs["/manager/bundle"].(os.FileInfo), fs["/manager/operator-deployment.yaml"].(os.FileInfo), fs["/manager/operator-service-account.yaml"].(os.FileInfo), fs["/manager/patch-image-pull-policy-always.yaml"].(os.FileInfo), @@ -811,6 +824,10 @@ var assets = func() http.FileSystem { fs["/manager/patch-toleration.yaml"].(os.FileInfo), fs["/manager/patch-watch-namespace-global.yaml"].(os.FileInfo), } + fs["/manager/bundle"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ + fs["/manager/bundle/manifests"].(os.FileInfo), + fs["/manager/bundle/metadata"].(os.FileInfo), + } fs["/prometheus"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ fs["/prometheus/operator-pod-monitor.yaml"].(os.FileInfo), fs["/prometheus/operator-prometheus-rule.yaml"].(os.FileInfo), diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go index 87c3e484d..843deb2e4 100644 --- a/pkg/trait/builder.go +++ b/pkg/trait/builder.go @@ -167,13 +167,18 @@ func (t *builderTrait) Apply(e *Environment) error { if err != nil { return err } + + imageName := getImageName(e) // Building task builderTask, err := t.builderTask(e, taskConfOrDefault(tasksConf, "builder")) if err != nil { - e.IntegrationKit.Status.Phase = v1.IntegrationKitPhaseError - e.IntegrationKit.Status.SetCondition("IntegrationKitPropertiesFormatValid", corev1.ConditionFalse, - "IntegrationKitPropertiesFormatValid", fmt.Sprintf("One or more properties where not formatted as expected: %s", err.Error())) - if err := e.Client.Status().Update(e.Ctx, e.IntegrationKit); err != nil { + if err := failIntegrationKit( + e, + "IntegrationKitPropertiesFormatValid", + corev1.ConditionFalse, + "IntegrationKitPropertiesFormatValid", + fmt.Sprintf("One or more properties where not formatted as expected: %s", err.Error()), + ); err != nil { return err } return nil @@ -188,21 +193,21 @@ func (t *builderTrait) Apply(e *Environment) error { realBuildStrategy = e.Platform.Status.Build.BuildConfiguration.Strategy } if len(t.Tasks) > 0 && realBuildStrategy != v1.BuildStrategyPod { - e.IntegrationKit.Status.Phase = v1.IntegrationKitPhaseError - e.IntegrationKit.Status.SetCondition("IntegrationKitTasksValid", + if err := failIntegrationKit( + e, + "IntegrationKitTasksValid", corev1.ConditionFalse, "IntegrationKitTasksValid", fmt.Sprintf("Pipeline tasks unavailable when using `%s` platform build strategy: use `%s` instead.", realBuildStrategy, v1.BuildStrategyPod), - ) - if err := e.Client.Status().Update(e.Ctx, e.IntegrationKit); err != nil { + ); err != nil { return err } return nil } - customTasks, err := t.customTasks(tasksConf) + customTasks, err := t.customTasks(tasksConf, imageName) if err != nil { return err } @@ -228,7 +233,7 @@ func (t *builderTrait) Apply(e *Environment) error { }, PublishTask: v1.PublishTask{ BaseImage: t.getBaseImage(e), - Image: getImageName(e), + Image: imageName, Registry: e.Platform.Status.Build.Registry, }, }}) @@ -241,7 +246,7 @@ func (t *builderTrait) Apply(e *Environment) error { }, PublishTask: v1.PublishTask{ BaseImage: t.getBaseImage(e), - Image: getImageName(e), + Image: imageName, Registry: e.Platform.Status.Build.Registry, }, }}) @@ -277,7 +282,7 @@ func (t *builderTrait) Apply(e *Environment) error { Configuration: *taskConfOrDefault(tasksConf, "buildah"), }, PublishTask: v1.PublishTask{ - Image: getImageName(e), + Image: imageName, Registry: e.Platform.Status.Build.Registry, }, Verbose: t.Verbose, @@ -301,7 +306,7 @@ func (t *builderTrait) Apply(e *Environment) error { Configuration: *taskConfOrDefault(tasksConf, "kaniko"), }, PublishTask: v1.PublishTask{ - Image: getImageName(e), + Image: imageName, Registry: e.Platform.Status.Build.Registry, }, Cache: v1.KanikoTaskCache{ @@ -317,6 +322,15 @@ func (t *builderTrait) Apply(e *Environment) error { if t.TasksFilter != "" { flt := strings.Split(t.TasksFilter, ",") if pipelineTasks, err = filter(pipelineTasks, flt); err != nil { + if err := failIntegrationKit( + e, + "IntegrationKitTasksValid", + corev1.ConditionFalse, + "IntegrationKitTasksValid", + err.Error(), + ); err != nil { + return err + } return err } } @@ -325,6 +339,16 @@ func (t *builderTrait) Apply(e *Environment) error { return nil } +// when this trait fails, we must report the failure into the related IntegrationKit if it affects the success of the Build. +func failIntegrationKit(e *Environment, conditionType v1.IntegrationKitConditionType, status corev1.ConditionStatus, reason, message string) error { + e.IntegrationKit.Status.Phase = v1.IntegrationKitPhaseError + e.IntegrationKit.Status.SetCondition(conditionType, status, reason, message) + if err := e.Client.Status().Update(e.Ctx, e.IntegrationKit); err != nil { + return err + } + return nil +} + func (t *builderTrait) builderTask(e *Environment, taskConf *v1.BuildConfiguration) (*v1.BuilderTask, error) { maven := v1.MavenBuildSpec{ MavenSpec: e.Platform.Status.Build.Maven, @@ -454,7 +478,7 @@ func (t *builderTrait) getBaseImage(e *Environment) string { return baseImage } -func (t *builderTrait) customTasks(tasksConf map[string]*v1.BuildConfiguration) ([]v1.Task, error) { +func (t *builderTrait) customTasks(tasksConf map[string]*v1.BuildConfiguration, imageName string) ([]v1.Task, error) { customTasks := make([]v1.Task, len(t.Tasks)) for i, t := range t.Tasks { @@ -476,6 +500,7 @@ func (t *builderTrait) customTasks(tasksConf map[string]*v1.BuildConfiguration) Name: splitted[0], Configuration: *taskConfOrDefault(tasksConf, splitted[0]), }, + PublishingImage: imageName, ContainerImage: splitted[1], ContainerCommands: containerCommands, }, @@ -603,5 +628,27 @@ func filter(tasks []v1.Task, filterTasks []string) ([]v1.Task, error) { return nil, fmt.Errorf("no task exist for %s name", f) } } + // make sure the last task is either a publishing task or a custom task + if len(filteredTasks) == 0 || !publishingOrUserTask(filteredTasks[len(filteredTasks)-1]) { + return nil, fmt.Errorf("last pipeline task is not a publishing or a user task") + } return filteredTasks, nil } + +// return true if the task is either a publishing task or a custom user task +func publishingOrUserTask(t v1.Task) bool { + if t.Custom != nil { + return true + } else if t.Spectrum != nil { + return true + } else if t.S2i != nil { + return true + } else if t.Jib != nil { + return true + } else if t.Buildah != nil { + return true + } else if t.Kaniko != nil { + return true + } + return false +} diff --git a/pkg/trait/builder_test.go b/pkg/trait/builder_test.go index 343dc5e31..bb0e66b0d 100644 --- a/pkg/trait/builder_test.go +++ b/pkg/trait/builder_test.go @@ -112,7 +112,16 @@ func createBuilderTestEnv(cluster v1.IntegrationPlatformCluster, strategy v1.Int if err != nil { panic(err) } - client, _ := test.NewFakeClient() + itk := &v1.IntegrationKit{ + Status: v1.IntegrationKitStatus{ + Phase: v1.IntegrationKitPhaseBuildSubmitted, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns", + Name: "my-kit", + }, + } + client, _ := test.NewFakeClient(itk) res := &Environment{ Ctx: context.TODO(), CamelCatalog: c, @@ -127,14 +136,7 @@ func createBuilderTestEnv(cluster v1.IntegrationPlatformCluster, strategy v1.Int Phase: v1.IntegrationPhaseDeploying, }, }, - IntegrationKit: &v1.IntegrationKit{ - Status: v1.IntegrationKitStatus{ - Phase: v1.IntegrationKitPhaseBuildSubmitted, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-kit", - }, - }, + IntegrationKit: itk, Platform: &v1.IntegrationPlatform{ Spec: v1.IntegrationPlatformSpec{ Cluster: cluster, @@ -231,7 +233,8 @@ func TestCustomTaskBuilderTraitInvalidStrategy(t *testing.T) { err := builderTrait.Apply(env) - assert.NotNil(t, err) + // The error will be reported to IntegrationKits + assert.Nil(t, err) assert.Equal(t, env.IntegrationKit.Status.Phase, v1.IntegrationKitPhaseError) assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Status, corev1.ConditionFalse) assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Type, v1.IntegrationKitConditionType("IntegrationKitTasksValid")) @@ -245,7 +248,8 @@ func TestCustomTaskBuilderTraitInvalidStrategyOverride(t *testing.T) { err := builderTrait.Apply(env) - assert.NotNil(t, err) + // The error will be reported to IntegrationKits + assert.Nil(t, err) assert.Equal(t, env.IntegrationKit.Status.Phase, v1.IntegrationKitPhaseError) assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Status, corev1.ConditionFalse) assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Type, v1.IntegrationKitConditionType("IntegrationKitTasksValid")) @@ -285,7 +289,8 @@ func TestInvalidMavenProfilesBuilderTrait(t *testing.T) { err := builderTrait.Apply(env) - assert.NotNil(t, err) + // The error will be reported to IntegrationKits + assert.Nil(t, err) assert.Equal(t, env.IntegrationKit.Status.Phase, v1.IntegrationKitPhaseError) assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Status, corev1.ConditionFalse) assert.Contains(t, env.IntegrationKit.Status.Conditions[0].Message, "fakeprofile") @@ -314,7 +319,7 @@ func TestBuilderCustomTasks(t *testing.T) { builderTrait.Tasks = append(builderTrait.Tasks, "test;alpine;ls") builderTrait.Tasks = append(builderTrait.Tasks, `test;alpine;mvn test`) - tasks, err := builderTrait.customTasks(nil) + tasks, err := builderTrait.customTasks(nil, "my-kit-img") assert.Nil(t, err) assert.Equal(t, 2, len(tasks)) @@ -332,7 +337,7 @@ func TestBuilderCustomTasksFailure(t *testing.T) { builderTrait := createNominalBuilderTraitTest() builderTrait.Tasks = append(builderTrait.Tasks, "test;alpine") - _, err := builderTrait.customTasks(nil) + _, err := builderTrait.customTasks(nil, "my-kit-img") assert.NotNil(t, err) } @@ -341,7 +346,7 @@ func TestBuilderCustomTasksScript(t *testing.T) { builderTrait := createNominalBuilderTraitTest() builderTrait.Tasks = append(builderTrait.Tasks, "test;alpine;/bin/bash -c \"cd test && ls; echo 'helooo'\"") - tasks, err := builderTrait.customTasks(nil) + tasks, err := builderTrait.customTasks(nil, "my-kit-img") assert.Nil(t, err) assert.Equal(t, 1, len(tasks)) @@ -499,26 +504,36 @@ func TestBuilderTasksFilterNotExistingTasks(t *testing.T) { assert.Equal(t, "no task exist for missing-task name", err.Error()) } -func TestBuilderTasksFilterOperatorTasks(t *testing.T) { +func TestBuilderTasksFilterMissingPublishTasks(t *testing.T) { env := createBuilderTestEnv(v1.IntegrationPlatformClusterKubernetes, v1.IntegrationPlatformBuildPublishStrategyJib, v1.BuildStrategyPod) builderTrait := createNominalBuilderTraitTest() builderTrait.TasksFilter = "builder,package" + err := builderTrait.Apply(env) + assert.NotNil(t, err) + assert.Equal(t, "last pipeline task is not a publishing or a user task", err.Error()) +} + +func TestBuilderTasksFilterOperatorTasks(t *testing.T) { + env := createBuilderTestEnv(v1.IntegrationPlatformClusterKubernetes, v1.IntegrationPlatformBuildPublishStrategyJib, v1.BuildStrategyPod) + builderTrait := createNominalBuilderTraitTest() + builderTrait.TasksFilter = "builder,package,jib" + err := builderTrait.Apply(env) assert.Nil(t, err) pipelineTasks := tasksByName(env.Pipeline) - assert.Equal(t, []string{"builder", "package"}, pipelineTasks) + assert.Equal(t, []string{"builder", "package", "jib"}, pipelineTasks) } func TestBuilderTasksFilterAndReorderOperatorTasks(t *testing.T) { env := createBuilderTestEnv(v1.IntegrationPlatformClusterKubernetes, v1.IntegrationPlatformBuildPublishStrategyJib, v1.BuildStrategyPod) builderTrait := createNominalBuilderTraitTest() - builderTrait.TasksFilter = "package,builder" + builderTrait.TasksFilter = "package,builder,jib" err := builderTrait.Apply(env) assert.Nil(t, err) pipelineTasks := tasksByName(env.Pipeline) - assert.Equal(t, []string{"package", "builder"}, pipelineTasks) + assert.Equal(t, []string{"package", "builder", "jib"}, pipelineTasks) } func TestBuilderTasksFilterAndReorderCustomTasks(t *testing.T) { diff --git a/pkg/util/test/client.go b/pkg/util/test/client.go index 9105719eb..081a6733a 100644 --- a/pkg/util/test/client.go +++ b/pkg/util/test/client.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/apache/camel-k/v2/pkg/apis" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/client" camel "github.com/apache/camel-k/v2/pkg/client/camel/clientset/versioned" fakecamelclientset "github.com/apache/camel-k/v2/pkg/client/camel/clientset/versioned/fake" @@ -68,6 +69,7 @@ func NewFakeClient(initObjs ...runtime.Object) (client.Client, error) { }, ). WithRuntimeObjects(initObjs...). + WithStatusSubresource(&v1.IntegrationKit{}). Build() camelClientset := fakecamelclientset.NewSimpleClientset(filterObjects(scheme, initObjs, func(gvk schema.GroupVersionKind) bool { diff --git a/resources/traits.yaml b/resources/traits.yaml index dac366094..a63e521e9 100755 --- a/resources/traits.yaml +++ b/resources/traits.yaml @@ -285,10 +285,10 @@ traits: with format `<name>;<container-image>;<container-command>`. - name: tasks-filter type: string - description: A list of tasks (available only when using `pod` strategy), sorted - by the order of execution in a csv format, ie, `<taskName1>,<taskName2>,...`. - Mind that you must include also the operator tasks (`builder`, `quarkus-native`, - `package`, `jib`, `spectrum`, `s2i`) if you need to execute them. + description: A list of tasks sorted by the order of execution in a csv format, + ie, `<taskName1>,<taskName2>,...`. Mind that you must include also the operator + tasks (`builder`, `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only wih `pod` strategy. - name: tasks-request-cpu type: '[]string' description: A list of request cpu configuration for the specific task with format
