Skip to content

Commit

Permalink
*: add xenon post-start.sh radondb#135
Browse files Browse the repository at this point in the history
  • Loading branch information
zhyass committed Jul 12, 2021
1 parent 66f4b64 commit f308c6c
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 8 deletions.
4 changes: 4 additions & 0 deletions cluster/container/init_sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ func (c *initSidecar) getEnvVars() []corev1.EnvVar {
Name: "SERVICE_NAME",
Value: c.GetNameForResource(utils.HeadlessSVC),
},
{
Name: "STATEFULSET_NAME",
Value: c.GetNameForResource(utils.StatefulSet),
},
{
Name: "ADMIT_DEFEAT_HEARBEAT_COUNT",
Value: strconv.Itoa(int(*c.Spec.XenonOpts.AdmitDefeatHearbeatCount)),
Expand Down
73 changes: 68 additions & 5 deletions sidecar/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ type Config struct {
NameSpace string
// The name of the headless service.
ServiceName string
// The name of the statefulset.
StatefulSetName string

// The password of the root user.
RootPassword string
Expand Down Expand Up @@ -70,6 +72,9 @@ type Config struct {
AdmitDefeatHearbeatCount int32
// The parameter in xenon means election timeout(ms)。
ElectionTimeout int32

// Whether the MySQL data exists.
existMySQLData bool
}

// NewConfig returns a pointer to Config.
Expand All @@ -94,10 +99,13 @@ func NewConfig() *Config {
electionTimeout = 10000
}

existMySQLData, _ := checkIfDataExists()

return &Config{
HostName: getEnvValue("POD_HOSTNAME"),
NameSpace: getEnvValue("NAMESPACE"),
ServiceName: getEnvValue("SERVICE_NAME"),
HostName: getEnvValue("POD_HOSTNAME"),
NameSpace: getEnvValue("NAMESPACE"),
ServiceName: getEnvValue("SERVICE_NAME"),
StatefulSetName: getEnvValue("STATEFULSET_NAME"),

RootPassword: getEnvValue("MYSQL_ROOT_PASSWORD"),

Expand All @@ -120,6 +128,8 @@ func NewConfig() *Config {

AdmitDefeatHearbeatCount: int32(admitDefeatHearbeatCount),
ElectionTimeout: int32(electionTimeout),

existMySQLData: existMySQLData,
}
}

Expand All @@ -128,11 +138,11 @@ func (cfg *Config) buildExtraConfig(filePath string) (*ini.File, error) {
conf := ini.Empty()
sec := conf.Section("mysqld")

id, err := generateServerID(cfg.HostName)
ordinal, err := getOrdinal(cfg.HostName)
if err != nil {
return nil, err
}
if _, err := sec.NewKey("server-id", strconv.Itoa(id)); err != nil {
if _, err := sec.NewKey("server-id", strconv.Itoa(mysqlServerIDOffset+ordinal)); err != nil {
return nil, err
}

Expand Down Expand Up @@ -254,3 +264,56 @@ func (cfg *Config) buildClientConfig() (*ini.File, error) {

return conf, nil
}

func (cfg *Config) buildBashPostStart() ([]byte, error) {
var str1, str2, str3 string
ordinal, err := getOrdinal(cfg.HostName)
if err != nil {
return nil, err
}
selfPeer := fmt.Sprintf("%s.%s.%s:%d", cfg.HostName, cfg.ServiceName, cfg.NameSpace, utils.XenonPeerPort)

str1 = fmt.Sprintf(`#!/bin/sh
while true; do
info=$(curl -i -X GET -u root:%s http://%s/v1/xenon/ping)
code=$(echo $info|grep "HTTP"|awk '{print $2}')
if [ "$code" -eq "200" ]; then
break
fi
done
if [ $ordinal -eq 0 ]; then`, cfg.RootPassword, selfPeer)

if cfg.existMySQLData {
str2 = `
echo "do nothing"`
} else {
str2 = fmt.Sprintf(`
for i in $(seq 11); do
curl -i -X POST -u root:%s http://%s/v1/raft/trytoleader
sleep 5
curl -i -X GET -u root:%s http://%s/v1/raft/status | grep LEADER
if [ $? -eq 0 ] ; then
break
fi
if [ $i -eq 11 ]; then
echo "wait trytoleader failed"
fi
done`, cfg.RootPassword, selfPeer, cfg.RootPassword, selfPeer)
}

str3 = fmt.Sprintf(`
else
i=0
while [ $i -lt %d ]; do
curl -i -X POST -d '{"address": "%s-$i.%s.%s:%d"}' -u root:%s http://%s/v1/cluster/add
curl -i -X POST -d '{"address": "%s"}' -u root:%s http://%s-$i.%s.%s:%d/v1/cluster/add
i=$((i+1))
done
fi
`, ordinal, cfg.StatefulSetName, cfg.ServiceName, cfg.NameSpace, utils.XenonPeerPort, cfg.RootPassword, selfPeer,
selfPeer, cfg.RootPassword, cfg.StatefulSetName, cfg.ServiceName, cfg.NameSpace, utils.XenonPeerPort,
)

return utils.StringToBytes(str1 + str2 + str3), nil
}
10 changes: 10 additions & 0 deletions sidecar/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ func runInitCommand(cfg *Config) error {
return fmt.Errorf("failed to save extra.cnf: %s", err)
}

// build post-start.sh.
bashPostStart, err := cfg.buildBashPostStart()
if err != nil {
return fmt.Errorf("failed to build post-start.sh: %s", err)
}
bashPostStartPath := path.Join(scriptsPath, "post-start.sh")
if err = ioutil.WriteFile(bashPostStartPath, bashPostStart, 0644); err != nil {
return fmt.Errorf("failed to write post-start.sh: %s", err)
}

// copy leader-start.sh from config-map to scripts mount.
leaderStartPath := path.Join(scriptsPath, "leader-start.sh")
if err = copyFile(path.Join(configMapPath, "leader-start.sh"), leaderStartPath); err != nil {
Expand Down
20 changes: 17 additions & 3 deletions sidecar/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ func getEnvValue(key string) string {
return value
}

// Generate mysql server-id from pod ordinal index.
func generateServerID(name string) (int, error) {
func getOrdinal(name string) (int, error) {
idx := strings.LastIndexAny(name, "-")
if idx == -1 {
return -1, fmt.Errorf("failed to extract ordinal from hostname: %s", name)
Expand All @@ -114,5 +113,20 @@ func generateServerID(name string) (int, error) {
log.Error(err, "failed to extract ordinal form hostname", "hostname", name)
return -1, fmt.Errorf("failed to extract ordinal from hostname: %s", name)
}
return mysqlServerIDOffset + ordinal, nil
return ordinal, nil
}

// nolint: gosec
func checkIfDataExists() (bool, error) {
path := fmt.Sprintf("%s/mysql", dataPath)
_, err := os.Open(path)

if os.IsNotExist(err) {
return false, nil
} else if err != nil {
log.Error(err, "failed to open file", "file", path)
return false, err
}

return true, nil
}

0 comments on commit f308c6c

Please sign in to comment.