Skip to content

Commit

Permalink
Merge pull request #70 from kmcrawford/elect-new-master-on-sigterm
Browse files Browse the repository at this point in the history
Elect a new master on sigterm
  • Loading branch information
jchanam authored Aug 17, 2018
2 parents ba9e885 + af9cfe8 commit c746c51
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 12 deletions.
19 changes: 10 additions & 9 deletions api/redisfailover/v1alpha2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@ type RedisFailoverSpec struct {

// RedisSettings defines the specification of the redis cluster
type RedisSettings struct {
Replicas int32 `json:"replicas,omitempty"`
Resources RedisFailoverResources `json:"resources,omitempty"`
Exporter bool `json:"exporter,omitempty"`
ExporterImage string `json:"exporterImage,omitempty"`
ExporterVersion string `json:"exporterVersion,omitempty"`
Image string `json:"image,omitempty"`
Version string `json:"version,omitempty"`
ConfigMap string `json:"configMap,omitempty"`
Storage RedisStorage `json:"storage,omitempty"`
Replicas int32 `json:"replicas,omitempty"`
Resources RedisFailoverResources `json:"resources,omitempty"`
Exporter bool `json:"exporter,omitempty"`
ExporterImage string `json:"exporterImage,omitempty"`
ExporterVersion string `json:"exporterVersion,omitempty"`
Image string `json:"image,omitempty"`
Version string `json:"version,omitempty"`
ConfigMap string `json:"configMap,omitempty"`
ShutdownConfigMap string `json:"shutdownConfigMap,omitempty"`
Storage RedisStorage `json:"storage,omitempty"`
}

// SentinelSettings defines the specification of the sentinel cluster
Expand Down
2 changes: 1 addition & 1 deletion charts/redisoperator/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: v1
description: A Helm chart for the Spotahome Redis Operator
name: redisoperator
version: 2.2.0
version: 2.3.0
14 changes: 14 additions & 0 deletions mocks/operator/redisfailover/service/RedisFailoverClient.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions operator/redisfailover/ensurer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ func (w *RedisFailoverHandler) Ensure(rf *redisfailoverv1alpha2.RedisFailover, l
if err := w.rfService.EnsureSentinelConfigMap(rf, labels, or); err != nil {
return err
}
if err := w.rfService.EnsureRedisShutdownConfigMap(rf, labels, or); err != nil {
return err
}
if err := w.rfService.EnsureRedisConfigMap(rf, labels, or); err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions operator/redisfailover/ensurer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func TestEnsure(t *testing.T) {
mrfs.On("EnsureSentinelService", rf, mock.Anything, mock.Anything).Once().Return(nil)
mrfs.On("EnsureSentinelConfigMap", rf, mock.Anything, mock.Anything).Once().Return(nil)
mrfs.On("EnsureRedisConfigMap", rf, mock.Anything, mock.Anything).Once().Return(nil)
mrfs.On("EnsureRedisShutdownConfigMap", rf, mock.Anything, mock.Anything).Once().Return(nil)
mrfs.On("EnsureRedisStatefulset", rf, mock.Anything, mock.Anything).Once().Return(nil)
mrfs.On("EnsureSentinelDeployment", rf, mock.Anything, mock.Anything).Once().Return(nil)

Expand Down
13 changes: 13 additions & 0 deletions operator/redisfailover/service/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type RedisFailoverClient interface {
EnsureSentinelDeployment(rFailover *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureRedisStatefulset(rFailover *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureRedisService(rFailover *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureRedisShutdownConfigMap(rFailover *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureRedisConfigMap(rFailover *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureNotPresentRedisService(rFailover *redisfailoverv1alpha2.RedisFailover) error
}
Expand Down Expand Up @@ -94,6 +95,18 @@ func (r *RedisFailoverKubeClient) EnsureRedisConfigMap(rf *redisfailoverv1alpha2
return nil
}

func (r *RedisFailoverKubeClient) EnsureRedisShutdownConfigMap(rf *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error {
if rf.Spec.Redis.ShutdownConfigMap != "" {
if _, err := r.K8SService.GetConfigMap(rf.Namespace, rf.Spec.Redis.ShutdownConfigMap); err != nil {
return err
}
} else {
cm := generateRedisShutdownConfigMap(rf, labels, ownerRefs)
return r.K8SService.CreateOrUpdateConfigMap(rf.Namespace, cm)
}
return nil
}

// EnsureRedisService makes sure the redis statefulset exists
func (r *RedisFailoverKubeClient) EnsureRedisService(rf *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error {
svc := generateRedisService(rf, labels, ownerRefs)
Expand Down
1 change: 1 addition & 0 deletions operator/redisfailover/service/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const (
sentinelConfigFileName = "sentinel.conf"
redisConfigFileName = "redis.conf"
redisName = "r"
redisShutdownName = "r-shutdown"
redisRoleName = "redis"
redisGroupName = "mymaster"
appLabel = "redis-failover"
Expand Down
51 changes: 49 additions & 2 deletions operator/redisfailover/service/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import (
)

const (
redisConfigurationVolumeName = "redis-config"
redisStorageVolumeName = "redis-data"
redisConfigurationVolumeName = "redis-config"
redisShutdownConfigurationVolumeName = "redis-shutdown-config"
redisStorageVolumeName = "redis-data"
)

func generateSentinelService(rf *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) *corev1.Service {
Expand Down Expand Up @@ -122,6 +123,28 @@ tcp-keepalive 60`,
}
}

func generateRedisShutdownConfigMap(rf *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) *corev1.ConfigMap {
name := GetRedisShutdownConfigMapName(rf)
namespace := rf.Namespace

labels = util.MergeLabels(labels, generateLabels(redisRoleName, rf.Name))

return &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: labels,
OwnerReferences: ownerRefs,
},
Data: map[string]string{
"shutdown.sh": `master=$(redis-cli -h ${RFS_REDIS_SERVICE_HOST} -p ${RFS_REDIS_SERVICE_PORT_SENTINEL} --csv SENTINEL get-master-addr-by-name mymaster | tr ',' ' ' | tr -d '\"' |cut -d' ' -f1)
if [[ $master == $(hostname -i) ]]; then
redis-cli -h ${RFS_REDIS_SERVICE_HOST} -p ${RFS_REDIS_SERVICE_PORT_SENTINEL} SENTINEL failover mymaster
fi`,
},
}
}

func generateRedisStatefulSet(rf *redisfailoverv1alpha2.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) *appsv1beta2.StatefulSet {
name := GetRedisName(rf)
namespace := rf.Namespace
Expand Down Expand Up @@ -202,6 +225,13 @@ func generateRedisStatefulSet(rf *redisfailoverv1alpha2.RedisFailover, labels ma
},
},
Resources: resources,
Lifecycle: &corev1.Lifecycle{
PreStop: &corev1.Handler{
Exec: &corev1.ExecAction{
Command: []string{"/bin/sh", "-c", "/redis-shutdown/shutdown.sh"},
},
},
},
},
},
Volumes: volumes,
Expand Down Expand Up @@ -541,6 +571,10 @@ func getRedisVolumeMounts(rf *redisfailoverv1alpha2.RedisFailover) []corev1.Volu
Name: redisConfigurationVolumeName,
MountPath: "/redis",
},
{
Name: redisShutdownConfigurationVolumeName,
MountPath: "/redis-shutdown",
},
{
Name: getRedisDataVolumeName(rf),
MountPath: "/data",
Expand All @@ -552,7 +586,9 @@ func getRedisVolumeMounts(rf *redisfailoverv1alpha2.RedisFailover) []corev1.Volu

func getRedisVolumes(rf *redisfailoverv1alpha2.RedisFailover) []corev1.Volume {
configMapName := GetRedisConfigMapName(rf)
shutdownConfigMapName := GetRedisShutdownConfigMapName(rf)

executeMode := int32(0744)
volumes := []corev1.Volume{
{
Name: redisConfigurationVolumeName,
Expand All @@ -564,6 +600,17 @@ func getRedisVolumes(rf *redisfailoverv1alpha2.RedisFailover) []corev1.Volume {
},
},
},
{
Name: redisShutdownConfigurationVolumeName,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: shutdownConfigMapName,
},
DefaultMode: &executeMode,
},
},
},
}

dataVolume := getRedisDataVolume(rf)
Expand Down
77 changes: 77 additions & 0 deletions operator/redisfailover/service/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (

func TestRedisStatefulSetStorageGeneration(t *testing.T) {
configMapName := rfservice.GetRedisConfigMapName(generateRF())
shutdownConfigMapName := rfservice.GetRedisShutdownConfigMapName(generateRF())
executeMode := int32(0744)
tests := []struct {
name string
ownerRefs []metav1.OwnerReference
Expand All @@ -37,6 +39,10 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
Name: "redis-config",
MountPath: "/redis",
},
{
Name: "redis-shutdown-config",
MountPath: "/redis-shutdown",
},
{
Name: "redis-data",
MountPath: "/data",
Expand All @@ -55,6 +61,17 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
},
},
},
{
Name: "redis-shutdown-config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: shutdownConfigMapName,
},
DefaultMode: &executeMode,
},
},
},
{
Name: "redis-data",
VolumeSource: corev1.VolumeSource{
Expand All @@ -81,6 +98,10 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
Name: "redis-config",
MountPath: "/redis",
},
{
Name: "redis-shutdown-config",
MountPath: "/redis-shutdown",
},
{
Name: "redis-data",
MountPath: "/data",
Expand All @@ -99,6 +120,17 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
},
},
},
{
Name: "redis-shutdown-config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: shutdownConfigMapName,
},
DefaultMode: &executeMode,
},
},
},
{
Name: "redis-data",
VolumeSource: corev1.VolumeSource{
Expand Down Expand Up @@ -131,6 +163,10 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
Name: "redis-config",
MountPath: "/redis",
},
{
Name: "redis-shutdown-config",
MountPath: "/redis-shutdown",
},
{
Name: "pvc-data",
MountPath: "/data",
Expand All @@ -149,6 +185,17 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
},
},
},
{
Name: "redis-shutdown-config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: shutdownConfigMapName,
},
DefaultMode: &executeMode,
},
},
},
},
},
},
Expand Down Expand Up @@ -207,6 +254,10 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
Name: "redis-config",
MountPath: "/redis",
},
{
Name: "redis-shutdown-config",
MountPath: "/redis-shutdown",
},
{
Name: "pvc-data",
MountPath: "/data",
Expand All @@ -225,6 +276,17 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
},
},
},
{
Name: "redis-shutdown-config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: shutdownConfigMapName,
},
DefaultMode: &executeMode,
},
},
},
},
},
},
Expand Down Expand Up @@ -288,6 +350,10 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
Name: "redis-config",
MountPath: "/redis",
},
{
Name: "redis-shutdown-config",
MountPath: "/redis-shutdown",
},
{
Name: "pvc-data",
MountPath: "/data",
Expand All @@ -306,6 +372,17 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
},
},
},
{
Name: "redis-shutdown-config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: shutdownConfigMapName,
},
DefaultMode: &executeMode,
},
},
},
},
},
},
Expand Down
13 changes: 13 additions & 0 deletions operator/redisfailover/service/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,24 @@ func GetRedisConfigMapName(rf *redisfailoverv1alpha2.RedisFailover) string {
return GetRedisName(rf)
}

// GetRedisShutdownConfigMapName returns the name for redis configmap
func GetRedisShutdownConfigMapName(rf *redisfailoverv1alpha2.RedisFailover) string {
if rf.Spec.Redis.ShutdownConfigMap != "" {
return rf.Spec.Redis.ShutdownConfigMap
}
return GetRedisShutdownName(rf)
}

// GetRedisName returns the name for redis resources
func GetRedisName(rf *redisfailoverv1alpha2.RedisFailover) string {
return generateName(redisName, rf.Name)
}

// GetRedisName returns the name for redis resources
func GetRedisShutdownName(rf *redisfailoverv1alpha2.RedisFailover) string {
return generateName(redisShutdownName, rf.Name)
}

// GetSentinelConfigMapName returns the name for sentinel configmap
func GetSentinelConfigMapName(rf *redisfailoverv1alpha2.RedisFailover) string {
if rf.Spec.Sentinel.ConfigMap != "" {
Expand Down

0 comments on commit c746c51

Please sign in to comment.