From c6a38c3674cf384ee894015231c1ed1d9e13aa32 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Thu, 12 Mar 2020 15:36:13 -0300 Subject: [PATCH] [KOGITO-1294] - Support for binary builds Signed-off-by: Ricardo Zanini --- README.md | 54 ++++- cmd/kogito/command/deploy/deploy_service.go | 55 ++++-- .../command/deploy/deploy_service_test.go | 27 ++- cmd/kogito/command/message/infra.go | 8 - cmd/kogito/command/message/kogitoapp.go | 23 +++ .../crds/app.kiegroup.org_kogitoapps_crd.yaml | 7 +- .../jbpm-quarkus-example-binary-builds.yaml | 10 + deploy/examples/jbpm-quarkus-example.yaml | 2 +- .../app.kiegroup.org_kogitoapps_crd.yaml | 72 +++---- .../app.kiegroup.org_kogitoapps_crd.yaml | 7 +- pkg/apis/app/v1alpha1/kogitoapp_types.go | 28 ++- .../app/v1alpha1/zz_generated.deepcopy.go | 11 +- pkg/apis/app/v1alpha1/zz_generated.openapi.go | 4 +- pkg/client/openshift/buildconfig.go | 10 +- .../kogitoapp/kogitoapp_controller.go | 11 +- .../kogitoapp/kogitoapp_controller_test.go | 4 +- .../kogitoapp/resource/build_config.go | 7 + .../kogitoapp/resource/build_config_binary.go | 37 ++++ .../resource/build_config_runtime.go | 88 +++++---- .../kogitoapp/resource/build_config_s2i.go | 7 +- .../resource/build_config_s2i_test.go | 4 +- .../kogitoapp/resource/build_config_test.go | 12 +- .../resource/deployment_config_test.go | 16 +- .../kogitoapp/resource/requested_resources.go | 63 +++--- .../resource/requested_resources_test.go | 25 ++- .../kogitoapp/resource/resources.go | 16 +- .../kogitoapp/resource/service_test.go | 4 +- .../kogitoapp/status/manage_status.go | 107 ++++++---- .../kogitoapp/status/manage_status_test.go | 186 +++++++++++++----- test/framework/kogitoapp.go | 5 +- 30 files changed, 604 insertions(+), 306 deletions(-) create mode 100644 cmd/kogito/command/message/kogitoapp.go create mode 100644 deploy/examples/jbpm-quarkus-example-binary-builds.yaml create mode 100644 pkg/controller/kogitoapp/resource/build_config_binary.go diff --git a/README.md b/README.md index e74af7291..3db98b469 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ Table of Contents ================= * [Kogito Operator](#kogito-operator) - * [Table of Contents](#table-of-contents) * [Kogito Operator requirements](#kogito-operator-requirements) * [Kogito Operator installation](#kogito-operator-installation) * [Deploying to OpenShift 4.x](#deploying-to-openshift-4x) @@ -18,6 +17,7 @@ Table of Contents * [Deploying to OpenShift 3.11](#deploying-to-openshift-311) * [Kogito Runtimes service deployment](#kogito-runtimes-service-deployment) * [Deploying a new service](#deploying-a-new-service) + * [Binary Builds](#binary-builds) * [Cleaning up a Kogito service deployment](#cleaning-up-a-kogito-service-deployment) * [Native X JVM builds](#native-x-jvm-builds) * [Troubleshooting Kogito Runtimes service deployment](#troubleshooting-kogito-runtimes-service-deployment) @@ -42,6 +42,7 @@ Table of Contents * [For Linux and macOS](#for-linux-and-macos) * [For Windows](#for-windows) * [Building the Kogito CLI from source](#building-the-kogito-cli-from-source) + * [Kogito CLI output format and environment variables](#kogito-cli-output-format-and-environment-variables) * [Deploying a Kogito service from source with the Kogito CLI](#deploying-a-kogito-service-from-source-with-the-kogito-cli) * [Prometheus integration with the Kogito Operator](#prometheus-integration-with-the-kogito-operator) * [Prometheus annotations](#prometheus-annotations) @@ -55,7 +56,7 @@ Table of Contents * [Kogito Operator development](#kogito-operator-development) * [Building the Kogito Operator](#building-the-kogito-operator) * [Deploying to OpenShift 4.x for development purposes](#deploying-to-openshift-4x-for-development-purposes) - * [Running BDD tests](#running-bdd-tests) + * [Running BDD Tests](#running-bdd-tests) * [Running BDD tests with current branch](#running-bdd-tests-with-current-branch) * [Running BDD tests with custom Kogito Build images' version](#running-bdd-tests-with-custom-kogito-build-images-version) * [Running smoke tests](#running-smoke-tests) @@ -139,6 +140,55 @@ Alternatively, you can use the [Kogito CLI](#kogito-cli) to deploy your services $ kogito deploy-service example-quarkus https://github.com/kiegroup/kogito-examples/ --context-dir=drools-quarkus-example ``` +### Binary Builds + +Kogito Operator can configure a build for you that will pull and build your application through the source to image (s2i) +feature (available only on OpenShift). + +Instead of using the cluster to build your entire application, you can upload your Kogito Service application binaries to the +cluster using **binary builds**. To create a new service without a specific Git URL, run the following command: + +```bash +$ kogito deploy-service example-quarkus +``` + +Access your application directory and run the following: + +```bash +$ mvn clean package +``` + +This command produces a target directory that contains all your binary files: + +```bash +$ ls -l target/ + +total 372 +drwxrwxr-x. 4 ricferna ricferna 4096 Mar 10 16:01 classes +-rw-rw-r--. 1 ricferna ricferna 19667 Mar 10 16:01 drools-quarkus-example-8.0.0-SNAPSHOT.jar +-rw-r--r--. 1 ricferna ricferna 311190 Mar 10 16:01 drools-quarkus-example-8.0.0-SNAPSHOT-runner.jar +-rw-rw-r--. 1 ricferna ricferna 14168 Mar 10 16:01 drools-quarkus-example-8.0.0-SNAPSHOT-sources.jar +drwxrwxr-x. 3 ricferna ricferna 4096 Mar 10 16:01 generated-sources +-rw-rw-r--. 1 ricferna ricferna 24 Mar 10 16:01 image_metadata.json +drwxrwxr-x. 2 ricferna ricferna 12288 Mar 10 16:01 lib +drwxrwxr-x. 2 ricferna ricferna 4096 Mar 10 16:01 maven-archiver +drwxrwxr-x. 3 ricferna ricferna 4096 Mar 10 16:01 maven-status +``` + +You can upload the entire directory to the cluster or you might elect only the relevant files: + +1. The `jar` runner and the `lib` directory for Quarkus runtime or just the uber jar if you're using Springboot +2. The `classes/persistence` directory where resides the generated protobuf files. +3. The `image_metadata.json` file, which contains the information about the image that will be built by the s2i feature + +Use the `oc` client to upload and start the image build: + +```bash +oc start-build example-quarkus-binary --from-dir=target +``` +And that's it. In a couple minutes you should have your Kogito Service application up and running using the same binaries +built locally. + ### Cleaning up a Kogito service deployment ```bash diff --git a/cmd/kogito/command/deploy/deploy_service.go b/cmd/kogito/command/deploy/deploy_service.go index 976413a63..cc832fb49 100644 --- a/cmd/kogito/command/deploy/deploy_service.go +++ b/cmd/kogito/command/deploy/deploy_service.go @@ -17,6 +17,7 @@ package deploy import ( "fmt" "github.com/kiegroup/kogito-cloud-operator/cmd/kogito/command/context" + "github.com/kiegroup/kogito-cloud-operator/cmd/kogito/command/message" "github.com/kiegroup/kogito-cloud-operator/cmd/kogito/command/shared" "github.com/kiegroup/kogito-cloud-operator/pkg/apis/app/v1alpha1" "github.com/kiegroup/kogito-cloud-operator/pkg/client/kubernetes" @@ -83,12 +84,13 @@ func (i *deployCommand) Command() *cobra.Command { func (i *deployCommand) RegisterHook() { i.command = &cobra.Command{ - Use: "deploy-service NAME SOURCE", + Use: "deploy-service NAME [SOURCE]", Short: "Deploys a new Kogito Runtime Service into the given Project", Aliases: []string{"deploy"}, - Long: `deploy-service will create a new Kogito Runtime Service from source in the Project context. + Long: `deploy-service will create a new Kogito Runtime Service in the Project context. + If the source is provided, the build will take place on the cluster, otherwise you must upload the application binaries via "oc start-build [NAME-binary] --from-dir=target". Project context is the namespace (Kubernetes) or project (OpenShift) where the Service will be deployed. - To know what's your context, use "kogito use-project". To set a new Project in the context use "kogito use-project NAME". + To know what's your context, use "kogito project". To set a new Project in the context use "kogito use-project NAME". Please note that this command requires the Kogito Operator installed in the cluster. For more information about the Kogito Operator installation please refer to https://github.com/kiegroup/kogito-cloud-operator#kogito-operator-installation. @@ -98,11 +100,13 @@ func (i *deployCommand) RegisterHook() { PostRun: i.CommonPostRun, // Args validation Args: func(cmd *cobra.Command, args []string) error { - if len(args) != 2 { - return fmt.Errorf("requires 2 args, received %v", len(args)) + if len(args) > 2 { + return fmt.Errorf("requires 1 arg, received %v", len(args)) } - if _, err := url.ParseRequestURI(args[1]); err != nil { - return fmt.Errorf("source is not a valid URL, received %s", args[1]) + if len(args) > 1 { + if _, err := url.ParseRequestURI(args[1]); err != nil { + return fmt.Errorf("source is not a valid URL, received %s", args[1]) + } } if err := util.ParseStringsForKeyPair(i.flags.buildEnv); err != nil { return fmt.Errorf("build environment variables are in the wrong format. Valid are key pairs like 'env=value', received %s", i.flags.buildEnv) @@ -161,11 +165,14 @@ func (i *deployCommand) InitHook() { i.command.Flags().BoolVar(&i.flags.enableIstio, "enable-istio", false, "Enable Istio integration by annotating the Kogito service pods with the right value for Istio controller to inject sidecars on it. Defaults to false") } -func (i *deployCommand) Exec(cmd *cobra.Command, args []string) error { +func (i *deployCommand) Exec(cmd *cobra.Command, args []string) (err error) { log := context.GetDefaultLogger() i.flags.name = args[0] - i.flags.source = args[1] - var err error + hasSource := false + if len(args) > 1 { + i.flags.source = args[1] + hasSource = true + } if len(i.flags.mavenMirrorURL) > 0 { if _, err := url.ParseRequestURI(i.flags.mavenMirrorURL); err != nil { @@ -204,13 +211,8 @@ func (i *deployCommand) Exec(cmd *cobra.Command, args []string) error { Replicas: &i.flags.Replicas, Runtime: v1alpha1.RuntimeType(i.flags.runtime), Build: &v1alpha1.KogitoAppBuildObject{ - Incremental: i.flags.incrementalBuild, - Env: shared.FromStringArrayToControllerEnvs(i.flags.buildEnv), - GitSource: &v1alpha1.GitSource{ - URI: &i.flags.source, - ContextDir: i.flags.contextDir, - Reference: i.flags.reference, - }, + Incremental: i.flags.incrementalBuild, + Env: shared.FromStringArrayToControllerEnvs(i.flags.buildEnv), ImageS2ITag: i.flags.imageS2I, ImageRuntimeTag: i.flags.imageRuntime, ImageVersion: i.flags.imageVersion, @@ -237,16 +239,27 @@ func (i *deployCommand) Exec(cmd *cobra.Command, args []string) error { }, } + if hasSource { + kogitoApp.Spec.Build.GitSource = v1alpha1.GitSource{ + URI: i.flags.source, + ContextDir: i.flags.contextDir, + Reference: i.flags.reference, + } + } + log.Debugf("Trying to deploy Kogito Service '%s'", kogitoApp.Name) // Create the Kogito application if err := kubernetes.ResourceC(i.Client).Create(kogitoApp); err != nil { return fmt.Errorf("Error while creating a new KogitoApp in the context: %v ", err) } - log.Infof("KogitoApp '%s' successfully created on namespace '%s'", kogitoApp.Name, kogitoApp.Namespace) - // TODO: We should provide this info with a -f flag - log.Infof("You can see the deployment status by using 'oc describe %s %s -n %s'", "kogitoapp", i.flags.name, i.flags.Project) - log.Infof("Your Kogito Runtime Service should be deploying. To see its logs, run 'oc logs -f bc/%s-builder -n %s'", i.flags.name, i.flags.Project) + log.Infof(message.KogitoAppSuccessfullyCreated, kogitoApp.Name, kogitoApp.Namespace) + if hasSource { + log.Infof(message.KogitoAppViewDeploymentStatus, i.flags.name, i.flags.Project) + log.Infof(message.KogitoAppViewBuildStatus, i.flags.name, i.flags.Project) + } else { + log.Infof(message.KogitoAppUploadBinariesInstruction, i.flags.name, i.flags.Project) + } return nil } diff --git a/cmd/kogito/command/deploy/deploy_service_test.go b/cmd/kogito/command/deploy/deploy_service_test.go index e9c7c21cd..a5372178d 100644 --- a/cmd/kogito/command/deploy/deploy_service_test.go +++ b/cmd/kogito/command/deploy/deploy_service_test.go @@ -29,7 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func Test_DeployCmd_OperatorAutoInstal(t *testing.T) { +func Test_DeployCmd_OperatorAutoInstall(t *testing.T) { ns := t.Name() cli := fmt.Sprintf("deploy-service example-drools https://github.com/kiegroup/kogito-examples --context-dir drools-quarkus-example --project %s", ns) test.SetupCliTest(cli, @@ -149,3 +149,28 @@ func Test_DeployCmd_WithInvalidMavenMirrorURL(t *testing.T) { _, _, err := test.ExecuteCli() assert.Error(t, err) } + +func Test_DeployCmd_WithoutGitURL(t *testing.T) { + ns := t.Name() + cli := fmt.Sprintf("deploy-service example-drools -p %s", ns) + test.SetupCliTest(cli, + context.CommandFactory{BuildCommands: BuildCommands}, + &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: ns}}, + &apiextensionsv1beta1.CustomResourceDefinition{ObjectMeta: metav1.ObjectMeta{Name: v1alpha1.KogitoAppCRDName}}) + lines, _, err := test.ExecuteCli() + assert.NoError(t, err) + assert.Contains(t, lines, "example-drools") + assert.Contains(t, lines, "-binary") + assert.NotContains(t, lines, "deploying") +} + +func Test_DeployCmd_WrongGitURL(t *testing.T) { + ns := t.Name() + cli := fmt.Sprintf("deploy-service example-drools invalid url -p %s", ns) + test.SetupCliTest(cli, + context.CommandFactory{BuildCommands: BuildCommands}, + &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: ns}}, + &apiextensionsv1beta1.CustomResourceDefinition{ObjectMeta: metav1.ObjectMeta{Name: v1alpha1.KogitoAppCRDName}}) + _, _, err := test.ExecuteCli() + assert.Error(t, err) +} diff --git a/cmd/kogito/command/message/infra.go b/cmd/kogito/command/message/infra.go index 323c27bf1..ba6b61920 100644 --- a/cmd/kogito/command/message/infra.go +++ b/cmd/kogito/command/message/infra.go @@ -16,20 +16,12 @@ package message // Messages for Infrastructure components const ( - KogitoInfraErrCreating = "Error while trying to create a new Kogito Infra: %s " - - InfinispanErrInstalling = "Error while trying to install Infinispan: %s " InfinispanSuccessfulInstalled = "Infinispan has been successfully installed in the Project %s." - InfinispanErrRemoving = "Error while trying to remove Infinispan: %s " InfinispanSuccessfulRemoved = "Infinispan has been successfully removed from the Project %s." - KafkaErrInstalling = "Error while trying to install Kafka: %s " KafkaSuccessfulInstalled = "Kafka has been successfully installed in the Project %s." - KafkaErrRemoving = "Error while trying to remove Kafka: %s " KafkaSuccessfulRemoved = "Kafka has been successfully removed from the Project %s." - KeycloakErrInstalling = "Error while trying to install Keycloak: %s " KeycloakSuccessfulInstalled = "Keycloak has been successfully installed in the Project %s." - KeycloakErrRemoving = "Error while trying to remove Keycloak: %s " KeycloakSuccessfulRemoved = "Keycloak has been successfully removed from the Project %s." ) diff --git a/cmd/kogito/command/message/kogitoapp.go b/cmd/kogito/command/message/kogitoapp.go new file mode 100644 index 000000000..a01add5db --- /dev/null +++ b/cmd/kogito/command/message/kogitoapp.go @@ -0,0 +1,23 @@ +// Copyright 2020 Red Hat, Inc. and/or its affiliates +// +// Licensed 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 message + +// Messages for KogitoApp deployment +const ( + KogitoAppSuccessfullyCreated = "KogitoApp '%s' successfully created on namespace '%s'" + KogitoAppViewDeploymentStatus = "You can see the deployment status by using 'oc describe kogitoapp %s -n %s'" + KogitoAppViewBuildStatus = "Your Kogito Runtime Service should be deploying. To see its logs, run 'oc logs -f bc/%s-builder -n %s'" + KogitoAppUploadBinariesInstruction = "Your Kogito Runtime Service needs the application binaries to proceed. To upload your binaries please run 'oc start-build %s-binary --from-dir=target -n %s' from your project's root" +) diff --git a/deploy/crds/app.kiegroup.org_kogitoapps_crd.yaml b/deploy/crds/app.kiegroup.org_kogitoapps_crd.yaml index 0c0384801..b6eab59c2 100644 --- a/deploy/crds/app.kiegroup.org_kogitoapps_crd.yaml +++ b/deploy/crds/app.kiegroup.org_kogitoapps_crd.yaml @@ -47,8 +47,9 @@ spec: type: object type: array gitSource: - description: GitSource Git coordinates to locate the source code - to build + description: Information about the git repository where the Kogito + App source code resides. If set, the operator will use source + to image strategy build. properties: contextDir: description: Context/subdirectory where the code is located, @@ -149,8 +150,6 @@ spec: type: string type: object type: array - required: - - gitSource type: object enableIstio: description: Annotates the pods managed by the operator with the required diff --git a/deploy/examples/jbpm-quarkus-example-binary-builds.yaml b/deploy/examples/jbpm-quarkus-example-binary-builds.yaml new file mode 100644 index 000000000..abcc0c9e5 --- /dev/null +++ b/deploy/examples/jbpm-quarkus-example-binary-builds.yaml @@ -0,0 +1,10 @@ +apiVersion: app.kiegroup.org/v1alpha1 +kind: KogitoApp +metadata: + name: example-quarkus-flash +spec: + # you only need to inform the correct image tag if you wish to build from a custom image + build: + imageVersion: 0.8.0-rc3 # will use it as a reference to create the imagestreams that the Operator uses + imageRuntimeTag: quay.io/ricardozanini/kogito-quarkus-jvm-ubi8:0.8.0-rc4 # custom image used by runtime/binary builds + # run this from your terminal on your project's root: oc start-build example-quarkus-flash-binary --from-dir=target \ No newline at end of file diff --git a/deploy/examples/jbpm-quarkus-example.yaml b/deploy/examples/jbpm-quarkus-example.yaml index 2f09cffb7..55c155bc1 100644 --- a/deploy/examples/jbpm-quarkus-example.yaml +++ b/deploy/examples/jbpm-quarkus-example.yaml @@ -13,4 +13,4 @@ spec: uri: 'https://github.com/kiegroup/kogito-examples' imageVersion: 0.8.0 # set your maven nexus repository - #mavenMirrorURL: http://nexus3-nexus.apps-crc.testing/repository/maven-public/ \ No newline at end of file + mavenMirrorURL: http://nexus3-nexus.apps-crc.testing/repository/maven-public/ \ No newline at end of file diff --git a/deploy/olm-catalog/kogito-operator/0.8.0/app.kiegroup.org_kogitoapps_crd.yaml b/deploy/olm-catalog/kogito-operator/0.8.0/app.kiegroup.org_kogitoapps_crd.yaml index 0c0384801..505cbc137 100644 --- a/deploy/olm-catalog/kogito-operator/0.8.0/app.kiegroup.org_kogitoapps_crd.yaml +++ b/deploy/olm-catalog/kogito-operator/0.8.0/app.kiegroup.org_kogitoapps_crd.yaml @@ -61,7 +61,7 @@ spec: description: Git URI for the s2i source type: string required: - - uri + - uri type: object imageRuntimeTag: description: Custom image used by the source to image process to @@ -102,15 +102,15 @@ spec: resource: description: Resource type like CPU and memory enum: - - cpu - - memory + - cpu + - memory type: string value: description: Value of this resource in Kubernetes format type: string required: - - resource - - value + - resource + - value type: object type: array requests: @@ -121,15 +121,15 @@ spec: resource: description: Resource type like CPU and memory enum: - - cpu - - memory + - cpu + - memory type: string value: description: Value of this resource in Kubernetes format type: string required: - - resource - - value + - resource + - value type: object type: array type: object @@ -144,13 +144,13 @@ spec: type: description: WebHook type, either GitHub or Generic enum: - - GitHub - - Generic + - GitHub + - Generic type: string type: object type: array required: - - gitSource + - gitSource type: object enableIstio: description: Annotates the pods managed by the operator with the required @@ -187,9 +187,9 @@ spec: Default to ''Auto'', which means it installs Infinispan if the service requires persistence.' enum: - - Always - - Never - - Auto + - Always + - Never + - Auto type: string installKafka: description: 'Set to ''Always'' to have Kafka installed automatically @@ -198,8 +198,8 @@ spec: the Kogito Service container via an environment variable named "KAFKA_BOOTSTRAP_SERVERS" e.g.: kafka-kogito:9092 Default to ''Never''' enum: - - Always - - Never + - Always + - Never type: string type: object replicas: @@ -220,15 +220,15 @@ spec: resource: description: Resource type like CPU and memory enum: - - cpu - - memory + - cpu + - memory type: string value: description: Value of this resource in Kubernetes format type: string required: - - resource - - value + - resource + - value type: object type: array requests: @@ -238,15 +238,15 @@ spec: resource: description: Resource type like CPU and memory enum: - - cpu - - memory + - cpu + - memory type: string value: description: Value of this resource in Kubernetes format type: string required: - - resource - - value + - resource + - value type: object type: array type: object @@ -254,8 +254,8 @@ spec: description: 'The name of the runtime used, either Quarkus or Springboot Default value: quarkus' enum: - - quarkus - - springboot + - quarkus + - springboot type: string service: description: 'Kubernetes Service configuration Default value: nil' @@ -267,7 +267,7 @@ spec: type: object type: object required: - - build + - build type: object status: description: KogitoAppStatus defines the observed state of KogitoApp @@ -330,8 +330,8 @@ spec: description: ConditionType is the type of condition type: string required: - - status - - type + - status + - type type: object type: array deployments: @@ -362,13 +362,13 @@ spec: description: External URL for the service type: string required: - - builds - - conditions - - deployments + - builds + - conditions + - deployments type: object type: object version: v1alpha1 versions: - - name: v1alpha1 - served: true - storage: true + - name: v1alpha1 + served: true + storage: true diff --git a/deploy/olm-catalog/kogito-operator/0.9.0/app.kiegroup.org_kogitoapps_crd.yaml b/deploy/olm-catalog/kogito-operator/0.9.0/app.kiegroup.org_kogitoapps_crd.yaml index 0c0384801..b6eab59c2 100644 --- a/deploy/olm-catalog/kogito-operator/0.9.0/app.kiegroup.org_kogitoapps_crd.yaml +++ b/deploy/olm-catalog/kogito-operator/0.9.0/app.kiegroup.org_kogitoapps_crd.yaml @@ -47,8 +47,9 @@ spec: type: object type: array gitSource: - description: GitSource Git coordinates to locate the source code - to build + description: Information about the git repository where the Kogito + App source code resides. If set, the operator will use source + to image strategy build. properties: contextDir: description: Context/subdirectory where the code is located, @@ -149,8 +150,6 @@ spec: type: string type: object type: array - required: - - gitSource type: object enableIstio: description: Annotates the pods managed by the operator with the required diff --git a/pkg/apis/app/v1alpha1/kogitoapp_types.go b/pkg/apis/app/v1alpha1/kogitoapp_types.go index daf8ff2a2..3db0756f0 100644 --- a/pkg/apis/app/v1alpha1/kogitoapp_types.go +++ b/pkg/apis/app/v1alpha1/kogitoapp_types.go @@ -70,6 +70,25 @@ type KogitoAppSpec struct { EnableIstio bool `json:"enableIstio,omitempty"` } +// GetBuild ... +func (k *KogitoAppSpec) GetBuild() *KogitoAppBuildObject { + if k == nil { + return nil + } + return k.Build +} + +// IsGitURIEmpty checks if the provided Git URI is empty or not +func (k *KogitoAppSpec) IsGitURIEmpty() bool { + if k == nil { + return true + } + if k.Build == nil || &k.Build.GitSource == nil { + return true + } + return len(k.Build.GitSource.URI) == 0 +} + // Resources Data to define Resources needed for each deployed pod // +k8s:openapi-gen=true type Resources struct { @@ -120,8 +139,11 @@ type KogitoAppBuildObject struct { // +listMapKey=name // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="Build Env Variables" - Env []Env `json:"env,omitempty"` - GitSource *GitSource `json:"gitSource"` + Env []Env `json:"env,omitempty"` + // Information about the git repository where the Kogito App source code resides. + // If set, the operator will use source to image strategy build. + // +optional + GitSource GitSource `json:"gitSource,omitempty"` // WebHook secrets for build configs // +listType=map // +listMapKey=type @@ -164,7 +186,7 @@ type GitSource struct { // Git URI for the s2i source // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="Git URI" - URI *string `json:"uri"` + URI string `json:"uri"` // Branch to use in the Git repository // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="Git Reference" diff --git a/pkg/apis/app/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/app/v1alpha1/zz_generated.deepcopy.go index 2e8a65a91..7f55fc314 100644 --- a/pkg/apis/app/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/app/v1alpha1/zz_generated.deepcopy.go @@ -169,11 +169,6 @@ func (in *Env) DeepCopy() *Env { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GitSource) DeepCopyInto(out *GitSource) { *out = *in - if in.URI != nil { - in, out := &in.URI, &out.URI - *out = new(string) - **out = **in - } return } @@ -363,11 +358,7 @@ func (in *KogitoAppBuildObject) DeepCopyInto(out *KogitoAppBuildObject) { *out = make([]Env, len(*in)) copy(*out, *in) } - if in.GitSource != nil { - in, out := &in.GitSource, &out.GitSource - *out = new(GitSource) - (*in).DeepCopyInto(*out) - } + out.GitSource = in.GitSource if in.Webhooks != nil { in, out := &in.Webhooks, &out.Webhooks *out = make([]WebhookSecret, len(*in)) diff --git a/pkg/apis/app/v1alpha1/zz_generated.openapi.go b/pkg/apis/app/v1alpha1/zz_generated.openapi.go index 698adc704..494d4fcf4 100644 --- a/pkg/apis/app/v1alpha1/zz_generated.openapi.go +++ b/pkg/apis/app/v1alpha1/zz_generated.openapi.go @@ -527,7 +527,8 @@ func schema_pkg_apis_app_v1alpha1_KogitoAppBuildObject(ref common.ReferenceCallb }, "gitSource": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/kiegroup/kogito-cloud-operator/pkg/apis/app/v1alpha1.GitSource"), + Description: "Information about the git repository where the Kogito App source code resides. If set, the operator will use source to image strategy build.", + Ref: ref("github.com/kiegroup/kogito-cloud-operator/pkg/apis/app/v1alpha1.GitSource"), }, }, "webhooks": { @@ -591,7 +592,6 @@ func schema_pkg_apis_app_v1alpha1_KogitoAppBuildObject(ref common.ReferenceCallb }, }, }, - Required: []string{"gitSource"}, }, }, Dependencies: []string{ diff --git a/pkg/client/openshift/buildconfig.go b/pkg/client/openshift/buildconfig.go index 988f8d716..8d0cfcd69 100644 --- a/pkg/client/openshift/buildconfig.go +++ b/pkg/client/openshift/buildconfig.go @@ -36,7 +36,7 @@ type BuildState struct { // BuildConfigInterface exposes OpenShift BuildConfig operations type BuildConfigInterface interface { - EnsureImageBuild(bc *buildv1.BuildConfig, labelSelector string) (BuildState, error) + EnsureImageBuild(bc *buildv1.BuildConfig, labelSelector, imageName string) (BuildState, error) TriggerBuild(bc *buildv1.BuildConfig, triggedBy string) (bool, error) GetBuildsStatus(bc *buildv1.BuildConfig, labelSelector string) (*v1alpha1.Builds, error) } @@ -54,15 +54,15 @@ type buildConfig struct { // EnsureImageBuild checks for the corresponding image for the build and retrieves the status of the builds. // Returns a BuildState structure describing it's results. Label selector is used to query for the right bc -func (b *buildConfig) EnsureImageBuild(bc *buildv1.BuildConfig, labelSelector string) (BuildState, error) { +func (b *buildConfig) EnsureImageBuild(bc *buildv1.BuildConfig, labelSelector, imageName string) (BuildState, error) { state := BuildState{ ImageExists: false, } - bcNamed := types.NamespacedName{ - Name: bc.Name, + imageNamed := types.NamespacedName{ + Name: imageName, Namespace: bc.Namespace, } - if img, err := ImageStreamC(b.client).FetchDockerImage(bcNamed); err != nil { + if img, err := ImageStreamC(b.client).FetchDockerImage(imageNamed); err != nil { return state, err } else if img == nil { log.Debugf("ImageStream not found for build %s", bc.Name) diff --git a/pkg/controller/kogitoapp/kogitoapp_controller.go b/pkg/controller/kogitoapp/kogitoapp_controller.go index 8b59d9ac5..cc8617e5e 100644 --- a/pkg/controller/kogitoapp/kogitoapp_controller.go +++ b/pkg/controller/kogitoapp/kogitoapp_controller.go @@ -298,9 +298,11 @@ func (r *ReconcileKogitoApp) triggerBuilds(instance *v1alpha1.KogitoApp, bcs ... } } else { for _, bc := range bcs { - log.Infof("Buildconfigs are created, triggering build %s", bc.GetName()) - if _, err := openshift.BuildConfigC(r.client).TriggerBuild(bc, instance.Name); err != nil { - return err + if bc.Labels[kogitores.LabelKeyBuildVariant] == string(kogitores.BuildVariantSource) { + log.Infof("Buildconfigs are created, triggering build %s", bc.GetName()) + if _, err := openshift.BuildConfigC(r.client).TriggerBuild(bc, instance.Name); err != nil { + return err + } } } } @@ -493,6 +495,9 @@ func getKubernetesResources(kogitoRes *kogitores.KogitoAppResources) []utilsres. if kogitoRes.BuildConfigRuntime != nil { k8sRes = append(k8sRes, kogitoRes.BuildConfigRuntime) } + if kogitoRes.BuildConfigBinary != nil { + k8sRes = append(k8sRes, kogitoRes.BuildConfigBinary) + } if kogitoRes.ImageStreamS2I != nil { k8sRes = append(k8sRes, kogitoRes.ImageStreamS2I) } diff --git a/pkg/controller/kogitoapp/kogitoapp_controller_test.go b/pkg/controller/kogitoapp/kogitoapp_controller_test.go index 539f54411..8ff22ed34 100644 --- a/pkg/controller/kogitoapp/kogitoapp_controller_test.go +++ b/pkg/controller/kogitoapp/kogitoapp_controller_test.go @@ -75,8 +75,8 @@ var ( }, Build: &v1alpha1.KogitoAppBuildObject{ Native: false, - GitSource: &v1alpha1.GitSource{ - URI: &gitURL, + GitSource: v1alpha1.GitSource{ + URI: gitURL, ContextDir: "jbpm-quarkus-example", }, }, diff --git a/pkg/controller/kogitoapp/resource/build_config.go b/pkg/controller/kogitoapp/resource/build_config.go index f30ffe90c..e4edb9f49 100644 --- a/pkg/controller/kogitoapp/resource/build_config.go +++ b/pkg/controller/kogitoapp/resource/build_config.go @@ -23,6 +23,7 @@ import ( // buildType which build can we perform? Supported are s2i and service type buildType string +type buildVariant string const ( // BuildTypeS2I source to image build type will take a source code and transform it into an executable service @@ -33,6 +34,12 @@ const ( BuildTypeRuntimeJvm buildType = "runtime-jvm" // LabelKeyBuildType is the label key to identify the build type LabelKeyBuildType = "buildtype" + // BuildVariantSource ... + BuildVariantSource buildVariant = "source" + // BuildVariantBinary ... + BuildVariantBinary buildVariant = "binary" + // LabelKeyBuildVariant describes the build variant + LabelKeyBuildVariant = "buildvariant" ) const ( diff --git a/pkg/controller/kogitoapp/resource/build_config_binary.go b/pkg/controller/kogitoapp/resource/build_config_binary.go new file mode 100644 index 000000000..96ba574d5 --- /dev/null +++ b/pkg/controller/kogitoapp/resource/build_config_binary.go @@ -0,0 +1,37 @@ +// Copyright 2020 Red Hat, Inc. and/or its affiliates +// +// Licensed 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 resource + +import ( + "fmt" + "github.com/kiegroup/kogito-cloud-operator/pkg/apis/app/v1alpha1" + buildv1 "github.com/openshift/api/build/v1" + v1 "k8s.io/api/core/v1" +) + +const ( + binaryBuildEnv = "BINARY_BUILD" +) + +func newBuildConfigRuntimeBinary(kogitoApp *v1alpha1.KogitoApp) (buildConfig buildv1.BuildConfig) { + buildConfig = getBCRuntime(kogitoApp, fmt.Sprintf("%s-%s", kogitoApp.Name, BuildVariantBinary), BuildVariantBinary) + buildConfig.Spec.Source.Type = buildv1.BuildSourceBinary + buildConfig.Spec.Strategy.SourceStrategy.Env = append(buildConfig.Spec.Strategy.SourceStrategy.Env, v1.EnvVar{Name: binaryBuildEnv, Value: "true"}) + // The comparator hits reconciliation if this are not set to empty values. TODO: fix on the operator-utils project + buildConfig.Spec.Source.Binary = &buildv1.BinaryBuildSource{AsFile: ""} + buildConfig.Spec.Triggers = []buildv1.BuildTriggerPolicy{} + + return buildConfig +} diff --git a/pkg/controller/kogitoapp/resource/build_config_runtime.go b/pkg/controller/kogitoapp/resource/build_config_runtime.go index fc3736a18..5fa0ebd07 100644 --- a/pkg/controller/kogitoapp/resource/build_config_runtime.go +++ b/pkg/controller/kogitoapp/resource/build_config_runtime.go @@ -17,9 +17,9 @@ package resource import ( "errors" "fmt" + "github.com/kiegroup/kogito-cloud-operator/pkg/client/meta" v1alpha1 "github.com/kiegroup/kogito-cloud-operator/pkg/apis/app/v1alpha1" - "github.com/kiegroup/kogito-cloud-operator/pkg/client/meta" buildv1 "github.com/openshift/api/build/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -37,36 +37,12 @@ func newBuildConfigRuntime(kogitoApp *v1alpha1.KogitoApp, fromBuild *buildv1.Bui return buildConfig, err } - buildType := BuildTypeRuntime - if kogitoApp.Spec.Runtime == v1alpha1.QuarkusRuntimeType && !kogitoApp.Spec.Build.Native { - buildType = BuildTypeRuntimeJvm - } - - // headers and base information - buildConfig = buildv1.BuildConfig{ - ObjectMeta: metav1.ObjectMeta{ - Name: kogitoApp.Name, - Namespace: kogitoApp.Namespace, - Labels: map[string]string{ - LabelKeyBuildType: string(buildType), - }, - }, - } - - buildConfig.Spec.Output.To = &corev1.ObjectReference{Kind: kindImageStreamTag, Name: fmt.Sprintf("%s:%s", kogitoApp.Name, tagLatest)} - setBCRuntimeSource(&buildConfig, fromBuild) - setBCRuntimeStrategy(kogitoApp, &buildConfig, buildType) - setBCRuntimeTriggers(&buildConfig, fromBuild) - meta.SetGroupVersionKind(&buildConfig.TypeMeta, meta.KindBuildConfig) - addDefaultMeta(&buildConfig.ObjectMeta, kogitoApp) - return buildConfig, err -} - -func setBCRuntimeSource(buildConfig *buildv1.BuildConfig, fromBuildConfig *buildv1.BuildConfig) { + buildConfig = getBCRuntime(kogitoApp, kogitoApp.Name, BuildVariantSource) + // source is the image produced by the s2i BuildConfig buildConfig.Spec.Source.Type = buildv1.BuildSourceImage buildConfig.Spec.Source.Images = []buildv1.ImageSource{ { - From: *fromBuildConfig.Spec.Output.To, + From: *fromBuild.Spec.Output.To, Paths: []buildv1.ImageSourcePath{ { DestinationDir: destinationDir, @@ -75,25 +51,51 @@ func setBCRuntimeSource(buildConfig *buildv1.BuildConfig, fromBuildConfig *build }, }, } -} - -func setBCRuntimeStrategy(kogitoApp *v1alpha1.KogitoApp, buildConfig *buildv1.BuildConfig, buildType buildType) { - imageName := resolveImageStreamTagNameForBuilds(kogitoApp, kogitoApp.Spec.Build.ImageRuntimeTag, buildType) - buildConfig.Spec.Strategy.Type = buildv1.SourceBuildStrategyType - buildConfig.Spec.Strategy.SourceStrategy = &buildv1.SourceBuildStrategy{ - From: corev1.ObjectReference{ - Name: imageName, - Namespace: kogitoApp.Namespace, - Kind: kindImageStreamTag, + // triggers once we have a change in the s2i produced image + buildConfig.Spec.Triggers = []buildv1.BuildTriggerPolicy{ + { + Type: buildv1.ImageChangeBuildTriggerType, + ImageChange: &buildv1.ImageChangeTrigger{From: fromBuild.Spec.Output.To}, }, } + + return buildConfig, nil } -func setBCRuntimeTriggers(buildConfig *buildv1.BuildConfig, fromBuildConfig *buildv1.BuildConfig) { - buildConfig.Spec.Triggers = []buildv1.BuildTriggerPolicy{ - { - Type: buildv1.ImageChangeBuildTriggerType, - ImageChange: &buildv1.ImageChangeTrigger{From: fromBuildConfig.Spec.Output.To}, +func getBCRuntime(kogitoApp *v1alpha1.KogitoApp, bcName string, variant buildVariant) buildv1.BuildConfig { + buildType := BuildTypeRuntime + if kogitoApp.Spec.Runtime == v1alpha1.QuarkusRuntimeType && !kogitoApp.Spec.Build.Native { + buildType = BuildTypeRuntimeJvm + } + buildConfig := buildv1.BuildConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: bcName, + Namespace: kogitoApp.Namespace, + Labels: map[string]string{ + LabelKeyBuildType: string(buildType), + LabelKeyBuildVariant: string(variant), + }, + }, + Spec: buildv1.BuildConfigSpec{ + CommonSpec: buildv1.CommonSpec{ + Output: buildv1.BuildOutput{ + To: &corev1.ObjectReference{Kind: kindImageStreamTag, Name: fmt.Sprintf("%s:%s", kogitoApp.Name, tagLatest)}, + }, + Strategy: buildv1.BuildStrategy{ + Type: buildv1.SourceBuildStrategyType, + SourceStrategy: &buildv1.SourceBuildStrategy{ + From: corev1.ObjectReference{ + Kind: kindImageStreamTag, + Namespace: kogitoApp.Namespace, + Name: resolveImageStreamTagNameForBuilds(kogitoApp, kogitoApp.Spec.Build.ImageRuntimeTag, buildType), + }, + }, + }, + }, + RunPolicy: buildv1.BuildRunPolicySerial, }, } + meta.SetGroupVersionKind(&buildConfig.TypeMeta, meta.KindBuildConfig) + addDefaultMeta(&buildConfig.ObjectMeta, kogitoApp) + return buildConfig } diff --git a/pkg/controller/kogitoapp/resource/build_config_s2i.go b/pkg/controller/kogitoapp/resource/build_config_s2i.go index 2ead3ecf8..5e20c8018 100644 --- a/pkg/controller/kogitoapp/resource/build_config_s2i.go +++ b/pkg/controller/kogitoapp/resource/build_config_s2i.go @@ -55,7 +55,7 @@ var ( // newBuildConfigS2I creates a new build configuration for source to image (s2i) builds func newBuildConfigS2I(kogitoApp *v1alpha1.KogitoApp) (buildConfig buildv1.BuildConfig, err error) { - if kogitoApp.Spec.Build == nil || kogitoApp.Spec.Build.GitSource == nil { + if kogitoApp.Spec.IsGitURIEmpty() { return buildConfig, errors.New("GitSource in the Kogito App Spec is required to create new build configurations") } @@ -64,7 +64,8 @@ func newBuildConfigS2I(kogitoApp *v1alpha1.KogitoApp) (buildConfig buildv1.Build Name: fmt.Sprintf("%s%s", kogitoApp.Name, BuildS2INameSuffix), Namespace: kogitoApp.Namespace, Labels: map[string]string{ - LabelKeyBuildType: string(BuildTypeS2I), + LabelKeyBuildType: string(BuildTypeS2I), + LabelKeyBuildVariant: string(BuildVariantSource), }, }, } @@ -85,7 +86,7 @@ func setBCS2ISource(kogitoApp *v1alpha1.KogitoApp, buildConfig *buildv1.BuildCon // Remove the trailing slash, as it will be removed by openshift buildConfig.Spec.Source.ContextDir = strings.TrimSuffix(kogitoApp.Spec.Build.GitSource.ContextDir, "/") buildConfig.Spec.Source.Git = &buildv1.GitBuildSource{ - URI: *kogitoApp.Spec.Build.GitSource.URI, + URI: kogitoApp.Spec.Build.GitSource.URI, Ref: kogitoApp.Spec.Build.GitSource.Reference, } } diff --git a/pkg/controller/kogitoapp/resource/build_config_s2i_test.go b/pkg/controller/kogitoapp/resource/build_config_s2i_test.go index c86d33874..073f043e1 100644 --- a/pkg/controller/kogitoapp/resource/build_config_s2i_test.go +++ b/pkg/controller/kogitoapp/resource/build_config_s2i_test.go @@ -81,8 +81,8 @@ func TestNewBuildConfigS2I(t *testing.T) { Runtime: v1alpha1.QuarkusRuntimeType, Build: &v1alpha1.KogitoAppBuildObject{ Incremental: true, - GitSource: &v1alpha1.GitSource{ - URI: &uri, + GitSource: v1alpha1.GitSource{ + URI: uri, }, Native: true, Resources: v1alpha1.Resources{ diff --git a/pkg/controller/kogitoapp/resource/build_config_test.go b/pkg/controller/kogitoapp/resource/build_config_test.go index 73a522a09..bbc5e5a49 100644 --- a/pkg/controller/kogitoapp/resource/build_config_test.go +++ b/pkg/controller/kogitoapp/resource/build_config_test.go @@ -37,8 +37,8 @@ func Test_BuidConfig_NonNativeBuild(t *testing.T) { Build: &v1alpha1.KogitoAppBuildObject{ // we'll try to trick the build Env: []v1alpha1.Env{{Name: nativeBuildEnvVarKey, Value: "true"}}, - GitSource: &v1alpha1.GitSource{ - URI: &uri, + GitSource: v1alpha1.GitSource{ + URI: uri, ContextDir: "jbpm-quarkus-example", }, Native: false, @@ -70,8 +70,8 @@ func Test_BuildConfig_WithCustomImage(t *testing.T) { Spec: v1alpha1.KogitoAppSpec{ Runtime: v1alpha1.QuarkusRuntimeType, Build: &v1alpha1.KogitoAppBuildObject{ - GitSource: &v1alpha1.GitSource{ - URI: &uri, + GitSource: v1alpha1.GitSource{ + URI: uri, ContextDir: "jbpm-quarkus-example", }, ImageVersion: "latest", @@ -100,8 +100,8 @@ func Test_buildConfigResource_New(t *testing.T) { }, Spec: v1alpha1.KogitoAppSpec{ Build: &v1alpha1.KogitoAppBuildObject{ - GitSource: &v1alpha1.GitSource{ - URI: &uri, + GitSource: v1alpha1.GitSource{ + URI: uri, ContextDir: "jbpm-quarkus-example", }, Native: true, diff --git a/pkg/controller/kogitoapp/resource/deployment_config_test.go b/pkg/controller/kogitoapp/resource/deployment_config_test.go index 9088ac4c7..28bc9fa5b 100644 --- a/pkg/controller/kogitoapp/resource/deployment_config_test.go +++ b/pkg/controller/kogitoapp/resource/deployment_config_test.go @@ -46,8 +46,8 @@ func Test_deploymentConfigResource_NewWithValidDocker(t *testing.T) { }, Spec: v1alpha1.KogitoAppSpec{ Build: &v1alpha1.KogitoAppBuildObject{ - GitSource: &v1alpha1.GitSource{ - URI: &uri, + GitSource: v1alpha1.GitSource{ + URI: uri, ContextDir: "jbpm-quarkus-example", }, }, @@ -92,8 +92,8 @@ func Test_deploymentConfigResource_NewWithInvalidDocker(t *testing.T) { }, Spec: v1alpha1.KogitoAppSpec{ Build: &v1alpha1.KogitoAppBuildObject{ - GitSource: &v1alpha1.GitSource{ - URI: &uri, + GitSource: v1alpha1.GitSource{ + URI: uri, ContextDir: "jbpm-quarkus-example", }, }, @@ -121,7 +121,8 @@ func Test_SetInfinispanEnvVars_QuarkusRuntime(t *testing.T) { objs := []runtime.Object{service, secret} fakeClient := test.CreateFakeClient(objs, nil, []runtime.Object{}) - SetInfinispanEnvVars(fakeClient, kogitoInfra, kogitoApp, dc) + err := SetInfinispanEnvVars(fakeClient, kogitoInfra, kogitoApp, dc) + assert.NoError(t, err) container := dc.Spec.Template.Spec.Containers[0] assert.Equal(t, 5, len(container.Env)) @@ -136,7 +137,7 @@ func Test_IstioEnabled(t *testing.T) { uri := "https://github.com/kiegroup/kogito-examples" kogitoApp := createTestKogitoApp(v1alpha1.QuarkusRuntimeType) kogitoApp.Spec.EnableIstio = true - kogitoApp.Spec.Build.GitSource = &v1alpha1.GitSource{URI: &uri} + kogitoApp.Spec.Build.GitSource = v1alpha1.GitSource{URI: uri} dockerImage := &dockerv10.DockerImage{ Config: &dockerv10.DockerConfig{ Labels: map[string]string{ @@ -177,7 +178,8 @@ func Test_SetInfinispanEnvVars_SpringBootRuntime(t *testing.T) { objs := []runtime.Object{service, secret} fakeClient := test.CreateFakeClient(objs, nil, []runtime.Object{}) - SetInfinispanEnvVars(fakeClient, kogitoInfra, kogitoApp, dc) + err := SetInfinispanEnvVars(fakeClient, kogitoInfra, kogitoApp, dc) + assert.NoError(t, err) container := dc.Spec.Template.Spec.Containers[0] assert.Equal(t, 5, len(container.Env)) diff --git a/pkg/controller/kogitoapp/resource/requested_resources.go b/pkg/controller/kogitoapp/resource/requested_resources.go index 55182ccb2..4854bb3cb 100644 --- a/pkg/controller/kogitoapp/resource/requested_resources.go +++ b/pkg/controller/kogitoapp/resource/requested_resources.go @@ -28,6 +28,8 @@ type builderChain struct { Error error } +// TODO: get rid of this once we have https://issues.redhat.com/browse/KOGITO-952 + func (c *builderChain) andBuild(f func(*builderChain) *builderChain) *builderChain { if c.Error == nil { return f(c) @@ -46,6 +48,7 @@ func GetRequestedResources(kogitoApp *v1alpha1.KogitoApp, client *client.Client) chain. andBuild(buildConfigS2IBuilder). andBuild(buildConfigRuntimeBuilder). + andBuild(buildConfigRuntimeBinaryBuilder). andBuild(protoBufConfigMap). andBuild(imageStreamBuilder). andBuild(runtimeImageGetter). @@ -57,29 +60,36 @@ func GetRequestedResources(kogitoApp *v1alpha1.KogitoApp, client *client.Client) } func buildConfigS2IBuilder(chain *builderChain) *builderChain { - bc, err := newBuildConfigS2I(chain.KogitoApp) - if err != nil { - chain.Error = err - return chain - } - - chain.Resources.BuildConfigS2I = &bc + if !chain.KogitoApp.Spec.IsGitURIEmpty() { + bc, err := newBuildConfigS2I(chain.KogitoApp) + if err != nil { + chain.Error = err + return chain + } + chain.Resources.BuildConfigS2I = &bc + } return chain } func buildConfigRuntimeBuilder(chain *builderChain) *builderChain { - bc, err := newBuildConfigRuntime( - chain.KogitoApp, - chain.Resources.BuildConfigS2I, - ) - if err != nil { - chain.Error = err - return chain + if !chain.KogitoApp.Spec.IsGitURIEmpty() { + bc, err := newBuildConfigRuntime( + chain.KogitoApp, + chain.Resources.BuildConfigS2I, + ) + if err != nil { + chain.Error = err + return chain + } + chain.Resources.BuildConfigRuntime = &bc } + return chain +} - chain.Resources.BuildConfigRuntime = &bc - +func buildConfigRuntimeBinaryBuilder(chain *builderChain) *builderChain { + bc := newBuildConfigRuntimeBinary(chain.KogitoApp) + chain.Resources.BuildConfigBinary = &bc return chain } @@ -90,10 +100,12 @@ func protoBufConfigMap(chain *builderChain) *builderChain { } func imageStreamBuilder(chain *builderChain) *builderChain { - isS2I := newImageStream(chain.KogitoApp, chain.Resources.BuildConfigS2I.Name) - chain.Resources.ImageStreamS2I = isS2I + if chain.Resources.BuildConfigS2I != nil { + isS2I := newImageStream(chain.KogitoApp, chain.Resources.BuildConfigS2I.Name) + chain.Resources.ImageStreamS2I = isS2I + } - isRuntime := newImageStream(chain.KogitoApp, chain.Resources.BuildConfigRuntime.Name) + isRuntime := newImageStream(chain.KogitoApp, chain.KogitoApp.Name) chain.Resources.ImageStreamRuntime = isRuntime return chain @@ -101,11 +113,10 @@ func imageStreamBuilder(chain *builderChain) *builderChain { func deploymentConfigBuilder(chain *builderChain) *builderChain { chain.Resources.DeploymentConfig = nil - if chain.Resources.RuntimeImage != nil { dc, err := newDeploymentConfig( chain.KogitoApp, - chain.Resources.BuildConfigRuntime, + chain.Resources.BuildConfigBinary, chain.Resources.RuntimeImage, ) if err != nil { @@ -158,18 +169,18 @@ func serviceMonitorBuilder(chain *builderChain) *builderChain { } func runtimeImageGetter(chain *builderChain) *builderChain { - bcNamespacedName := types.NamespacedName{ - Namespace: chain.Resources.BuildConfigRuntime.Namespace, - Name: chain.Resources.BuildConfigRuntime.Name, + imageStreamName := types.NamespacedName{ + Namespace: chain.KogitoApp.Namespace, + Name: chain.KogitoApp.Name, } chain.Resources.DeploymentConfig = nil - if dockerImage, err := openshift.ImageStreamC(chain.Client).FetchDockerImage(bcNamespacedName); err != nil { + if dockerImage, err := openshift.ImageStreamC(chain.Client).FetchDockerImage(imageStreamName); err != nil { chain.Error = err } else if dockerImage != nil { chain.Resources.RuntimeImage = dockerImage } else { - log.Warnf("Couldn't find an image with name '%s' in the namespace '%s'. The DeploymentConfig will be created once the build is done.", bcNamespacedName.Name, bcNamespacedName.Namespace) + log.Warnf("Couldn't find an image with name '%s' in the namespace '%s'. The DeploymentConfig will be created once the build is done.", imageStreamName.Name, imageStreamName.Namespace) } return chain diff --git a/pkg/controller/kogitoapp/resource/requested_resources_test.go b/pkg/controller/kogitoapp/resource/requested_resources_test.go index f9ee4b34a..9600b6b8f 100644 --- a/pkg/controller/kogitoapp/resource/requested_resources_test.go +++ b/pkg/controller/kogitoapp/resource/requested_resources_test.go @@ -41,8 +41,8 @@ func createKogitoApp() *v1alpha1.KogitoApp { }, Spec: v1alpha1.KogitoAppSpec{ Build: &v1alpha1.KogitoAppBuildObject{ - GitSource: &v1alpha1.GitSource{ - URI: &uri, + GitSource: v1alpha1.GitSource{ + URI: uri, }, }, }, @@ -112,3 +112,24 @@ func TestBuildResources_CreateAllSuccess(t *testing.T) { assert.Len(t, resources.DeploymentConfig.Spec.Template.Spec.Containers[0].Ports, 1) assert.Equal(t, resources.DeploymentConfig.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort, int32(8080)) } + +func Test_buildConfigS2IBuilder(t *testing.T) { + blankBuildSpec := &builderChain{ + KogitoApp: &v1alpha1.KogitoApp{ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: t.Name()}}, + Resources: &KogitoAppResources{}, + } + gitURLGiven := &builderChain{ + KogitoApp: &v1alpha1.KogitoApp{ + ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: t.Name()}, + Spec: v1alpha1.KogitoAppSpec{Build: &v1alpha1.KogitoAppBuildObject{GitSource: v1alpha1.GitSource{URI: "http://anything.com"}}}}, + Resources: &KogitoAppResources{}, + } + + chain := buildConfigS2IBuilder(blankBuildSpec) + assert.NotNil(t, chain) + assert.Nil(t, chain.Resources.BuildConfigS2I) + + chain = buildConfigS2IBuilder(gitURLGiven) + assert.NotNil(t, chain) + assert.NotNil(t, chain.Resources.BuildConfigS2I) +} diff --git a/pkg/controller/kogitoapp/resource/resources.go b/pkg/controller/kogitoapp/resource/resources.go index 75d9a34da..dd188d724 100644 --- a/pkg/controller/kogitoapp/resource/resources.go +++ b/pkg/controller/kogitoapp/resource/resources.go @@ -31,9 +31,9 @@ var log = logger.GetLogger("builder_kogitoapp") // KogitoAppResources has a reference for every resource needed to deploy the KogitoApp type KogitoAppResources struct { - KogitoAppResourcesStatus BuildConfigS2I *buildv1.BuildConfig BuildConfigRuntime *buildv1.BuildConfig + BuildConfigBinary *buildv1.BuildConfig ImageStreamS2I *imgv1.ImageStream ImageStreamRuntime *imgv1.ImageStream DeploymentConfig *appsv1.DeploymentConfig @@ -43,17 +43,3 @@ type KogitoAppResources struct { RuntimeImage *dockerv10.DockerImage ProtoBufCM *corev1.ConfigMap } - -// KogitoAppResourceStatusKind defines the kind of the resource status in the cluster -type KogitoAppResourceStatusKind struct { - IsNew bool -} - -// KogitoAppResourcesStatus defines the resource status in the cluster -type KogitoAppResourcesStatus struct { - BuildConfigS2IStatus KogitoAppResourceStatusKind - BuildConfigRuntimeStatus KogitoAppResourceStatusKind - DeploymentConfigStatus KogitoAppResourceStatusKind - RouteStatus KogitoAppResourceStatusKind - ServiceStatus KogitoAppResourceStatusKind -} diff --git a/pkg/controller/kogitoapp/resource/service_test.go b/pkg/controller/kogitoapp/resource/service_test.go index e88832997..0157ae94b 100644 --- a/pkg/controller/kogitoapp/resource/service_test.go +++ b/pkg/controller/kogitoapp/resource/service_test.go @@ -36,8 +36,8 @@ func Test_serviceResource_NewWithAndWithoutDockerImg(t *testing.T) { }, Spec: v1alpha1.KogitoAppSpec{ Build: &v1alpha1.KogitoAppBuildObject{ - GitSource: &v1alpha1.GitSource{ - URI: &uri, + GitSource: v1alpha1.GitSource{ + URI: uri, ContextDir: "jbpm-quarkus-example", }, }, diff --git a/pkg/controller/kogitoapp/status/manage_status.go b/pkg/controller/kogitoapp/status/manage_status.go index 86d76d46d..ece0b8e80 100644 --- a/pkg/controller/kogitoapp/status/manage_status.go +++ b/pkg/controller/kogitoapp/status/manage_status.go @@ -262,21 +262,39 @@ func statusUpdateForImageBuild(instance *v1alpha1.KogitoApp, resources *resource func ensureApplicationImageExists(instance *v1alpha1.KogitoApp, resources *resource.KogitoAppResources, client *client.Client) ( exists bool, running bool, updated bool, runtimeFailed bool, s2iFailed bool, err error) { - runtimeState, err := - openshift.BuildConfigC(client).EnsureImageBuild( - resources.BuildConfigRuntime, - getBCLabelsAsUniqueSelectors(resources.BuildConfigRuntime)) - if err != nil { - return false, false, false, false, false, err + var runtimeState openshift.BuildState + + if resources.BuildConfigRuntime != nil { + runtimeState, err = + openshift.BuildConfigC(client).EnsureImageBuild( + resources.BuildConfigRuntime, + getBCLabelsAsUniqueSelectors(resources.BuildConfigRuntime), + instance.Name) + if err != nil { + return false, false, false, false, false, err + } + } else { + runtimeState, err = + openshift.BuildConfigC(client).EnsureImageBuild( + resources.BuildConfigBinary, + getBCLabelsAsUniqueSelectors(resources.BuildConfigBinary), + instance.Name) + if err != nil { + return false, false, false, false, false, err + } } // verify service build and image if runtimeState.ImageExists { log.Debugf("Final application image exists there's no need to trigger any build") } else { + buildName := resources.BuildConfigBinary.Name + if resources.BuildConfigRuntime != nil { + buildName = resources.BuildConfigRuntime.Name + } log.Warnf("Image not found for %s. The image could being built. Check with 'oc get is/%s -n %s'", - resources.BuildConfigRuntime.Name, - resources.BuildConfigRuntime.Name, + buildName, + buildName, instance.Namespace) } @@ -291,44 +309,47 @@ func ensureApplicationImageExists(instance *v1alpha1.KogitoApp, resources *resou log.Infof("Image for '%s' is being pushed to the registry", instance.Name) } - // verify s2i build and image - s2iState, err := - openshift.BuildConfigC(client).EnsureImageBuild( - resources.BuildConfigS2I, - getBCLabelsAsUniqueSelectors(resources.BuildConfigS2I)) - if err != nil { - return false, runtimeRunning, runtimeUpdated, runtimeError, false, err - } - - var s2iUpdated, s2iRunning, s2iError bool - if s2iState.Builds == nil { - s2iRunning = true - } else { - s2iUpdated, s2iRunning, s2iError = checkBuildsStatus(s2iState.Builds, &instance.Status.Builds) - } + if resources.BuildConfigS2I != nil { + // verify s2i build and image + s2iState, err := + openshift.BuildConfigC(client).EnsureImageBuild( + resources.BuildConfigS2I, + getBCLabelsAsUniqueSelectors(resources.BuildConfigS2I), + resources.BuildConfigS2I.Name) + if err != nil { + return false, runtimeRunning, runtimeUpdated, runtimeError, false, err + } - if s2iRunning { - // build is running, nothing to do - log.Infof("Application '%s' build is still running. Won't trigger a new build.", instance.Name) - } else if !s2iState.ImageExists && !s2iRunning { - log.Warnf("There's no image nor build for '%s' running", resources.BuildConfigS2I.Name) - } + var s2iUpdated, s2iRunning, s2iError bool + if s2iState.Builds == nil { + s2iRunning = true + } else { + s2iUpdated, s2iRunning, s2iError = checkBuildsStatus(s2iState.Builds, &instance.Status.Builds) + } - if runtimeState.ImageExists && !runtimeRunning && s2iState.ImageExists && !s2iRunning { - log.Debugf("There are images for both builds, nothing to do") - } + if s2iRunning { + // build is running, nothing to do + log.Infof("Application '%s' build is still running. Won't trigger a new build.", instance.Name) + } else if !s2iState.ImageExists && !s2iRunning { + log.Warnf("There's no image nor build for '%s' running", resources.BuildConfigS2I.Name) + } - if runtimeUpdated || s2iUpdated { - instance.Status.Builds.New = append(runtimeState.Builds.New, s2iState.Builds.New...) - instance.Status.Builds.Pending = append(runtimeState.Builds.Pending, s2iState.Builds.Pending...) - instance.Status.Builds.Running = append(runtimeState.Builds.Running, s2iState.Builds.Running...) - instance.Status.Builds.Error = append(runtimeState.Builds.Error, s2iState.Builds.Error...) - instance.Status.Builds.Failed = append(runtimeState.Builds.Failed, s2iState.Builds.Failed...) - instance.Status.Builds.Cancelled = append(runtimeState.Builds.Cancelled, s2iState.Builds.Cancelled...) - instance.Status.Builds.Complete = append(runtimeState.Builds.Complete, s2iState.Builds.Complete...) + if runtimeState.ImageExists && !runtimeRunning && s2iState.ImageExists && !s2iRunning { + log.Debugf("There are images for both builds, nothing to do") + } + if runtimeUpdated || s2iUpdated { + instance.Status.Builds.New = append(runtimeState.Builds.New, s2iState.Builds.New...) + instance.Status.Builds.Pending = append(runtimeState.Builds.Pending, s2iState.Builds.Pending...) + instance.Status.Builds.Running = append(runtimeState.Builds.Running, s2iState.Builds.Running...) + instance.Status.Builds.Error = append(runtimeState.Builds.Error, s2iState.Builds.Error...) + instance.Status.Builds.Failed = append(runtimeState.Builds.Failed, s2iState.Builds.Failed...) + instance.Status.Builds.Cancelled = append(runtimeState.Builds.Cancelled, s2iState.Builds.Cancelled...) + instance.Status.Builds.Complete = append(runtimeState.Builds.Complete, s2iState.Builds.Complete...) + } + return runtimeState.ImageExists && s2iState.ImageExists, runtimeRunning || s2iRunning, runtimeUpdated || s2iUpdated, runtimeError, s2iError, nil } - return runtimeState.ImageExists && s2iState.ImageExists, runtimeRunning || s2iRunning, runtimeUpdated || s2iUpdated, runtimeError, s2iError, nil + return runtimeState.ImageExists, runtimeRunning, runtimeUpdated, runtimeError, false, nil } func checkBuildsStatus(state *v1alpha1.Builds, lastState *v1alpha1.Builds) (updated bool, running bool, newFailed bool) { @@ -354,11 +375,13 @@ func checkBuildsStatus(state *v1alpha1.Builds, lastState *v1alpha1.Builds) (upda } func getBCLabelsAsUniqueSelectors(bc *obuildv1.BuildConfig) string { - return fmt.Sprintf("%s=%s,%s=%s", + return fmt.Sprintf("%s=%s,%s=%s,%s=%s", resource.LabelKeyAppName, bc.Labels[resource.LabelKeyAppName], resource.LabelKeyBuildType, bc.Labels[resource.LabelKeyBuildType], + resource.LabelKeyBuildVariant, + bc.Labels[resource.LabelKeyBuildVariant], ) } diff --git a/pkg/controller/kogitoapp/status/manage_status_test.go b/pkg/controller/kogitoapp/status/manage_status_test.go index eccbbfe0c..ae024eb83 100644 --- a/pkg/controller/kogitoapp/status/manage_status_test.go +++ b/pkg/controller/kogitoapp/status/manage_status_test.go @@ -564,8 +564,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "tests2i", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, } @@ -575,8 +576,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "testruntime", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, } @@ -595,7 +597,7 @@ func Test_statusUpdateForImageBuild(t *testing.T) { runtimeImage := &imgv1.ImageStreamTag{ ObjectMeta: metav1.ObjectMeta{ - Name: "testruntime:latest", + Name: "test:latest", Namespace: "test", }, Image: imgv1.Image{ @@ -610,8 +612,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "tests2ibuild", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -624,8 +627,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "testruntimebuild", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -638,8 +642,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "tests2ibuildfail", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -652,8 +657,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "testruntimebuildfail", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -666,8 +672,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "tests2ibuildcomplete", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -680,8 +687,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "testruntimebuildcomplete", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -722,8 +730,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "tests2i", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, }, @@ -732,8 +741,20 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "testruntime", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), + }, + }, + }, + BuildConfigBinary: &obuildv1.BuildConfig{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "testruntime-binary", + Labels: map[string]string{ + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantBinary), }, }, }, @@ -763,8 +784,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "tests2i", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, }, @@ -773,8 +795,20 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "testruntime", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), + }, + }, + }, + BuildConfigBinary: &obuildv1.BuildConfig{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "testruntime-binary", + Labels: map[string]string{ + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantBinary), }, }, }, @@ -809,8 +843,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "tests2i", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, }, @@ -819,8 +854,20 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "testruntime", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), + }, + }, + }, + BuildConfigBinary: &obuildv1.BuildConfig{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "testruntime-binary", + Labels: map[string]string{ + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantBinary), }, }, }, @@ -850,8 +897,9 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "tests2i", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, }, @@ -860,8 +908,20 @@ func Test_statusUpdateForImageBuild(t *testing.T) { Namespace: "test", Name: "testruntime", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), + }, + }, + }, + BuildConfigBinary: &obuildv1.BuildConfig{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "testruntime-binary", + Labels: map[string]string{ + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantBinary), }, }, }, @@ -912,8 +972,9 @@ func Test_ensureApplicationImageExists(t *testing.T) { Namespace: "test", Name: "tests2i", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, } @@ -923,8 +984,9 @@ func Test_ensureApplicationImageExists(t *testing.T) { Namespace: "test", Name: "testruntime", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, } @@ -943,7 +1005,7 @@ func Test_ensureApplicationImageExists(t *testing.T) { runtimeImage := &imgv1.ImageStreamTag{ ObjectMeta: metav1.ObjectMeta{ - Name: "testruntime:latest", + Name: "test:latest", Namespace: "test", }, Image: imgv1.Image{ @@ -958,8 +1020,9 @@ func Test_ensureApplicationImageExists(t *testing.T) { Namespace: "test", Name: "tests2ibuild", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -972,8 +1035,9 @@ func Test_ensureApplicationImageExists(t *testing.T) { Namespace: "test", Name: "testruntimebuild", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -986,8 +1050,9 @@ func Test_ensureApplicationImageExists(t *testing.T) { Namespace: "test", Name: "tests2ibuildfail", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -1000,8 +1065,9 @@ func Test_ensureApplicationImageExists(t *testing.T) { Namespace: "test", Name: "testruntimebuildfail", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, Status: obuildv1.BuildStatus{ @@ -1038,8 +1104,9 @@ func Test_ensureApplicationImageExists(t *testing.T) { Namespace: "test", Name: "tests2i", Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, }, @@ -1048,8 +1115,20 @@ func Test_ensureApplicationImageExists(t *testing.T) { Namespace: "test", Name: "testruntime", Labels: map[string]string{ - "app": "test", - "buildtype": "runtime", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), + }, + }, + }, + BuildConfigBinary: &obuildv1.BuildConfig{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "testruntime-binary", + Labels: map[string]string{ + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeRuntime), + resource.LabelKeyBuildVariant: string(resource.BuildVariantBinary), }, }, }, @@ -1217,13 +1296,14 @@ func Test_getBCLabelsAsUniqueSelectors(t *testing.T) { &obuildv1.BuildConfig{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ - "app": "test", - "buildtype": "s2i", + "app": "test", + resource.LabelKeyBuildType: string(resource.BuildTypeS2I), + resource.LabelKeyBuildVariant: string(resource.BuildVariantSource), }, }, }, }, - "app=test,buildtype=s2i", + fmt.Sprintf("app=test,%s=%s,%s=%s", resource.LabelKeyBuildType, resource.BuildTypeS2I, resource.LabelKeyBuildVariant, resource.BuildVariantSource), }, } for _, tt := range tests { diff --git a/test/framework/kogitoapp.go b/test/framework/kogitoapp.go index d75e773e9..408dbda40 100644 --- a/test/framework/kogitoapp.go +++ b/test/framework/kogitoapp.go @@ -60,9 +60,8 @@ func crDeployExample(namespace string, kogitoAppDeployment KogitoAppDeployment) kogitoApp := getKogitoAppStub(namespace, kogitoAppDeployment.AppName, kogitoAppDeployment.Labels) kogitoApp.Spec.Runtime = kogitoAppDeployment.Runtime - gitProjectURI := GetConfigExamplesRepositoryURI() kogitoApp.Spec.Build.Native = kogitoAppDeployment.Native - kogitoApp.Spec.Build.GitSource.URI = &gitProjectURI + kogitoApp.Spec.Build.GitSource.URI = GetConfigExamplesRepositoryURI() kogitoApp.Spec.Build.GitSource.ContextDir = kogitoAppDeployment.ContextDir kogitoApp.Spec.Build.GitSource.Reference = GetConfigExamplesRepositoryRef() @@ -163,7 +162,7 @@ func getKogitoAppStub(namespace, appName string, labels map[string]string) *v1al Spec: v1alpha1.KogitoAppSpec{ Build: &v1alpha1.KogitoAppBuildObject{ Env: []v1alpha1.Env{}, - GitSource: &v1alpha1.GitSource{}, + GitSource: v1alpha1.GitSource{}, }, }, }