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 {
