Skip to content

Commit

Permalink
Remove Cache Service Support. Resolves infinispan#2072
Browse files Browse the repository at this point in the history
  • Loading branch information
rigazilla authored May 16, 2024
1 parent 19ec56a commit a19b424
Show file tree
Hide file tree
Showing 29 changed files with 37 additions and 781 deletions.
33 changes: 7 additions & 26 deletions api/v1/infinispan_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ func (i *Infinispan) Default() {
i.Spec.Version = versionManager.Latest().Ref()
}
if i.Spec.Service.Type == "" {
i.Spec.Service.Type = ServiceTypeCache
}
if i.Spec.Service.Type == ServiceTypeCache && i.Spec.Service.ReplicationFactor == 0 {
i.Spec.Service.ReplicationFactor = 2
i.Spec.Service.Type = ServiceTypeDataGrid
}
if i.Spec.Container.Memory == "" {
i.Spec.Container.Memory = consts.DefaultMemorySize.String()
Expand Down Expand Up @@ -224,9 +221,9 @@ func (i *Infinispan) ValidateUpdate(oldRuntimeObj runtime.Object) error {
}

if old.IsDataGrid() && i.IsCache() {
errMsg := "ServiceType Cache configured is deprecated and will be removed in future releases. ServiceType DataGrid is recomended."
eventRec.Event(i, corev1.EventTypeWarning, "DeprecatedCacheService", errMsg)
log.Info(errMsg, "Request.Namespace", i.Namespace, "Request.Name", i.Name)
msg := "CacheService is no longer supported."
err := field.Forbidden(field.NewPath("spec").Child("service").Child("type"), msg)
allErrs = append(allErrs, err)
}

return errorListToError(i, allErrs)
Expand Down Expand Up @@ -285,7 +282,9 @@ func (i *Infinispan) validate() error {
}
}

if err := i.validateCacheService(); err != nil {
if i.IsCache() {
msg := "CacheService is no longer supported."
err := field.Forbidden(field.NewPath("spec").Child("service").Child("type"), msg)
allErrs = append(allErrs, err)
}

Expand Down Expand Up @@ -470,21 +469,3 @@ func errorListToError(i *Infinispan, allErrs field.ErrorList) error {
}
return nil
}

func (i *Infinispan) validateCacheService() *field.Error {
// If a CacheService is requested, checks that the pods have enough memory
if i.Spec.Service.Type == ServiceTypeCache {
// We can ignore error here as we have already checked Memory spec is valid
_, memoryQ, _ := i.Spec.Container.GetMemoryResources()
memory := memoryQ.Value()
nativeMemoryOverhead := (memory * consts.CacheServiceJvmNativePercentageOverhead) / 100
occupiedMemory := (consts.CacheServiceJvmNativeMb * 1024 * 1024) +
(consts.CacheServiceFixedMemoryXmxMb * 1024 * 1024) +
nativeMemoryOverhead
if memory < occupiedMemory {
msg := fmt.Sprintf("Not enough memory allocated. The Cache Service requires at least %d bytes", occupiedMemory)
return field.Invalid(field.NewPath("spec").Child("container").Child("memory"), i.Spec.Container.Memory, msg)
}
}
return nil
}
43 changes: 5 additions & 38 deletions api/v1/infinispan_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,20 @@ var _ = Describe("Infinispan Webhooks", func() {
})

