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

Refactor sidecar command, add configs #241

Merged
merged 4 commits into from
Mar 11, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions cmd/mysql-operator-sidecar/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,13 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"

"github.com/presslabs/mysql-operator/pkg/sidecar/appclone"
"github.com/presslabs/mysql-operator/pkg/sidecar/appconf"
"github.com/presslabs/mysql-operator/pkg/sidecar/apphelper"
"github.com/presslabs/mysql-operator/pkg/sidecar/apptakebackup"
"github.com/presslabs/mysql-operator/pkg/sidecar"
)

var log = logf.Log.WithName("sidecar")

func main() {
stopCh := signals.SetupSignalHandler()
stop := signals.SetupSignalHandler()

cmd := &cobra.Command{
Use: "mysql-operator-sidecar",
Expand All @@ -59,11 +56,14 @@ func main() {
// setup logging
logf.SetLogger(logf.ZapLogger(debug))

// init configs
cfg := sidecar.NewConfig()

confCmd := &cobra.Command{
Use: "init-configs",
Short: "Init subcommand, for init files.",
Run: func(cmd *cobra.Command, args []string) {
err := appconf.RunConfigCommand(stopCh)
err := sidecar.RunConfigCommand(cfg)
if err != nil {
log.Error(err, "init command failed")
os.Exit(1)
Expand All @@ -76,7 +76,7 @@ func main() {
Use: "clone",
Short: "Clone data from a bucket or prior node.",
Run: func(cmd *cobra.Command, args []string) {
err := appclone.RunCloneCommand(stopCh)
err := sidecar.RunCloneCommand(cfg)
if err != nil {
log.Error(err, "clone command failed")
os.Exit(1)
Expand All @@ -85,18 +85,18 @@ func main() {
}
cmd.AddCommand(cloneCmd)

helperCmd := &cobra.Command{
sidecarCmd := &cobra.Command{
Use: "run",
Short: "Configs mysql users, replication, and serve backups.",
Run: func(cmd *cobra.Command, args []string) {
err := apphelper.RunRunCommand(stopCh)
err := sidecar.RunSidecarCommand(cfg, stop)
if err != nil {
log.Error(err, "run command failed")
os.Exit(1)
}
},
}
cmd.AddCommand(helperCmd)
cmd.AddCommand(sidecarCmd)

takeBackupCmd := &cobra.Command{
Use: "take-backup-to",
Expand All @@ -108,7 +108,7 @@ func main() {
return nil
},
Run: func(cmd *cobra.Command, args []string) {
err := apptakebackup.RunTakeBackupCommand(stopCh, args[0], args[1])
err := sidecar.RunTakeBackupCommand(cfg, args[0], args[1])
if err != nil {
log.Error(err, "take backup command failed")
os.Exit(1)
Expand Down
50 changes: 19 additions & 31 deletions pkg/sidecar/appclone/appclone.go → pkg/sidecar/appclone.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,22 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package appclone
package sidecar

import (
"fmt"
"os"
"os/exec"
"strings"

logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"

"github.com/presslabs/mysql-operator/pkg/sidecar/util"
)

var log = logf.Log.WithName("sidecar.appclone")

// RunCloneCommand clone the data from source.
// nolint: gocyclo
func RunCloneCommand(stopCh <-chan struct{}) error {
log.Info("clonning command", "host", util.GetHostname())
func RunCloneCommand(cfg *Config) error {
log.Info("clonning command", "host", cfg.Hostname)

// skip cloning if data exists.
if !util.ShouldBootstrapNode() {
if !shouldBootstrapNode() {
log.Info("data exists and is initialized, skipping cloning.")
return nil
}
Expand All @@ -49,22 +43,21 @@ func RunCloneCommand(stopCh <-chan struct{}) error {
return fmt.Errorf("removing lost+found: %s", err)
}

if util.NodeRole() == "master" {
initBucket := util.GetInitBucket()
if len(initBucket) == 0 {
if cfg.NodeRole() == MasterNode {
if len(cfg.InitBucketURL) == 0 {
log.Info("skip cloning init bucket uri is not set.")
// let mysqld initialize data dir
return nil
}
err := cloneFromBucket(initBucket)
err := cloneFromBucket(cfg.InitBucketURL)
if err != nil {
return fmt.Errorf("failed to clone from bucket, err: %s", err)
}
} else {
// clonging from prior node
if util.GetServerID() > 100 {
sourceHost := util.GetHostFor(util.GetServerID() - 1)
err := cloneFromSource(sourceHost)
if cfg.ServerID > 100 {
sourceHost := cfg.FQDNForServer(cfg.ServerID - 1)
err := cloneFromSource(cfg, sourceHost)
if err != nil {
return fmt.Errorf("failed to clone from %s, err: %s", sourceHost, err)
}
Expand All @@ -88,15 +81,15 @@ func cloneFromBucket(initBucket string) error {

log.Info("cloning from bucket", "bucket", initBucket)

if _, err := os.Stat(util.RcloneConfigFile); os.IsNotExist(err) {
if _, err := os.Stat(rcloneConfigFile); os.IsNotExist(err) {
log.Error(err, "rclone config file does not exists")
return err
}
// rclone --config={conf file} cat {bucket uri}
// writes to stdout the content of the bucket uri
// nolint: gosec
rclone := exec.Command("rclone", "-vv",
fmt.Sprintf("--config=%s", util.RcloneConfigFile), "cat", initBucket)
fmt.Sprintf("--config=%s", rcloneConfigFile), "cat", initBucket)

// gzip reads from stdin decompress and then writes to stdout
// nolint: gosec
Expand All @@ -106,7 +99,7 @@ func cloneFromBucket(initBucket string) error {
// extracts files from stdin (-x) and writes them to mysql
// data target dir
// nolint: gosec
xbstream := exec.Command("xbstream", "-x", "-C", util.DataDir)
xbstream := exec.Command("xbstream", "-x", "-C", dataDir)

var err error
// rclone | gzip | xbstream
Expand Down Expand Up @@ -150,10 +143,10 @@ func cloneFromBucket(initBucket string) error {
return nil
}

func cloneFromSource(host string) error {
func cloneFromSource(cfg *Config, host string) error {
log.Info("cloning from node", "host", host)

backupBody, err := util.RequestABackup(host, util.ServerBackupEndpoint)
backupBody, err := requestABackup(cfg, host, serverBackupEndpoint)
if err != nil {
return fmt.Errorf("fail to get backup: %s", err)
}
Expand All @@ -162,7 +155,7 @@ func cloneFromSource(host string) error {
// extracts files from stdin (-x) and writes them to mysql
// data target dir
// nolint: gosec
xbstream := exec.Command("xbstream", "-x", "-C", util.DataDir)
xbstream := exec.Command("xbstream", "-x", "-C", dataDir)

xbstream.Stdin = backupBody
xbstream.Stderr = os.Stderr
Expand All @@ -179,14 +172,9 @@ func cloneFromSource(host string) error {
}

func xtrabackupPreperData() error {
replUser := util.GetReplUser()
replPass := util.GetReplPass()

// TODO: remove user and password for here, not needed.
// nolint: gosec
xtbkCmd := exec.Command("xtrabackup", "--prepare",
fmt.Sprintf("--target-dir=%s", util.DataDir),
fmt.Sprintf("--user=%s", replUser), fmt.Sprintf("--password=%s", replPass))
fmt.Sprintf("--target-dir=%s", dataDir))

xtbkCmd.Stderr = os.Stderr

Expand All @@ -195,7 +183,7 @@ func xtrabackupPreperData() error {

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

if os.IsNotExist(err) {
Expand All @@ -208,6 +196,6 @@ func checkIfDataExists() bool {
}

func deleteLostFound() error {
path := fmt.Sprintf("%s/lost+found", util.DataDir)
path := fmt.Sprintf("%s/lost+found", dataDir)
return os.RemoveAll(path)
}
52 changes: 26 additions & 26 deletions pkg/sidecar/appconf/appconf.go → pkg/sidecar/appconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,65 +14,65 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package appconf
package sidecar

import (
"fmt"
"os"
"path"
"strconv"

"github.com/go-ini/ini"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"

"github.com/presslabs/mysql-operator/pkg/sidecar/util"
pkgutil "github.com/presslabs/mysql-operator/pkg/util"
)

var log = logf.Log.WithName("sidecar.appconf")

const (
rStrLen = 18
)

// RunConfigCommand generates my.cnf, client.cnf and 10-dynamic.cnf files.
func RunConfigCommand(stopCh <-chan struct{}) error {
role := util.NodeRole()
log.Info("configuring server", "host", util.GetHostname(), "role", role)
func RunConfigCommand(cfg *Config) error {
log.Info("configuring server", "host", cfg.Hostname, "role", cfg.NodeRole())
var err error

if err := util.CopyFile(util.MountConfigDir+"/my.cnf", util.ConfigDir+"/my.cnf"); err != nil {
if err = copyFile(mountConfigDir+"/my.cnf", configDir+"/my.cnf"); err != nil {
return fmt.Errorf("copy file my.cnf: %s", err)
}

if err = os.Mkdir(confDPath, os.FileMode(0755)); err != nil {
if !os.IsExist(err) {
return fmt.Errorf("error mkdir %s/conf.d: %s", configDir, err)
}
}

uPass := pkgutil.RandomString(rStrLen)
reportHost := util.GetHostFor(util.GetServerID())
reportHost := cfg.FQDNForServer(cfg.ServerID)

var dynCFG, utilityCFG, clientCFG *ini.File
var err error
var identityCFG, utilityCFG, clientCFG *ini.File

if dynCFG, err = getDynamicConfigs(util.GetServerID(), reportHost); err != nil {
// mysql server identity configs
if identityCFG, err = getIdentityConfigs(cfg.ServerID, reportHost); err != nil {
return fmt.Errorf("failed to get dynamic configs: %s", err)
}

if err = os.Mkdir(util.ConfDPath, os.FileMode(0755)); err != nil {
if !os.IsExist(err) {
return fmt.Errorf("error mkdir %s/conf.d: %s", util.ConfigDir, err)
}
}
if err = dynCFG.SaveTo(util.ConfDPath + "/10-dynamic.cnf"); err != nil {
if err = identityCFG.SaveTo(path.Join(confDPath, "10-identity.cnf")); err != nil {
return fmt.Errorf("failed to save configs: %s", err)
}
if utilityCFG, err = getUtilityUserConfigs(util.UtilityUser, uPass); err != nil {

// mysql server utility user configs
if utilityCFG, err = getUtilityUserConfigs(utilityUser, uPass); err != nil {
return fmt.Errorf("failed to configure utility user: %s", err)
}
if err = utilityCFG.SaveTo(util.ConfDPath + "/10-utility-user.cnf"); err != nil {
if err = utilityCFG.SaveTo(path.Join(confDPath, "10-utility-user.cnf")); err != nil {
return fmt.Errorf("failed to configure utility user: %s", err)
}

if clientCFG, err = getClientConfigs(util.UtilityUser, uPass); err != nil {
// mysql client connect credentials
if clientCFG, err = getClientConfigs(utilityUser, uPass); err != nil {
return fmt.Errorf("failed to get client configs: %s", err)
}

if err = clientCFG.SaveTo(util.ConfigDir + "/client.cnf"); err != nil {
if err = clientCFG.SaveTo(path.Join(configDir, "client.cnf")); err != nil {
return fmt.Errorf("failed to save configs: %s", err)
}

Expand All @@ -87,7 +87,7 @@ func getClientConfigs(user, pass string) (*ini.File, error) {
if _, err := client.NewKey("host", "127.0.0.1"); err != nil {
return nil, err
}
if _, err := client.NewKey("port", util.MysqlPort); err != nil {
if _, err := client.NewKey("port", mysqlPort); err != nil {
return nil, err
}
if _, err := client.NewKey("user", user); err != nil {
Expand All @@ -100,7 +100,7 @@ func getClientConfigs(user, pass string) (*ini.File, error) {
return cfg, nil
}

func getDynamicConfigs(id int, reportHost string) (*ini.File, error) {
func getIdentityConfigs(id int, reportHost string) (*ini.File, error) {
cfg := ini.Empty()
mysqld := cfg.Section("mysqld")

Expand Down
Loading