From b430d68246746c9dd045584ce0f258054fa8c6a7 Mon Sep 17 00:00:00 2001 From: eberlep Date: Fri, 18 Jun 2021 13:00:39 +0200 Subject: [PATCH] Add proper support for the shared_buffer configuration parameter (#220) --- api/v1/postgres_types.go | 23 +++++++++- api/v1/postgres_types_test.go | 85 +++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 api/v1/postgres_types_test.go diff --git a/api/v1/postgres_types.go b/api/v1/postgres_types.go index 53b67af8..e2610268 100644 --- a/api/v1/postgres_types.go +++ b/api/v1/postgres_types.go @@ -9,6 +9,7 @@ package v1 import ( "fmt" "reflect" + "strconv" "regexp" @@ -17,6 +18,7 @@ import ( "inet.af/netaddr" 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/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -50,6 +52,8 @@ const ( BackupConfigLabelName string = "postgres.database.fits.cloud/is-backup" // BackupConfigKey defines the key under which the BackupConfig is stored in the data map. BackupConfigKey = "config" + // SharedBufferParameterKey defines the key under which the shared buffer size is stored in the parameters map. Defined by the postgres-operator/patroni + SharedBufferParameterKey = "shared_buffer" ) var ( @@ -401,8 +405,8 @@ func (p *Postgres) ToUnstructuredZalandoPostgresql(z *zalando.Postgresql, c *cor z.Spec.NumberOfInstances = p.Spec.NumberOfInstances z.Spec.PostgresqlParam.PgVersion = p.Spec.Version - // TODO set shared_buffer from p.Spec.Size.SharedBuffer - // z.Spec.PostgresqlParam.Parameters = map[string]string{} + z.Spec.PostgresqlParam.Parameters = map[string]string{} + setSharedBufferSize(z.Spec.PostgresqlParam.Parameters, p.Spec.Size.SharedBuffer) z.Spec.Resources.ResourceRequests.CPU = p.Spec.Size.CPU z.Spec.Resources.ResourceRequests.Memory = p.Spec.Size.Memory z.Spec.Resources.ResourceLimits.CPU = p.Spec.Size.CPU @@ -542,3 +546,18 @@ func (p *Postgres) buildSidecars(c *corev1.ConfigMap) []zalando.Sidecar { return sidecars } + +// setSharedBufferSize converts and, if valid, sets the shared_buffer parameter in the given map. +func setSharedBufferSize(parameters map[string]string, shmSize string) { + // First step is to convert the string back to a quantity + size, err := resource.ParseQuantity(shmSize) + if err == nil { + // if successful, get the given shared buffer size in bytes. + sizeInBytes, ok := size.AsInt64() + if ok && sizeInBytes >= (32*1024*1024) { + // if more than 32Mi (our minimum value), convert the value to MB as required by postgres (although the docs are not very specific about that) + sizeInMB := sizeInBytes / (1024 * 1024) + parameters[SharedBufferParameterKey] = strconv.FormatInt(sizeInMB, 10) + "MB" + } + } +} diff --git a/api/v1/postgres_types_test.go b/api/v1/postgres_types_test.go new file mode 100644 index 00000000..04d55481 --- /dev/null +++ b/api/v1/postgres_types_test.go @@ -0,0 +1,85 @@ +/* +/ SPDX-FileCopyrightText: 2021 Finanz Informatik Technologie Services GmbHs +/ +/ SPDX-License-Identifier: AGPL-1.0-only +*/ + +package v1 + +import ( + "testing" +) + +func Test_setSharedBufferSize(t *testing.T) { + + tests := []struct { + name string + input string + expected string + }{ + { + name: "default", + input: "64Mi", + expected: "64MB", + }, + { + name: "min", + input: "32Mi", + expected: "32MB", + }, + { + name: "belowMin", + input: "31Mi", + expected: "", + }, + { + name: "Gibibytes", + input: "1Gi", + expected: "1024MB", + }, + { + name: "Kibibytes", + input: "102400Ki", + expected: "100MB", + }, + { + name: "Bytes", + input: "67108864", + expected: "64MB", + }, + { + name: "empty", + input: "", + expected: "", + }, + { + name: "empty2", + input: " ", + expected: "", + }, + { + name: "invalid", + input: "64MB", + expected: "", + }, + } + for _, tt := range tests { + tt := tt // pin! + t.Run(tt.name, func(t *testing.T) { + parameters := map[string]string{} + + setSharedBufferSize(parameters, tt.input) + + result, ok := parameters[SharedBufferParameterKey] + if ok { + if tt.expected != result { + t.Errorf("Adapter.ScopedGet() assertion failed: expected %q, got %q\n", tt.expected, result) + } + } else { + if tt.expected != "" { + t.Errorf("Conversion failed") + } + } + }) + } +}