diff --git a/controllers/builder/containerbuilder.go b/controllers/builder/containerbuilder.go index 15918a86f..a3fc344a2 100644 --- a/controllers/builder/containerbuilder.go +++ b/controllers/builder/containerbuilder.go @@ -138,7 +138,7 @@ func (c *containerBuilderManager) scheduleNewKanikoBuildWithContainerFile(build workflowDefinition: workflowDef, workflow: workflow, dockerfile: platform.GetCustomizedDockerfile(c.commonConfig.Data[c.commonConfig.Data[configKeyDefaultBuilderResourceName]], *c.platform), - imageTag: workflowdef.GetWorkflowAppImageNameTag(workflow), + imageTag: buildNamespacedImageTag(workflow), } if c.platform.Spec.Build.Config.Timeout == nil { @@ -199,3 +199,10 @@ func newBuild(buildInput kanikoBuildInput, platform api.PlatformContainerBuild, WithBuildArgs(buildInput.task.BuildArgs). WithEnvs(buildInput.task.Envs).Schedule() } + +// buildNamespacedImageTag For the kaniko build we prepend the namespace to the calculated image name/tag to avoid potential +// collisions if the same workflows is deployed in a different namespace. In OpenShift this last is not needed since the +// ImageStreams are already namespaced. +func buildNamespacedImageTag(workflow *operatorapi.SonataFlow) string { + return workflow.Namespace + "/" + workflowdef.GetWorkflowAppImageNameTag(workflow) +} diff --git a/controllers/workflowdef/image.go b/controllers/workflowdef/image.go index 982cf10ad..760a233e3 100644 --- a/controllers/workflowdef/image.go +++ b/controllers/workflowdef/image.go @@ -20,7 +20,6 @@ package workflowdef import ( - "github.com/apache/incubator-kie-kogito-serverless-operator/api/metadata" "github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08" "github.com/apache/incubator-kie-kogito-serverless-operator/version" ) @@ -33,12 +32,19 @@ const ( defaultOperatorImage = "quay.io/kiegroup/kogito-serverless-operator" ) -// GetWorkflowAppImageNameTag retrieve the tag for the image based on the Workflow based annotation, :latest otherwise +// GetWorkflowAppImageNameTag returns the image name with tag to use for the image to be produced for a given workflow. +// Before, we generated the tags based on the workflow version annotation, however this produced the following undesired +// effects. Empirically, it was detected that, if we deploy a workflow several times, for instance, the workflow is deleted +// for a modification, and then deployed again. When the build cycle is produced, etc., if the workflow version +// remains the same, e.g. 1.0.0, the bits for the new image are not written in the respective registry (because an image +// with the given tag already exists), and thus, when the workflow executes the old bits are executed. +// To avoid this, the workflow version must be changed, for example to 2.0.0, and thus the subsequent image will have +// a different tag, and the expected bits will be stored at the registry and finally executed. +// This workflow version bump must be produced by the users, but we don't have control over this. +// So by now, considering that the operator images build is oriented to "dev" and "preview" scenarios, and +// not for "production" scenarios, we decided to use "latest" as the tag. In that way, we ensure that the last image +// produced bits will be used to execute a given workflow. func GetWorkflowAppImageNameTag(w *v1alpha08.SonataFlow) string { - v := w.Annotations[metadata.Version] - if v != "" { - return w.Name + ":" + v - } return w.Name + ":" + latestImageTag } diff --git a/test/e2e/platform_test.go b/test/e2e/platform_test.go index 49afd5aed..24115567a 100644 --- a/test/e2e/platform_test.go +++ b/test/e2e/platform_test.go @@ -117,9 +117,9 @@ var _ = Describe("Validate the persistence", Ordered, func() { } }, Entry("with both Job Service and Data Index and ephemeral persistence and the workflow in a dev profile", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, ephemeral), - XEntry("with both Job Service and Data Index and ephemeral persistence and the workflow in a production profile", test.GetSonataFlowE2EPlatformServicesDirectory(), production, ephemeral), + Entry("with both Job Service and Data Index and ephemeral persistence and the workflow in a production profile", test.GetSonataFlowE2EPlatformServicesDirectory(), production, ephemeral), Entry("with both Job Service and Data Index and postgreSQL persistence and the workflow in a dev profile", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, postgreSQL), - XEntry("with both Job Service and Data Index and postgreSQL persistence and the workflow in a production profile", test.GetSonataFlowE2EPlatformServicesDirectory(), production, postgreSQL), + Entry("with both Job Service and Data Index and postgreSQL persistence and the workflow in a production profile", test.GetSonataFlowE2EPlatformServicesDirectory(), production, postgreSQL), ) })