Skip to content

Commit

Permalink
feat(deploy): add config map to specify the xline bootup args
Browse files Browse the repository at this point in the history
Signed-off-by: Phoeniix Zhao <[email protected]>
  • Loading branch information
Phoenix500526 committed Dec 18, 2023
1 parent 377f0c1 commit 5b18b0f
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 1 deletion.
5 changes: 5 additions & 0 deletions api/v1alpha1/xlinecluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ type XlineClusterSpec struct {
// The replicas of xline nodes
// +kubebuilder:validation:Minimum=3
Replicas int32 `json:"replicas"`

// The config items of xline server
// +optional
Config map[string]string `json:"config"`
}

// XlineClusterStatus defines the observed state of XlineCluster
Expand All @@ -78,6 +82,7 @@ type XlineClusterStatus struct {
type XlineClusterOprStage string

const (
StageXlineConfigMap XlineClusterOprStage = "Xline/ConfigMap"
StageXlineService XlineClusterOprStage = "Xline/Service"
StageXlineStatefulSet XlineClusterOprStage = "Xline/Statefulset"
StageComplete XlineClusterOprStage = "complete"
Expand Down
7 changes: 7 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ spec:
spec:
description: XlineClusterSpec defines the desired state of XlineCluster
properties:
config:
additionalProperties:
type: string
description: The config items of xline server
type: object
image:
description: Xline cluster image
type: string
Expand Down
6 changes: 6 additions & 0 deletions internal/reconciler/cluster_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ func (r *ClusterStageRecResult) AsXlineClusterRecStatus() xapi.XlineClusterRecSt

// reconcile xline cluster resources.
func (r *XlineClusterReconciler) recXlineResources() ClusterStageRecResult {
// create an xline configmap
configMap := tran.MakeConfigMap(r.CR, r.Schema)
if err := r.CreateOrUpdate(configMap, &corev1.ConfigMap{}); err != nil {
return clusterStageFail(xapi.StageXlineConfigMap, err)
}

// create a xline service
service := tran.MakeService(r.CR, r.Schema)
if err := r.CreateOrUpdate(service, &corev1.Service{}); err != nil {
Expand Down
42 changes: 42 additions & 0 deletions internal/transformer/xlinecluster_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"

xapi "github.com/xline-kv/xline-operator/api/v1alpha1"
"github.com/xline-kv/xline-operator/internal/util"
appv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -13,6 +14,13 @@ import (
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

func GetConfigMapKey(xlineClusterName types.NamespacedName) types.NamespacedName {
return types.NamespacedName{
Namespace: xlineClusterName.Namespace,
Name: fmt.Sprintf("%s-config", xlineClusterName.Name),
}
}

func GetServiceKey(xlineClusterName types.NamespacedName) types.NamespacedName {
return types.NamespacedName{
Namespace: xlineClusterName.Namespace,
Expand Down Expand Up @@ -46,6 +54,33 @@ func GetMemberTopology(stsRef types.NamespacedName, svcName string, replicas int
return strings.Join(members, ",")
}

func defaultConfigMap(clusterName string) map[string]string {
return map[string]string{
"init-leader": fmt.Sprintf("%s-sts-0", clusterName),
"log-level": "info",
"engine": "rocksdb",
"data-dir": "/usr/local/xline/data-dir",
"jwt-pubkey": "",
"jwt-prikey": "",
}
}

func MakeConfigMap(cr *xapi.XlineCluster, scheme *runtime.Scheme) *corev1.ConfigMap {
defaultConf := defaultConfigMap(cr.ObjKey().Name)
data := util.IntersectAndMergeMaps(cr.Spec.Config, defaultConf)
configMapRef := GetConfigMapKey(cr.ObjKey())
configMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: configMapRef.Name,
Namespace: configMapRef.Namespace,
Labels: GetXlineInstanceLabels(cr.ObjKey()),
},
Data: data,
}
_ = controllerutil.SetOwnerReference(cr, configMap, scheme)
return configMap
}

func MakeService(cr *xapi.XlineCluster, scheme *runtime.Scheme) *corev1.Service {
svcRef := GetServiceKey(cr.ObjKey())
svcLabel := GetXlineInstanceLabels(cr.ObjKey())
Expand All @@ -71,6 +106,7 @@ func MakeService(cr *xapi.XlineCluster, scheme *runtime.Scheme) *corev1.Service

func MakeStatefulSet(cr *xapi.XlineCluster, scheme *runtime.Scheme) *appv1.StatefulSet {
crName := types.NamespacedName{Namespace: cr.Namespace, Name: cr.Name}
configMapRef := GetConfigMapKey(cr.ObjKey())
stsRef := GetStatefulSetKey(crName)
stsLabels := GetXlineInstanceLabels(crName)
svcName := GetServiceKey(cr.ObjKey()).Name
Expand All @@ -85,6 +121,12 @@ func MakeStatefulSet(cr *xapi.XlineCluster, scheme *runtime.Scheme) *appv1.State
},
Env: []corev1.EnvVar{
{Name: "MEMBERS", Value: GetMemberTopology(stsRef, svcName, int(cr.Spec.Replicas))},
{Name: "INIT_LEADER", ValueFrom: util.NewEnvVarConfigMapSource(configMapRef.Name, "init-leader")},
{Name: "RUST_LOG", ValueFrom: util.NewEnvVarConfigMapSource(configMapRef.Name, "log-level")},
{Name: "ENGINE", ValueFrom: util.NewEnvVarConfigMapSource(configMapRef.Name, "engine")},
{Name: "DATA_DIR", ValueFrom: util.NewEnvVarConfigMapSource(configMapRef.Name, "data-dir")},
{Name: "AUTH_PUBLIC_KEY", ValueFrom: util.NewEnvVarConfigMapSource(configMapRef.Name, "jwt-pubkey")},
{Name: "AUTH_PRIVATE_KEY", ValueFrom: util.NewEnvVarConfigMapSource(configMapRef.Name, "jwt-prikey")},
},
}

Expand Down
23 changes: 23 additions & 0 deletions internal/util/kubeutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
)

Expand Down Expand Up @@ -34,3 +35,25 @@ func Md5HashOr(obj any, fallback string) string {
}
return hash
}

// IntersectAndMergeMaps patch the m1 on the m2
func IntersectAndMergeMaps[K comparable, V any](m1, m2 map[K]V) map[K]V {
if len(m1) == 0 || m1 == nil || len(m2) == 0 || m2 == nil {
return m2
}
for k := range m2 {
if value, ok := m1[k]; ok {
m2[k] = value
}
}
return m2
}

func NewEnvVarConfigMapSource(cmName string, key string) *corev1.EnvVarSource {
return &corev1.EnvVarSource{
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
LocalObjectReference: corev1.LocalObjectReference{Name: cmName},
Key: key,
},
}
}
15 changes: 15 additions & 0 deletions internal/util/kubeutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,18 @@ func TestK8sObjKeyStr(t *testing.T) {
objkey := types.NamespacedName{Name: "xline", Namespace: "default"}
assert.Equal(t, K8sObjKeyStr(objkey), "xline.default")
}

func TestIntersectAndMergeMaps(t *testing.T) {
m1 := map[string]string{}
m2 := map[string]string{"hello": "world"}
assert.Equal(t, IntersectAndMergeMaps(m1, m2), m2)
assert.Equal(t, IntersectAndMergeMaps(nil, m2), m2)

m1 = map[string]string{"hello": "Sun"}
m2 = map[string]string{"hello": "Earth", "world": "Moon"}
assert.Equal(t, IntersectAndMergeMaps(m1, m2), map[string]string{"hello": "Sun", "world": "Moon"})

assert.Equal(t, IntersectAndMergeMaps(m1, nil), map[string]string(nil))
assert.Equal(t, IntersectAndMergeMaps(m1, map[string]string{}), map[string]string{})

}
3 changes: 2 additions & 1 deletion tests/e2e/cases/manifests/cluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ kind: XlineCluster
metadata:
name: my-xline-cluster
spec:
version: v0.6.0
# TODO: replace it with ghcr.io/xline-kv/xline:v0.6.1 when xline 0.6.1 is ready.
version: v0.6.1
image: phoenix500526/xline
imagePullPolicy: IfNotPresent
replicas: 3

0 comments on commit 5b18b0f

Please sign in to comment.