This is an automated email from the ASF dual-hosted git repository.

lburgazzoli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit f312d55bd9f1ffe9277efb381a0c043724adb852
Author: nferraro <ni.ferr...@gmail.com>
AuthorDate: Tue Jun 4 16:47:36 2019 +0200

    Fix #703: automatically configure global build strategy
---
 pkg/cmd/install.go                               | 12 +++--
 pkg/controller/build/schedule_pod.go             | 21 ++++++++
 pkg/controller/integrationplatform/initialize.go | 12 +++--
 pkg/install/serviceaccount.go                    | 67 ++++++++++++++++++++++++
 pkg/platform/operator.go                         | 10 ++++
 5 files changed, 116 insertions(+), 6 deletions(-)

diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index ab91a9e..65d6b67 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -60,6 +60,7 @@ func newCmdInstall(rootCmdOptions *RootCmdOptions) 
*cobra.Command {
 
        cmd.Flags().BoolVarP(&impl.wait, "wait", "w", false, "Waits for the 
platform to be running")
        cmd.Flags().BoolVar(&impl.clusterSetupOnly, "cluster-setup", false, 
"Execute cluster-wide operations only (may require admin rights)")
+       cmd.Flags().BoolVar(&impl.skipOperatorSetup, "skip-operator-setup", 
false, "Do not install the operator in the namespace (in case there's a global 
one)")
        cmd.Flags().BoolVar(&impl.skipClusterSetup, "skip-cluster-setup", 
false, "Skip the cluster-setup phase")
        cmd.Flags().BoolVar(&impl.exampleSetup, "example", false, "Install 
example integration")
 
@@ -98,6 +99,7 @@ type installCmdOptions struct {
        *RootCmdOptions
        wait              bool
        clusterSetupOnly  bool
+       skipOperatorSetup bool
        skipClusterSetup  bool
        exampleSetup      bool
        outputFormat      string
@@ -149,9 +151,13 @@ func (o *installCmdOptions) install(_ *cobra.Command, _ 
[]string) error {
 
                namespace := o.Namespace
 
-               err = install.OperatorOrCollect(o.Context, c, namespace, 
o.operatorImage, collection)
-               if err != nil {
-                       return err
+               if !o.skipOperatorSetup {
+                       err = install.OperatorOrCollect(o.Context, c, 
namespace, o.operatorImage, collection)
+                       if err != nil {
+                               return err
+                       }
+               } else {
+                       fmt.Println("Camel K operator installation skipped")
                }
 
                platform, err := install.PlatformOrCollect(o.Context, c, 
namespace, o.registry, collection)
diff --git a/pkg/controller/build/schedule_pod.go 
b/pkg/controller/build/schedule_pod.go
index 212e0f6..60a9278 100644
--- a/pkg/controller/build/schedule_pod.go
+++ b/pkg/controller/build/schedule_pod.go
@@ -22,6 +22,7 @@ import (
        "sync"
 
        "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+       "github.com/apache/camel-k/pkg/install"
        "github.com/apache/camel-k/pkg/platform"
        "github.com/apache/camel-k/pkg/util/defaults"
 
@@ -105,6 +106,11 @@ func (action *schedulePodAction) Handle(ctx 
context.Context, build *v1alpha1.Bui
                return err
        }
 
+       // Ensure service account is present
+       if err := action.ensureServiceAccount(ctx, pod); err != nil {
+               return errors.Wrap(err, "cannot ensure service account is 
present")
+       }
+
        err = action.client.Delete(ctx, pod)
        if err != nil && !k8serrors.IsNotFound(err) {
                return errors.Wrap(err, "cannot delete build pod")
@@ -122,6 +128,21 @@ func (action *schedulePodAction) Handle(ctx 
context.Context, build *v1alpha1.Bui
        return action.client.Status().Update(ctx, target)
 }
 
+func (action *schedulePodAction) ensureServiceAccount(ctx context.Context, 
buildPod *corev1.Pod) error {
+       sa := corev1.ServiceAccount{}
+       saKey := k8sclient.ObjectKey{
+               Name:      "camel-k-operator",
+               Namespace: buildPod.Namespace,
+       }
+
+       err := action.client.Get(ctx, saKey, &sa)
+       if err != nil && k8serrors.IsNotFound(err) {
+               // Create a proper service account
+               return install.ServiceAccountRoles(ctx, action.client, 
buildPod.Namespace)
+       }
+       return err
+}
+
 func newBuildPod(build *v1alpha1.Build, operatorImage string) *corev1.Pod {
        builderImage := operatorImage
        if builderImage == "" {
diff --git a/pkg/controller/integrationplatform/initialize.go 
b/pkg/controller/integrationplatform/initialize.go
index f8c2f9b..d8cea6e 100644
--- a/pkg/controller/integrationplatform/initialize.go
+++ b/pkg/controller/integrationplatform/initialize.go
@@ -93,11 +93,17 @@ func (action *initializeAction) Handle(ctx context.Context, 
ip *v1alpha1.Integra
        }
 
        if target.Spec.Build.BuildStrategy == "" {
-               if target.Spec.Build.PublishStrategy == 
v1alpha1.IntegrationPlatformBuildPublishStrategyKaniko {
-                       // The build output has to be shared with Kaniko via a 
persistent volume
+               // If the operator is global, a global build strategy should be 
used
+               if platform.IsCurrentOperatorGlobal() {
+                       // The only global strategy we have for now
                        target.Spec.Build.BuildStrategy = 
v1alpha1.IntegrationPlatformBuildStrategyPod
                } else {
-                       target.Spec.Build.BuildStrategy = 
v1alpha1.IntegrationPlatformBuildStrategyRoutine
+                       if target.Spec.Build.PublishStrategy == 
v1alpha1.IntegrationPlatformBuildPublishStrategyKaniko {
+                               // The build output has to be shared with 
Kaniko via a persistent volume
+                               target.Spec.Build.BuildStrategy = 
v1alpha1.IntegrationPlatformBuildStrategyPod
+                       } else {
+                               target.Spec.Build.BuildStrategy = 
v1alpha1.IntegrationPlatformBuildStrategyRoutine
+                       }
                }
        }
 
diff --git a/pkg/install/serviceaccount.go b/pkg/install/serviceaccount.go
new file mode 100644
index 0000000..7a9cf9f
--- /dev/null
+++ b/pkg/install/serviceaccount.go
@@ -0,0 +1,67 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package install
+
+import (
+       "context"
+       "github.com/apache/camel-k/pkg/client"
+       "github.com/apache/camel-k/pkg/util/knative"
+       "github.com/apache/camel-k/pkg/util/openshift"
+)
+
+// ServiceAccountRoles installs the service account and related roles in the 
given namespace
+func ServiceAccountRoles(ctx context.Context, c client.Client, namespace 
string) error {
+       isOpenshift, err := openshift.IsOpenShift(c)
+       if err != nil {
+               return err
+       }
+       if isOpenshift {
+               if err := installServiceAccountRolesOpenshift(ctx, c, 
namespace); err != nil {
+                       return err
+               }
+       } else {
+               if err := installServiceAccountRolesKubernetes(ctx, c, 
namespace); err != nil {
+                       return err
+               }
+       }
+       // Install Knative resources if required
+       isKnative, err := knative.IsInstalled(ctx, c)
+       if err != nil {
+               return err
+       }
+       if isKnative {
+               return installKnative(ctx, c, namespace, nil)
+       }
+       return nil
+}
+
+func installServiceAccountRolesOpenshift(ctx context.Context, c client.Client, 
namespace string) error {
+       return ResourcesOrCollect(ctx, c, namespace, nil, 
IdentityResourceCustomizer,
+               "operator-service-account.yaml",
+               "operator-role-openshift.yaml",
+               "operator-role-binding.yaml",
+       )
+}
+
+func installServiceAccountRolesKubernetes(ctx context.Context, c 
client.Client, namespace string) error {
+       return ResourcesOrCollect(ctx, c, namespace, nil, 
IdentityResourceCustomizer,
+               "operator-service-account.yaml",
+               "operator-role-kubernetes.yaml",
+               "operator-role-binding.yaml",
+       )
+}
diff --git a/pkg/platform/operator.go b/pkg/platform/operator.go
index f180cd9..2ffd051 100644
--- a/pkg/platform/operator.go
+++ b/pkg/platform/operator.go
@@ -21,11 +21,13 @@ import (
        "context"
        "errors"
        "os"
+       "strings"
 
        v1 "k8s.io/api/core/v1"
        "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
+const operatorWatchNamespaceEnvVariable = "WATCH_NAMESPACE"
 const operatorNamespaceEnvVariable = "NAMESPACE"
 const operatorPodNameEnvVariable = "POD_NAME"
 
@@ -55,3 +57,11 @@ func GetCurrentOperatorImage(ctx context.Context, c 
client.Client) (string, erro
        }
        return pod.Spec.Containers[0].Image, nil
 }
+
+// IsCurrentOperatorGlobal returns true if the operator is configured to watch 
all namespaces
+func IsCurrentOperatorGlobal() bool {
+       if watchNamespace, envSet := 
os.LookupEnv(operatorWatchNamespaceEnvVariable); !envSet || 
strings.TrimSpace(watchNamespace) == "" {
+               return true
+       }
+       return false
+}

Reply via email to