Skip to content

Commit

Permalink
fix(#3393): Make CronJob functionality optional
Browse files Browse the repository at this point in the history
- Explicitly check for CronJob batch/v1 API availability before using it
- CronJob batch/v1 API is not available on OpenShift 3.x
- Disable cron job e2e test on OpenShift 3.x
  • Loading branch information
christophd committed Jun 30, 2022
1 parent 56d3bc6 commit d4dfc48
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 34 deletions.
11 changes: 3 additions & 8 deletions e2e/common/cli/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ package common

import (
"bytes"
"reflect"
"strings"
"testing"
"text/template"
Expand All @@ -36,9 +35,8 @@ import (
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/install"
"github.com/apache/camel-k/pkg/util/defaults"
"github.com/apache/camel-k/pkg/util/kubernetes"
"github.com/apache/camel-k/pkg/util/openshift"
console "github.com/openshift/api/console/v1"
consolev1 "github.com/openshift/api/console/v1"
corev1 "k8s.io/api/core/v1"
)

Expand Down Expand Up @@ -98,11 +96,8 @@ func TestConsoleCliDownload(t *testing.T) {
ocp, err := openshift.IsOpenShift(TestClient())
assert.Nil(t, err)

ok, err := kubernetes.IsAPIResourceInstalled(TestClient(), "console.openshift.io/v1", reflect.TypeOf(console.ConsoleCLIDownload{}).Name())
assert.Nil(t, err)

if !ocp || !ok {
t.Skip("This test requires ConsoleCliDownload object which is available on OpenShift 4 only.")
if !ocp || !IsAPIResourceInstalled(t, TestClient(), "console.openshift.io/v1", consolev1.ConsoleCLIDownload{}) {
t.Skip("This test requires ConsoleCliDownload object which is available on OpenShift 4+ only.")
return
}

Expand Down
6 changes: 6 additions & 0 deletions e2e/common/cron_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,19 @@ import (

. "github.com/onsi/gomega"

batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"

. "github.com/apache/camel-k/e2e/support"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
)

func TestRunCronExample(t *testing.T) {
if !IsAPIResourceInstalled(t, TestClient(), "batch/v1", batchv1.CronJob{}) {
t.Skip("This test requires CronJob batch/v1 API installed.")
return
}

WithNewTestNamespace(t, func(ns string) {
Expect(Kamel("install", "-n", ns).Execute()).To(Succeed())

Expand Down
6 changes: 6 additions & 0 deletions e2e/support/test_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -1933,3 +1933,9 @@ func GetOutputStringAsync(cmd *cobra.Command) func() string {
return buffer.String()
}
}

func IsAPIResourceInstalled(t *testing.T, client client.Client, groupVersion string, obj interface{}) bool {
ok, err := kubernetes.IsAPIResourceInstalled(client, groupVersion, reflect.TypeOf(obj).Name())
assert.Nil(t, err)
return ok
}
26 changes: 19 additions & 7 deletions pkg/cmd/operator/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"
"math/rand"
"os"
"reflect"
"runtime"
"strconv"
"strings"
Expand Down Expand Up @@ -192,6 +193,23 @@ func Run(healthPort, monitoringPort int32, leaderElection bool, leaderElectionID
exitOnError(err, "cannot create Integration label selector")
selector := labels.NewSelector().Add(*hasIntegrationLabel)

selectors := cache.SelectorsByObject{
&corev1.Pod{}: {Label: selector},
&appsv1.Deployment{}: {Label: selector},
&batchv1.Job{}: {Label: selector},
&servingv1.Service{}: {Label: selector},
}

if ok, err := kubernetes.IsAPIResourceInstalled(c, batchv1.SchemeGroupVersion.String(), reflect.TypeOf(batchv1.CronJob{}).Name()); ok && err == nil {
selectors = cache.SelectorsByObject{
&corev1.Pod{}: {Label: selector},
&appsv1.Deployment{}: {Label: selector},
&batchv1.CronJob{}: {Label: selector},
&batchv1.Job{}: {Label: selector},
&servingv1.Service{}: {Label: selector},
}
}

mgr, err := manager.New(c.GetConfig(), manager.Options{
Namespace: watchNamespace,
EventBroadcaster: broadcaster,
Expand All @@ -204,13 +222,7 @@ func Run(healthPort, monitoringPort int32, leaderElection bool, leaderElectionID
MetricsBindAddress: ":" + strconv.Itoa(int(monitoringPort)),
NewCache: cache.BuilderWithOptions(
cache.Options{
SelectorsByObject: cache.SelectorsByObject{
&corev1.Pod{}: {Label: selector},
&appsv1.Deployment{}: {Label: selector},
&batchv1.CronJob{}: {Label: selector},
&batchv1.Job{}: {Label: selector},
&servingv1.Service{}: {Label: selector},
},
SelectorsByObject: selectors,
},
),
})
Expand Down
7 changes: 5 additions & 2 deletions pkg/controller/integration/integration_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,6 @@ func add(mgr manager.Manager, c client.Client, r reconcile.Reconciler) error {
})).
// Watch for the owned Deployments
Owns(&appsv1.Deployment{}, builder.WithPredicates(StatusChangedPredicate{})).
// Watch for the owned CronJobs
Owns(&batchv1.CronJob{}, builder.WithPredicates(StatusChangedPredicate{})).
// Watch for the Integration Pods
Watches(&source.Kind{Type: &corev1.Pod{}},
handler.EnqueueRequestsFromMapFunc(func(a ctrl.Object) []reconcile.Request {
Expand All @@ -225,6 +223,11 @@ func add(mgr manager.Manager, c client.Client, r reconcile.Reconciler) error {
}
}))

if ok, err := kubernetes.IsAPIResourceInstalled(c, batchv1.SchemeGroupVersion.String(), reflect.TypeOf(batchv1.CronJob{}).Name()); ok && err == nil {
// Watch for the owned CronJobs
b.Owns(&batchv1.CronJob{}, builder.WithPredicates(StatusChangedPredicate{}))
}

// Watch for the owned Knative Services conditionally
if ok, err := kubernetes.IsAPIResourceInstalled(c, servingv1.SchemeGroupVersion.String(), reflect.TypeOf(servingv1.Service{}).Name()); err != nil {
return err
Expand Down
23 changes: 13 additions & 10 deletions pkg/trait/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package trait
import (
"fmt"
"path"
"reflect"

appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
Expand Down Expand Up @@ -297,17 +298,19 @@ func (t *containerTrait) configureContainer(e *Environment) error {
return err
}

// CronJob
if err := e.Resources.VisitCronJobE(func(cron *batchv1.CronJob) error {
for _, envVar := range e.EnvVars {
envvar.SetVar(&container.Env, envVar)
}
if ok, err := kubernetes.IsAPIResourceInstalled(e.Client, batchv1.SchemeGroupVersion.String(), reflect.TypeOf(batchv1.CronJob{}).Name()); ok && err == nil {
// CronJob
if err := e.Resources.VisitCronJobE(func(cron *batchv1.CronJob) error {
for _, envVar := range e.EnvVars {
envvar.SetVar(&container.Env, envVar)
}

containers = &cron.Spec.JobTemplate.Spec.Template.Spec.Containers
visited = true
return nil
}); err != nil {
return err
containers = &cron.Spec.JobTemplate.Spec.Template.Spec.Containers
visited = true
return nil
}); err != nil {
return err
}
}

if visited {
Expand Down
2 changes: 2 additions & 0 deletions pkg/trait/container_probes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ func newTestProbesEnv(t *testing.T, integration *v1.Integration) Environment {
assert.Nil(t, err)
assert.NotNil(t, catalog)

client, _ := test.NewFakeClient()
traitCatalog := NewCatalog(nil)

return Environment{
Catalog: traitCatalog,
CamelCatalog: catalog,
Client: client,
Platform: &v1.IntegrationPlatform{},
Integration: integration,
Resources: kubernetes.NewCollection(),
Expand Down
2 changes: 2 additions & 0 deletions pkg/trait/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ func TestContainerWithDefaults(t *testing.T) {
catalog, err := camel.DefaultCatalog()
assert.Nil(t, err)

client, _ := test.NewFakeClient()
traitCatalog := NewCatalog(nil)

environment := Environment{
CamelCatalog: catalog,
Catalog: traitCatalog,
Client: client,
Integration: &v1.Integration{
ObjectMeta: metav1.ObjectMeta{
Name: ServiceTestName,
Expand Down
17 changes: 10 additions & 7 deletions pkg/trait/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package trait
import (
"fmt"
"path/filepath"
"reflect"
"strings"

appsv1 "k8s.io/api/apps/v1"
Expand Down Expand Up @@ -118,13 +119,15 @@ func (t *mountTrait) Apply(e *Environment) error {
return err
}

// CronJob
if err := e.Resources.VisitCronJobE(func(cron *batchv1.CronJob) error {
volumes = &cron.Spec.JobTemplate.Spec.Template.Spec.Volumes
visited = true
return nil
}); err != nil {
return err
if ok, err := kubernetes.IsAPIResourceInstalled(e.Client, batchv1.SchemeGroupVersion.String(), reflect.TypeOf(batchv1.CronJob{}).Name()); ok && err == nil {
// CronJob
if err := e.Resources.VisitCronJobE(func(cron *batchv1.CronJob) error {
volumes = &cron.Spec.JobTemplate.Spec.Template.Spec.Volumes
visited = true
return nil
}); err != nil {
return err
}
}

if visited {
Expand Down

0 comments on commit d4dfc48

Please sign in to comment.