Skip to content

Commit

Permalink
Merge branch 'release-v1.16.x' into sergicastro-patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
sergicastro authored Nov 20, 2024
2 parents 82b90e8 + 9f720b8 commit e75b828
Show file tree
Hide file tree
Showing 43 changed files with 664 additions and 215 deletions.
35 changes: 34 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: Build

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

on:
push:
tags: [ 'v[0-9]+.[0-9]+-tetrate-v[0-9]+' ] # v1.16-tetrate-v7
Expand All @@ -12,13 +16,42 @@ env:
GOPROXY: https://proxy.golang.org

jobs:
test: ## This jobs takes around 2h to complete. Let's not make this a requirement for PRs until we can make it faster.
# All test running sequentially take around ~2h.
# Splitting them in groups that take more or less the same time makes PR's readiness faster
test-group:
strategy:
fail-fast: false
matrix:
label:
- "group:1"
- "group:2"
- "group:3"
- "group:4"
- "group:5"
runs-on: ubuntu-latest
env:
PLATFORMS: linux/amd64
TEST_LABEL: ${{ matrix.label }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- run: make test

# Have a fixed test to run once matrix tests are completed so we can make this required
test:
runs-on: ubuntu-latest
# We need this to run always to force-fail (and not skip) if any needed
# job has failed. Otherwise, a skipped job will not fail the workflow.
if: always()
steps:
- run: |
echo "tests completed"
[ "${{
contains(needs.*.result, 'failure') ||
contains(needs.*.result, 'cancelled') ||
contains(needs.*.result, 'skipped')
}}" == "false" ] || exit 1
needs:
- test-group
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,15 @@ fmt: ## Run go fmt against code.
vet: ## Run go vet against code.
go vet ./...

ifdef TEST_LABEL
TEST_LABEL_ARGS=-args "-ginkgo.label-filter=${TEST_LABEL}"
endif

# Define a TEST_LABEL environment variable to run a specific group of tests.
# Run something like `make test TEST_LABEL=group:1` to run only the tests in the group labeled "group:1".
.PHONY: test
test: build envtest kind ## Run tests.
KIND_EXEC_PATH=$(KIND) go test $(shell pwd)/test -run $(shell pwd)/test/suite_test.go -v -test.timeout 10000s
KIND_EXEC_PATH=$(KIND) go test $(shell pwd)/test -v -test.timeout 10000s $(TEST_LABEL_ARGS)

##@ Build

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ package failover

import (
"errors"
"strconv"

core "k8s.io/api/core/v1"
v1 "reactive-tech.io/kubegres/api/v1"
"reactive-tech.io/kubegres/controllers/ctx"
"reactive-tech.io/kubegres/controllers/operation"
"reactive-tech.io/kubegres/controllers/states"
"reactive-tech.io/kubegres/controllers/states/statefulset"
"strconv"
)

