You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2021/10/21 16:12:09 UTC
[camel-k] branch main updated (5964887 -> eb4e32e)
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git.
from 5964887 chore(dev): add .editorconfig
new 05fb571 Fix #2687: allow multiple secondary platforms on the same namespace
new ba9623b Fix #2687: select platform based on annotations
new 23f92a0 Fix #2687: cascade platform to resources
new 59466e1 Fix #2687: use annotations for both operator and platform
new 5927f54 Fix #2687: disallow namespaced names for platform
new 977081a Fix #2687: align with latest main
new 3a50603 Fix #2687: add e2e tests
new 6434548 Fix #2687: add documentation for multiple operators and platforms
new eb4e32e Fix #2687: fix profile on slow platform reconciliation
The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
docs/modules/ROOT/nav-end.adoc | 1 +
docs/modules/ROOT/pages/architecture/advanced.adoc | 76 +++++++++++++++++++
docs/modules/traits/pages/cron.adoc | 11 +++
e2e/common/secondary_platform_test.go | 74 +++++++++++++++++++
e2e/support/test_support.go | 71 +++++++++++++++---
pkg/apis/camel/v1/common_types.go | 5 +-
pkg/builder/builder.go | 2 +-
pkg/builder/image.go | 8 +-
pkg/cmd/run.go | 19 +++++
pkg/controller/integration/initialize.go | 2 +-
.../integration/integration_controller.go | 3 +-
pkg/controller/integration/kits.go | 2 +-
pkg/controller/integration/platform_setup.go | 6 +-
pkg/controller/integrationkit/build.go | 15 +++-
.../integrationkit/integrationkit_controller.go | 2 +-
pkg/controller/integrationplatform/create.go | 3 +-
pkg/controller/integrationplatform/initialize.go | 10 ++-
pkg/controller/kameletbinding/common.go | 2 +-
pkg/platform/operator.go | 4 +-
pkg/platform/platform.go | 85 ++++++++++++++++++----
pkg/trait/builder.go | 1 +
pkg/trait/container.go | 8 +-
pkg/trait/platform.go | 2 +-
pkg/trait/quarkus.go | 8 +-
pkg/trait/trait.go | 9 ++-
25 files changed, 376 insertions(+), 53 deletions(-)
create mode 100644 docs/modules/ROOT/pages/architecture/advanced.adoc
create mode 100644 e2e/common/secondary_platform_test.go
[camel-k] 02/09: Fix #2687: select platform based on annotations
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit ba9623bd8d5f5808e7715a4170eaac0fe2a130bf
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Wed Oct 13 17:54:24 2021 +0200
Fix #2687: select platform based on annotations
---
docs/modules/traits/pages/cron.adoc | 11 ++++++++
pkg/apis/camel/v1/common_types.go | 7 ++---
pkg/builder/builder.go | 2 +-
pkg/builder/image.go | 8 +++---
pkg/controller/integration/initialize.go | 2 +-
pkg/controller/integration/kits.go | 2 +-
pkg/controller/integration/platform_setup.go | 2 +-
pkg/controller/kameletbinding/common.go | 2 +-
pkg/platform/platform.go | 38 ++++++++++++++++++++++++++--
pkg/trait/builder.go | 1 +
pkg/trait/trait.go | 9 ++++---
11 files changed, 65 insertions(+), 19 deletions(-)
diff --git a/docs/modules/traits/pages/cron.adoc b/docs/modules/traits/pages/cron.adoc
index 7e67e51..8708acf 100755
--- a/docs/modules/traits/pages/cron.adoc
+++ b/docs/modules/traits/pages/cron.adoc
@@ -76,6 +76,17 @@ while `35m` or `50s` cannot).
| Optional deadline in seconds for starting the job if it misses scheduled
time for any reason. Missed jobs executions will be counted as failed ones.
+| cron.active-deadline-seconds
+| int64
+| Specifies the duration in seconds, relative to the start time, that the job
+may be continuously active before it is considered to be failed.
+It defaults to 60s.
+
+| cron.backoff-limit
+| int32
+| Specifies the number of retries before marking the job failed.
+It defaults to 2.
+
|===
// End of autogenerated code - DO NOT EDIT! (configuration)
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index 649ce6e..571f547 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -23,9 +23,10 @@ import (
)
const (
- TraitAnnotationPrefix = "trait.camel.apache.org/"
- OperatorIDLabel = "camel.apache.org/operator.id"
- SecondaryPlatformLabel = "camel.apache.org/secondary.platform"
+ TraitAnnotationPrefix = "trait.camel.apache.org/"
+ OperatorIDLabel = "camel.apache.org/operator.id"
+ SecondaryPlatformLabel = "camel.apache.org/secondary.platform"
+ PlatformSelectorAnnotation = "camel.apache.org/platform.id"
)
// BuildStrategy specifies how the Build should be executed
diff --git a/pkg/builder/builder.go b/pkg/builder/builder.go
index 5668119..fea59f7 100644
--- a/pkg/builder/builder.go
+++ b/pkg/builder/builder.go
@@ -88,7 +88,7 @@ func (t *builderTask) Do(ctx context.Context) v1.BuildStatus {
steps, err := StepsFrom(t.task.Steps...)
if err != nil {
- t.log.Errorf(err,"invalid builder steps: %s", t.task.Steps)
+ t.log.Errorf(err, "invalid builder steps: %s", t.task.Steps)
result.Failed(err)
return result
}
diff --git a/pkg/builder/image.go b/pkg/builder/image.go
index 637ca97..9d1835e 100644
--- a/pkg/builder/image.go
+++ b/pkg/builder/image.go
@@ -28,7 +28,6 @@ import (
ctrl "sigs.k8s.io/controller-runtime/pkg/client"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
- "github.com/apache/camel-k/pkg/platform"
"github.com/apache/camel-k/pkg/util"
"github.com/apache/camel-k/pkg/util/defaults"
)
@@ -146,11 +145,10 @@ func incrementalImageContext(ctx *builderContext) error {
}
}
} else {
- pl, err := platform.GetCurrent(ctx.C, ctx, ctx.Namespace)
- if err != nil {
- return err
+ if ctx.BaseImage == "" {
+ // TODO: transient workaround to be removed in 1.8.x
+ ctx.BaseImage = defaults.BaseImage()
}
- ctx.BaseImage = pl.Status.Build.BaseImage
}
return nil
diff --git a/pkg/controller/integration/initialize.go b/pkg/controller/integration/initialize.go
index 8f72899..c168fa7 100644
--- a/pkg/controller/integration/initialize.go
+++ b/pkg/controller/integration/initialize.go
@@ -68,7 +68,7 @@ func (action *initializeAction) Handle(ctx context.Context, integration *v1.Inte
kitName := integration.Spec.IntegrationKit.Name
if kitNamespace == "" {
- pl, err := platform.GetCurrent(ctx, action.client, integration.Namespace)
+ pl, err := platform.GetForResource(ctx, action.client, integration)
if err != nil && !k8serrors.IsNotFound(err) {
return nil, err
}
diff --git a/pkg/controller/integration/kits.go b/pkg/controller/integration/kits.go
index 49927da..f28723d 100644
--- a/pkg/controller/integration/kits.go
+++ b/pkg/controller/integration/kits.go
@@ -36,7 +36,7 @@ import (
)
func lookupKitsForIntegration(ctx context.Context, c ctrl.Reader, integration *v1.Integration, options ...ctrl.ListOption) ([]v1.IntegrationKit, error) {
- pl, err := platform.GetCurrent(ctx, c, integration.Namespace)
+ pl, err := platform.GetForResource(ctx, c, integration)
if err != nil && !errors.IsNotFound(err) {
return nil, err
}
diff --git a/pkg/controller/integration/platform_setup.go b/pkg/controller/integration/platform_setup.go
index 97cd3bb..de6ac1f 100644
--- a/pkg/controller/integration/platform_setup.go
+++ b/pkg/controller/integration/platform_setup.go
@@ -55,7 +55,7 @@ func (action *platformSetupAction) Handle(ctx context.Context, integration *v1.I
return nil, err
}
- pl, err := platform.GetCurrent(ctx, action.client, integration.Namespace)
+ pl, err := platform.GetForResource(ctx, action.client, integration)
if err != nil && !k8serrors.IsNotFound(err) {
return nil, err
} else if pl != nil {
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index ce219d8..08892fd 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -231,7 +231,7 @@ func determineProfile(ctx context.Context, c client.Client, binding *v1alpha1.Ka
if binding.Spec.Integration != nil && binding.Spec.Integration.Profile != "" {
return binding.Spec.Integration.Profile, nil
}
- pl, err := platform.GetCurrent(ctx, c, binding.Namespace)
+ pl, err := platform.GetForResource(ctx, c, binding)
if err != nil && !k8serrors.IsNotFound(err) {
return "", errors.Wrap(err, "error while retrieving the integration platform")
}
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index d273f3d..8cd6466 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -19,9 +19,12 @@ package platform
import (
"context"
+ "fmt"
+ "strings"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/util/kubernetes"
+ corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
@@ -33,8 +36,39 @@ const (
DefaultPlatformName = "camel-k"
)
-// GetCurrent returns the currently installed platform (local or global)
-func GetCurrent(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) {
+func GetForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object) (*v1.IntegrationPlatform, error) {
+ ref, err := extractPlatformSelector(o)
+ if err != nil {
+ return nil, err
+ }
+ if ref != nil {
+ return get(ctx, c, ref.Namespace, ref.Name)
+ }
+ return getCurrent(ctx, c, o.GetNamespace())
+}
+
+func extractPlatformSelector(o k8sclient.Object) (*corev1.ObjectReference, error) {
+ selectedPlatform := o.GetAnnotations()[v1.PlatformSelectorAnnotation]
+ if selectedPlatform == "" {
+ return nil, nil
+ }
+ parts := strings.Split(selectedPlatform, "/")
+ if len(parts) == 0 || len(parts) > 2 {
+ return nil, fmt.Errorf("Invalid platform selector: expected \"[namespace/]name\", got %q", selectedPlatform)
+ }
+ namespace := o.GetNamespace()
+ if len(parts) == 2 {
+ namespace = parts[0]
+ }
+ name := parts[len(parts)-1]
+ return &corev1.ObjectReference{
+ Namespace: namespace,
+ Name: name,
+ }, nil
+}
+
+// getCurrent returns the currently installed platform (local or global)
+func getCurrent(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) {
return find(ctx, c, namespace, true)
}
diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go
index 7a78a25..03db319 100644
--- a/pkg/trait/builder.go
+++ b/pkg/trait/builder.go
@@ -145,6 +145,7 @@ func (t *builderTrait) builderTask(e *Environment) (*v1.BuilderTask, error) {
BaseTask: v1.BaseTask{
Name: "builder",
},
+ BaseImage: e.Platform.Status.Build.BaseImage,
Runtime: e.CamelCatalog.Runtime,
Dependencies: e.IntegrationKit.Spec.Dependencies,
Maven: maven,
diff --git a/pkg/trait/trait.go b/pkg/trait/trait.go
index fe837f9..cbb3a9c 100644
--- a/pkg/trait/trait.go
+++ b/pkg/trait/trait.go
@@ -29,6 +29,7 @@ import (
"github.com/apache/camel-k/pkg/client"
"github.com/apache/camel-k/pkg/platform"
"github.com/apache/camel-k/pkg/util/kubernetes"
+ k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
func Apply(ctx context.Context, c client.Client, integration *v1.Integration, kit *v1.IntegrationKit) (*Environment, error) {
@@ -64,14 +65,14 @@ func newEnvironment(ctx context.Context, c client.Client, integration *v1.Integr
return nil, errors.New("neither integration nor kit are set")
}
- namespace := ""
+ var obj k8sclient.Object
if integration != nil {
- namespace = integration.Namespace
+ obj = integration
} else if kit != nil {
- namespace = kit.Namespace
+ obj = kit
}
- pl, err := platform.GetCurrent(ctx, c, namespace)
+ pl, err := platform.GetForResource(ctx, c, obj)
if err != nil && !k8serrors.IsNotFound(err) {
return nil, err
}
[camel-k] 07/09: Fix #2687: add e2e tests
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 3a5060398e58114bade7febbc6661e98e13fa327
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Mon Oct 18 15:50:35 2021 +0200
Fix #2687: add e2e tests
---
e2e/common/secondary_platform_test.go | 74 +++++++++++++++++++++++++++++++++++
e2e/support/test_support.go | 53 ++++++++++++++++++++++++-
pkg/cmd/run.go | 19 +++++++++
3 files changed, 145 insertions(+), 1 deletion(-)
diff --git a/e2e/common/secondary_platform_test.go b/e2e/common/secondary_platform_test.go
new file mode 100644
index 0000000..55ef6c4
--- /dev/null
+++ b/e2e/common/secondary_platform_test.go
@@ -0,0 +1,74 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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 common
+
+import (
+ "testing"
+
+ . "github.com/apache/camel-k/e2e/support"
+ v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+ . "github.com/onsi/gomega"
+ corev1 "k8s.io/api/core/v1"
+)
+
+func TestSecondaryPlatform(t *testing.T) {
+ WithNewTestNamespace(t, func(ns string) {
+ Expect(Kamel("install", "-n", ns).Execute()).To(Succeed())
+ Expect(ConfigureSecondayPlatfromWith(ns, func(p *v1.IntegrationPlatform) {
+ p.Name = "secondary"
+ if p.Spec.Traits == nil {
+ p.Spec.Traits = make(map[string]v1.TraitSpec)
+ }
+ p.Spec.Traits["container"] = v1.TraitSpec{
+ Configuration: AsTraitConfiguration(map[string]string{
+ "limitCPU": "0.1",
+ }),
+ }
+ })).To(Succeed())
+
+ Expect(Kamel("run", "-n", ns, "--name", "limited", "--annotation", "camel.apache.org/platform.id=secondary", "files/yaml.yaml").Execute()).To(Succeed())
+
+ Eventually(IntegrationPod(ns, "limited"), TestTimeoutMedium).Should(Not(BeNil()))
+ Eventually(IntegrationPodHas(ns, "limited", func(pod *corev1.Pod) bool {
+ if len(pod.Spec.Containers) != 1 {
+ return false
+ }
+ cpuLimits := pod.Spec.Containers[0].Resources.Limits.Cpu()
+ return cpuLimits != nil && cpuLimits.AsApproximateFloat64() > 0
+ }), TestTimeoutShort).Should(BeTrue())
+ Expect(Kamel("delete", "limited", "-n", ns).Execute()).To(Succeed())
+
+ Expect(Kamel("run", "-n", ns, "--name", "normal", "files/yaml.yaml").Execute()).To(Succeed())
+ Eventually(IntegrationPod(ns, "normal"), TestTimeoutShort).Should(Not(BeNil()))
+ Eventually(IntegrationPodHas(ns, "normal", func(pod *corev1.Pod) bool {
+ if len(pod.Spec.Containers) != 1 {
+ return false
+ }
+ cpuLimits := pod.Spec.Containers[0].Resources.Limits.Cpu()
+ return cpuLimits == nil || cpuLimits.IsZero()
+ }), TestTimeoutShort).Should(BeTrue())
+
+ // Clean up
+ Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+ })
+}
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index 64dbf5c..13fbd02 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -37,6 +37,7 @@ import (
"testing"
"time"
+ "github.com/apache/camel-k/pkg/platform"
"github.com/google/uuid"
"github.com/onsi/gomega"
"github.com/pkg/errors"
@@ -369,6 +370,16 @@ func IntegrationPod(ns string, name string) func() *corev1.Pod {
}
}
+func IntegrationPodHas(ns string, name string, predicate func(pod *corev1.Pod) bool) func() bool {
+ return func() bool {
+ pod := IntegrationPod(ns, name)()
+ if pod == nil {
+ return false
+ }
+ return predicate(pod)
+ }
+}
+
func IntegrationPods(ns string, name string) func() []corev1.Pod {
return func() []corev1.Pod {
lst := corev1.PodList{
@@ -1018,7 +1029,21 @@ func Platform(ns string) func() *v1.IntegrationPlatform {
return nil
}
if len(lst.Items) > 1 {
- panic("multiple integration platforms found in namespace " + ns)
+ var pl *v1.IntegrationPlatform
+ for _, p := range lst.Items {
+ p := p
+ if platform.IsSecondary(&p) {
+ continue
+ }
+ if pl != nil {
+ panic("multiple primary integration platforms found in namespace " + ns)
+ }
+ pl = &p
+ }
+ if pl == nil {
+ panic(fmt.Sprintf("multiple integration platforms found in namespace %q but no one is primary", ns))
+ }
+ return pl
}
return &lst.Items[0]
}
@@ -1080,6 +1105,22 @@ func AssignPlatformToOperator(ns, operator string) error {
return TestClient().Update(TestContext, pl)
}
+func ConfigureSecondayPlatfromWith(ns string, customizer func(pl *v1.IntegrationPlatform)) error {
+ pl := Platform(ns)()
+ if pl == nil {
+ return errors.New("cannot find primary platform")
+ }
+ if pl.Annotations == nil {
+ pl.Annotations = make(map[string]string)
+ }
+ pl.Annotations[v1.SecondaryPlatformAnnotation] = "true"
+ pl.ObjectMeta.ResourceVersion = ""
+ pl.Name = ""
+ pl.Status = v1.IntegrationPlatformStatus{}
+ customizer(pl)
+ return TestClient().Create(TestContext, pl)
+}
+
func CRDs() func() []metav1.APIResource {
return func() []metav1.APIResource {
@@ -1509,6 +1550,16 @@ func asEndpointProperties(props map[string]string) *v1alpha1.EndpointProperties
}
}
+func AsTraitConfiguration(props map[string]string) v1.TraitConfiguration {
+ bytes, err := json.Marshal(props)
+ if err != nil {
+ panic(err)
+ }
+ return v1.TraitConfiguration{
+ RawMessage: bytes,
+ }
+}
+
/*
Namespace testing functions
*/
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 45d755d..f7f4ba4 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -98,6 +98,7 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions)
cmd.Flags().StringArrayP("volume", "v", nil, "Mount a volume into the integration container. E.g \"-v pvcname:/container/path\"")
cmd.Flags().StringArrayP("env", "e", nil, "Set an environment variable in the integration container. E.g \"-e MY_VAR=my-value\"")
cmd.Flags().StringArray("property-file", nil, "[Deprecated] Bind a property file to the integration. E.g. \"--property-file integration.properties\"")
+ cmd.Flags().StringArray("annotation", nil, "Add an annotation to the integration. E.g. \"--annotation my.company=hello\"")
cmd.Flags().StringArray("label", nil, "Add a label to the integration. E.g. \"--label my.company=hello\"")
cmd.Flags().StringArray("source", nil, "Add source file to your integration, this is added to the list of files listed as arguments of the command")
cmd.Flags().String("pod-template", "", "The path of the YAML file containing a PodSpec template to be used for the Integration pods")
@@ -140,6 +141,7 @@ type runCmdOptions struct {
// Deprecated: PropertyFiles has been deprecated in 1.5
PropertyFiles []string `mapstructure:"property-files" yaml:",omitempty"`
Labels []string `mapstructure:"labels" yaml:",omitempty"`
+ Annotations []string `mapstructure:"annotations" yaml:",omitempty"`
Sources []string `mapstructure:"sources" yaml:",omitempty"`
}
@@ -256,6 +258,13 @@ func (o *runCmdOptions) validate() error {
}
}
+ for _, annotation := range o.Annotations {
+ parts := strings.SplitN(annotation, "=", 2)
+ if len(parts) != 2 {
+ return fmt.Errorf(`invalid annotation specification %s. Expected "<annotationkey>=<annotationvalue>"`, annotation)
+ }
+ }
+
return nil
}
@@ -520,6 +529,16 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C
}
}
+ for _, annotation := range o.Annotations {
+ parts := strings.SplitN(annotation, "=", 2)
+ if len(parts) == 2 {
+ if integration.Annotations == nil {
+ integration.Annotations = make(map[string]string)
+ }
+ integration.Annotations[parts[0]] = parts[1]
+ }
+ }
+
srcs := make([]string, 0, len(sources)+len(o.Sources))
srcs = append(srcs, sources...)
srcs = append(srcs, o.Sources...)
[camel-k] 03/09: Fix #2687: cascade platform to resources
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 23f92a039a391dec8b8788605bc2f990c262b969
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Thu Oct 14 10:50:46 2021 +0200
Fix #2687: cascade platform to resources
---
pkg/controller/integrationkit/build.go | 14 +++--
.../integrationkit/integrationkit_controller.go | 2 +-
pkg/platform/platform.go | 59 ++++++++++++++--------
pkg/trait/container.go | 5 ++
pkg/trait/platform.go | 2 +-
pkg/trait/quarkus.go | 5 ++
6 files changed, 62 insertions(+), 25 deletions(-)
diff --git a/pkg/controller/integrationkit/build.go b/pkg/controller/integrationkit/build.go
index 9f1c0ca..cb74cd0 100644
--- a/pkg/controller/integrationkit/build.go
+++ b/pkg/controller/integrationkit/build.go
@@ -90,6 +90,13 @@ func (action *buildAction) handleBuildSubmitted(ctx context.Context, kit *v1.Int
if operatorID != "" {
labels[v1.OperatorIDLabel] = operatorID
}
+ var annotations map[string]string
+ if v, ok := kit.Annotations[v1.PlatformSelectorAnnotation]; ok {
+ annotations = map[string]string{
+ v1.PlatformSelectorAnnotation: v,
+ }
+ }
+
timeout := env.Platform.Status.Build.GetTimeout()
if layout := labels[v1.IntegrationKitLayoutLabel]; env.Platform.Spec.Build.Timeout == nil && layout == v1.IntegrationKitLayoutNative {
// Increase the timeout to a sensible default
@@ -103,9 +110,10 @@ func (action *buildAction) handleBuildSubmitted(ctx context.Context, kit *v1.Int
Kind: v1.BuildKind,
},
ObjectMeta: metav1.ObjectMeta{
- Namespace: kit.Namespace,
- Name: kit.Name,
- Labels: labels,
+ Namespace: kit.Namespace,
+ Name: kit.Name,
+ Labels: labels,
+ Annotations: annotations,
},
Spec: v1.BuildSpec{
Strategy: env.Platform.Status.Build.BuildStrategy,
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go
index 1eebefa..b82d354 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -216,7 +216,7 @@ func (r *reconcileIntegrationKit) Reconcile(ctx context.Context, request reconci
return r.update(ctx, &instance, target)
} else {
// Platform is always local to the kit
- pl, err := platform.GetOrFindLocal(ctx, r.client, target.Namespace, target.Status.Platform, true)
+ pl, err := platform.GetOrFindLocalForResource(ctx, r.client, target, true)
if err != nil || pl.Status.Phase != v1.IntegrationPlatformPhaseReady {
target.Status.Phase = v1.IntegrationKitPhaseWaitingForPlatform
} else {
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index 8cd6466..e7e0774 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -37,6 +37,18 @@ const (
)
func GetForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object) (*v1.IntegrationPlatform, error) {
+ return GetOrFindForResource(ctx, c, o, true)
+}
+
+func GetOrFindForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object, active bool) (*v1.IntegrationPlatform, error) {
+ return getOrFindForResource(ctx, c, o, active, false)
+}
+
+func GetOrFindLocalForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object, active bool) (*v1.IntegrationPlatform, error) {
+ return getOrFindForResource(ctx, c, o, active, true)
+}
+
+func getOrFindForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object, active bool, local bool) (*v1.IntegrationPlatform, error) {
ref, err := extractPlatformSelector(o)
if err != nil {
return nil, err
@@ -44,7 +56,14 @@ func GetForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object)
if ref != nil {
return get(ctx, c, ref.Namespace, ref.Name)
}
- return getCurrent(ctx, c, o.GetNamespace())
+ if it, ok := o.(*v1.Integration); ok {
+ return getOrFind(ctx, c, it.Namespace, it.Status.Platform, active, local)
+ } else if ik, ok := o.(*v1.IntegrationKit); ok {
+ return getOrFind(ctx, c, ik.Namespace, ik.Status.Platform, active, local)
+ } else if b, ok := o.(*v1.Build); ok {
+ return getOrFind(ctx, c, b.Namespace, b.Status.Platform, active, local)
+ }
+ return find(ctx, c, o.GetNamespace(), active, local)
}
func extractPlatformSelector(o k8sclient.Object) (*corev1.ObjectReference, error) {
@@ -67,22 +86,24 @@ func extractPlatformSelector(o k8sclient.Object) (*corev1.ObjectReference, error
}, nil
}
-// getCurrent returns the currently installed platform (local or global)
-func getCurrent(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) {
- return find(ctx, c, namespace, true)
+func getOrFind(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool, local bool) (*v1.IntegrationPlatform, error) {
+ if local {
+ return getOrFindLocal(ctx, c, namespace, name, active)
+ }
+ return getOrFindAny(ctx, c, namespace, name, active)
}
-// GetOrFind returns the named platform or any other platform in the local namespace or the global one
-func GetOrFind(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool) (*v1.IntegrationPlatform, error) {
+// getOrFindAny returns the named platform or any other platform in the local namespace or the global one
+func getOrFindAny(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool) (*v1.IntegrationPlatform, error) {
if name != "" {
return get(ctx, c, namespace, name)
}
- return find(ctx, c, namespace, active)
+ return findAny(ctx, c, namespace, active)
}
-// GetOrFindLocal returns the named platform or any other platform in the local namespace
-func GetOrFindLocal(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool) (*v1.IntegrationPlatform, error) {
+// getOrFindLocal returns the named platform or any other platform in the local namespace
+func getOrFindLocal(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool) (*v1.IntegrationPlatform, error) {
if name != "" {
return kubernetes.GetIntegrationPlatform(ctx, c, name, namespace)
}
@@ -102,8 +123,15 @@ func get(ctx context.Context, c k8sclient.Reader, namespace string, name string)
return p, err
}
-// find returns the currently installed platform or any platform existing in local or operator namespace
-func find(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1.IntegrationPlatform, error) {
+func find(ctx context.Context, c k8sclient.Reader, namespace string, active bool, local bool) (*v1.IntegrationPlatform, error) {
+ if local {
+ return findLocal(ctx, c, namespace, active)
+ }
+ return findAny(ctx, c, namespace, active)
+}
+
+// findAny returns the currently installed platform or any platform existing in local or operator namespace
+func findAny(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1.IntegrationPlatform, error) {
p, err := findLocal(ctx, c, namespace, active)
if err != nil && k8serrors.IsNotFound(err) {
operatorNamespace := GetOperatorNamespace()
@@ -153,15 +181,6 @@ func ListPrimaryPlatforms(ctx context.Context, c k8sclient.Reader, namespace str
return &lst, nil
}
-// ListAllPlatforms returns all platforms installed in a given namespace
-func ListAllPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) {
- lst := v1.NewIntegrationPlatformList()
- if err := c.List(ctx, &lst, k8sclient.InNamespace(namespace)); err != nil {
- return nil, err
- }
- return &lst, nil
-}
-
// IsActive determines if the given platform is being used
func IsActive(p *v1.IntegrationPlatform) bool {
return p.Status.Phase != "" && p.Status.Phase != v1.IntegrationPlatformPhaseDuplicate
diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index ea4973f..00c9826 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -220,6 +220,11 @@ func (t *containerTrait) configureImageIntegrationKit(e *Environment) error {
if operatorID != "" {
kit.Labels[v1.OperatorIDLabel] = operatorID
}
+ if v, ok := e.Integration.Annotations[v1.PlatformSelectorAnnotation]; ok {
+ kit.Annotations = map[string]string{
+ v1.PlatformSelectorAnnotation: v,
+ }
+ }
t.L.Infof("image %s", kit.Spec.Image)
e.Resources.Add(kit)
diff --git a/pkg/trait/platform.go b/pkg/trait/platform.go
index d0d9b23..e273040 100644
--- a/pkg/trait/platform.go
+++ b/pkg/trait/platform.go
@@ -101,7 +101,7 @@ func (t *platformTrait) Apply(e *Environment) error {
}
func (t *platformTrait) getOrCreatePlatform(e *Environment) (*v1.IntegrationPlatform, error) {
- pl, err := platform.GetOrFind(e.Ctx, t.Client, e.Integration.Namespace, e.Integration.Status.Platform, false)
+ pl, err := platform.GetOrFindForResource(e.Ctx, t.Client, e.Integration, false)
if err != nil && k8serrors.IsNotFound(err) {
if IsTrue(t.CreateDefault) {
platformName := e.Integration.Status.Platform
diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go
index 2b53549..1c66527 100644
--- a/pkg/trait/quarkus.go
+++ b/pkg/trait/quarkus.go
@@ -265,6 +265,11 @@ func (t *quarkusTrait) newIntegrationKit(e *Environment, packageType quarkusPack
if operatorID != "" {
kit.Labels[v1.OperatorIDLabel] = operatorID
}
+ if v, ok := integration.Annotations[v1.PlatformSelectorAnnotation]; ok {
+ kit.Annotations = map[string]string{
+ v1.PlatformSelectorAnnotation: v,
+ }
+ }
traits := t.getKitTraits(e)
[camel-k] 06/09: Fix #2687: align with latest main
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 977081a80a386cf0b810d73848ef603b2a7f8449
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Fri Oct 15 11:32:18 2021 +0200
Fix #2687: align with latest main
---
pkg/controller/integration/integration_controller.go | 3 ++-
pkg/platform/platform.go | 2 --
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 239cbba..a4d6dfa 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -87,7 +87,8 @@ func add(mgr manager.Manager, c client.Client, r reconcile.Reconciler) error {
// Observe the time to first readiness metric
previous := old.Status.GetCondition(v1.IntegrationConditionReady)
if next := it.Status.GetCondition(v1.IntegrationConditionReady); (previous == nil || previous.Status != corev1.ConditionTrue && (previous.FirstTruthyTime == nil || previous.FirstTruthyTime.IsZero())) &&
- next != nil && next.Status == corev1.ConditionTrue && next.FirstTruthyTime != nil && !next.FirstTruthyTime.IsZero() {
+ next != nil && next.Status == corev1.ConditionTrue && next.FirstTruthyTime != nil && !next.FirstTruthyTime.IsZero() &&
+ it.Status.InitializationTimestamp != nil {
duration := next.FirstTruthyTime.Time.Sub(it.Status.InitializationTimestamp.Time)
Log.WithValues("request-namespace", it.Namespace, "request-name", it.Name).
ForIntegration(it).Infof("First readiness after %s", duration)
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index 78873de..8bb2a46 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -51,8 +51,6 @@ func getOrFindForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.O
return getOrFind(ctx, c, it.Namespace, it.Status.Platform, active, local)
} else if ik, ok := o.(*v1.IntegrationKit); ok {
return getOrFind(ctx, c, ik.Namespace, ik.Status.Platform, active, local)
- } else if b, ok := o.(*v1.Build); ok {
- return getOrFind(ctx, c, b.Namespace, b.Status.Platform, active, local)
}
return find(ctx, c, o.GetNamespace(), active, local)
}
[camel-k] 05/09: Fix #2687: disallow namespaced names for platform
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 5927f5408b0ec64139d16ef6a85be55091af2b21
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Thu Oct 14 13:26:44 2021 +0200
Fix #2687: disallow namespaced names for platform
---
pkg/platform/platform.go | 31 ++-----------------------------
1 file changed, 2 insertions(+), 29 deletions(-)
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index 73b365f..78873de 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -19,12 +19,9 @@ package platform
import (
"context"
- "fmt"
- "strings"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/util/kubernetes"
- corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -47,12 +44,8 @@ func GetOrFindLocalForResource(ctx context.Context, c k8sclient.Reader, o k8scli
}
func getOrFindForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object, active bool, local bool) (*v1.IntegrationPlatform, error) {
- ref, err := extractPlatformSelector(o)
- if err != nil {
- return nil, err
- }
- if ref != nil {
- return get(ctx, c, ref.Namespace, ref.Name)
+ if selectedPlatform, ok := o.GetAnnotations()[v1.PlatformSelectorAnnotation]; ok {
+ return get(ctx, c, o.GetNamespace(), selectedPlatform)
}
if it, ok := o.(*v1.Integration); ok {
return getOrFind(ctx, c, it.Namespace, it.Status.Platform, active, local)
@@ -64,26 +57,6 @@ func getOrFindForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.O
return find(ctx, c, o.GetNamespace(), active, local)
}
-func extractPlatformSelector(o k8sclient.Object) (*corev1.ObjectReference, error) {
- selectedPlatform := o.GetAnnotations()[v1.PlatformSelectorAnnotation]
- if selectedPlatform == "" {
- return nil, nil
- }
- parts := strings.Split(selectedPlatform, "/")
- if len(parts) == 0 || len(parts) > 2 {
- return nil, fmt.Errorf("Invalid platform selector: expected \"[namespace/]name\", got %q", selectedPlatform)
- }
- namespace := o.GetNamespace()
- if len(parts) == 2 {
- namespace = parts[0]
- }
- name := parts[len(parts)-1]
- return &corev1.ObjectReference{
- Namespace: namespace,
- Name: name,
- }, nil
-}
-
func getOrFind(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool, local bool) (*v1.IntegrationPlatform, error) {
if local {
return getOrFindLocal(ctx, c, namespace, name, active)
[camel-k] 09/09: Fix #2687: fix profile on slow platform
reconciliation
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit eb4e32e6d1e10018416d7ba7f53563ff638527f3
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Thu Oct 21 15:19:14 2021 +0200
Fix #2687: fix profile on slow platform reconciliation
---
pkg/controller/integration/platform_setup.go | 4 ++++
pkg/platform/platform.go | 2 ++
2 files changed, 6 insertions(+)
diff --git a/pkg/controller/integration/platform_setup.go b/pkg/controller/integration/platform_setup.go
index de6ac1f..8d01324 100644
--- a/pkg/controller/integration/platform_setup.go
+++ b/pkg/controller/integration/platform_setup.go
@@ -78,6 +78,10 @@ func determineBestProfile(ctx context.Context, c client.Client, integration *v1.
// Use platform profile if set
return p.Status.Profile
}
+ if p.Spec.Profile != "" {
+ // Use platform spec profile if set
+ return p.Spec.Profile
+ }
if knative.IsEnabledInNamespace(ctx, c, integration.Namespace) {
return v1.TraitProfileKnative
}
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index 8bb2a46..f0abb99 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -176,6 +176,8 @@ func IsSecondary(p *v1.IntegrationPlatform) bool {
func GetProfile(p *v1.IntegrationPlatform) v1.TraitProfile {
if p.Status.Profile != "" {
return p.Status.Profile
+ } else if p.Spec.Profile != "" {
+ return p.Spec.Profile
}
switch p.Status.Cluster {
[camel-k] 04/09: Fix #2687: use annotations for both operator and
platform
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 59466e182d2e56fd3bf02861d79dd0b2dfec8d48
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Thu Oct 14 13:24:07 2021 +0200
Fix #2687: use annotations for both operator and platform
---
e2e/support/test_support.go | 18 +++++++++---------
pkg/apis/camel/v1/common_types.go | 9 +++++----
pkg/controller/integrationkit/build.go | 13 ++++++-------
pkg/platform/operator.go | 4 ++--
pkg/platform/platform.go | 23 +++++++++++++++--------
pkg/trait/container.go | 13 +++++++------
pkg/trait/quarkus.go | 13 +++++++------
7 files changed, 51 insertions(+), 42 deletions(-)
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index 60fce20..64dbf5c 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -428,10 +428,10 @@ func AssignIntegrationToOperator(ns, name, operator string) error {
if it == nil {
return fmt.Errorf("cannot assign integration %q to operator: integration not found", name)
}
- if it.Labels == nil {
- it.Labels = make(map[string]string)
+ if it.Annotations == nil {
+ it.Annotations = make(map[string]string)
}
- it.Labels[v1.OperatorIDLabel] = operator
+ it.Annotations[v1.OperatorIDAnnotation] = operator
return TestClient().Update(TestContext, it)
}
@@ -745,10 +745,10 @@ func AssignKameletBindingToOperator(ns, name, operator string) error {
if klb == nil {
return fmt.Errorf("cannot assign kamelet binding %q to operator: kamelet binding not found", name)
}
- if klb.Labels == nil {
- klb.Labels = make(map[string]string)
+ if klb.Annotations == nil {
+ klb.Annotations = make(map[string]string)
}
- klb.Labels[v1.OperatorIDLabel] = operator
+ klb.Annotations[v1.OperatorIDAnnotation] = operator
return TestClient().Update(TestContext, klb)
}
@@ -1073,10 +1073,10 @@ func AssignPlatformToOperator(ns, operator string) error {
if pl == nil {
return errors.New("cannot assign platform to operator: no platform found")
}
- if pl.Labels == nil {
- pl.Labels = make(map[string]string)
+ if pl.Annotations == nil {
+ pl.Annotations = make(map[string]string)
}
- pl.Labels[v1.OperatorIDLabel] = operator
+ pl.Annotations[v1.OperatorIDAnnotation] = operator
return TestClient().Update(TestContext, pl)
}
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index 571f547..45e9f91 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -23,10 +23,11 @@ import (
)
const (
- TraitAnnotationPrefix = "trait.camel.apache.org/"
- OperatorIDLabel = "camel.apache.org/operator.id"
- SecondaryPlatformLabel = "camel.apache.org/secondary.platform"
- PlatformSelectorAnnotation = "camel.apache.org/platform.id"
+ TraitAnnotationPrefix = "trait.camel.apache.org/"
+
+ OperatorIDAnnotation = "camel.apache.org/operator.id"
+ SecondaryPlatformAnnotation = "camel.apache.org/secondary.platform"
+ PlatformSelectorAnnotation = "camel.apache.org/platform.id"
)
// BuildStrategy specifies how the Build should be executed
diff --git a/pkg/controller/integrationkit/build.go b/pkg/controller/integrationkit/build.go
index cb74cd0..47fa5c6 100644
--- a/pkg/controller/integrationkit/build.go
+++ b/pkg/controller/integrationkit/build.go
@@ -86,15 +86,14 @@ func (action *buildAction) handleBuildSubmitted(ctx context.Context, kit *v1.Int
labels := kubernetes.FilterCamelCreatorLabels(kit.Labels)
labels[v1.IntegrationKitLayoutLabel] = kit.Labels[v1.IntegrationKitLayoutLabel]
+
+ var annotations = make(map[string]string)
+ if v, ok := kit.Annotations[v1.PlatformSelectorAnnotation]; ok {
+ annotations[v1.PlatformSelectorAnnotation] = v
+ }
operatorID := defaults.OperatorID()
if operatorID != "" {
- labels[v1.OperatorIDLabel] = operatorID
- }
- var annotations map[string]string
- if v, ok := kit.Annotations[v1.PlatformSelectorAnnotation]; ok {
- annotations = map[string]string{
- v1.PlatformSelectorAnnotation: v,
- }
+ annotations[v1.OperatorIDAnnotation] = operatorID
}
timeout := env.Platform.Status.Build.GetTimeout()
diff --git a/pkg/platform/operator.go b/pkg/platform/operator.go
index d34c898..d8efd79 100644
--- a/pkg/platform/operator.go
+++ b/pkg/platform/operator.go
@@ -108,7 +108,7 @@ func IsOperatorHandler(object ctrl.Object) bool {
if object == nil {
return true
}
- resourceID := object.GetLabels()[camelv1.OperatorIDLabel]
+ resourceID := object.GetAnnotations()[camelv1.OperatorIDAnnotation]
operatorID := defaults.OperatorID()
return resourceID == operatorID
}
@@ -155,7 +155,7 @@ func (f FilteringFuncs) Update(e event.UpdateEvent) bool {
return false
}
if e.ObjectOld != nil && e.ObjectNew != nil &&
- e.ObjectOld.GetLabels()[camelv1.OperatorIDLabel] != e.ObjectNew.GetLabels()[camelv1.OperatorIDLabel] {
+ e.ObjectOld.GetAnnotations()[camelv1.OperatorIDAnnotation] != e.ObjectNew.GetAnnotations()[camelv1.OperatorIDAnnotation] {
// Always force reconciliation when the object becomes managed by the current operator
return true
}
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index e7e0774..73b365f 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -26,8 +26,6 @@ import (
"github.com/apache/camel-k/pkg/util/kubernetes"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/apimachinery/pkg/selection"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -167,15 +165,24 @@ func findLocal(ctx context.Context, c k8sclient.Reader, namespace string, active
// ListPrimaryPlatforms returns all non-secondary platforms installed in a given namespace (only one will be active)
func ListPrimaryPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) {
- lst := v1.NewIntegrationPlatformList()
- primaryPlatform, err := labels.NewRequirement(v1.SecondaryPlatformLabel, selection.DoesNotExist, []string{})
+ lst, err := ListAllPlatforms(ctx, c, namespace)
if err != nil {
return nil, err
}
- opt := k8sclient.MatchingLabelsSelector{
- labels.NewSelector().Add(*primaryPlatform),
+
+ filtered := v1.NewIntegrationPlatformList()
+ for _, pl := range lst.Items {
+ if val, present := pl.Annotations[v1.SecondaryPlatformAnnotation]; !present || val != "true" {
+ filtered.Items = append(filtered.Items, pl)
+ }
}
- if err := c.List(ctx, &lst, k8sclient.InNamespace(namespace), opt); err != nil {
+ return &filtered, nil
+}
+
+// ListAllPlatforms returns all platforms installed in a given namespace
+func ListAllPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) {
+ lst := v1.NewIntegrationPlatformList()
+ if err := c.List(ctx, &lst, k8sclient.InNamespace(namespace)); err != nil {
return nil, err
}
return &lst, nil
@@ -188,7 +195,7 @@ func IsActive(p *v1.IntegrationPlatform) bool {
// IsSecondary determines if the given platform is marked as secondary
func IsSecondary(p *v1.IntegrationPlatform) bool {
- if l, ok := p.Labels[v1.SecondaryPlatformLabel]; ok && l == "true" {
+ if l, ok := p.Annotations[v1.SecondaryPlatformAnnotation]; ok && l == "true" {
return true
}
return false
diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index 00c9826..bf9316f 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -216,14 +216,15 @@ func (t *containerTrait) configureImageIntegrationKit(e *Environment) error {
kubernetes.CamelCreatorLabelVersion: e.Integration.ResourceVersion,
}
- operatorID := defaults.OperatorID()
- if operatorID != "" {
- kit.Labels[v1.OperatorIDLabel] = operatorID
+ if kit.Annotations == nil {
+ kit.Annotations = make(map[string]string)
}
if v, ok := e.Integration.Annotations[v1.PlatformSelectorAnnotation]; ok {
- kit.Annotations = map[string]string{
- v1.PlatformSelectorAnnotation: v,
- }
+ kit.Annotations[v1.PlatformSelectorAnnotation] = v
+ }
+ operatorID := defaults.OperatorID()
+ if operatorID != "" {
+ kit.Annotations[v1.OperatorIDAnnotation] = operatorID
}
t.L.Infof("image %s", kit.Spec.Image)
diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go
index 1c66527..327afcc 100644
--- a/pkg/trait/quarkus.go
+++ b/pkg/trait/quarkus.go
@@ -261,14 +261,15 @@ func (t *quarkusTrait) newIntegrationKit(e *Environment, packageType quarkusPack
kubernetes.CamelCreatorLabelVersion: integration.ResourceVersion,
}
- operatorID := defaults.OperatorID()
- if operatorID != "" {
- kit.Labels[v1.OperatorIDLabel] = operatorID
+ if kit.Annotations == nil {
+ kit.Annotations = make(map[string]string)
}
if v, ok := integration.Annotations[v1.PlatformSelectorAnnotation]; ok {
- kit.Annotations = map[string]string{
- v1.PlatformSelectorAnnotation: v,
- }
+ kit.Annotations[v1.PlatformSelectorAnnotation] = v
+ }
+ operatorID := defaults.OperatorID()
+ if operatorID != "" {
+ kit.Annotations[v1.OperatorIDAnnotation] = operatorID
}
traits := t.getKitTraits(e)
[camel-k] 01/09: Fix #2687: allow multiple secondary platforms on
the same namespace
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 05fb571f3e6fdbb36fb70581085b00327f80e35d
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Tue Oct 12 17:29:03 2021 +0200
Fix #2687: allow multiple secondary platforms on the same namespace
---
pkg/apis/camel/v1/common_types.go | 5 ++--
pkg/controller/integrationplatform/create.go | 3 ++-
pkg/controller/integrationplatform/initialize.go | 10 +++++---
pkg/platform/platform.go | 32 +++++++++++++++++++++---
4 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index 78aa968..649ce6e 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -23,8 +23,9 @@ import (
)
const (
- TraitAnnotationPrefix = "trait.camel.apache.org/"
- OperatorIDLabel = "camel.apache.org/operator.id"
+ TraitAnnotationPrefix = "trait.camel.apache.org/"
+ OperatorIDLabel = "camel.apache.org/operator.id"
+ SecondaryPlatformLabel = "camel.apache.org/secondary.platform"
)
// BuildStrategy specifies how the Build should be executed
diff --git a/pkg/controller/integrationplatform/create.go b/pkg/controller/integrationplatform/create.go
index 6835ee5..2b4a071 100644
--- a/pkg/controller/integrationplatform/create.go
+++ b/pkg/controller/integrationplatform/create.go
@@ -20,6 +20,7 @@ package integrationplatform
import (
"context"
+ platformutil "github.com/apache/camel-k/pkg/platform"
"github.com/apache/camel-k/pkg/resources"
"github.com/apache/camel-k/pkg/util/defaults"
@@ -53,7 +54,7 @@ func (action *createAction) Handle(ctx context.Context, platform *v1.Integration
}
}
- if defaults.InstallDefaultKamelets() {
+ if !platformutil.IsSecondary(platform) && defaults.InstallDefaultKamelets() {
// Kamelet Catalog installed on platform reconciliation for cases where users install a global operator
if err := install.KameletCatalog(ctx, action.client, platform.Namespace); err != nil {
return nil, err
diff --git a/pkg/controller/integrationplatform/initialize.go b/pkg/controller/integrationplatform/initialize.go
index ccedcb5..eea1a50 100644
--- a/pkg/controller/integrationplatform/initialize.go
+++ b/pkg/controller/integrationplatform/initialize.go
@@ -49,7 +49,7 @@ func (action *initializeAction) CanHandle(platform *v1.IntegrationPlatform) bool
}
func (action *initializeAction) Handle(ctx context.Context, platform *v1.IntegrationPlatform) (*v1.IntegrationPlatform, error) {
- duplicate, err := action.isDuplicate(ctx, platform)
+ duplicate, err := action.isPrimaryDuplicate(ctx, platform)
if err != nil {
return nil, err
}
@@ -96,8 +96,12 @@ func (action *initializeAction) Handle(ctx context.Context, platform *v1.Integra
return platform, nil
}
-func (action *initializeAction) isDuplicate(ctx context.Context, thisPlatform *v1.IntegrationPlatform) (bool, error) {
- platforms, err := platformutil.ListPlatforms(ctx, action.client, thisPlatform.Namespace)
+func (action *initializeAction) isPrimaryDuplicate(ctx context.Context, thisPlatform *v1.IntegrationPlatform) (bool, error) {
+ if platformutil.IsSecondary(thisPlatform) {
+ // Always reconcile secondary platforms
+ return false, nil
+ }
+ platforms, err := platformutil.ListPrimaryPlatforms(ctx, action.client, thisPlatform.Namespace)
if err != nil {
return false, err
}
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index d566b5e..d273f3d 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -23,6 +23,8 @@ import (
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/util/kubernetes"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/apimachinery/pkg/selection"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -80,7 +82,7 @@ func find(ctx context.Context, c k8sclient.Reader, namespace string, active bool
// findLocal returns the currently installed platform or any platform existing in local namespace
func findLocal(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1.IntegrationPlatform, error) {
- lst, err := ListPlatforms(ctx, c, namespace)
+ lst, err := ListPrimaryPlatforms(ctx, c, namespace)
if err != nil {
return nil, err
}
@@ -101,8 +103,24 @@ func findLocal(ctx context.Context, c k8sclient.Reader, namespace string, active
return nil, k8serrors.NewNotFound(v1.Resource("IntegrationPlatform"), DefaultPlatformName)
}
-// ListPlatforms returns all platforms installed in a given namespace (only one will be active)
-func ListPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) {
+// ListPrimaryPlatforms returns all non-secondary platforms installed in a given namespace (only one will be active)
+func ListPrimaryPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) {
+ lst := v1.NewIntegrationPlatformList()
+ primaryPlatform, err := labels.NewRequirement(v1.SecondaryPlatformLabel, selection.DoesNotExist, []string{})
+ if err != nil {
+ return nil, err
+ }
+ opt := k8sclient.MatchingLabelsSelector{
+ labels.NewSelector().Add(*primaryPlatform),
+ }
+ if err := c.List(ctx, &lst, k8sclient.InNamespace(namespace), opt); err != nil {
+ return nil, err
+ }
+ return &lst, nil
+}
+
+// ListAllPlatforms returns all platforms installed in a given namespace
+func ListAllPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) {
lst := v1.NewIntegrationPlatformList()
if err := c.List(ctx, &lst, k8sclient.InNamespace(namespace)); err != nil {
return nil, err
@@ -115,6 +133,14 @@ func IsActive(p *v1.IntegrationPlatform) bool {
return p.Status.Phase != "" && p.Status.Phase != v1.IntegrationPlatformPhaseDuplicate
}
+// IsSecondary determines if the given platform is marked as secondary
+func IsSecondary(p *v1.IntegrationPlatform) bool {
+ if l, ok := p.Labels[v1.SecondaryPlatformLabel]; ok && l == "true" {
+ return true
+ }
+ return false
+}
+
// GetProfile returns the current profile of the platform (if present) or returns the default one for the cluster
func GetProfile(p *v1.IntegrationPlatform) v1.TraitProfile {
if p.Status.Profile != "" {
[camel-k] 08/09: Fix #2687: add documentation for multiple
operators and platforms
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 64345485e2d2a266b6e858929b7ae417168e375b
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Mon Oct 18 18:08:42 2021 +0200
Fix #2687: add documentation for multiple operators and platforms
---
docs/modules/ROOT/nav-end.adoc | 1 +
docs/modules/ROOT/pages/architecture/advanced.adoc | 76 ++++++++++++++++++++++
2 files changed, 77 insertions(+)
diff --git a/docs/modules/ROOT/nav-end.adoc b/docs/modules/ROOT/nav-end.adoc
index e49c4d3..2eeda4a 100644
--- a/docs/modules/ROOT/nav-end.adoc
+++ b/docs/modules/ROOT/nav-end.adoc
@@ -14,6 +14,7 @@
*** xref:architecture/cr/camel-catalog.adoc[CamelCatalog]
** xref:architecture/runtime.adoc[Runtime]
** xref:architecture/traits.adoc[Traits]
+** xref:architecture/advanced.adoc[Advanced Installation]
* xref:apis/camel.adoc[API]
* xref:uninstalling.adoc[Uninstalling]
* xref:contributing/developers.adoc[Contributing]
diff --git a/docs/modules/ROOT/pages/architecture/advanced.adoc b/docs/modules/ROOT/pages/architecture/advanced.adoc
new file mode 100644
index 0000000..8734675
--- /dev/null
+++ b/docs/modules/ROOT/pages/architecture/advanced.adoc
@@ -0,0 +1,76 @@
+[[advanced-installation]]
+= Advanced Installation
+
+This section provides information about special installation modes for the Camel K operator.
+These are advanced configuration options that normally are not needed by Camel K users,
+ but they may be useful for particular use cases.
+
+[[advanced-installation-multiple-operators]]
+== Multiple Operators and Selective Upgrades
+
+It's possible to setup multiple Camel K operators in a cluster to watch the same namespaces. It's not
+possible to configure Camel K this way using OLM (Operator Hub), since OLM prevents two operators from watching the same namespaces,
+but it's technically possible to achieve this setup manually.
+
+A typical example is when you install two global operators in different namespaces (e.g. `kamel install --global --olm=false -n camel-ns-1` and `kamel install --global --olm=false -n camel-ns-2`).
+In this situation, both operators will watch the same resources in the cluster, so that if a user creates an integration in any namespace,
+both operators will contend the integration and the reconciliation will most probably result in an error (actual behavior is undefined).
+
+To avoid contention, it's possible to specify for each operator an ID and then assign any custom resource (CR) to a specific operator using an annotation.
+The assigned operator will be responsible for the reconciliation of the annotated CR.
+
+In detail, the Camel K operator supports the environment variable `KAMEL_OPERATOR_ID`. The value is an identifier that can be equal to any string (e.g. `KAMEL_OPERATOR_ID=operator-1`).
+Once the operator is assigned an ID, it will *only reconcile* Camel custom resources that are assigned to that ID (unannotated resources will be ignored as well).
+
+To assign a resource to a specific operator, the user can annotate it with `camel.apache.org/operator.id`. For example:
+
+[source,yaml]
+----
+kind: Integration
+apiVersion: camel.apache.org/v1
+metadata:
+ annotations:
+ camel.apache.org/operator.id: operator-1
+# ...
+----
+
+The annotation can be put on any resource belonging to the "camel.apache.org" group.
+
+NOTE: When a resource creates additional resources in order to proceed with the reconciliation (for example
+an Integration may create an IntegrationKit, which in turn creates a Build resource), the annotation will be propagated to
+all resources created in the process, so they'll be all reconciled by the same operator.
+
+By using the `camel.apache.org/operator.id` annotation, it's possible to move integrations between two or more operators running different
+versions of the Camel K platform, i.e. *selectively upgrading or downgrading* them.
+
+[[advanced-installation-multiple-platforms]]
+== Configuring Multiple Integration Platforms
+
+Any running Camel K integration is associated to a shared IntegrationPlatform resource that contains general configuration options.
+The integration platform is located in the integration namespace (or also in the operator namespace, in case of global installation)
+and typically only one ("primary", see later) integration platform is allowed to obtain a "Ready" state in a namespace, while others get the "Duplicate" state (i.e. IntegrationPlatform resources
+are somewhat "singleton" in a namespace).
+
+There's a way to allow two or more integration platforms to get a "Ready" state in a namespace and for them to be used by integrations:
+platforms can be marked with the annotation `camel.apache.org/secondary.platform=true`.
+That annotation marks the platform as *secondary* so that it will never be used as default platform during the reconciliation of an integration,
+unless explicitly selected (any resource belonging to the "camel.apache.org" group can select a particular integration platform).
+Secondary platforms are also allowed to reach the "Ready" state without becoming "Duplicate".
+
+To specify which integration platform should be used to reconcile a specific CR, the CR can be annotated like in the following example:
+
+[source,yaml]
+----
+kind: Integration
+apiVersion: camel.apache.org/v1
+metadata:
+ annotations:
+ camel.apache.org/platform.id: my-platform-name
+# ...
+----
+
+The value of the `camel.apache.org/platform.id` annotation must match the name of an IntegrationPlatform custom resource, in the annotated resource namespace or
+also in the operator namespace.
+
+The selection of a secondary IntegrationPlatform enables new configuration scenarios, for example, sharing global configuration options for groups of integrations, or also
+providing per-operator specific configuration options e.g. when you install multiple global operators in the same namespace.