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 03bb989d9ad9753f3b2354e0d35d418e853d1cdd
Author: Antonin Stefanutti <[email protected]>
AuthorDate: Mon Dec 6 15:09:04 2021 +0100

    chore: Parallel Kamelets install
---
 go.mod                  |   1 +
 pkg/install/kamelets.go | 106 ++++++++++++++++++++++++++++--------------------
 2 files changed, 63 insertions(+), 44 deletions(-)

diff --git a/go.mod b/go.mod
index 34497e8..e11b03b 100644
--- a/go.mod
+++ b/go.mod
@@ -43,6 +43,7 @@ require (
        go.uber.org/multierr v1.6.0
        go.uber.org/zap v1.19.1
        golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
+       golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
        gopkg.in/inf.v0 v0.9.1
        gopkg.in/yaml.v2 v2.4.0
        k8s.io/api v0.21.4
diff --git a/pkg/install/kamelets.go b/pkg/install/kamelets.go
index 91bebee..b2ad752 100644
--- a/pkg/install/kamelets.go
+++ b/pkg/install/kamelets.go
@@ -1,12 +1,12 @@
 /*
 Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
+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
+the License. You may obtain a copy of the License at
 
-   http://www.apache.org/licenses/LICENSE-2.0
+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,
@@ -20,19 +20,22 @@ package install
 import (
        "context"
        "fmt"
-       "io/ioutil"
+       "io/fs"
        "os"
        "path"
+       "path/filepath"
        "strings"
 
-       "github.com/apache/camel-k/pkg/util"
+       "golang.org/x/sync/errgroup"
 
-       "github.com/pkg/errors"
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
        "k8s.io/apimachinery/pkg/types"
 
+       "github.com/pkg/errors"
+
        "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
        "github.com/apache/camel-k/pkg/client"
+       "github.com/apache/camel-k/pkg/util"
        "github.com/apache/camel-k/pkg/util/defaults"
        "github.com/apache/camel-k/pkg/util/kubernetes"
 )
@@ -42,7 +45,7 @@ const (
        defaultKameletDir = "/kamelets/"
 )
 
-// KameletCatalog installs the bundled KameletCatalog into one namespace.
+// KameletCatalog installs the bundled Kamelets into the specified namespace.
 func KameletCatalog(ctx context.Context, c client.Client, namespace string) 
error {
        kameletDir := os.Getenv(kameletDirEnv)
        if kameletDir == "" {
@@ -58,57 +61,72 @@ func KameletCatalog(ctx context.Context, c client.Client, 
namespace string) erro
                return fmt.Errorf("kamelet directory %q is a file", kameletDir)
        }
 
-       files, err := ioutil.ReadDir(kameletDir)
+       g, gCtx := errgroup.WithContext(ctx)
+
+       err = filepath.WalkDir(kameletDir, func(p string, f fs.DirEntry, err 
error) error {
+               if err != nil {
+                       return err
+               }
+               if f.IsDir() && f.Name() != d.Name() {
+                       return fs.SkipDir
+               }
+               if !(strings.HasSuffix(f.Name(), ".yaml") || 
strings.HasSuffix(f.Name(), ".yml")) {
+                       return nil
+               }
+               // We may want to throttle the creation of Go routines if the 
number of bundled Kamelets increases.
+               g.Go(func() error {
+                       return createOrReplaceKamelet(gCtx, c, 
path.Join(kameletDir, f.Name()), namespace)
+               })
+               return nil
+       })
        if err != nil {
                return err
        }
 
-       for _, file := range files {
-               if file.IsDir() || !(strings.HasSuffix(file.Name(), ".yaml") || 
strings.HasSuffix(file.Name(), ".yml")) {
-                       continue
-               }
+       return g.Wait()
+}
 
-               content, err := util.ReadFile(path.Join(kameletDir, 
file.Name()))
-               if err != nil {
-                       return err
-               }
+func createOrReplaceKamelet(ctx context.Context, c client.Client, path string, 
namespace string) error {
+       fmt.Printf("Install file: %s in %s", path, namespace)
+
+       content, err := util.ReadFile(path)
+       if err != nil {
+               return err
+       }
 
-               obj, err := kubernetes.LoadResourceFromYaml(c.GetScheme(), 
string(content))
+       obj, err := kubernetes.LoadResourceFromYaml(c.GetScheme(), 
string(content))
+       if err != nil {
+               return err
+       }
+       if k, ok := obj.(*v1alpha1.Kamelet); ok {
+               existing := &v1alpha1.Kamelet{}
+               err = c.Get(ctx, types.NamespacedName{Namespace: namespace, 
Name: k.Name}, existing)
                if err != nil {
-                       return err
+                       if k8serrors.IsNotFound(err) {
+                               existing = nil
+                       } else {
+                               return err
+                       }
                }
-               if k, ok := obj.(*v1alpha1.Kamelet); ok {
-                       existing := &v1alpha1.Kamelet{}
-                       err = c.Get(ctx, types.NamespacedName{Namespace: 
namespace, Name: k.Name}, existing)
-                       if err != nil {
-                               if k8serrors.IsNotFound(err) {
-                                       existing = nil
-                               } else {
-                                       return err
-                               }
+
+               if existing == nil || 
existing.Labels[v1alpha1.KameletBundledLabel] == "true" {
+                       if k.GetAnnotations() == nil {
+                               k.SetAnnotations(make(map[string]string))
                        }
+                       k.GetAnnotations()[kamelVersionAnnotation] = 
defaults.Version
 
-                       if existing == nil || 
existing.Labels[v1alpha1.KameletBundledLabel] == "true" {
-                               if k.GetAnnotations() == nil {
-                                       
k.SetAnnotations(make(map[string]string))
-                               }
-                               k.GetAnnotations()[kamelVersionAnnotation] = 
defaults.Version
-
-                               if k.GetLabels() == nil {
-                                       k.SetLabels(make(map[string]string))
-                               }
-                               k.GetLabels()[v1alpha1.KameletBundledLabel] = 
"true"
-                               k.GetLabels()[v1alpha1.KameletReadOnlyLabel] = 
"true"
-
-                               err := ObjectOrCollect(ctx, c, namespace, nil, 
true, k)
-                               if err != nil {
-                                       return errors.Wrapf(err, "could not 
create resource from file %q", path.Join(kameletDir, file.Name()))
-                               }
+                       if k.GetLabels() == nil {
+                               k.SetLabels(make(map[string]string))
                        }
+                       k.GetLabels()[v1alpha1.KameletBundledLabel] = "true"
+                       k.GetLabels()[v1alpha1.KameletReadOnlyLabel] = "true"
 
+                       err := ObjectOrCollect(ctx, c, namespace, nil, true, k)
+                       if err != nil {
+                               return errors.Wrapf(err, "could not create 
resource from file %q", path)
+                       }
                }
        }
-
        return nil
 }
 

Reply via email to