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

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

commit 23401b21aebd9b26aaa3f4152813a4c1c718536b
Author: Antonin Stefanutti <[email protected]>
AuthorDate: Thu Dec 9 12:29:46 2021 +0100

    chore: Try SSA for Kamelet install only once
---
 pkg/install/kamelets.go | 116 ++++++++++++++++++++++++++----------------------
 1 file changed, 63 insertions(+), 53 deletions(-)

diff --git a/pkg/install/kamelets.go b/pkg/install/kamelets.go
index 5712b55..82a818b 100644
--- a/pkg/install/kamelets.go
+++ b/pkg/install/kamelets.go
@@ -27,6 +27,7 @@ import (
        "path"
        "path/filepath"
        "strings"
+       "sync"
        "sync/atomic"
 
        "golang.org/x/sync/errgroup"
@@ -56,12 +57,9 @@ var (
        log = logf.Log
 
        hasServerSideApply atomic.Value
+       tryServerSideApply sync.Once
 )
 
-func init() {
-       hasServerSideApply.Store(true)
-}
-
 // KameletCatalog installs the bundled Kamelets into the specified namespace.
 func KameletCatalog(ctx context.Context, c client.Client, namespace string) 
error {
        kameletDir := os.Getenv(kameletDirEnv)
@@ -92,7 +90,36 @@ func KameletCatalog(ctx context.Context, c client.Client, 
namespace string) erro
                }
                // We may want to throttle the creation of Go routines if the 
number of bundled Kamelets increases.
                g.Go(func() error {
-                       return applyKamelet(gCtx, c, path.Join(kameletDir, 
f.Name()), namespace)
+                       kamelet, err := loadKamelet(path.Join(kameletDir, 
f.Name()), namespace, c.GetScheme())
+                       if err != nil {
+                               return err
+                       }
+                       once := false
+                       tryServerSideApply.Do(func() {
+                               once = true
+                               if err = serverSideApply(gCtx, c, kamelet); err 
!= nil {
+                                       if isIncompatibleServerError(err) {
+                                               log.Info("Fallback to 
client-side apply for installing bundled Kamelets")
+                                               hasServerSideApply.Store(false)
+                                               err = nil
+                                       } else {
+                                               tryServerSideApply = sync.Once{}
+                                       }
+                               } else {
+                                       hasServerSideApply.Store(true)
+                               }
+                       })
+                       if err != nil {
+                               return err
+                       }
+                       if v := hasServerSideApply.Load(); v.(bool) {
+                               if !once {
+                                       return serverSideApply(gCtx, c, kamelet)
+                               }
+                       } else {
+                               return clientSideApply(gCtx, c, kamelet)
+                       }
+                       return nil
                })
                return nil
        })
@@ -103,54 +130,6 @@ func KameletCatalog(ctx context.Context, c client.Client, 
namespace string) erro
        return g.Wait()
 }
 
-func applyKamelet(ctx context.Context, c client.Client, path string, namespace 
string) error {
-       content, err := util.ReadFile(path)
-       if err != nil {
-               return err
-       }
-
-       obj, err := kubernetes.LoadResourceFromYaml(c.GetScheme(), 
string(content))
-       if err != nil {
-               return err
-       }
-       kamelet, ok := obj.(*v1alpha1.Kamelet)
-       if !ok {
-               return fmt.Errorf("cannot load Kamelet from file %q", path)
-       }
-
-       kamelet.Namespace = namespace
-
-       if kamelet.GetAnnotations() == nil {
-               kamelet.SetAnnotations(make(map[string]string))
-       }
-       kamelet.GetAnnotations()[kamelVersionAnnotation] = defaults.Version
-
-       if kamelet.GetLabels() == nil {
-               kamelet.SetLabels(make(map[string]string))
-       }
-       kamelet.GetLabels()[v1alpha1.KameletBundledLabel] = "true"
-       kamelet.GetLabels()[v1alpha1.KameletReadOnlyLabel] = "true"
-
-       if v := hasServerSideApply.Load(); v.(bool) {
-               err := serverSideApply(ctx, c, kamelet)
-               switch {
-               case err == nil:
-                       return nil
-               case isIncompatibleServerError(err):
-                       log.Info("Fallback to client-side apply for installing 
bundled Kamelets")
-                       hasServerSideApply.Store(false)
-               default:
-                       return fmt.Errorf("could not apply Kamelet from file 
%q: %w", path, err)
-               }
-       }
-       err = clientSideApply(ctx, c, kamelet)
-       if err != nil {
-               return fmt.Errorf("could not apply Kamelet from file %q: %w", 
path, err)
-       }
-
-       return nil
-}
-
 func serverSideApply(ctx context.Context, c client.Client, resource 
runtime.Object) error {
        target, err := patch.PositiveApplyPatch(resource)
        if err != nil {
@@ -198,6 +177,37 @@ func isIncompatibleServerError(err error) bool {
        return false
 }
 
+func loadKamelet(path string, namespace string, scheme *runtime.Scheme) 
(*v1alpha1.Kamelet, error) {
+       content, err := util.ReadFile(path)
+       if err != nil {
+               return nil, err
+       }
+
+       obj, err := kubernetes.LoadResourceFromYaml(scheme, string(content))
+       if err != nil {
+               return nil, err
+       }
+       kamelet, ok := obj.(*v1alpha1.Kamelet)
+       if !ok {
+               return nil, fmt.Errorf("cannot load Kamelet from file %q", path)
+       }
+
+       kamelet.Namespace = namespace
+
+       if kamelet.GetAnnotations() == nil {
+               kamelet.SetAnnotations(make(map[string]string))
+       }
+       kamelet.GetAnnotations()[kamelVersionAnnotation] = defaults.Version
+
+       if kamelet.GetLabels() == nil {
+               kamelet.SetLabels(make(map[string]string))
+       }
+       kamelet.GetLabels()[v1alpha1.KameletBundledLabel] = "true"
+       kamelet.GetLabels()[v1alpha1.KameletReadOnlyLabel] = "true"
+
+       return kamelet, nil
+}
+
 // KameletViewerRole installs the role that allows any user ro access kamelets 
in the global namespace.
 func KameletViewerRole(ctx context.Context, c client.Client, namespace string) 
error {
        if err := Resource(ctx, c, namespace, true, IdentityResourceCustomizer, 
"/viewer/user-global-kamelet-viewer-role.yaml"); err != nil {

Reply via email to