From commits-return-72947-archive-asf-public=cust-asf.ponee.io@camel.apache.org Wed May 29 17:54:14 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id A0F7D18064C for ; Wed, 29 May 2019 19:54:13 +0200 (CEST) Received: (qmail 60284 invoked by uid 500); 29 May 2019 17:54:13 -0000 Mailing-List: contact commits-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list commits@camel.apache.org Received: (qmail 60275 invoked by uid 99); 29 May 2019 17:54:12 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 29 May 2019 17:54:12 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id BF9148A311; Wed, 29 May 2019 17:54:07 +0000 (UTC) Date: Wed, 29 May 2019 17:54:07 +0000 To: "commits@camel.apache.org" Subject: [camel-k] branch master updated: Fix #698: 2nd attempt MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <155915244766.22418.12804662034789735095@gitbox.apache.org> From: astefanutti@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: camel-k X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: a11029594592123a2512abd8ce30fddae3789e55 X-Git-Newrev: c8720172137b05bf4422562f8308f379f63672f9 X-Git-Rev: c8720172137b05bf4422562f8308f379f63672f9 X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated This is an automated email from the ASF dual-hosted git repository. astefanutti pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git The following commit(s) were added to refs/heads/master by this push: new c872017 Fix #698: 2nd attempt c872017 is described below commit c8720172137b05bf4422562f8308f379f63672f9 Author: nferraro AuthorDate: Wed May 29 15:16:09 2019 +0200 Fix #698: 2nd attempt --- deploy/operator-deployment.yaml | 5 +++ deploy/resources.go | 27 +++------------- pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go | 26 ++++++--------- pkg/cmd/install.go | 4 ++- pkg/controller/build/schedule_pod.go | 21 ++++++++++--- pkg/controller/integration/initialize.go | 3 ++ pkg/controller/integrationplatform/create.go | 8 ++--- pkg/install/common.go | 24 +++++++++----- pkg/install/operator.go | 36 ++++++++++++++------- pkg/platform/operator.go | 40 ++++++++++++++++++++++++ test/testing_env.go | 2 +- 11 files changed, 129 insertions(+), 67 deletions(-) diff --git a/deploy/operator-deployment.yaml b/deploy/operator-deployment.yaml index 21f7ed6..82af532 100644 --- a/deploy/operator-deployment.yaml +++ b/deploy/operator-deployment.yaml @@ -36,3 +36,8 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name + # NAMESPACE is always the operator namespace, independently from WATCH_NAMESPACE + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace diff --git a/deploy/resources.go b/deploy/resources.go index faafb19..71f27fa 100644 --- a/deploy/resources.go +++ b/deploy/resources.go @@ -10683,6 +10683,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name + # NAMESPACE is always the operator namespace, independently from WATCH_NAMESPACE + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace ` Resources["operator-role-binding-knative.yaml"] = @@ -11057,28 +11062,6 @@ spec: - runtime:kotlin - camel:core ` - Resources["platform-integration-context-spring-boot.yaml"] = - ` -apiVersion: camel.apache.org/v1alpha1 -kind: IntegrationContext -metadata: - name: spring-boot - labels: - app: "camel-k" - camel.apache.org/context.created.by.kind: Operator - camel.apache.org/context.created.by.name: camel-k-operator - camel.apache.org/context.type: platform -spec: - dependencies: - - runtime:jvm - - runtime:spring-boot - - camel:core - traits: - springboot: - configuration: - enabled: "true" - -` Resources["user-cluster-role.yaml"] = ` kind: ClusterRole diff --git a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go index ac2e148..1233a9e 100644 --- a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go @@ -1,21 +1,5 @@ // +build !ignore_autogenerated -/* -Copyright The Kubernetes Authors. - -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. -*/ - // Code generated by deepcopy-gen. DO NOT EDIT. package v1alpha1 @@ -799,6 +783,11 @@ func (in *IntegrationPlatformSpec) DeepCopyInto(out *IntegrationPlatformSpec) { (*out)[key] = *val.DeepCopy() } } + if in.Configuration != nil { + in, out := &in.Configuration, &out.Configuration + *out = make([]ConfigurationSpec, len(*in)) + copy(*out, *in) + } return } @@ -899,6 +888,11 @@ func (in *IntegrationStatus) DeepCopyInto(out *IntegrationStatus) { *out = new(Failure) (*in).DeepCopyInto(*out) } + if in.Configuration != nil { + in, out := &in.Configuration, &out.Configuration + *out = make([]ConfigurationSpec, len(*in)) + copy(*out, *in) + } return } diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go index 658d623..a2ca340 100644 --- a/pkg/cmd/install.go +++ b/pkg/cmd/install.go @@ -69,6 +69,7 @@ func newCmdInstall(rootCmdOptions *RootCmdOptions) *cobra.Command { cmd.Flags().StringVar(&impl.camelVersion, "camel-version", "", "Set the camel version") cmd.Flags().StringVar(&impl.runtimeVersion, "runtime-version", "", "Set the camel-k runtime version") cmd.Flags().StringVar(&impl.baseImage, "base-image", "", "Set the base image used to run integrations") + cmd.Flags().StringVar(&impl.operatorImage, "operator-image", "", "Set the operator image used for the operator deployment") cmd.Flags().StringSliceVar(&impl.contexts, "context", nil, "Add a camel context to build at startup, by default all known contexts are built") cmd.Flags().StringVar(&impl.buildStrategy, "build-strategy", "", "Set the build strategy") cmd.Flags().StringVar(&impl.buildTimeout, "build-timeout", "", "Set how long the build process can last") @@ -96,6 +97,7 @@ type installCmdOptions struct { camelVersion string runtimeVersion string baseImage string + operatorImage string localRepository string buildStrategy string buildTimeout string @@ -139,7 +141,7 @@ func (o *installCmdOptions) install(_ *cobra.Command, _ []string) error { namespace := o.Namespace - err = install.OperatorOrCollect(o.Context, c, namespace, collection) + err = install.OperatorOrCollect(o.Context, c, namespace, o.operatorImage, collection) if err != nil { return err } diff --git a/pkg/controller/build/schedule_pod.go b/pkg/controller/build/schedule_pod.go index 8bbb7c9..be34557 100644 --- a/pkg/controller/build/schedule_pod.go +++ b/pkg/controller/build/schedule_pod.go @@ -21,6 +21,9 @@ import ( "context" "sync" + "github.com/apache/camel-k/pkg/platform" + "github.com/apache/camel-k/pkg/util/defaults" + corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -31,7 +34,6 @@ import ( "github.com/pkg/errors" "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" - "github.com/apache/camel-k/pkg/util/defaults" ) // NewSchedulePodAction creates a new schedule action @@ -88,10 +90,16 @@ func (action *schedulePodAction) Handle(ctx context.Context, build *v1alpha1.Bui return nil } + // Try to get operator image name before starting the build + operatorImage, err := platform.GetCurrentOperatorImage(ctx, action.client) + if err != nil { + return err + } + // Otherwise, let's create the build pod // We may want to explicitly manage build priority as opposed to relying on // the reconcile loop to handle the queuing - pod := newBuildPod(build) + pod := newBuildPod(build, operatorImage) // Set the Build instance as the owner and controller if err := controllerutil.SetControllerReference(build, pod, action.client.GetScheme()); err != nil { @@ -115,7 +123,11 @@ func (action *schedulePodAction) Handle(ctx context.Context, build *v1alpha1.Bui return action.client.Status().Update(ctx, target) } -func newBuildPod(build *v1alpha1.Build) *corev1.Pod { +func newBuildPod(build *v1alpha1.Build, operatorImage string) *corev1.Pod { + builderImage := operatorImage + if builderImage == "" { + builderImage = defaults.ImageName + ":" + defaults.Version + } pod := &corev1.Pod{ TypeMeta: metav1.TypeMeta{ APIVersion: corev1.SchemeGroupVersion.String(), @@ -130,7 +142,8 @@ func newBuildPod(build *v1alpha1.Build) *corev1.Pod { Containers: []corev1.Container{ { Name: "builder", - Image: defaults.ImageName + ":" + defaults.Version, + Image: builderImage, + ImagePullPolicy: "IfNotPresent", Args: []string{ "camel-k-builder", build.Namespace, diff --git a/pkg/controller/integration/initialize.go b/pkg/controller/integration/initialize.go index 636b0f6..b2e716e 100644 --- a/pkg/controller/integration/initialize.go +++ b/pkg/controller/integration/initialize.go @@ -50,6 +50,9 @@ func (action *initializeAction) CanHandle(integration *v1alpha1.Integration) boo // Handle handles the integrations func (action *initializeAction) Handle(ctx context.Context, integration *v1alpha1.Integration) error { pl, err := platform.GetCurrentPlatform(ctx, action.client, integration.Namespace) + if err != nil { + return err + } // The integration platform needs to be ready before starting to create integrations if err != nil || pl.Status.Phase != v1alpha1.IntegrationPlatformPhaseReady { diff --git a/pkg/controller/integrationplatform/create.go b/pkg/controller/integrationplatform/create.go index 572fb31..023852e 100644 --- a/pkg/controller/integrationplatform/create.go +++ b/pkg/controller/integrationplatform/create.go @@ -50,7 +50,7 @@ func (action *createAction) Handle(ctx context.Context, platform *v1alpha1.Integ for k := range deploy.Resources { if strings.HasPrefix(k, "camel-catalog-") { action.L.Infof("Installing camel catalog: %s", k) - err := install.Resources(ctx, action.client, platform.Namespace, k) + err := install.Resources(ctx, action.client, platform.Namespace, install.IdentityResourceCustomizer, k) if err != nil { return err } @@ -79,21 +79,21 @@ func (action *createAction) Handle(ctx context.Context, platform *v1alpha1.Integ if len(res) > 0 { action.L.Info("Installing custom platform resources") - err := install.Resources(ctx, action.client, platform.Namespace, res...) + err := install.Resources(ctx, action.client, platform.Namespace, install.IdentityResourceCustomizer, res...) if err != nil { return err } } } else { action.L.Info("Installing default platform resources") - err := install.Resources(ctx, action.client, platform.Namespace, p.DefaultContexts...) + err := install.Resources(ctx, action.client, platform.Namespace, install.IdentityResourceCustomizer, p.DefaultContexts...) if err != nil { return err } if platform.Spec.Profile == v1alpha1.TraitProfileKnative { action.L.Info("Installing knative resources") - err := install.Resources(ctx, action.client, platform.Namespace, p.KnativeContexts...) + err := install.Resources(ctx, action.client, platform.Namespace, install.IdentityResourceCustomizer, p.KnativeContexts...) if err != nil { return err } diff --git a/pkg/install/common.go b/pkg/install/common.go index d7a15fb..f8a9fbe 100644 --- a/pkg/install/common.go +++ b/pkg/install/common.go @@ -29,15 +29,23 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +// ResourceCustomizer can be used to inject code that changes the objects before they are created +type ResourceCustomizer func(object runtime.Object)runtime.Object +// IdentityResourceCustomizer is a ResourceCustomizer that does nothing +var IdentityResourceCustomizer = func(object runtime.Object)runtime.Object { + return object +} + + // Resources installs named resources from the project resource directory -func Resources(ctx context.Context, c client.Client, namespace string, names ...string) error { - return ResourcesOrCollect(ctx, c, namespace, nil, names...) +func Resources(ctx context.Context, c client.Client, namespace string, customizer ResourceCustomizer, names ...string) error { + return ResourcesOrCollect(ctx, c, namespace, nil, customizer, names...) } // ResourcesOrCollect -- -func ResourcesOrCollect(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection, names ...string) error { +func ResourcesOrCollect(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection, customizer ResourceCustomizer, names ...string) error { for _, name := range names { - if err := ResourceOrCollect(ctx, c, namespace, collection, name); err != nil { + if err := ResourceOrCollect(ctx, c, namespace, collection, customizer, name); err != nil { return err } } @@ -45,18 +53,18 @@ func ResourcesOrCollect(ctx context.Context, c client.Client, namespace string, } // Resource installs a single named resource from the project resource directory -func Resource(ctx context.Context, c client.Client, namespace string, name string) error { - return ResourceOrCollect(ctx, c, namespace, nil, name) +func Resource(ctx context.Context, c client.Client, namespace string, customizer ResourceCustomizer, name string) error { + return ResourceOrCollect(ctx, c, namespace, nil, customizer, name) } // ResourceOrCollect -- -func ResourceOrCollect(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection, name string) error { +func ResourceOrCollect(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection, customizer ResourceCustomizer, name string) error { obj, err := kubernetes.LoadResourceFromYaml(c.GetScheme(), deploy.Resources[name]) if err != nil { return err } - return RuntimeObjectOrCollect(ctx, c, namespace, collection, obj) + return RuntimeObjectOrCollect(ctx, c, namespace, collection, customizer(obj)) } // RuntimeObject installs a single runtime object diff --git a/pkg/install/operator.go b/pkg/install/operator.go index aa2be13..8b1c8bb 100644 --- a/pkg/install/operator.go +++ b/pkg/install/operator.go @@ -21,6 +21,9 @@ import ( "context" "errors" + v1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/runtime" + "github.com/apache/camel-k/deploy" "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/apache/camel-k/pkg/client" @@ -31,22 +34,33 @@ import ( ) // Operator installs the operator resources in the given namespace -func Operator(ctx context.Context, c client.Client, namespace string) error { - return OperatorOrCollect(ctx, c, namespace, nil) +func Operator(ctx context.Context, c client.Client, customImage string, namespace string) error { + return OperatorOrCollect(ctx, c, namespace, customImage, nil) } // OperatorOrCollect installs the operator resources or adds them to the collector if present -func OperatorOrCollect(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection) error { +func OperatorOrCollect(ctx context.Context, c client.Client, namespace string, customImage string, collection *kubernetes.Collection) error { + customizer := IdentityResourceCustomizer + if customImage != "" { + customizer = func(o runtime.Object) runtime.Object { + if d, ok := o.(*v1.Deployment); ok { + if d.Labels["camel.apache.org/component"] == "operator" { + d.Spec.Template.Spec.Containers[0].Image = customImage + } + } + return o + } + } isOpenshift, err := openshift.IsOpenShift(c) if err != nil { return err } if isOpenshift { - if err := installOpenshift(ctx, c, namespace, collection); err != nil { + if err := installOpenshift(ctx, c, namespace, customizer, collection); err != nil { return err } } else { - if err := installKubernetes(ctx, c, namespace, collection); err != nil { + if err := installKubernetes(ctx, c, namespace, customizer, collection); err != nil { return err } } @@ -61,8 +75,8 @@ func OperatorOrCollect(ctx context.Context, c client.Client, namespace string, c return nil } -func installOpenshift(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection) error { - return ResourcesOrCollect(ctx, c, namespace, collection, +func installOpenshift(ctx context.Context, c client.Client, namespace string, customizer ResourceCustomizer, collection *kubernetes.Collection) error { + return ResourcesOrCollect(ctx, c, namespace, collection, customizer, "operator-service-account.yaml", "operator-role-openshift.yaml", "operator-role-binding.yaml", @@ -70,8 +84,8 @@ func installOpenshift(ctx context.Context, c client.Client, namespace string, co ) } -func installKubernetes(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection) error { - return ResourcesOrCollect(ctx, c, namespace, collection, +func installKubernetes(ctx context.Context, c client.Client, namespace string, customizer ResourceCustomizer, collection *kubernetes.Collection) error { + return ResourcesOrCollect(ctx, c, namespace, collection, customizer, "operator-service-account.yaml", "operator-role-kubernetes.yaml", "operator-role-binding.yaml", @@ -80,7 +94,7 @@ func installKubernetes(ctx context.Context, c client.Client, namespace string, c } func installKnative(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection) error { - return ResourcesOrCollect(ctx, c, namespace, collection, + return ResourcesOrCollect(ctx, c, namespace, collection, IdentityResourceCustomizer, "operator-role-knative.yaml", "operator-role-binding-knative.yaml", ) @@ -143,7 +157,7 @@ func Example(ctx context.Context, c client.Client, namespace string) error { // ExampleOrCollect -- func ExampleOrCollect(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection) error { - return ResourcesOrCollect(ctx, c, namespace, collection, + return ResourcesOrCollect(ctx, c, namespace, collection, IdentityResourceCustomizer, "cr-example.yaml", ) } diff --git a/pkg/platform/operator.go b/pkg/platform/operator.go new file mode 100644 index 0000000..4431364 --- /dev/null +++ b/pkg/platform/operator.go @@ -0,0 +1,40 @@ +package platform + +import ( + "context" + "errors" + "os" + + v1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const operatorNamespaceEnvVariable = "NAMESPACE" +const operatorPodNameEnvVariable = "POD_NAME" + +// GetCurrentOperatorImage returns the image currently used by the running operator if present (when running out of cluster, it may be absent). +func GetCurrentOperatorImage(ctx context.Context, c client.Client) (string, error) { + var podNamespace string + var podName string + var envSet bool + if podNamespace, envSet = os.LookupEnv(operatorNamespaceEnvVariable); !envSet || podNamespace == "" { + return "", nil + } + if podName, envSet = os.LookupEnv(operatorPodNameEnvVariable); !envSet || podName == "" { + return "", nil + } + + podKey := client.ObjectKey{ + Namespace: podNamespace, + Name: podName, + } + pod := v1.Pod{} + + if err := c.Get(ctx, podKey, &pod); err != nil { + return "", err + } + if len(pod.Spec.Containers) == 0 { + return "", errors.New("no containers found in operator pod") + } + return pod.Spec.Containers[0].Image, nil +} diff --git a/test/testing_env.go b/test/testing_env.go index dbeae00..91763c6 100644 --- a/test/testing_env.go +++ b/test/testing_env.go @@ -55,7 +55,7 @@ func init() { panic(err) } - err = install.Operator(testContext, testClient, getTargetNamespace()) + err = install.Operator(testContext, testClient, "", getTargetNamespace()) if err != nil { panic(err) }