diff --git a/api/v1beta1/openstacklightspeed_types.go b/api/v1beta1/openstacklightspeed_types.go index 027870e..cfbc8ad 100644 --- a/api/v1beta1/openstacklightspeed_types.go +++ b/api/v1beta1/openstacklightspeed_types.go @@ -19,6 +19,7 @@ package v1beta1 import ( "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/util" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -91,6 +92,40 @@ type DatabaseSpec struct { Class string `json:"class,omitempty"` } +// ContainerResourcesSpec defines resource requirements for each container +// managed by the operator. Defaults are applied by the API server via +// kubebuilder markers. Users may override any container's resources in +// the CR; the provided value replaces the default entirely. +type ContainerResourcesSpec struct { + // +kubebuilder:validation:Optional + // +kubebuilder:default:={requests: {cpu: "500m", memory: "2Gi"}, limits: {cpu: "2", memory: "8Gi"}} + // LlamaStack sets compute resources for the llama-stack (OGX) container + // in the lightspeed-stack deployment. + LlamaStack corev1.ResourceRequirements `json:"llamaStack,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default:={requests: {cpu: "250m", memory: "512Mi"}, limits: {cpu: "1", memory: "2Gi"}} + // LightspeedService sets compute resources for the lightspeed-service-api + // container in the lightspeed-stack deployment. + LightspeedService corev1.ResourceRequirements `json:"lightspeedService,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default:={requests: {cpu: "30m", memory: "300Mi"}, limits: {cpu: "500m", memory: "2Gi"}} + // Postgres sets compute resources for the PostgreSQL container. + Postgres corev1.ResourceRequirements `json:"postgres,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default:={requests: {cpu: "500m", memory: "2Gi"}, limits: {cpu: "2", memory: "4Gi"}} + // OKP sets compute resources for the Offline Knowledge Portal container. + OKP corev1.ResourceRequirements `json:"okp,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default:={requests: {cpu: "50m", memory: "64Mi"}, limits: {cpu: "200m", memory: "256Mi"}} + // ConsolePlugin sets compute resources for the lightspeed-console-plugin + // container and its init container. + ConsolePlugin corev1.ResourceRequirements `json:"consolePlugin,omitempty"` +} + // OpenStackLightspeedSpec defines the desired state of OpenStackLightspeed type OpenStackLightspeedSpec struct { OpenStackLightspeedCore `json:",inline"` @@ -105,6 +140,14 @@ type OpenStackLightspeedSpec struct { // OKP configures the Offline Knowledge Portal (OKP) RAG source. OKP *OKPSpec `json:"okp,omitempty"` + // +kubebuilder:validation:Optional + // +kubebuilder:default:={} + // Resources configures compute resource requirements for individual + // containers managed by the operator. Each field has sensible defaults + // applied by the API server. Override any container's resources to + // replace its defaults entirely. + Resources ContainerResourcesSpec `json:"resources,omitempty"` + // +kubebuilder:validation:Optional // +kubebuilder:pruning:PreserveUnknownFields // Dev contains developer/experimental configuration. diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 4fec34e..e831fef 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -25,6 +25,26 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerResourcesSpec) DeepCopyInto(out *ContainerResourcesSpec) { + *out = *in + in.LlamaStack.DeepCopyInto(&out.LlamaStack) + in.LightspeedService.DeepCopyInto(&out.LightspeedService) + in.Postgres.DeepCopyInto(&out.Postgres) + in.OKP.DeepCopyInto(&out.OKP) + in.ConsolePlugin.DeepCopyInto(&out.ConsolePlugin) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourcesSpec. +func (in *ContainerResourcesSpec) DeepCopy() *ContainerResourcesSpec { + if in == nil { + return nil + } + out := new(ContainerResourcesSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DatabaseSpec) DeepCopyInto(out *DatabaseSpec) { *out = *in @@ -210,6 +230,7 @@ func (in *OpenStackLightspeedSpec) DeepCopyInto(out *OpenStackLightspeedSpec) { *out = new(OKPSpec) (*in).DeepCopyInto(*out) } + in.Resources.DeepCopyInto(&out.Resources) in.Dev.DeepCopyInto(&out.Dev) } diff --git a/bundle/manifests/lightspeed.openstack.org_openstacklightspeeds.yaml b/bundle/manifests/lightspeed.openstack.org_openstacklightspeeds.yaml index 4863a73..43ca0c3 100644 --- a/bundle/manifests/lightspeed.openstack.org_openstacklightspeeds.yaml +++ b/bundle/manifests/lightspeed.openstack.org_openstacklightspeeds.yaml @@ -172,6 +172,353 @@ spec: When false, uses reference_url (online). type: boolean type: object + resources: + default: {} + description: |- + Resources configures compute resource requirements for individual + containers managed by the operator. Each field has sensible defaults + applied by the API server. Override any container's resources to + replace its defaults entirely. + properties: + consolePlugin: + default: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 50m + memory: 64Mi + description: |- + ConsolePlugin sets compute resources for the lightspeed-console-plugin + container and its init container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + lightspeedService: + default: + limits: + cpu: "1" + memory: 2Gi + requests: + cpu: 250m + memory: 512Mi + description: |- + LightspeedService sets compute resources for the lightspeed-service-api + container in the lightspeed-stack deployment. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + llamaStack: + default: + limits: + cpu: "2" + memory: 8Gi + requests: + cpu: 500m + memory: 2Gi + description: |- + LlamaStack sets compute resources for the llama-stack (OGX) container + in the lightspeed-stack deployment. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + okp: + default: + limits: + cpu: "2" + memory: 4Gi + requests: + cpu: 500m + memory: 2Gi + description: OKP sets compute resources for the Offline Knowledge + Portal container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + postgres: + default: + limits: + cpu: 500m + memory: 2Gi + requests: + cpu: 30m + memory: 300Mi + description: Postgres sets compute resources for the PostgreSQL + container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + type: object tlsCACertBundle: description: Configmap name containing a CA Certificates bundle type: string diff --git a/config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml b/config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml index 12fa78b..3865877 100644 --- a/config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml +++ b/config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml @@ -172,6 +172,353 @@ spec: When false, uses reference_url (online). type: boolean type: object + resources: + default: {} + description: |- + Resources configures compute resource requirements for individual + containers managed by the operator. Each field has sensible defaults + applied by the API server. Override any container's resources to + replace its defaults entirely. + properties: + consolePlugin: + default: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 50m + memory: 64Mi + description: |- + ConsolePlugin sets compute resources for the lightspeed-console-plugin + container and its init container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + lightspeedService: + default: + limits: + cpu: "1" + memory: 2Gi + requests: + cpu: 250m + memory: 512Mi + description: |- + LightspeedService sets compute resources for the lightspeed-service-api + container in the lightspeed-stack deployment. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + llamaStack: + default: + limits: + cpu: "2" + memory: 8Gi + requests: + cpu: 500m + memory: 2Gi + description: |- + LlamaStack sets compute resources for the llama-stack (OGX) container + in the lightspeed-stack deployment. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + okp: + default: + limits: + cpu: "2" + memory: 4Gi + requests: + cpu: 500m + memory: 2Gi + description: OKP sets compute resources for the Offline Knowledge + Portal container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + postgres: + default: + limits: + cpu: 500m + memory: 2Gi + requests: + cpu: 30m + memory: 300Mi + description: Postgres sets compute resources for the PostgreSQL + container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + type: object tlsCACertBundle: description: Configmap name containing a CA Certificates bundle type: string diff --git a/config/samples/api_v1beta1_openstacklightspeed.yaml b/config/samples/api_v1beta1_openstacklightspeed.yaml index ed262d0..0711ed2 100644 --- a/config/samples/api_v1beta1_openstacklightspeed.yaml +++ b/config/samples/api_v1beta1_openstacklightspeed.yaml @@ -15,6 +15,29 @@ spec: # database: # size: "5Gi" # class: "my-storage-class" + # Uncomment to customize container resource requests/limits: + # resources: + # llamaStack: + # requests: + # cpu: "500m" + # memory: "2Gi" + # limits: + # cpu: "2" + # memory: "8Gi" + # lightspeedService: + # requests: + # cpu: "250m" + # memory: "512Mi" + # limits: + # cpu: "1" + # memory: "2Gi" + # postgres: + # requests: + # cpu: "30m" + # memory: "300Mi" + # limits: + # cpu: "500m" + # memory: "2Gi" # Uncomment to customize log levels (DEBUG, INFO, WARNING, ERROR, CRITICAL): # logging: # ogxLogLevel: "all=info" diff --git a/go.mod b/go.mod index 8f5f00a..954cd88 100644 --- a/go.mod +++ b/go.mod @@ -82,15 +82,15 @@ require ( go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect - golang.org/x/mod v0.35.0 // indirect - golang.org/x/net v0.55.0 // indirect + golang.org/x/mod v0.37.0 // indirect + golang.org/x/net v0.56.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/term v0.43.0 // indirect - golang.org/x/text v0.37.0 // indirect + golang.org/x/sync v0.21.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/term v0.44.0 // indirect + golang.org/x/text v0.39.0 // indirect golang.org/x/time v0.12.0 // indirect - golang.org/x/tools v0.44.0 // indirect + golang.org/x/tools v0.47.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect diff --git a/go.sum b/go.sum index 9f0e618..2c3b091 100644 --- a/go.sum +++ b/go.sum @@ -200,41 +200,41 @@ golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/y golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= -golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= -golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= +golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= -golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= +golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= -golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= +golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= +golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/controller/console_deployment.go b/internal/controller/console_deployment.go index ba39845..04aa202 100644 --- a/internal/controller/console_deployment.go +++ b/internal/controller/console_deployment.go @@ -20,10 +20,10 @@ import ( "fmt" consolev1 "github.com/openshift/api/console/v1" + apiv1beta1 "github.com/openstack-k8s-operators/lightspeed-operator/api/v1beta1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -48,7 +48,9 @@ const consoleLocalesPath = "/usr/share/nginx/html/locales/en/" + consoleLocalesF // buildConsoleDeploymentSpec builds the Deployment spec for the console plugin. // Includes an init container that rewrites OpenShift references to OpenStack // in the locales JSON file using an emptyDir volume. -func buildConsoleDeploymentSpec(consoleImage string) appsv1.DeploymentSpec { +func buildConsoleDeploymentSpec(consoleImage string, instance *apiv1beta1.OpenStackLightspeed) appsv1.DeploymentSpec { + consoleRes := instance.Spec.Resources.ConsolePlugin + replicas := int32(1) volumeDefaultMode := VolumeDefaultMode labels := generateConsoleSelectorLabels() @@ -86,16 +88,7 @@ func buildConsoleDeploymentSpec(consoleImage string) appsv1.DeploymentSpec { "awk '" + consoleLocalesRewriteAwk + "' " + consoleLocalesPath + " > /locales-rewrite/" + consoleLocalesFilename, }, - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("50m"), - corev1.ResourceMemory: resource.MustParse("64Mi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("200m"), - corev1.ResourceMemory: resource.MustParse("256Mi"), - }, - }, + Resources: consoleRes, VolumeMounts: []corev1.VolumeMount{ { Name: "locales-rewrite", @@ -119,16 +112,7 @@ func buildConsoleDeploymentSpec(consoleImage string) appsv1.DeploymentSpec { SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: toPtr(false), }, - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("50m"), - corev1.ResourceMemory: resource.MustParse("64Mi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("200m"), - corev1.ResourceMemory: resource.MustParse("256Mi"), - }, - }, + Resources: consoleRes, VolumeMounts: []corev1.VolumeMount{ { Name: "lightspeed-console-plugin-cert", diff --git a/internal/controller/console_reconciler.go b/internal/controller/console_reconciler.go index 3006153..7025c56 100644 --- a/internal/controller/console_reconciler.go +++ b/internal/controller/console_reconciler.go @@ -181,7 +181,7 @@ func resolveConsoleImage(ctx context.Context, h *common_helper.Helper) string { } // reconcileConsoleDeploymentResource ensures the console plugin deployment exists. -func reconcileConsoleDeploymentResource(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileConsoleDeploymentResource(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() consoleImage := resolveConsoleImage(ctx, h) @@ -194,7 +194,7 @@ func reconcileConsoleDeploymentResource(h *common_helper.Helper, ctx context.Con } result, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), deployment, func() error { - spec := buildConsoleDeploymentSpec(consoleImage) + spec := buildConsoleDeploymentSpec(consoleImage, instance) deployment.Spec.Replicas = spec.Replicas deployment.Spec.Selector = spec.Selector deployment.Spec.Template = spec.Template diff --git a/internal/controller/console_reconciler_test.go b/internal/controller/console_reconciler_test.go index 9185506..fe15842 100644 --- a/internal/controller/console_reconciler_test.go +++ b/internal/controller/console_reconciler_test.go @@ -48,7 +48,10 @@ var _ = Describe("Console Plugin", func() { var spec appsv1.DeploymentSpec BeforeEach(func() { - spec = buildConsoleDeploymentSpec(apiv1beta1.OpenStackLightspeedDefaultValues.ConsoleImagePF5URL) + instance := &apiv1beta1.OpenStackLightspeed{ + Spec: apiv1beta1.OpenStackLightspeedSpec{}, + } + spec = buildConsoleDeploymentSpec(apiv1beta1.OpenStackLightspeedDefaultValues.ConsoleImagePF5URL, instance) }) It("should have one replica", func() { diff --git a/internal/controller/lcore_deployment.go b/internal/controller/lcore_deployment.go index 8f146f1..60d8348 100644 --- a/internal/controller/lcore_deployment.go +++ b/internal/controller/lcore_deployment.go @@ -109,16 +109,7 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins TimeoutSeconds: LlamaStackProbeTimeoutSeconds, FailureThreshold: LlamaStackProbeFailureThreshold, }, - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("2Gi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("2"), - corev1.ResourceMemory: resource.MustParse("8Gi"), - }, - }, + Resources: instance.Spec.Resources.LlamaStack, ImagePullPolicy: corev1.PullIfNotPresent, } @@ -145,25 +136,16 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins } lightspeedStackContainer := corev1.Container{ - Name: "lightspeed-service-api", - Image: apiv1beta1.OpenStackLightspeedDefaultValues.LCoreImageURL, - Args: []string{"-c", VectorDBVolumeLightspeedStackConfigPath}, - Ports: []corev1.ContainerPort{{Name: "https", ContainerPort: OpenStackLightspeedAppServerContainerPort}}, - VolumeMounts: lightspeedStackMounts, - Env: lsEnvVars, - StartupProbe: buildLightspeedStackStartupProbe(), - LivenessProbe: buildLightspeedStackLivenessProbe(), - ReadinessProbe: buildLightspeedStackReadinessProbe(), - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("250m"), - corev1.ResourceMemory: resource.MustParse("512Mi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("1"), - corev1.ResourceMemory: resource.MustParse("2Gi"), - }, - }, + Name: "lightspeed-service-api", + Image: apiv1beta1.OpenStackLightspeedDefaultValues.LCoreImageURL, + Args: []string{"-c", VectorDBVolumeLightspeedStackConfigPath}, + Ports: []corev1.ContainerPort{{Name: "https", ContainerPort: OpenStackLightspeedAppServerContainerPort}}, + VolumeMounts: lightspeedStackMounts, + Env: lsEnvVars, + StartupProbe: buildLightspeedStackStartupProbe(), + LivenessProbe: buildLightspeedStackLivenessProbe(), + ReadinessProbe: buildLightspeedStackReadinessProbe(), + Resources: instance.Spec.Resources.LightspeedService, ImagePullPolicy: corev1.PullIfNotPresent, } containers := []corev1.Container{llamaStackContainer, lightspeedStackContainer} @@ -216,7 +198,17 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins return corev1.PodTemplateSpec{}, err } - initContainers := buildInitContainers(instance) + initResources := corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("100m"), + corev1.ResourceMemory: resource.MustParse("256Mi"), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("500m"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + } + initContainers := buildInitContainers(instance, initResources) return corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -238,7 +230,7 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins // and Lightspeed Stack configuration files, incorporating information from // the provided vector database images. For details on their logic, see: // (1) assets/vector_database_collect.sh and (2) assets/vector_database_build.py. -func buildInitContainers(instance *apiv1beta1.OpenStackLightspeed) []corev1.Container { +func buildInitContainers(instance *apiv1beta1.OpenStackLightspeed, initResources corev1.ResourceRequirements) []corev1.Container { securityContext := &corev1.SecurityContext{ RunAsNonRoot: &[]bool{true}[0], AllowPrivilegeEscalation: &[]bool{false}[0], @@ -247,17 +239,6 @@ func buildInitContainers(instance *apiv1beta1.OpenStackLightspeed) []corev1.Cont }, } - resourceRequirements := corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("100m"), - corev1.ResourceMemory: resource.MustParse("256Mi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("1Gi"), - }, - } - var containers []corev1.Container containers = append(containers, corev1.Container{ Name: "vector-database-collect", @@ -268,7 +249,7 @@ func buildInitContainers(instance *apiv1beta1.OpenStackLightspeed) []corev1.Cont "--enable-okp", }, SecurityContext: securityContext, - Resources: resourceRequirements, + Resources: initResources, VolumeMounts: []corev1.VolumeMount{ { Name: VectorDBVolumeName, @@ -298,7 +279,7 @@ func buildInitContainers(instance *apiv1beta1.OpenStackLightspeed) []corev1.Cont Image: apiv1beta1.OpenStackLightspeedDefaultValues.LCoreImageURL, Command: configBuildCmd, SecurityContext: securityContext, - Resources: resourceRequirements, + Resources: initResources, VolumeMounts: []corev1.VolumeMount{ { Name: VectorDBVolumeName, diff --git a/internal/controller/okp_reconciler.go b/internal/controller/okp_reconciler.go index 22dfe95..fcfff9d 100644 --- a/internal/controller/okp_reconciler.go +++ b/internal/controller/okp_reconciler.go @@ -24,7 +24,6 @@ import ( apiv1beta1 "github.com/openstack-k8s-operators/lightspeed-operator/api/v1beta1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -150,16 +149,7 @@ func buildOKPPodTemplateSpec(instance *apiv1beta1.OpenStackLightspeed) corev1.Po InitialDelaySeconds: 60, PeriodSeconds: 20, }, - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("2Gi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("2"), - corev1.ResourceMemory: resource.MustParse("4Gi"), - }, - }, + Resources: instance.Spec.Resources.OKP, ImagePullPolicy: corev1.PullIfNotPresent, }, }, diff --git a/internal/controller/postgres_deployment.go b/internal/controller/postgres_deployment.go index 88638aa..f051d54 100644 --- a/internal/controller/postgres_deployment.go +++ b/internal/controller/postgres_deployment.go @@ -21,12 +21,11 @@ import ( apiv1beta1 "github.com/openstack-k8s-operators/lightspeed-operator/api/v1beta1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // buildPostgresPodTemplateSpec builds the pod template spec for the Postgres deployment. -func buildPostgresPodTemplateSpec() corev1.PodTemplateSpec { +func buildPostgresPodTemplateSpec(instance *apiv1beta1.OpenStackLightspeed) corev1.PodTemplateSpec { // Build volumes and volume mounts volumes := []corev1.Volume{} volumeMounts := []corev1.VolumeMount{} @@ -180,17 +179,8 @@ func buildPostgresPodTemplateSpec() corev1.PodTemplateSpec { LivenessProbe: buildPostgresProbe(PostgresLivenessProbePeriodSeconds, PostgresLivenessProbeTimeoutSeconds, PostgresLivenessProbeFailureThreshold, 0), ReadinessProbe: buildPostgresProbe(PostgresReadinessProbePeriodSeconds, PostgresReadinessProbeTimeoutSeconds, PostgresReadinessProbeFailureThreshold, 0), VolumeMounts: volumeMounts, - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("30m"), - corev1.ResourceMemory: resource.MustParse("300Mi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("2Gi"), - }, - }, - Env: envVars, + Resources: instance.Spec.Resources.Postgres, + Env: envVars, }, }, Volumes: volumes, diff --git a/internal/controller/postgres_reconciler.go b/internal/controller/postgres_reconciler.go index 5adfb93..0f8db2d 100644 --- a/internal/controller/postgres_reconciler.go +++ b/internal/controller/postgres_reconciler.go @@ -307,7 +307,7 @@ func reconcilePostgresDeploymentTask(h *common_helper.Helper, ctx context.Contex } // Build the desired deployment pod spec - podTemplateSpec := buildPostgresPodTemplateSpec() + podTemplateSpec := buildPostgresPodTemplateSpec(instance) // Initialize annotations map if needed if podTemplateSpec.Annotations == nil { diff --git a/test/kuttl/common/openstack-lightspeed-instance/assert-openstack-lightspeed-instance.yaml b/test/kuttl/common/openstack-lightspeed-instance/assert-openstack-lightspeed-instance.yaml index 421c70d..7224fd9 100644 --- a/test/kuttl/common/openstack-lightspeed-instance/assert-openstack-lightspeed-instance.yaml +++ b/test/kuttl/common/openstack-lightspeed-instance/assert-openstack-lightspeed-instance.yaml @@ -82,6 +82,13 @@ spec: spec: containers: - name: okp + resources: + requests: + cpu: 500m + memory: 2Gi + limits: + cpu: "2" + memory: 4Gi ports: - name: okp containerPort: 8080 diff --git a/test/kuttl/tests/update-openstacklightspeed/07-update-openstack-lightspeed-instance.yaml b/test/kuttl/tests/update-openstacklightspeed/07-update-openstack-lightspeed-instance.yaml index e845505..cef67dc 100644 --- a/test/kuttl/tests/update-openstacklightspeed/07-update-openstack-lightspeed-instance.yaml +++ b/test/kuttl/tests/update-openstacklightspeed/07-update-openstack-lightspeed-instance.yaml @@ -34,5 +34,41 @@ spec: ogxLogLevel: "core=debug,providers=info" lightspeedStackLogLevel: ERROR dataverseExporterLogLevel: ERROR + resources: + llamaStack: + requests: + cpu: "500m" + memory: "2Gi" + limits: + cpu: "2" + memory: "9Gi" + lightspeedService: + requests: + cpu: "250m" + memory: "512Mi" + limits: + cpu: "1" + memory: "3Gi" + postgres: + requests: + cpu: "30m" + memory: "300Mi" + limits: + cpu: "500m" + memory: "3Gi" + okp: + requests: + cpu: "500m" + memory: "2Gi" + limits: + cpu: "2" + memory: "5Gi" + consolePlugin: + requests: + cpu: "50m" + memory: "64Mi" + limits: + cpu: "200m" + memory: "300Mi" dev: okpChunkFilterQuery: "product:(*openstack* OR *openshift*)" diff --git a/test/kuttl/tests/update-openstacklightspeed/08-assert-openstacklightspeed-update.yaml b/test/kuttl/tests/update-openstacklightspeed/08-assert-openstacklightspeed-update.yaml index fb300f8..9f339cf 100644 --- a/test/kuttl/tests/update-openstacklightspeed/08-assert-openstacklightspeed-update.yaml +++ b/test/kuttl/tests/update-openstacklightspeed/08-assert-openstacklightspeed-update.yaml @@ -40,11 +40,7 @@ spec: memory: 300Mi limits: cpu: 500m - memory: 2Gi -status: - replicas: 1 - readyReplicas: 1 - availableReplicas: 1 + memory: 3Gi --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy @@ -52,6 +48,26 @@ metadata: name: lightspeed-postgres-server namespace: openstack-lightspeed +# OKP Deployment with custom resources +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: lightspeed-okp-server + namespace: openstack-lightspeed +spec: + template: + spec: + containers: + - name: okp + resources: + requests: + cpu: 500m + memory: 2Gi + limits: + cpu: "2" + memory: 5Gi + # LCore resources --- apiVersion: v1 @@ -83,7 +99,6 @@ kind: Deployment metadata: name: lightspeed-stack-deployment namespace: openstack-lightspeed - generation: 2 spec: template: spec: @@ -98,7 +113,7 @@ spec: memory: 2Gi limits: cpu: "2" - memory: 8Gi + memory: 9Gi env: - name: OPENSTACK_LIGHTSPEED_PROVIDER_API_KEY valueFrom: @@ -148,7 +163,7 @@ spec: memory: 512Mi limits: cpu: "1" - memory: 2Gi + memory: 3Gi env: - name: LIGHTSPEED_STACK_LOG_LEVEL value: ERROR @@ -194,11 +209,6 @@ spec: - name: tls-certs secret: secretName: lightspeed-tls -status: - replicas: 1 - readyReplicas: 1 - availableReplicas: 1 - observedGeneration: 2 --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy @@ -258,10 +268,19 @@ spec: memory: 64Mi limits: cpu: 200m - memory: 256Mi + memory: 300Mi volumeMounts: - name: locales-rewrite mountPath: /locales-rewrite + containers: + - name: lightspeed-console-plugin + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 200m + memory: 300Mi --- apiVersion: v1 kind: Service @@ -292,6 +311,42 @@ spec: llmAPIVersion: v1.1 feedbackEnabled: false transcriptsEnabled: false + resources: + llamaStack: + requests: + cpu: 500m + memory: 2Gi + limits: + cpu: "2" + memory: 9Gi + lightspeedService: + requests: + cpu: 250m + memory: 512Mi + limits: + cpu: "1" + memory: 3Gi + postgres: + requests: + cpu: 30m + memory: 300Mi + limits: + cpu: 500m + memory: 3Gi + okp: + requests: + cpu: 500m + memory: 2Gi + limits: + cpu: "2" + memory: 5Gi + consolePlugin: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 200m + memory: 300Mi logging: ogxLogLevel: "core=debug,providers=info" lightspeedStackLogLevel: ERROR