Context("Infinispan", func() {
It("Should initiate Cache Service defaults", func() {
It("Should return an error if CR is CacheService", func() {

created := &Infinispan{
failed := &Infinispan{
ObjectMeta: metav1.ObjectMeta{
Name: key.Name,
Namespace: key.Namespace,
},
Spec: InfinispanSpec{
Service: InfinispanServiceSpec{Type: ServiceTypeCache},
Replicas: 1,
},
}

Expect(k8sClient.Create(ctx, created)).Should(Succeed())

Expect(k8sClient.Get(ctx, key, created)).Should(Succeed())
spec := created.Spec
// Ensure default values correctly set
Expect(spec.Service.Type).Should(Equal(ServiceTypeCache))
Expect(spec.Service.ReplicationFactor).Should(Equal(int32(2)))
Expect(spec.Container.Memory).Should(Equal(consts.DefaultMemorySize.String()))
Expect(spec.Security.EndpointAuthentication).Should(Equal(pointer.BoolPtr(true)))
Expect(spec.Security.EndpointSecretName).Should(Equal(created.GetSecretName()))
Expect(spec.Upgrades.Type).Should(Equal(UpgradeTypeShutdown))
Expect(spec.ConfigListener.Enabled).Should(BeTrue())
Expect(spec.ConfigListener.Logging.Level).Should(Equal(ConfigListenerLoggingInfo))
Expect(spec.Jmx.Enabled).Should(Equal(false))
err := k8sClient.Create(ctx, failed)
expectInvalidErrStatus(err, statusDetailCause{"FieldValueForbidden", "spec.service.type", "CacheService is no longer supported."})
})

It("Should initiate DataGrid defaults", func() {
Expand Down Expand Up @@ -261,25 +249,6 @@ var _ = Describe("Infinispan Webhooks", func() {
expectInvalidErrStatus(err, statusDetailCause{metav1.CauseTypeFieldValueRequired, "spec.security.endpointEncryption.certSecretName", "certificateSourceType=Secret' to be configured"})
})

It("Should return error if Cache Service does not have sufficient memory", func() {

failed := &Infinispan{
ObjectMeta: metav1.ObjectMeta{
Name: key.Name,
Namespace: key.Namespace,
},
Spec: InfinispanSpec{
Replicas: 1,
Container: InfinispanContainerSpec{
Memory: "1Mi",
},
},
}

err := k8sClient.Create(ctx, failed)
expectInvalidErrStatus(err, statusDetailCause{metav1.CauseTypeFieldValueInvalid, "spec.container.memory", "Not enough memory allocated"})
})

It("Should return error if malformed memory or CPU request is greater than limit", func() {

failed := &Infinispan{
Expand Down Expand Up @@ -358,8 +327,6 @@ var _ = Describe("Infinispan Webhooks", func() {

err := k8sClient.Create(ctx, failed)
expectInvalidErrStatus(err, []statusDetailCause{{
"FieldValueForbidden", "spec.service.type", "spec.service.type=DataGrid",
}, {
"FieldValueForbidden", "spec.service.sites", "XSite not supported",
}}...)
})
Expand Down
14 changes: 1 addition & 13 deletions api/v1/types_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,19 +504,7 @@ func getRequestLimits(str string) (requests resource.Quantity, limits resource.Q
}

func (ispn *Infinispan) GetJavaOptions() string {
switch ispn.Spec.Service.Type {
case ServiceTypeDataGrid:
return ispn.Spec.Container.ExtraJvmOpts
case ServiceTypeCache:
switch ispn.ImageType() {
case ImageTypeJVM:
return fmt.Sprintf(consts.CacheServiceJavaOptions, consts.CacheServiceFixedMemoryXmxMb, consts.CacheServiceFixedMemoryXmxMb, consts.CacheServiceMaxRamMb,
consts.CacheServiceMinHeapFreeRatio, consts.CacheServiceMaxHeapFreeRatio, ispn.Spec.Container.ExtraJvmOpts)
case ImageTypeNative:
return fmt.Sprintf(consts.CacheServiceNativeJavaOptions, consts.CacheServiceFixedMemoryXmxMb, consts.CacheServiceFixedMemoryXmxMb, ispn.Spec.Container.ExtraJvmOpts)
}
}
return ""
return ispn.Spec.Container.ExtraJvmOpts
}

// GetLogCategoriesForConfig return a map of log category for the Infinispan configuration
Expand Down
45 changes: 6 additions & 39 deletions controllers/cache_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"

"github.com/infinispan/infinispan-operator/pkg/infinispan/version"
"github.com/infinispan/infinispan-operator/pkg/reconcile/pipeline/infinispan/handler/manage"
"k8s.io/apimachinery/pkg/util/validation"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -193,6 +192,11 @@ func (r *CacheReconciler) Reconcile(ctx context.Context, request ctrl.Request) (
return ctrl.Result{}, nil
}

if infinispan.IsCache() {
reqLogger.Info("Ignoring Cache CR as cluster is marked as CacheService")
return ctrl.Result{}, nil
}

ispnClient, err := NewInfinispan(ctx, infinispan, r.versionManager, r.kubernetes)
if err != nil {
return ctrl.Result{}, fmt.Errorf("unable to create Infinispan client: %w", err)
Expand Down Expand Up @@ -274,50 +278,13 @@ func (r *cacheRequest) ispnCreateOrUpdate() (*ctrl.Result, error) {
return &ctrl.Result{}, err
}

if r.infinispan.IsDataGrid() {
err = r.reconcileDataGrid(cacheExists, cacheClient)
} else {
err = r.reconcileCacheService(cacheExists, cacheClient)
}
err = r.reconcileDataGrid(cacheExists, cacheClient)
if err != nil {
return &ctrl.Result{Requeue: true}, err
}
return nil, nil
}

func (r *cacheRequest) reconcileCacheService(cacheExists bool, cache api.Cache) error {
spec := r.cache.Spec
if spec.TemplateName != "" || spec.Template != "" {
err := fmt.Errorf("cannot create a cache with a template in a CacheService cluster")
r.reqLogger.Error(err, "Error creating cache")
return err
}

if cacheExists {
r.reqLogger.Info("cache already exists")
return nil
}

podList, err := PodList(r.infinispan, r.kubernetes, r.ctx)
if err != nil {
r.reqLogger.Error(err, "failed to list pods")
return err
}

template, err := manage.DefaultCacheTemplateXML(podList.Items[0].Name, r.infinispan, r.kubernetes, r.reqLogger)
if err != nil {
err = fmt.Errorf("unable to obtain default cache template: %w", err)
r.reqLogger.Error(err, "Error getting default XML")
return err
}
if err = cache.Create(template, mime.ApplicationXml); err != nil {
err = fmt.Errorf("unable to create cache using default template: %w", err)
r.reqLogger.Error(err, "Error in creating cache")
return err
}
return nil
}

func (r *cacheRequest) reconcileDataGrid(cacheExists bool, cache api.Cache) error {
spec := r.cache.Spec

Expand Down
4 changes: 0 additions & 4 deletions documentation/asciidoc/stories/assembly_cache_cr.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ include::{topics}/proc_creating_caches.adoc[leveloffset=+1]
include::{topics}/proc_updating_caches.adoc[leveloffset=+1]
include::{topics}/proc_adding_cache_stores.adoc[leveloffset=+1]

//Cache Service
include::{topics}/proc_creating_caches_cache_service.adoc[leveloffset=+1]
include::{topics}/ref_default_cache_service_config.adoc[leveloffset=+2]

// Restore the parent context.
ifdef::parent-context[:context: {parent-context}]
ifndef::parent-context[:!context:]
10 changes: 1 addition & 9 deletions documentation/asciidoc/stories/assembly_creating_services.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ifdef::context[:parent-context: {context}]
= Setting up {brandname} services

[role="_abstract"]
Use {ispn_operator} to create clusters of either {cacheservice} or {datagridservice} pods.
Use {ispn_operator} to create clusters of {datagridservice} pods.

include::{topics}/con_services.adoc[leveloffset=+1]

Expand Down Expand Up @@ -34,14 +34,6 @@ ifdef::community[]
include::{topics}/proc_specifying_server_image.adoc[leveloffset=+1]
endif::community[]

//Cache Service
include::{topics}/proc_creating_cache_service.adoc[leveloffset=+1]
include::{topics}/ref_cache_service_resources.adoc[leveloffset=+2]

//Automatic scaling
include::{topics}/con_automatic_scaling.adoc[leveloffset=+1]
include::{topics}/proc_configuring_autoscaling.adoc[leveloffset=+2]

//Labeling
include::{topics}/proc_adding_labels_annotations.adoc[leveloffset=+1]
include::{topics}/proc_adding_labels_annotations_env.adoc[leveloffset=+1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
:brandname: Infinispan
:fullbrandname: Infinispan
:datagridservice: Data Grid Service
:cacheservice: Cache Service

//
// Clients and CLI
Expand Down
31 changes: 0 additions & 31 deletions documentation/asciidoc/topics/con_automatic_scaling.adoc

This file was deleted.

23 changes: 2 additions & 21 deletions documentation/asciidoc/topics/con_services.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,12 @@

[role="_abstract"]
Services are stateful applications, based on the {brandname} Server image, that provide flexible and robust in-memory data storage.
When you create {brandname} clusters you specify either `DataGrid` or `Cache` as the service type with the `spec.service.type` field.
{brandname} operator supports only `DataGrid` service type which deploys {brandname} clusters with full configuration and capabilities. `Cache` service type is no longer supported.

`DataGrid` service type:: Deploy {brandname} clusters with full configuration and capabilities.
`Cache` service type:: Deploy {brandname} clusters with minimal configuration.

//Community content
ifdef::community[]
The {brandname} team recommends the `DataGrid` service type for clusters because it lets you:
endif::community[]
//Downstream content
ifdef::downstream[]
Red Hat recommends the `DataGrid` service type for clusters because it lets you:
endif::downstream[]
DataGrid` service type for clusters lets you:

* Back up data across global clusters with cross-site replication.
* Create caches with any valid configuration.
* Add file-based cache stores to save data in a persistent volume.
* Query values across caches using the {brandname} Query API.
* Use advanced {brandname} features and capabilities.

[IMPORTANT]
====
The `Cache` service type was designed to provide a convenient way to create a low-latency data store with minimal configuration.
Additional development on the `Infinispan` CRD has shown that the `DataGrid` CR offers a better approach to achieving this goal, ultimately giving users more choice and less deployment overhead.
For this reason, the `Cache` service type is planned for removal in the next version of the `Infinispan` CRD and is no longer under active development.
The `DataGrid` service type continues to benefit from new features and improved tooling to automate complex operations such as cluster upgrades and data migration.
====
2 changes: 0 additions & 2 deletions documentation/asciidoc/topics/proc_allocating_storage.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
= Allocating storage resources

[role="_abstract"]
You can allocate storage for {datagridservice} pods but not {cacheservice} pods.

By default, {ispn_operator} allocates `1Gi` for the persistent volume claim.
However you should adjust the amount of storage available to {datagridservice} pods so that {brandname} can preserve cluster state during shutdown.

Expand Down
44 changes: 0 additions & 44 deletions documentation/asciidoc/topics/proc_configuring_autoscaling.adoc

This file was deleted.

Loading

0 comments on commit a19b424

Please sign in to comment.