Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating scripts configMap no longer causes Elasticsearch restart #7114

Merged
merged 2 commits into from
Aug 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 23 additions & 4 deletions pkg/controller/elasticsearch/nodespec/podspec.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"context"
"fmt"
"hash/fnv"
"sort"
"strings"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -98,7 +99,7 @@ func BuildPodTemplateSpec(
if err := client.Get(context.Background(), types.NamespacedName{Namespace: es.Namespace, Name: esv1.ScriptsConfigMap(es.Name)}, esScripts); err != nil {
return corev1.PodTemplateSpec{}, err
}
annotations := buildAnnotations(es, cfg, keystoreResources, esScripts.ResourceVersion)
annotations := buildAnnotations(es, cfg, keystoreResources, getScriptsConfigMapContent(esScripts))

// Attempt to detect if the default data directory is mounted in a volume.
// If not, it could be a bug, a misconfiguration, or a custom storage configuration that requires the user to
Expand Down Expand Up @@ -189,7 +190,7 @@ func buildAnnotations(
es esv1.Elasticsearch,
cfg settings.CanonicalConfig,
keystoreResources *keystore.Resources,
scriptsVersion string,
scriptsContent string,
) map[string]string {
// start from our defaults
annotations := map[string]string{
Expand All @@ -199,8 +200,8 @@ func buildAnnotations(
configHash := fnv.New32a()
// hash of the ES config to rotate the pod on config changes
hash.WriteHashObject(configHash, cfg)
// hash of the scripts' version to rotate the pod if the scripts have changed
_, _ = configHash.Write([]byte(scriptsVersion))
// hash of the scripts' content to rotate the pod if the scripts have changed
_, _ = configHash.Write([]byte(scriptsContent))

if es.HasDownwardNodeLabels() {
// list of node labels expected on the pod to rotate the pod when the list is updated
Expand Down Expand Up @@ -245,3 +246,21 @@ func enableLog4JFormatMsgNoLookups(builder *defaults.PodTemplateBuilder) {
}
}
}

// Get contents of the script ConfigMap to generate config hash, excluding the suspended_pods.txt, as it may change over time.
func getScriptsConfigMapContent(cm *corev1.ConfigMap) string {
cr7258 marked this conversation as resolved.
Show resolved Hide resolved
var builder strings.Builder
var keys []string

for k := range cm.Data {
if k != initcontainer.SuspendedHostsFile {
keys = append(keys, k)
}
}
sort.Strings(keys)

for _, k := range keys {
builder.WriteString(cm.Data[k])
}
return builder.String()
}
33 changes: 23 additions & 10 deletions pkg/controller/elasticsearch/nodespec/podspec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ func TestBuildPodTemplateSpec(t *testing.T) {
"pod-template-label-name": "pod-template-label-value",
},
Annotations: map[string]string{
"elasticsearch.k8s.elastic.co/config-hash": "3893049321",
"elasticsearch.k8s.elastic.co/config-hash": "533641620",
"pod-template-annotation-name": "pod-template-annotation-value",
"co.elastic.logs/module": "elasticsearch",
},
Expand Down Expand Up @@ -364,7 +364,7 @@ func Test_buildAnnotations(t *testing.T) {
cfg map[string]interface{}
esAnnotations map[string]string
keystoreResources *keystore.Resources
scriptsVersion string
scriptsContent string
}
tests := []struct {
name string
Expand Down Expand Up @@ -410,15 +410,15 @@ func Test_buildAnnotations(t *testing.T) {
},
},
{
name: "With keystore and scripts version",
name: "With keystore and scripts content",
args: args{
keystoreResources: &keystore.Resources{
Version: "42",
},
scriptsVersion: "84",
scriptsContent: "scripts content",
},
expectedAnnotations: map[string]string{
"elasticsearch.k8s.elastic.co/config-hash": "1607725946",
"elasticsearch.k8s.elastic.co/config-hash": "99942575",
},
},
{
Expand All @@ -427,10 +427,10 @@ func Test_buildAnnotations(t *testing.T) {
keystoreResources: &keystore.Resources{
Version: "43",
},
scriptsVersion: "84",
scriptsContent: "scripts content",
},
expectedAnnotations: map[string]string{
"elasticsearch.k8s.elastic.co/config-hash": "1624503565",
"elasticsearch.k8s.elastic.co/config-hash": "83164956",
},
},
{
Expand All @@ -439,10 +439,10 @@ func Test_buildAnnotations(t *testing.T) {
keystoreResources: &keystore.Resources{
Version: "42",
},
scriptsVersion: "85",
scriptsContent: "another scripts content",
},
expectedAnnotations: map[string]string{
"elasticsearch.k8s.elastic.co/config-hash": "3194693445",
"elasticsearch.k8s.elastic.co/config-hash": "1050348692",
},
},
}
Expand All @@ -453,7 +453,7 @@ func Test_buildAnnotations(t *testing.T) {
require.NoError(t, err)
cfg, err := settings.NewMergedESConfig(es.Name, ver, corev1.IPv4Protocol, es.Spec.HTTP, *es.Spec.NodeSets[0].Config)
require.NoError(t, err)
got := buildAnnotations(es, cfg, tt.args.keystoreResources, tt.args.scriptsVersion)
got := buildAnnotations(es, cfg, tt.args.keystoreResources, tt.args.scriptsContent)

for expectedAnnotation, expectedValue := range tt.expectedAnnotations {
actualValue, exists := got[expectedAnnotation]
Expand Down Expand Up @@ -564,3 +564,16 @@ func Test_enableLog4JFormatMsgNoLookups(t *testing.T) {
})
}
}

func Test_getScriptsConfigMapContent(t *testing.T) {
cm := &corev1.ConfigMap{
Data: map[string]string{
PreStopHookScriptConfigKey: "value1#",
initcontainer.PrepareFsScriptConfigKey: "value2#",
ReadinessProbeScriptConfigKey: "value3#",
initcontainer.SuspendScriptConfigKey: "value4#",
initcontainer.SuspendedHostsFile: "value5#",
},
}
assert.Equal(t, "value1#value2#value3#value4#", getScriptsConfigMapContent(cm))
}