1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Feature] ArangoMember Overrides (#1398)

This commit is contained in:
Adam Janikowski 2023-09-15 13:46:38 +02:00 committed by GitHub
parent 0aa65c6ec9
commit 5bdd1687cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 506 additions and 52 deletions

View file

@ -18,6 +18,7 @@
- (Feature) Add basic metrics for ArangoDeploymentReplication CR
- (Bugfix) Use ArangoMember as owner reference for syncmaster secrets instead of Deployment
- (Improvement) Remove PodSchedulingFailure condition instead of setting to false, restart pod if it could not be scheduled
- (Feature) Add ArangoMember overrides
## [1.2.32](https://github.com/arangodb/kube-arangodb/tree/1.2.32) (2023-08-07)
- (Feature) Backup lifetime - remove Backup once its lifetime has been reached

View file

@ -0,0 +1,65 @@
# API Reference for ArangoMember V1
## Spec
### .spec.deploymentUID: string
DeploymentUID define Deployment UID.
[Code Reference](/pkg/apis/deployment/v1/arango_member_spec.go#L34)
### .spec.group: int
Group define Member Groups.
[Code Reference](/pkg/apis/deployment/v1/arango_member_spec.go#L29)
### .spec.id: string
[Code Reference](/pkg/apis/deployment/v1/arango_member_spec.go#L31)
### .spec.overrides.resources: core.ResourceRequirements
Resources holds resource requests & limits. Overrides template provided on the group level.
Links:
* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#resourcerequirements-v1-core)
[Code Reference](/pkg/apis/deployment/v1/arango_member_spec_overrides.go#L38)
### .spec.overrides.volumeClaimTemplate: core.PersistentVolumeClaim
VolumeClaimTemplate specifies a template for volume claims. Overrides template provided on the group level.
Links:
* [Documentation of core.PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#persistentvolumeclaim-v1-core)
[Code Reference](/pkg/apis/deployment/v1/arango_member_spec_overrides.go#L33)
### .spec.template.checksum: string
Checksum keep the Pod Spec Checksum (with ignored fields).
[Code Reference](/pkg/apis/deployment/v1/arango_member_pod_template.go#L60)
### .spec.template.endpoint: string
Deprecated: Endpoint is not saved into the template
[Code Reference](/pkg/apis/deployment/v1/arango_member_pod_template.go#L63)
### .spec.template.podSpec: core.PodTemplateSpec
PodSpec specifies the Pod Spec used for this Member.
Links:
* [Documentation of core.PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#podtemplatespec-v1-core)
[Code Reference](/pkg/apis/deployment/v1/arango_member_pod_template.go#L54)
### .spec.template.podSpecChecksum: string
PodSpecChecksum keep the Pod Spec Checksum (without ignored fields).
[Code Reference](/pkg/apis/deployment/v1/arango_member_pod_template.go#L57)

1
go.mod
View file

@ -28,6 +28,7 @@ require (
github.com/arangodb/go-driver v1.4.1
github.com/arangodb/go-driver/v2 v2.0.0-20211021031401-d92dcd5a4c83
github.com/arangodb/go-upgrade-rules v0.0.0-20180809110947-031b4774ff21
github.com/arangodb/rebalancer v0.1.1
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9
github.com/gin-gonic/gin v1.9.1

2
go.sum
View file

@ -82,6 +82,8 @@ github.com/arangodb/go-upgrade-rules v0.0.0-20180809110947-031b4774ff21 h1:+W7D5
github.com/arangodb/go-upgrade-rules v0.0.0-20180809110947-031b4774ff21/go.mod h1:RkPIG6JJ2pcJUoymc18NxAJGraZd+iAEVnOTDjZey/w=
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2LcQBbxd0ZFdbGSyRKTYMZCfBbw/pMJFOk1g=
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho=
github.com/arangodb/rebalancer v0.1.1 h1:8MikmxlhywKnw/wiDqctD8FFwBZhAAF1E3mIqh8nzCA=
github.com/arangodb/rebalancer v0.1.1/go.mod h1:wLvglmYNuoTUYbLQq/UESIMVkINmSX9eZWC5QB9kNyk=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=

View file

@ -147,6 +147,13 @@ func Test_GenerateAPIDocs(t *testing.T) {
},
},
fmt.Sprintf("%s/pkg/apis/deployment/v1", root))
generateDocs(t, map[string]map[string]interface{}{
"ArangoMember.V1": {
"Spec": api.ArangoMember{}.Spec,
},
},
fmt.Sprintf("%s/pkg/apis/deployment/v1", root))
}
func generateDocs(t *testing.T, objects map[string]map[string]interface{}, paths ...string) {
@ -320,7 +327,7 @@ func iterateOverObjectDirect(t *testing.T, docs map[string]*ast.Field, name stri
doc, ok := docs[docName]
if !ok && !f.Anonymous {
require.True(t, ok, docName)
require.True(t, ok, docName, f.Name)
}
if !f.Anonymous {

View file

@ -48,11 +48,18 @@ func GetArangoMemberPodTemplate(pod *core.PodTemplateSpec, podSpecChecksum strin
}
type ArangoMemberPodTemplate struct {
PodSpec *core.PodTemplateSpec `json:"podSpec,omitempty"`
PodSpecChecksum string `json:"podSpecChecksum,omitempty"`
Checksum string `json:"checksum,omitempty"`
// PodSpec specifies the Pod Spec used for this Member.
// +doc/type: core.PodTemplateSpec
// +doc/link: Documentation of core.PodTemplateSpec|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#podtemplatespec-v1-core
PodSpec *core.PodTemplateSpec `json:"podSpec,omitempty"`
// deprecated
// PodSpecChecksum keep the Pod Spec Checksum (without ignored fields).
PodSpecChecksum string `json:"podSpecChecksum,omitempty"`
// Checksum keep the Pod Spec Checksum (with ignored fields).
Checksum string `json:"checksum,omitempty"`
// Deprecated: Endpoint is not saved into the template
Endpoint *string `json:"endpoint,omitempty"`
}

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -25,9 +25,17 @@ import (
)
type ArangoMemberSpec struct {
Group ServerGroup `json:"group,omitempty"`
ID string `json:"id,omitempty"`
DeploymentUID types.UID `json:"deploymentUID,omitempty"`
// Group define Member Groups.
Group ServerGroup `json:"group,omitempty"`
ID string `json:"id,omitempty"`
// DeploymentUID define Deployment UID.
DeploymentUID types.UID `json:"deploymentUID,omitempty"`
// Overrides define Member Overrides (Override values from ServerGroup).
Overrides *ArangoMemberSpecOverrides `json:"overrides,omitempty"`
// Template keeps template which is gonna be applied on the Pod.
Template *ArangoMemberPodTemplate `json:"template,omitempty"`
}

View file

@ -0,0 +1,125 @@
//
// DISCLAIMER
//
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed 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.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v1
import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/util"
)
type ArangoMemberSpecOverrides struct {
// VolumeClaimTemplate specifies a template for volume claims. Overrides template provided on the group level.
// +doc/type: core.PersistentVolumeClaim
// +doc/link: Documentation of core.PersistentVolumeClaim|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#persistentvolumeclaim-v1-core
VolumeClaimTemplate *core.PersistentVolumeClaim `json:"volumeClaimTemplate,omitempty"`
// Resources holds resource requests & limits. Overrides template provided on the group level.
// +doc/type: core.ResourceRequirements
// +doc/link: Documentation of core.ResourceRequirements|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#resourcerequirements-v1-core
Resources core.ResourceRequirements `json:"resources,omitempty"`
}
func (a *ArangoMemberSpecOverrides) HasVolumeClaimTemplate(g *ServerGroupSpec) bool {
if g != nil {
if g.HasVolumeClaimTemplate() {
return true
}
}
if a != nil {
return a.VolumeClaimTemplate != nil
}
return false
}
func (a *ArangoMemberSpecOverrides) GetVolumeClaimTemplate(g *ServerGroupSpec) *core.PersistentVolumeClaim {
if a != nil {
if a.VolumeClaimTemplate != nil {
return a.VolumeClaimTemplate.DeepCopy()
}
}
if g != nil {
if g.VolumeClaimTemplate != nil {
return g.VolumeClaimTemplate.DeepCopy()
}
}
return &core.PersistentVolumeClaim{}
}
func (a *ArangoMemberSpecOverrides) GetResources(g *ServerGroupSpec) core.ResourceRequirements {
rl := core.ResourceList{}
rr := core.ResourceList{}
if g != nil {
if l := g.Resources.Limits; len(l) > 0 {
for k, v := range l {
rl[k] = v
}
}
if l := g.Resources.Requests; len(l) > 0 {
for k, v := range l {
rr[k] = v
}
}
}
if a != nil {
if l := a.Resources.Limits; len(l) > 0 {
for k, v := range l {
rl[k] = v
}
}
if l := a.Resources.Requests; len(l) > 0 {
for k, v := range l {
rr[k] = v
}
}
}
ret := core.ResourceRequirements{}
if len(rl) > 0 {
ret.Limits = rl
}
if len(rr) > 0 {
ret.Requests = rr
}
return ret
}
func (a *ArangoMemberSpecOverrides) GetStorageClassName(g *ServerGroupSpec) string {
if a != nil {
if z := a.VolumeClaimTemplate; z != nil {
return util.TypeOrDefault[string](z.Spec.StorageClassName)
}
}
if g != nil {
return g.GetStorageClassName()
}
return ""
}

View file

@ -534,6 +534,11 @@ func (in *ArangoMemberPodTemplate) DeepCopy() *ArangoMemberPodTemplate {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoMemberSpec) DeepCopyInto(out *ArangoMemberSpec) {
*out = *in
if in.Overrides != nil {
in, out := &in.Overrides, &out.Overrides
*out = new(ArangoMemberSpecOverrides)
(*in).DeepCopyInto(*out)
}
if in.Template != nil {
in, out := &in.Template, &out.Template
*out = new(ArangoMemberPodTemplate)
@ -552,6 +557,28 @@ func (in *ArangoMemberSpec) DeepCopy() *ArangoMemberSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoMemberSpecOverrides) DeepCopyInto(out *ArangoMemberSpecOverrides) {
*out = *in
if in.VolumeClaimTemplate != nil {
in, out := &in.VolumeClaimTemplate, &out.VolumeClaimTemplate
*out = new(corev1.PersistentVolumeClaim)
(*in).DeepCopyInto(*out)
}
in.Resources.DeepCopyInto(&out.Resources)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMemberSpecOverrides.
func (in *ArangoMemberSpecOverrides) DeepCopy() *ArangoMemberSpecOverrides {
if in == nil {
return nil
}
out := new(ArangoMemberSpecOverrides)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoMemberStatus) DeepCopyInto(out *ArangoMemberStatus) {
*out = *in

View file

@ -48,11 +48,18 @@ func GetArangoMemberPodTemplate(pod *core.PodTemplateSpec, podSpecChecksum strin
}
type ArangoMemberPodTemplate struct {
PodSpec *core.PodTemplateSpec `json:"podSpec,omitempty"`
PodSpecChecksum string `json:"podSpecChecksum,omitempty"`
Checksum string `json:"checksum,omitempty"`
// PodSpec specifies the Pod Spec used for this Member.
// +doc/type: core.PodTemplateSpec
// +doc/link: Documentation of core.PodTemplateSpec|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#podtemplatespec-v1-core
PodSpec *core.PodTemplateSpec `json:"podSpec,omitempty"`
// deprecated
// PodSpecChecksum keep the Pod Spec Checksum (without ignored fields).
PodSpecChecksum string `json:"podSpecChecksum,omitempty"`
// Checksum keep the Pod Spec Checksum (with ignored fields).
Checksum string `json:"checksum,omitempty"`
// Deprecated: Endpoint is not saved into the template
Endpoint *string `json:"endpoint,omitempty"`
}

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -25,9 +25,17 @@ import (
)
type ArangoMemberSpec struct {
Group ServerGroup `json:"group,omitempty"`
ID string `json:"id,omitempty"`
DeploymentUID types.UID `json:"deploymentUID,omitempty"`
// Group define Member Groups.
Group ServerGroup `json:"group,omitempty"`
ID string `json:"id,omitempty"`
// DeploymentUID define Deployment UID.
DeploymentUID types.UID `json:"deploymentUID,omitempty"`
// Overrides define Member Overrides (Override values from ServerGroup).
Overrides *ArangoMemberSpecOverrides `json:"overrides,omitempty"`
// Template keeps template which is gonna be applied on the Pod.
Template *ArangoMemberPodTemplate `json:"template,omitempty"`
}

View file

@ -0,0 +1,125 @@
//
// DISCLAIMER
//
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed 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.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v2alpha1
import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/util"
)
type ArangoMemberSpecOverrides struct {
// VolumeClaimTemplate specifies a template for volume claims. Overrides template provided on the group level.
// +doc/type: core.PersistentVolumeClaim
// +doc/link: Documentation of core.PersistentVolumeClaim|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#persistentvolumeclaim-v1-core
VolumeClaimTemplate *core.PersistentVolumeClaim `json:"volumeClaimTemplate,omitempty"`
// Resources holds resource requests & limits. Overrides template provided on the group level.
// +doc/type: core.ResourceRequirements
// +doc/link: Documentation of core.ResourceRequirements|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#resourcerequirements-v1-core
Resources core.ResourceRequirements `json:"resources,omitempty"`
}
func (a *ArangoMemberSpecOverrides) HasVolumeClaimTemplate(g *ServerGroupSpec) bool {
if g != nil {
if g.HasVolumeClaimTemplate() {
return true
}
}
if a != nil {
return a.VolumeClaimTemplate != nil
}
return false
}
func (a *ArangoMemberSpecOverrides) GetVolumeClaimTemplate(g *ServerGroupSpec) *core.PersistentVolumeClaim {
if a != nil {
if a.VolumeClaimTemplate != nil {
return a.VolumeClaimTemplate.DeepCopy()
}
}
if g != nil {
if g.VolumeClaimTemplate != nil {
return g.VolumeClaimTemplate.DeepCopy()
}
}
return &core.PersistentVolumeClaim{}
}
func (a *ArangoMemberSpecOverrides) GetResources(g *ServerGroupSpec) core.ResourceRequirements {
rl := core.ResourceList{}
rr := core.ResourceList{}
if g != nil {
if l := g.Resources.Limits; len(l) > 0 {
for k, v := range l {
rl[k] = v
}
}
if l := g.Resources.Requests; len(l) > 0 {
for k, v := range l {
rr[k] = v
}
}
}
if a != nil {
if l := a.Resources.Limits; len(l) > 0 {
for k, v := range l {
rl[k] = v
}
}
if l := a.Resources.Requests; len(l) > 0 {
for k, v := range l {
rr[k] = v
}
}
}
ret := core.ResourceRequirements{}
if len(rl) > 0 {
ret.Limits = rl
}
if len(rr) > 0 {
ret.Requests = rr
}
return ret
}
func (a *ArangoMemberSpecOverrides) GetStorageClassName(g *ServerGroupSpec) string {
if a != nil {
if z := a.VolumeClaimTemplate; z != nil {
return util.TypeOrDefault[string](z.Spec.StorageClassName)
}
}
if g != nil {
return g.GetStorageClassName()
}
return ""
}

View file

@ -534,6 +534,11 @@ func (in *ArangoMemberPodTemplate) DeepCopy() *ArangoMemberPodTemplate {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoMemberSpec) DeepCopyInto(out *ArangoMemberSpec) {
*out = *in
if in.Overrides != nil {
in, out := &in.Overrides, &out.Overrides
*out = new(ArangoMemberSpecOverrides)
(*in).DeepCopyInto(*out)
}
if in.Template != nil {
in, out := &in.Template, &out.Template
*out = new(ArangoMemberPodTemplate)
@ -552,6 +557,28 @@ func (in *ArangoMemberSpec) DeepCopy() *ArangoMemberSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoMemberSpecOverrides) DeepCopyInto(out *ArangoMemberSpecOverrides) {
*out = *in
if in.VolumeClaimTemplate != nil {
in, out := &in.VolumeClaimTemplate, &out.VolumeClaimTemplate
*out = new(v1.PersistentVolumeClaim)
(*in).DeepCopyInto(*out)
}
in.Resources.DeepCopyInto(&out.Resources)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMemberSpecOverrides.
func (in *ArangoMemberSpecOverrides) DeepCopy() *ArangoMemberSpecOverrides {
if in == nil {
return nil
}
out := new(ArangoMemberSpecOverrides)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoMemberStatus) DeepCopyInto(out *ArangoMemberStatus) {
*out = *in

View file

@ -118,11 +118,6 @@ func (a *actionArangoMemberUpdatePodSpec) Start(ctx context.Context) (bool, erro
return false, err
}
if z := m.Endpoint; z != nil {
q := *z
template.Endpoint = &q
}
if err := inspector.WithArangoMemberUpdate(ctx, cache, name, func(member *api.ArangoMember) (bool, error) {
if !member.Spec.Template.Equals(template) {
member.Spec.Template = template.DeepCopy()

View file

@ -89,11 +89,13 @@ func (a *actionPVCResize) Start(ctx context.Context) (bool, error) {
return true, nil
}
am := cache.ArangoMember().V1().GetSimpleOptional(m.ArangoMemberName(a.actionCtx.GetName(), group))
var res core.ResourceList
if groupSpec.HasVolumeClaimTemplate() {
res = groupSpec.GetVolumeClaimTemplate().Spec.Resources.Requests
if am.Spec.Overrides.HasVolumeClaimTemplate(&groupSpec) {
res = am.Spec.Overrides.GetVolumeClaimTemplate(&groupSpec).Spec.Resources.Requests
} else {
res = groupSpec.Resources.Requests
res = am.Spec.Overrides.GetResources(&groupSpec).Requests
}
if requestedSize, ok := res[core.ResourceStorage]; ok {

View file

@ -108,15 +108,17 @@ func (r *Reconciler) isStorageClassChanged(_ context.Context, apiObject k8sutil.
return false, "", nil
}
groupSpec := spec.GetServerGroupSpec(group)
storageClassName := groupSpec.GetStorageClassName()
if storageClassName == "" {
// A storage class is not set.
cache, ok := context.ACS().ClusterCache(member.ClusterID)
if !ok {
return false, "", nil
}
cache, ok := context.ACS().ClusterCache(member.ClusterID)
if !ok {
am := cache.ArangoMember().V1().GetSimpleOptional(member.ArangoMemberName(context.GetName(), group))
groupSpec := spec.GetServerGroupSpec(group)
storageClassName := am.Spec.Overrides.GetStorageClassName(&groupSpec)
if storageClassName == "" {
// A storage class is not set.
return false, "", nil
}
@ -184,6 +186,8 @@ func (r *Reconciler) isVolumeSizeChanged(_ context.Context, _ k8sutil.APIObject,
return false, "", nil
}
am := cache.ArangoMember().V1().GetSimpleOptional(member.ArangoMemberName(context.GetName(), group))
pvc, ok := cache.PersistentVolumeClaim().V1().GetSimple(member.PersistentVolumeClaim.GetName())
if !ok {
r.log.
@ -195,7 +199,7 @@ func (r *Reconciler) isVolumeSizeChanged(_ context.Context, _ k8sutil.APIObject,
}
groupSpec := spec.GetServerGroupSpec(group)
ok, volumeSize, requestedSize := shouldVolumeResize(groupSpec, pvc)
ok, volumeSize, requestedSize := shouldVolumeResize(groupSpec, am, pvc)
if !ok {
return false, "", nil
}
@ -227,13 +231,14 @@ func (r *Reconciler) isVolumeSizeChanged(_ context.Context, _ k8sutil.APIObject,
// shouldVolumeResize returns false when a volume should not resize.
// Currently, it is only possible to shrink a volume size.
// When return true then the actual and required volume size are returned.
func shouldVolumeResize(groupSpec api.ServerGroupSpec,
func shouldVolumeResize(groupSpec api.ServerGroupSpec, am *api.ArangoMember,
pvc *core.PersistentVolumeClaim) (bool, resource.Quantity, resource.Quantity) {
var res core.ResourceList
if groupSpec.HasVolumeClaimTemplate() {
res = groupSpec.GetVolumeClaimTemplate().Spec.Resources.Requests
if am.Spec.Overrides.HasVolumeClaimTemplate(&groupSpec) {
res = am.Spec.Overrides.GetVolumeClaimTemplate(&groupSpec).Spec.Resources.Requests
} else {
res = groupSpec.Resources.Requests
res = am.Spec.Overrides.GetResources(&groupSpec).Requests
}
if requestedSize, ok := res[core.ResourceStorage]; ok {

View file

@ -110,7 +110,7 @@ func (r *Reconciler) syncMemberStatus(ctx context.Context, apiObject k8sutil.API
amember, ok := cache.ArangoMember().V1().GetSimple(name)
if !ok {
r.log.Error("Unable to get cache")
r.log.Error("Unable to get member")
continue
}

View file

@ -84,12 +84,21 @@ func (r *Reconciler) createRotateServerStorageResizePlanInternal(spec api.Deploy
// Only make changes when phase is created
continue
}
if member.Member.PersistentVolumeClaim.GetName() == "" {
// Plan is irrelevant without PVC
continue
}
groupSpec := spec.GetServerGroupSpec(member.Group)
cache, ok := context.ACS().ClusterCache(member.Member.ClusterID)
if !ok {
// Do not work without cache
continue
}
am := cache.ArangoMember().V1().GetSimpleOptional(member.Member.ArangoMemberName(context.GetName(), member.Group))
if groupSpec.VolumeResizeMode.Get() != mode {
continue
}
@ -110,10 +119,10 @@ func (r *Reconciler) createRotateServerStorageResizePlanInternal(spec api.Deploy
}
var res core.ResourceList
if groupSpec.HasVolumeClaimTemplate() {
res = groupSpec.GetVolumeClaimTemplate().Spec.Resources.Requests
if am.Spec.Overrides.HasVolumeClaimTemplate(&groupSpec) {
res = am.Spec.Overrides.GetVolumeClaimTemplate(&groupSpec).Spec.Resources.Requests
} else {
res = groupSpec.Resources.Requests
res = am.Spec.Overrides.GetResources(&groupSpec).Requests
}
if requestedSize, ok := res[core.ResourceStorage]; ok {
if volumeSize, ok := pvc.Spec.Resources.Requests[core.ResourceStorage]; ok {

View file

@ -56,6 +56,7 @@ import (
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/arangod/conn"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/errors/panics"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
arangomemberv1 "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/arangomember/v1"
@ -701,7 +702,10 @@ type LastLogRecord struct {
}
func (l *LastLogRecord) Run(e *zerolog.Event, level zerolog.Level, msg string) {
l.t.Log(msg)
for _, s := range panics.GetStack(0) {
l.t.Logf("Stack: %s", s.String())
}
l.t.Logf(msg)
l.msg = msg
}
@ -717,6 +721,7 @@ type testCase struct {
kclient.FakeDataInput
Extender func(t *testing.T, r *Reconciler, c *testCase)
Data func(t *testing.T, in kclient.FakeDataInput, c *testCase) kclient.FakeDataInput
}
func (t testCase) Inspector(test *testing.T) inspectorInterface.Inspector {
@ -1235,6 +1240,10 @@ func TestCreatePlan(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
if testCase.Data != nil {
testCase.FakeDataInput = testCase.Data(t, testCase.FakeDataInput, &testCase)
}
i := testCase.Inspector(t)
testCase.context.Inspector = i
@ -1263,6 +1272,10 @@ func TestCreatePlan(t *testing.T) {
err, _ := r.CreatePlan(ctx)
if event := testCase.context.RecordedEvent; event != nil {
t.Logf("Event recorded: %s : %s : %s", event.Type, event.Reason, event.Message)
}
// Assert
if testCase.ExpectedEvent != nil {
require.NotNil(t, testCase.context.RecordedEvent)

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -81,6 +81,14 @@ func (p *arangoMembersInspectorV1) GetSimple(name string) (*api.ArangoMember, bo
return arangoMember, true
}
func (p *arangoMembersInspectorV1) GetSimpleOptional(name string) *api.ArangoMember {
a, ok := p.GetSimple(name)
if !ok {
return &api.ArangoMember{}
}
return a
}
func (p *arangoMembersInspectorV1) Iterate(action ins.Action, filters ...ins.Filter) error {
for _, arangoMember := range p.arangoMembers {
if err := p.iterateArangoMember(arangoMember, action, filters...); err != nil {

View file

@ -76,6 +76,7 @@ type ArangoDContainer struct {
groupSpec api.ServerGroupSpec
spec api.DeploymentSpec
group api.ServerGroup
arangoMember api.ArangoMember
imageInfo api.ImageInfo
cachedStatus interfaces.Inspector
input pod.Input
@ -206,9 +207,11 @@ func (a *ArangoDContainer) GetEnvs() ([]core.EnvVar, []core.EnvFromSource) {
envs.Add(true, k8sutil.GetLifecycleEnv()...)
if a.groupSpec.Resources.Limits != nil {
resources := a.member.arangoMember.Spec.Overrides.GetResources(&a.groupSpec)
if resources.Limits != nil {
if a.groupSpec.GetOverrideDetectedTotalMemory() {
if limits, ok := a.groupSpec.Resources.Limits[core.ResourceMemory]; ok {
if limits, ok := resources.Limits[core.ResourceMemory]; ok {
envs.Add(true, core.EnvVar{
Name: ArangoDBOverrideDetectedTotalMemoryEnv,
Value: fmt.Sprintf("%d", limits.Value()),
@ -217,7 +220,7 @@ func (a *ArangoDContainer) GetEnvs() ([]core.EnvVar, []core.EnvFromSource) {
}
if a.groupSpec.GetOverrideDetectedNumberOfCores() {
if limits, ok := a.groupSpec.Resources.Limits[core.ResourceCPU]; ok {
if limits, ok := resources.Limits[core.ResourceCPU]; ok {
envs.Add(true, core.EnvVar{
Name: ArangoDBOverrideDetectedNumberOfCoresEnv,
Value: fmt.Sprintf("%d", limits.Value()),
@ -278,7 +281,7 @@ func (a *ArangoDContainer) GetEnvs() ([]core.EnvVar, []core.EnvFromSource) {
}
func (a *ArangoDContainer) GetResourceRequirements() core.ResourceRequirements {
return k8sutil.ExtractPodResourceRequirement(a.groupSpec.Resources)
return k8sutil.ExtractPodResourceRequirement(a.arangoMember.Spec.Overrides.GetResources(&a.groupSpec))
}
func (a *ArangoDContainer) GetLifecycle() (*core.Lifecycle, error) {
@ -529,6 +532,7 @@ func (m *MemberArangoDPod) GetContainerCreator() interfaces.ContainerCreator {
resources: m.resources,
imageInfo: m.imageInfo,
groupSpec: m.groupSpec,
arangoMember: m.arangoMember,
cachedStatus: m.cachedStatus,
input: m.AsInput(),
status: m.status,

View file

@ -55,6 +55,7 @@ type ArangoSyncContainer struct {
imageInfo api.ImageInfo
apiObject meta.Object
memberStatus api.MemberStatus
arangoMember api.ArangoMember
tlsKeyfileSecretName string
clientAuthCASecretName string
masterJWTSecretName string
@ -147,7 +148,7 @@ func (a *ArangoSyncContainer) GetProbes() (*core.Probe, *core.Probe, *core.Probe
}
func (a *ArangoSyncContainer) GetResourceRequirements() core.ResourceRequirements {
return k8sutil.ExtractPodResourceRequirement(a.groupSpec.Resources)
return k8sutil.ExtractPodResourceRequirement(a.arangoMember.Spec.Overrides.GetResources(&a.groupSpec))
}
func (a *ArangoSyncContainer) GetLifecycle() (*core.Lifecycle, error) {
@ -319,6 +320,7 @@ func (m *MemberSyncPod) GetContainerCreator() interfaces.ContainerCreator {
imageInfo: m.imageInfo,
apiObject: m.apiObject,
memberStatus: m.memberStatus,
arangoMember: m.arangoMember,
tlsKeyfileSecretName: m.tlsKeyfileSecretName,
clientAuthCASecretName: m.clientAuthCASecretName,
masterJWTSecretName: m.masterJWTSecretName,

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -61,10 +61,15 @@ func (r *Resources) EnsurePVCs(ctx context.Context, cachedStatus inspectorInterf
continue
}
storageClassName := spec.GetStorageClassName()
am, exists := cachedStatus.ArangoMember().V1().GetSimple(m.ArangoMemberName(deploymentName, group))
if !exists {
continue
}
storageClassName := am.Spec.Overrides.GetStorageClassName(&spec)
role := group.AsRole()
resources := spec.Resources
vct := spec.VolumeClaimTemplate
resources := am.Spec.Overrides.GetResources(&spec)
vct := am.Spec.Overrides.GetVolumeClaimTemplate(&spec)
finalizers := r.createPVCFinalizers()
err := globals.GetGlobalTimeouts().Kubernetes().RunWithTimeout(ctx, func(ctxChild context.Context) error {
return k8sutil.CreatePersistentVolumeClaim(ctxChild, cachedStatus.PersistentVolumeClaimsModInterface().V1(),

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -29,6 +29,7 @@ type Inspector interface {
gvk.GVK
GetSimple(name string) (*api.ArangoMember, bool)
GetSimpleOptional(name string) *api.ArangoMember
Iterate(action Action, filters ...Filter) error
Read() ReadInterface
}