diff --git a/controllers/mysqlcluster_controller.go b/controllers/mysqlcluster_controller.go index 7d7c590e..297b3430 100644 --- a/controllers/mysqlcluster_controller.go +++ b/controllers/mysqlcluster_controller.go @@ -99,8 +99,8 @@ func (r *MysqlClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request } }() - configMapSyncer := clustersyncer.NewConfigMapSyncer(r.Client, instance) - if err = syncer.Sync(ctx, configMapSyncer, r.Recorder); err != nil { + mysqlCMSyncer := clustersyncer.NewMysqlCMSyncer(r.Client, instance) + if err = syncer.Sync(ctx, mysqlCMSyncer, r.Recorder); err != nil { return ctrl.Result{}, err } @@ -109,7 +109,8 @@ func (r *MysqlClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request return ctrl.Result{}, err } - cmRev := configMapSyncer.Object().(*corev1.ConfigMap).ResourceVersion + // Todo: modify mysql cm will trigger rolling update but it will not be applied. + cmRev := mysqlCMSyncer.Object().(*corev1.ConfigMap).ResourceVersion sctRev := secretSyncer.Object().(*corev1.Secret).ResourceVersion r.XenonExecutor.SetRootPassword(instance.Spec.MysqlOpts.RootPassword) @@ -124,6 +125,7 @@ func (r *MysqlClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request clustersyncer.NewFollowerSVCSyncer(r.Client, instance), clustersyncer.NewStatefulSetSyncer(r.Client, instance, cmRev, sctRev, r.SQLRunnerFactory, r.XenonExecutor), clustersyncer.NewPDBSyncer(r.Client, instance), + clustersyncer.NewXenonCMSyncer(r.Client, instance), } if instance.Spec.MetricsOpts.Enabled { diff --git a/mysqlcluster/container/backup.go b/mysqlcluster/container/backup.go index 8a401a49..c1633ffc 100644 --- a/mysqlcluster/container/backup.go +++ b/mysqlcluster/container/backup.go @@ -128,13 +128,12 @@ func (c *backupSidecar) getReadinessProbe() *corev1.Probe { func (c *backupSidecar) getVolumeMounts() []corev1.VolumeMount { return []corev1.VolumeMount{ { - Name: utils.ConfVolumeName, - MountPath: utils.ConfVolumeMountPath, + Name: utils.MysqlConfVolumeName, + MountPath: utils.MysqlConfVolumeMountPath, }, { Name: utils.DataVolumeName, MountPath: utils.DataVolumeMountPath, - SubPath: utils.MysqlDataSubPath, }, { Name: utils.LogsVolumeName, diff --git a/mysqlcluster/container/init_mysql.go b/mysqlcluster/container/init_mysql.go index d02d3dab..a6d1b946 100644 --- a/mysqlcluster/container/init_mysql.go +++ b/mysqlcluster/container/init_mysql.go @@ -110,13 +110,12 @@ func (c *initMysql) getReadinessProbe() *corev1.Probe { func (c *initMysql) getVolumeMounts() []corev1.VolumeMount { return []corev1.VolumeMount{ { - Name: utils.ConfVolumeName, - MountPath: utils.ConfVolumeMountPath, + Name: utils.MysqlConfVolumeName, + MountPath: utils.MysqlConfVolumeMountPath, }, { Name: utils.DataVolumeName, MountPath: utils.DataVolumeMountPath, - SubPath: utils.MysqlDataSubPath, }, { Name: utils.LogsVolumeName, diff --git a/mysqlcluster/container/init_mysql_test.go b/mysqlcluster/container/init_mysql_test.go index db729af1..8d7c7a39 100644 --- a/mysqlcluster/container/init_mysql_test.go +++ b/mysqlcluster/container/init_mysql_test.go @@ -53,13 +53,12 @@ var ( } initMysqlVolumeMounts = []corev1.VolumeMount{ { - Name: utils.ConfVolumeName, - MountPath: utils.ConfVolumeMountPath, + Name: utils.MysqlConfVolumeName, + MountPath: utils.MysqlConfVolumeMountPath, }, { Name: utils.DataVolumeName, MountPath: utils.DataVolumeMountPath, - SubPath: utils.MysqlDataSubPath, }, { Name: utils.LogsVolumeName, diff --git a/mysqlcluster/container/init_sidecar.go b/mysqlcluster/container/init_sidecar.go index f1e47502..7193c0da 100644 --- a/mysqlcluster/container/init_sidecar.go +++ b/mysqlcluster/container/init_sidecar.go @@ -163,20 +163,28 @@ func (c *initSidecar) getReadinessProbe() *corev1.Probe { func (c *initSidecar) getVolumeMounts() []corev1.VolumeMount { volumeMounts := []corev1.VolumeMount{ { - Name: utils.ConfVolumeName, - MountPath: utils.ConfVolumeMountPath, + Name: utils.MysqlConfVolumeName, + MountPath: utils.MysqlConfVolumeMountPath, }, { - Name: utils.ConfMapVolumeName, - MountPath: utils.ConfMapVolumeMountPath, + Name: utils.MysqlCMVolumeName, + MountPath: utils.MysqlCMVolumeMountPath, + }, + { + Name: utils.XenonCMVolumeName, + MountPath: utils.XenonCMVolumeMountPath, + }, + { + Name: utils.XenonMetaVolumeName, + MountPath: utils.XenonMetaVolumeMountPath, }, { Name: utils.ScriptsVolumeName, MountPath: utils.ScriptsVolumeMountPath, }, { - Name: utils.XenonVolumeName, - MountPath: utils.XenonVolumeMountPath, + Name: utils.XenonConfVolumeName, + MountPath: utils.XenonConfVolumeMountPath, }, { Name: utils.InitFileVolumeName, @@ -202,12 +210,6 @@ func (c *initSidecar) getVolumeMounts() []corev1.VolumeMount { corev1.VolumeMount{ Name: utils.DataVolumeName, MountPath: utils.DataVolumeMountPath, - SubPath: utils.MysqlDataSubPath, - }, - corev1.VolumeMount{ - Name: utils.DataVolumeName, - MountPath: utils.XenonDataVolumeMountPath, - SubPath: utils.XenonDataSubPath, }, ) } diff --git a/mysqlcluster/container/init_sidecar_test.go b/mysqlcluster/container/init_sidecar_test.go index 86981882..21d08537 100644 --- a/mysqlcluster/container/init_sidecar_test.go +++ b/mysqlcluster/container/init_sidecar_test.go @@ -272,20 +272,28 @@ var ( } defaultInitsidecarVolumeMounts = []corev1.VolumeMount{ { - Name: utils.ConfVolumeName, - MountPath: utils.ConfVolumeMountPath, + Name: utils.MysqlConfVolumeName, + MountPath: utils.MysqlConfVolumeMountPath, }, { - Name: utils.ConfMapVolumeName, - MountPath: utils.ConfMapVolumeMountPath, + Name: utils.MysqlCMVolumeName, + MountPath: utils.MysqlCMVolumeMountPath, + }, + { + Name: utils.XenonCMVolumeName, + MountPath: utils.XenonCMVolumeMountPath, + }, + { + Name: utils.XenonMetaVolumeName, + MountPath: utils.XenonMetaVolumeMountPath, }, { Name: utils.ScriptsVolumeName, MountPath: utils.ScriptsVolumeMountPath, }, { - Name: utils.XenonVolumeName, - MountPath: utils.XenonVolumeMountPath, + Name: utils.XenonConfVolumeName, + MountPath: utils.XenonConfVolumeMountPath, }, { Name: utils.InitFileVolumeName, @@ -437,7 +445,7 @@ func TestGetInitSidecarVolumeMounts(t *testing.T) { MysqlCluster: &testToKuDBMysqlCluster, } tokudbCase := EnsureContainer("init-sidecar", &testTokuDBCluster) - tokuDBVolumeMounts := make([]corev1.VolumeMount, 6, 7) + tokuDBVolumeMounts := make([]corev1.VolumeMount, 8, 9) copy(tokuDBVolumeMounts, defaultInitsidecarVolumeMounts) tokuDBVolumeMounts = append(tokuDBVolumeMounts, corev1.VolumeMount{ Name: utils.SysVolumeName, @@ -453,20 +461,12 @@ func TestGetInitSidecarVolumeMounts(t *testing.T) { MysqlCluster: &testPersistenceMysqlCluster, } persistenceCase := EnsureContainer("init-sidecar", &testPersistenceCluster) - persistenceVolumeMounts := make([]corev1.VolumeMount, 6, 7) + persistenceVolumeMounts := make([]corev1.VolumeMount, 8, 9) copy(persistenceVolumeMounts, defaultInitsidecarVolumeMounts) - persistenceVolumeMounts = append(persistenceVolumeMounts, - corev1.VolumeMount{ - Name: utils.DataVolumeName, - MountPath: utils.DataVolumeMountPath, - SubPath: utils.MysqlDataSubPath, - }, - corev1.VolumeMount{ - Name: utils.DataVolumeName, - MountPath: utils.XenonDataVolumeMountPath, - SubPath: utils.XenonDataSubPath, - }, - ) + persistenceVolumeMounts = append(persistenceVolumeMounts, corev1.VolumeMount{ + Name: utils.DataVolumeName, + MountPath: utils.DataVolumeMountPath, + }) assert.Equal(t, persistenceVolumeMounts, persistenceCase.VolumeMounts) } } diff --git a/mysqlcluster/container/mysql.go b/mysqlcluster/container/mysql.go index 8a00fd61..acef63c6 100644 --- a/mysqlcluster/container/mysql.go +++ b/mysqlcluster/container/mysql.go @@ -135,13 +135,12 @@ func (c *mysql) getReadinessProbe() *corev1.Probe { func (c *mysql) getVolumeMounts() []corev1.VolumeMount { return []corev1.VolumeMount{ { - Name: utils.ConfVolumeName, - MountPath: utils.ConfVolumeMountPath, + Name: utils.MysqlConfVolumeName, + MountPath: utils.MysqlConfVolumeMountPath, }, { Name: utils.DataVolumeName, MountPath: utils.DataVolumeMountPath, - SubPath: utils.MysqlDataSubPath, }, { Name: utils.LogsVolumeName, diff --git a/mysqlcluster/container/mysql_test.go b/mysqlcluster/container/mysql_test.go index 49dddb53..d6ce41a7 100644 --- a/mysqlcluster/container/mysql_test.go +++ b/mysqlcluster/container/mysql_test.go @@ -141,13 +141,12 @@ func TestGetMysqlReadinessProbe(t *testing.T) { func TestGetMysqlVolumeMounts(t *testing.T) { volumeMounts := []corev1.VolumeMount{ { - Name: "conf", + Name: "mysql-conf", MountPath: "/etc/mysql", }, { Name: "data", MountPath: "/var/lib/mysql", - SubPath: "mysql", }, { Name: "logs", diff --git a/mysqlcluster/container/xenon.go b/mysqlcluster/container/xenon.go index f1bd5c15..a0be9447 100644 --- a/mysqlcluster/container/xenon.go +++ b/mysqlcluster/container/xenon.go @@ -115,13 +115,12 @@ func (c *xenon) getVolumeMounts() []corev1.VolumeMount { MountPath: utils.ScriptsVolumeMountPath, }, { - Name: utils.DataVolumeName, - MountPath: utils.XenonDataVolumeMountPath, - SubPath: utils.XenonDataSubPath, + Name: utils.XenonConfVolumeName, + MountPath: utils.XenonConfVolumeMountPath, }, { - Name: utils.XenonVolumeName, - MountPath: utils.XenonVolumeMountPath, + Name: utils.XenonMetaVolumeName, + MountPath: utils.XenonMetaVolumeMountPath, }, { Name: utils.SysLocalTimeZone, diff --git a/mysqlcluster/container/xenon_test.go b/mysqlcluster/container/xenon_test.go index d67a18cf..1d57e5ec 100644 --- a/mysqlcluster/container/xenon_test.go +++ b/mysqlcluster/container/xenon_test.go @@ -135,13 +135,12 @@ func TestGetXenonVolumeMounts(t *testing.T) { MountPath: "/scripts", }, { - Name: "data", - MountPath: "/var/lib/xenon", - SubPath: "xenon", + Name: "xenon-conf", + MountPath: "/etc/xenon", }, { - Name: "xenon", - MountPath: "/etc/xenon", + Name: "xenon-meta", + MountPath: "/var/lib/xenon", }, { Name: utils.SysLocalTimeZone, diff --git a/mysqlcluster/mysqlcluster.go b/mysqlcluster/mysqlcluster.go index 46e6603b..44a1f742 100644 --- a/mysqlcluster/mysqlcluster.go +++ b/mysqlcluster/mysqlcluster.go @@ -193,7 +193,7 @@ func (c *MysqlCluster) EnsureVolumes() []corev1.Volume { volumes = append(volumes, corev1.Volume{ - Name: utils.ConfVolumeName, + Name: utils.MysqlConfVolumeName, VolumeSource: corev1.VolumeSource{ EmptyDir: &corev1.EmptyDirVolumeSource{}, }, @@ -205,7 +205,7 @@ func (c *MysqlCluster) EnsureVolumes() []corev1.Volume { }, }, corev1.Volume{ - Name: utils.ConfMapVolumeName, + Name: utils.MysqlCMVolumeName, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ @@ -214,6 +214,22 @@ func (c *MysqlCluster) EnsureVolumes() []corev1.Volume { }, }, }, + corev1.Volume{ + Name: utils.XenonCMVolumeName, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: c.GetNameForResource(utils.XenonMetaData), + }, + }, + }, + }, + corev1.Volume{ + Name: utils.XenonMetaVolumeName, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, corev1.Volume{ Name: utils.ScriptsVolumeName, VolumeSource: corev1.VolumeSource{ @@ -221,7 +237,7 @@ func (c *MysqlCluster) EnsureVolumes() []corev1.Volume { }, }, corev1.Volume{ - Name: utils.XenonVolumeName, + Name: utils.XenonConfVolumeName, VolumeSource: corev1.VolumeSource{ EmptyDir: &corev1.EmptyDirVolumeSource{}, }, @@ -294,6 +310,8 @@ func (c *MysqlCluster) GetNameForResource(name utils.ResourceName) string { return fmt.Sprintf("%s-metrics", c.Name) case utils.Secret: return fmt.Sprintf("%s-secret", c.Name) + case utils.XenonMetaData: + return fmt.Sprintf("%s-xenon", c.Name) default: return c.Name } diff --git a/mysqlcluster/mysqlcluster_test.go b/mysqlcluster/mysqlcluster_test.go index 2349bdc3..e479869b 100644 --- a/mysqlcluster/mysqlcluster_test.go +++ b/mysqlcluster/mysqlcluster_test.go @@ -245,7 +245,7 @@ func TestGetPodHostName(t *testing.T) { func TestEnsureVolumes(t *testing.T) { volume := []corev1.Volume{ { - Name: utils.ConfVolumeName, + Name: utils.MysqlConfVolumeName, VolumeSource: corev1.VolumeSource{ EmptyDir: &corev1.EmptyDirVolumeSource{}, }, @@ -257,7 +257,7 @@ func TestEnsureVolumes(t *testing.T) { }, }, { - Name: utils.ConfMapVolumeName, + Name: utils.MysqlCMVolumeName, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ @@ -266,6 +266,22 @@ func TestEnsureVolumes(t *testing.T) { }, }, }, + { + Name: utils.XenonCMVolumeName, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "sample-xenon", + }, + }, + }, + }, + { + Name: utils.XenonMetaVolumeName, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, { Name: utils.ScriptsVolumeName, VolumeSource: corev1.VolumeSource{ @@ -273,7 +289,7 @@ func TestEnsureVolumes(t *testing.T) { }, }, { - Name: utils.XenonVolumeName, + Name: utils.XenonConfVolumeName, VolumeSource: corev1.VolumeSource{ EmptyDir: &corev1.EmptyDirVolumeSource{}, }, diff --git a/mysqlcluster/syncer/config_map.go b/mysqlcluster/syncer/mysql_cm.go similarity index 96% rename from mysqlcluster/syncer/config_map.go rename to mysqlcluster/syncer/mysql_cm.go index d80601f9..8659950e 100644 --- a/mysqlcluster/syncer/config_map.go +++ b/mysqlcluster/syncer/mysql_cm.go @@ -31,8 +31,8 @@ import ( "github.com/radondb/radondb-mysql-kubernetes/utils" ) -// NewConfigMapSyncer returns configmap syncer. -func NewConfigMapSyncer(cli client.Client, c *mysqlcluster.MysqlCluster) syncer.Interface { +// NewMysqlCMSyncer returns mysql configmap syncer. +func NewMysqlCMSyncer(cli client.Client, c *mysqlcluster.MysqlCluster) syncer.Interface { cm := &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ APIVersion: "v1", diff --git a/mysqlcluster/syncer/xenon_cm.go b/mysqlcluster/syncer/xenon_cm.go new file mode 100644 index 00000000..6cdd84f7 --- /dev/null +++ b/mysqlcluster/syncer/xenon_cm.go @@ -0,0 +1,88 @@ +/* +Copyright 2021 RadonDB. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package syncer + +import ( + "encoding/json" + "fmt" + + "github.com/presslabs/controller-util/syncer" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/radondb/radondb-mysql-kubernetes/mysqlcluster" + "github.com/radondb/radondb-mysql-kubernetes/utils" +) + +// NewXenonCMSyncer returns xenon configmap syncer. +func NewXenonCMSyncer(cli client.Client, c *mysqlcluster.MysqlCluster) syncer.Interface { + cm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: c.GetNameForResource(utils.XenonMetaData), + Namespace: c.Namespace, + Labels: c.GetLabels(), + }, + } + + return syncer.NewObjectSyncer("ConfigMap", c.Unwrap(), cm, cli, func() error { + if int(*c.Spec.Replicas) == 0 { + return nil + } + + metaData, err := buildXenonMetaData(c) + if err != nil { + return fmt.Errorf("failed to build xenon metadata: %s", err) + } + + cm.Data = map[string]string{ + "peers.json": metaData, + } + + return nil + }) +} + +type XenonMetaData struct { + Idlepeers []string `json:"idlepeers"` + Peers []string `json:"peers"` +} + +// buildXenonMetaData build the default metadata of xenon. +func buildXenonMetaData(c *mysqlcluster.MysqlCluster) (string, error) { + replicas := c.Spec.Replicas + xenonMetaData := XenonMetaData{} + for i := 0; i < int(*replicas); i++ { + xenonMetaData.Peers = append(xenonMetaData.Peers, + fmt.Sprintf("%s-%d.%s.%s:%d", + c.GetNameForResource(utils.StatefulSet), + i, + c.GetNameForResource(utils.HeadlessSVC), + c.Namespace, + utils.XenonPort, + )) + } + metaJson, err := json.Marshal(xenonMetaData) + if err != nil { + return "", err + } + return string(metaJson), nil +} diff --git a/sidecar/config.go b/sidecar/config.go index 51b93193..f303e051 100644 --- a/sidecar/config.go +++ b/sidecar/config.go @@ -344,7 +344,7 @@ func (cfg *Config) buildXenonConf() []byte { "election-timeout": %d, "admit-defeat-hearbeat-count": %d, "heartbeat-timeout": %d, - "meta-datadir": "/var/lib/xenon/", + "meta-datadir": "%s", "semi-sync-degrade": true, "purge-binlog-disabled": true, "super-idle": false @@ -353,7 +353,7 @@ func (cfg *Config) buildXenonConf() []byte { `, hostName, utils.XenonPort, hostName, utils.XenonPeerPort, cfg.ReplicationPassword, cfg.ReplicationUser, cfg.GtidPurged, requestTimeout, pingTimeout, cfg.RootPassword, version, srcSysVars, replicaSysVars, cfg.ElectionTimeout, - cfg.AdmitDefeatHearbeatCount, heartbeatTimeout) + cfg.AdmitDefeatHearbeatCount, heartbeatTimeout, xenonConfigPath) return utils.StringToBytes(str) } @@ -533,19 +533,19 @@ func (cfg *Config) executeS3Restore(path string) error { } } // Xtrabackup prepare and apply-log-only. - cmd := exec.Command(xtrabackupCommand, "--defaults-file="+utils.ConfVolumeMountPath+"/my.cnf", "--prepare", "--apply-log-only", "--target-dir=/root/backup") + cmd := exec.Command(xtrabackupCommand, "--defaults-file="+utils.MysqlConfVolumeMountPath+"/my.cnf", "--prepare", "--apply-log-only", "--target-dir=/root/backup") cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("failed to xtrabackup prepare and apply-log-only : %s", err) } // Xtrabackup prepare. - cmd = exec.Command(xtrabackupCommand, "--defaults-file="+utils.ConfVolumeMountPath+"/my.cnf", "--prepare", "--target-dir=/root/backup") + cmd = exec.Command(xtrabackupCommand, "--defaults-file="+utils.MysqlConfVolumeMountPath+"/my.cnf", "--prepare", "--target-dir=/root/backup") cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("failed to xtrabackup prepare : %s", err) } // Xtrabackup copy-back to /var/lib/mysql. - cmd = exec.Command(xtrabackupCommand, "--defaults-file="+utils.ConfVolumeMountPath+"/my.cnf", "--datadir="+utils.DataVolumeMountPath, "--copy-back", "--copy-back", "--target-dir=/root/backup") + cmd = exec.Command(xtrabackupCommand, "--defaults-file="+utils.MysqlConfVolumeMountPath+"/my.cnf", "--datadir="+utils.DataVolumeMountPath, "--copy-back", "--copy-back", "--target-dir=/root/backup") cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("failed to xtrabackup copy-back : %s", err) @@ -577,13 +577,13 @@ func (cfg *Config) executeCloneRestore() error { os.RemoveAll(path.Join([]string{utils.DataVolumeMountPath, d.Name()}...)) } // Xtrabackup prepare and apply-log-only. - cmd := exec.Command(xtrabackupCommand, "--defaults-file="+utils.ConfVolumeMountPath+"/my.cnf", "--use-memory=3072M", "--prepare", "--apply-log-only", "--target-dir=/backup/"+cfg.XRestoreFrom) + cmd := exec.Command(xtrabackupCommand, "--defaults-file="+utils.MysqlConfVolumeMountPath+"/my.cnf", "--use-memory=3072M", "--prepare", "--apply-log-only", "--target-dir=/backup/"+cfg.XRestoreFrom) cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("failed to xtrabackup prepare apply-log-only : %s", err) } // Xtrabackup Prepare. - cmd = exec.Command(xtrabackupCommand, "--defaults-file="+utils.ConfVolumeMountPath+"/my.cnf", "--use-memory=3072M", "--prepare", "--target-dir=/backup/"+cfg.XRestoreFrom) + cmd = exec.Command(xtrabackupCommand, "--defaults-file="+utils.MysqlConfVolumeMountPath+"/my.cnf", "--use-memory=3072M", "--prepare", "--target-dir=/backup/"+cfg.XRestoreFrom) cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("failed to xtrabackup prepare : %s", err) @@ -595,7 +595,7 @@ func (cfg *Config) executeCloneRestore() error { } log.Info("get master gtid purged :", "gtid purged", cfg.GtidPurged) // Xtrabackup copy-back. - cmd = exec.Command(xtrabackupCommand, "--defaults-file="+utils.ConfVolumeMountPath+"/my.cnf", "--use-memory=3072M", "--datadir="+utils.DataVolumeMountPath, "--copy-back", "--target-dir=/backup/"+cfg.XRestoreFrom) + cmd = exec.Command(xtrabackupCommand, "--defaults-file="+utils.MysqlConfVolumeMountPath+"/my.cnf", "--use-memory=3072M", "--datadir="+utils.DataVolumeMountPath, "--copy-back", "--target-dir=/backup/"+cfg.XRestoreFrom) cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("failed to xtrabackup copy-back : %s", err) diff --git a/sidecar/init.go b/sidecar/init.go index d00ae5de..aa7c2a2a 100644 --- a/sidecar/init.go +++ b/sidecar/init.go @@ -134,17 +134,15 @@ func runInitCommand(cfg *Config) error { if err = os.Chown(dataPath, uid, gid); err != nil { return fmt.Errorf("failed to chown %s: %s", dataPath, err) } - // chown -R mysql:mysql /var/lib/xenon. - if err = os.Chown(xenonDataPath, uid, gid); err != nil { - return fmt.Errorf("failed to chown %s: %s", xenonDataPath, err) - } } // copy appropriate my.cnf from config-map to config mount. - if err = copyFile(path.Join(configMapPath, "my.cnf"), path.Join(configPath, "my.cnf")); err != nil { + if err = copyFile(path.Join(mysqlCMPath, "my.cnf"), path.Join(mysqlConfigPath, "my.cnf")); err != nil { return fmt.Errorf("failed to copy my.cnf: %s", err) } + buildDefaultXenonMeta(uid, gid) + // build client.conf. clientConfig, err := cfg.buildClientConfig() if err != nil { @@ -270,7 +268,7 @@ func RunRequestBackup(cfg *Config, host string) error { // Save plugin.cnf and extra.cnf to specified path. func saveCnfTo(targetPath string, extraCnf *ini.File) error { - if err := copyFile(path.Join(configMapPath, utils.PluginConfigs), path.Join(targetPath, utils.PluginConfigs)); err != nil { + if err := copyFile(path.Join(mysqlCMPath, utils.PluginConfigs), path.Join(targetPath, utils.PluginConfigs)); err != nil { return fmt.Errorf("failed to copy plugin.cnf: %s", err) } if err := extraCnf.SaveTo(path.Join(targetPath, "extra.cnf")); err != nil { @@ -294,3 +292,21 @@ chown -R mysql.mysql %s`, // chown -R mysql.mysql extra.cnf path.Join(extraConfPath, "extra.cnf")) } + +func buildDefaultXenonMeta(uid, gid int) error { + metaFile := fmt.Sprintf("%s/peers.json", xenonConfigPath) + // mkdir var/lib/xenon. + // https://github.com/radondb/xenon/blob/master/src/raft/raft.go#L118 + if err := os.MkdirAll(xenonConfigPath, 0777); err != nil { + return fmt.Errorf("failed to mkdir %s: %s", xenonConfigPath, err) + } + // copy appropriate peers.json from config-map to config mount. + if err := copyFile(path.Join(xenonCMPath, "peers.json"), path.Join(xenonConfigPath, "peers.json")); err != nil { + return fmt.Errorf("failed to copy peers.json: %s", err) + } + // chown -R mysql:mysql /var/lib/xenon/peers.json. + if err := os.Chown(metaFile, uid, gid); err != nil { + return fmt.Errorf("failed to chown %s: %s", metaFile, err) + } + return nil +} diff --git a/sidecar/util.go b/sidecar/util.go index 71570dd1..1787929d 100644 --- a/sidecar/util.go +++ b/sidecar/util.go @@ -31,22 +31,26 @@ var ( // MysqlServerIDOffset represents the offset with which all server ids are shifted from 0 mysqlServerIDOffset = 100 - // configPath is the mysql configs path. - configPath = utils.ConfVolumeMountPath + // mysqlConfigPath is the mysql configs path. + mysqlConfigPath = utils.MysqlConfVolumeMountPath + + // xenonConfigPath is the xenon meta path. + xenonConfigPath = utils.XenonMetaVolumeMountPath // clientConfPath is the client.cnf path. clientConfPath = utils.ConfClientPath // extraConfPath is the mysql extra configs path. - extraConfPath = utils.ConfVolumeMountPath + "/conf.d" + extraConfPath = utils.MysqlConfVolumeMountPath + "/conf.d" + + // mysqlCMPath is the mounted configmap. + mysqlCMPath = utils.MysqlCMVolumeMountPath - // configMapPath is the mounted configmap. - configMapPath = utils.ConfMapVolumeMountPath + // xenonCMPath is the mounted configmap. + xenonCMPath = utils.XenonCMVolumeMountPath // dataPath is the mysql data path. dataPath = utils.DataVolumeMountPath - // xenonMetaDataPath is the xenon metadata path. - xenonDataPath = utils.XenonDataVolumeMountPath // // scriptsPath is the scripts path used for xenon. // scriptsPath = utils.ScriptsVolumeMountPath @@ -55,7 +59,7 @@ var ( sysPath = utils.SysVolumeMountPath // xenonPath is the xenon configs path. - xenonPath = utils.XenonVolumeMountPath + xenonPath = utils.XenonConfVolumeMountPath // initFilePath is the init files path for mysql. initFilePath = utils.InitFileVolumeMountPath diff --git a/utils/constants.go b/utils/constants.go index 1da37f79..6e90971d 100644 --- a/utils/constants.go +++ b/utils/constants.go @@ -91,27 +91,28 @@ const ( BackupUser = "sys_backup" // volumes names. - ConfVolumeName = "conf" - ConfMapVolumeName = "config-map" - LogsVolumeName = "logs" - DataVolumeName = "data" - SysVolumeName = "host-sys" - ScriptsVolumeName = "scripts" - XenonVolumeName = "xenon" - InitFileVolumeName = "init-mysql" + MysqlConfVolumeName = "mysql-conf" + MysqlCMVolumeName = "mysql-cm" + XenonMetaVolumeName = "xenon-meta" + XenonCMVolumeName = "xenon-cm" + LogsVolumeName = "logs" + DataVolumeName = "data" + SysVolumeName = "host-sys" + ScriptsVolumeName = "scripts" + XenonConfVolumeName = "xenon-conf" + InitFileVolumeName = "init-mysql" // volumes mount path. - ConfVolumeMountPath = "/etc/mysql" - ConfMapVolumeMountPath = "/mnt/config-map" + MysqlConfVolumeMountPath = "/etc/mysql" + MysqlCMVolumeMountPath = "/mnt/mysql-cm" + XenonMetaVolumeMountPath = "/var/lib/xenon" + XenonCMVolumeMountPath = "/mnt/xenon-cm" LogsVolumeMountPath = "/var/log/mysql" DataVolumeMountPath = "/var/lib/mysql" - XenonDataVolumeMountPath = "/var/lib/xenon" SysVolumeMountPath = "/host-sys" ScriptsVolumeMountPath = "/scripts" - XenonVolumeMountPath = "/etc/xenon" + XenonConfVolumeMountPath = "/etc/xenon" InitFileVolumeMountPath = "/docker-entrypoint-initdb.d" - MysqlDataSubPath = "mysql" - XenonDataSubPath = "xenon" // Volume timezone name. SysLocalTimeZone = "localtime" @@ -162,6 +163,8 @@ const ( ServiceAccount ResourceName = "service-account" // PodDisruptionBudget is the name of pod disruption budget for the statefulset. PodDisruptionBudget ResourceName = "pdb" + // XenonMetaData is the name of the configmap that contains xenon metadata. + XenonMetaData ResourceName = "xenon-metadata" ) // JobType