type PrimaryToReplicaFailOver struct {
Expand Down Expand Up @@ -244,9 +245,9 @@ func (r *PrimaryToReplicaFailOver) promoteReplicaToPrimary(newPrimary statefulse
newPrimary.StatefulSet.Labels["replicationRole"] = ctx.PrimaryRoleName
newPrimary.StatefulSet.Spec.Template.Labels["replicationRole"] = ctx.PrimaryRoleName
volumeMount := core.VolumeMount{
Name: "base-config",
Name: r.resourcesStates.Config.ConfigLocations.PromoteReplica,
MountPath: "/tmp/promote_replica_to_primary.sh",
SubPath: "promote_replica_to_primary.sh",
SubPath: states.ConfigMapDataKeyPromoteReplica,
}

initContainer := &newPrimary.StatefulSet.Spec.Template.Spec.InitContainers[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ func (r *CustomConfigSpecEnforcer) GetSpecName() string {

func (r *CustomConfigSpecEnforcer) CheckForSpecDifference(statefulSet *apps.StatefulSet) StatefulSetSpecDifference {

statefulSetCopy := *statefulSet
hasStatefulSetChanged, changesDetails := r.customConfigSpecHelper.ConfigureStatefulSet(&statefulSetCopy)
// We need to create a deep copy of the statefulSet to avoid modifying the original object, as we are only checking for differences.
// Original statefulSet will be modified by the EnforceSpec method.
statefulSetCopy := statefulSet.DeepCopy()
hasStatefulSetChanged, changesDetails := r.customConfigSpecHelper.ConfigureStatefulSet(statefulSetCopy)

if hasStatefulSetChanged {
return StatefulSetSpecDifference{
Expand All @@ -58,6 +60,6 @@ func (r *CustomConfigSpecEnforcer) EnforceSpec(statefulSet *apps.StatefulSet) (w
return wasSpecUpdated, nil
}

func (r *CustomConfigSpecEnforcer) OnSpecEnforcedSuccessfully(statefulSet *apps.StatefulSet) error {
func (r *CustomConfigSpecEnforcer) OnSpecEnforcedSuccessfully(*apps.StatefulSet) error {
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,22 @@ func extractCustom(src map[string]string) map[string]string {

func (r *CustomMetadataSpecEnforcer) EnforceSpec(statefulSet *apps.StatefulSet) (bool, error) {
md := getCustomMetadata(r.kubegresContext.Kubegres.GetObjectMeta())
merge(statefulSet.ObjectMeta.Labels, md.Labels)
merge(statefulSet.ObjectMeta.Annotations, md.Annotations)
merge(statefulSet.Spec.Template.ObjectMeta.Labels, md.Labels)
merge(statefulSet.Spec.Template.ObjectMeta.Annotations, md.Annotations)
statefulSet.ObjectMeta.Labels = merge(statefulSet.ObjectMeta.Labels, md.Labels)
statefulSet.ObjectMeta.Annotations = merge(statefulSet.ObjectMeta.Annotations, md.Annotations)
statefulSet.Spec.Template.ObjectMeta.Labels = merge(statefulSet.Spec.Template.ObjectMeta.Labels, md.Labels)
statefulSet.Spec.Template.ObjectMeta.Annotations = merge(statefulSet.Spec.Template.ObjectMeta.Annotations, md.Annotations)
return true, nil
}

func merge(dst map[string]string, src map[string]string) {
for key, value := range src {
dst[key] = value
func merge(a map[string]string, b map[string]string) map[string]string {
result := make(map[string]string, len(a)+len(b))
for key, value := range a {
result[key] = value
}
for key, value := range b {
result[key] = value
}
return result
}

func (r *CustomMetadataSpecEnforcer) OnSpecEnforcedSuccessfully(*apps.StatefulSet) error {
Expand Down
60 changes: 56 additions & 4 deletions controllers/spec/enforcer/statefulset_spec/VolumeSpecEnforcer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ limitations under the License.
package statefulset_spec

import (
"reflect"

apps "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
"reactive-tech.io/kubegres/controllers/ctx"
"reflect"
)

type VolumeSpecEnforcer struct {
Expand Down Expand Up @@ -52,12 +53,21 @@ func (r *VolumeSpecEnforcer) CheckForSpecDifference(statefulSet *apps.StatefulSe
}
}

currentCustomVolumeMountsInit, hasInitContainer := r.getVolumeMountsFromInitContainer(statefulSet)
currentCustomVolumeMounts := r.getCurrentCustomVolumeMounts(statefulSet)
expectedCustomVolumeMounts := r.kubegresContext.Kubegres.Spec.Volume.VolumeMounts

if hasInitContainer && !r.compareVolumeMounts(currentCustomVolumeMountsInit, expectedCustomVolumeMounts) {
return StatefulSetSpecDifference{
SpecName: "Volume.VolumeMounts[initContainer]",
Current: r.volumeMountsToString(currentCustomVolumeMountsInit),
Expected: r.volumeMountsToString(expectedCustomVolumeMounts),
}
}

if !r.compareVolumeMounts(currentCustomVolumeMounts, expectedCustomVolumeMounts) {
return StatefulSetSpecDifference{
SpecName: "Volume.VolumeMounts",
SpecName: "Volume.VolumeMounts[container]",
Current: r.volumeMountsToString(currentCustomVolumeMounts),
Expected: r.volumeMountsToString(expectedCustomVolumeMounts),
}
Expand All @@ -70,6 +80,7 @@ func (r *VolumeSpecEnforcer) EnforceSpec(statefulSet *apps.StatefulSet) (wasSpec

r.removeCustomVolumes(statefulSet)
r.removeCustomVolumeMounts(statefulSet)
r.removeCustomVolumeMountsFromInitContainer(statefulSet)

if r.kubegresContext.Kubegres.Spec.Volume.Volumes != nil {
statefulSet.Spec.Template.Spec.Volumes = append(statefulSet.Spec.Template.Spec.Volumes, r.kubegresContext.Kubegres.Spec.Volume.Volumes...)
Expand All @@ -79,10 +90,14 @@ func (r *VolumeSpecEnforcer) EnforceSpec(statefulSet *apps.StatefulSet) (wasSpec
statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts = append(statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts, r.kubegresContext.Kubegres.Spec.Volume.VolumeMounts...)
}

if len(statefulSet.Spec.Template.Spec.InitContainers) > 0 && statefulSet.Spec.Template.Spec.InitContainers[0].VolumeMounts != nil {
statefulSet.Spec.Template.Spec.InitContainers[0].VolumeMounts = append(statefulSet.Spec.Template.Spec.InitContainers[0].VolumeMounts, r.kubegresContext.Kubegres.Spec.Volume.VolumeMounts...)
}

return true, nil
}

func (r *VolumeSpecEnforcer) OnSpecEnforcedSuccessfully(statefulSet *apps.StatefulSet) error {
func (r *VolumeSpecEnforcer) OnSpecEnforcedSuccessfully(*apps.StatefulSet) error {
return nil
}

Expand All @@ -109,7 +124,7 @@ func (r *VolumeSpecEnforcer) doesExpectedVolumeExist(expectedCustomVolume v1.Vol
return false
}

func (r *VolumeSpecEnforcer) compareVolumeMounts(currentCustomVolumeMounts []v1.VolumeMount, expectedCustomVolumeMounts []v1.VolumeMount) bool {
func (r *VolumeSpecEnforcer) compareVolumeMounts(currentCustomVolumeMounts, expectedCustomVolumeMounts []v1.VolumeMount) bool {

if len(expectedCustomVolumeMounts) != len(currentCustomVolumeMounts) {
return false
Expand Down Expand Up @@ -158,6 +173,23 @@ func (r *VolumeSpecEnforcer) getCurrentCustomVolumeMounts(statefulSet *apps.Stat
return customVolumeMounts
}

func (r *VolumeSpecEnforcer) getVolumeMountsFromInitContainer(statefulSet *apps.StatefulSet) ([]v1.VolumeMount, bool) {

if len(statefulSet.Spec.Template.Spec.InitContainers) == 0 {
return nil, false
}

initContainer := &statefulSet.Spec.Template.Spec.InitContainers[0]
var customVolumeMounts []v1.VolumeMount

for _, volumeMount := range initContainer.VolumeMounts {
if !r.kubegresContext.IsReservedVolumeName(volumeMount.Name) {
customVolumeMounts = append(customVolumeMounts, volumeMount)
}
}
return customVolumeMounts, true
}

func (r *VolumeSpecEnforcer) removeCustomVolumes(statefulSet *apps.StatefulSet) {

currentCustomVolumes := r.getCurrentCustomVolumes(statefulSet)
Expand Down Expand Up @@ -209,6 +241,26 @@ func (r *VolumeSpecEnforcer) removeCustomVolumeMounts(statefulSet *apps.Stateful
}
}

func (r *VolumeSpecEnforcer) removeCustomVolumeMountsFromInitContainer(statefulSet *apps.StatefulSet) {

currentCustomVolumeMounts, hasInit := r.getVolumeMountsFromInitContainer(statefulSet)
if !hasInit || len(currentCustomVolumeMounts) == 0 {
return
}

currentCustomVolumeMountsCopy := make([]v1.VolumeMount, len(currentCustomVolumeMounts))
copy(currentCustomVolumeMountsCopy, currentCustomVolumeMounts)

initContainer := &statefulSet.Spec.Template.Spec.InitContainers[0]

for _, customVolumeMount := range currentCustomVolumeMountsCopy {
index := r.getIndexOfVolumeMount(customVolumeMount, initContainer.VolumeMounts)
if index >= 0 {
initContainer.VolumeMounts = append(initContainer.VolumeMounts[:index], initContainer.VolumeMounts[index+1:]...)
}
}
}

func (r *VolumeSpecEnforcer) getIndexOfVolumeMount(volumeMountToSearch v1.VolumeMount, volumeMounts []v1.VolumeMount) int {
index := 0
for _, volumeMount := range volumeMounts {
Expand Down
37 changes: 23 additions & 14 deletions controllers/spec/template/CustomConfigSpecHelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ func (r *CustomConfigSpecHelper) ConfigureStatefulSet(statefulSet *v1.StatefulSe
hasStatefulSetChanged = true
}

if r.updateVolumeMountNameIfChanged(configMap.ConfigLocations.CopyPrimaryDataToReplica, states.ConfigMapDataKeyCopyPrimaryDataToReplica, statefulSet) {
differenceDetails += r.createDescriptionMsg(configMap.ConfigLocations.CopyPrimaryDataToReplica, states.ConfigMapDataKeyCopyPrimaryDataToReplica)
hasStatefulSetChanged = true
}

if r.updateVolumeMountNameIfChanged(configMap.ConfigLocations.PrimaryCreateReplicaRole, states.ConfigMapDataKeyPrimaryCreateReplicaRole, statefulSet) {
differenceDetails += r.createDescriptionMsg(configMap.ConfigLocations.PrimaryCreateReplicaRole, states.ConfigMapDataKeyPrimaryCreateReplicaRole)
hasStatefulSetChanged = true
}

// No need to check for states.ConfigMapDataKeyPromoteReplica as this is only used by the failover enforcer

statefulSetTemplateSpec := &statefulSet.Spec.Template.Spec

customConfigMapVolume := r.getCustomConfigMapVolume(statefulSetTemplateSpec.Volumes)
Expand Down Expand Up @@ -89,32 +101,29 @@ func (r *CustomConfigSpecHelper) ConfigureStatefulSet(statefulSet *v1.StatefulSe

func (r *CustomConfigSpecHelper) updateVolumeMountNameIfChanged(volumeName, configMapDataKey string, statefulSet *v1.StatefulSet) (updated bool) {

volumeMounts := statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts

for i := 0; i < len(volumeMounts); i++ {
volumeMount := volumeMounts[i]
for i, volumeMount := range statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts {
if volumeMount.SubPath == configMapDataKey && volumeMount.Name != volumeName {
statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts[i].Name = volumeName
updated = true
}
}

if len(statefulSet.Spec.Template.Spec.InitContainers) > 0 {
for i, volume := range statefulSet.Spec.Template.Spec.InitContainers[0].VolumeMounts {
if volume.SubPath == configMapDataKey && volume.Name != volumeName {
statefulSet.Spec.Template.Spec.InitContainers[0].VolumeMounts[i].Name = volumeName
updated = true
}
}
}

return updated
}

func (r *CustomConfigSpecHelper) createDescriptionMsg(volumeMountName, configMapDataKey string) string {
return "VolumeMount with subPath: '" + configMapDataKey + "' was updated to name: '" + volumeMountName + "' - "
}

func (r *CustomConfigSpecHelper) getVolumeMountIndex(configMapDataKey string, statefulSet *v1.StatefulSet) int {
volumeMounts := statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts
for i := 0; i < len(volumeMounts); i++ {
if volumeMounts[i].SubPath == configMapDataKey {
return i
}
}
return -1
}

func (r *CustomConfigSpecHelper) getCustomConfigMapVolume(volumes []core.Volume) *core.Volume {
for _, volume := range volumes {
if volume.Name == ctx.CustomConfigMapVolumeName {
Expand Down
3 changes: 3 additions & 0 deletions controllers/spec/template/ResourcesCreatorFromTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ func (r *ResourcesCreatorFromTemplate) initStatefulSet(

if postgresSpec.Volume.VolumeMounts != nil {
statefulSetTemplate.Spec.Template.Spec.Containers[0].VolumeMounts = append(statefulSetTemplate.Spec.Template.Spec.Containers[0].VolumeMounts, r.kubegresContext.Kubegres.Spec.Volume.VolumeMounts...)
if len(statefulSetTemplate.Spec.Template.Spec.InitContainers) > 0 {
statefulSetTemplate.Spec.Template.Spec.InitContainers[0].VolumeMounts = append(statefulSetTemplate.Spec.Template.Spec.InitContainers[0].VolumeMounts, r.kubegresContext.Kubegres.Spec.Volume.VolumeMounts...)
}
}

if postgresSpec.SecurityContext != nil {
Expand Down
Loading

0 comments on commit e75b828

Please sign in to comment.