2017-01-20 09:41:27 -08:00
|
|
|
/*
|
|
|
|
|
Copyright 2016 The Rook Authors. All rights reserved.
|
|
|
|
|
|
|
|
|
|
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 mon
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
2017-01-19 13:31:22 -08:00
|
|
|
"strings"
|
2017-01-20 09:41:27 -08:00
|
|
|
|
|
|
|
|
"github.com/rook/rook/pkg/clusterd"
|
|
|
|
|
"github.com/rook/rook/pkg/util"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
2017-09-09 17:33:28 +02:00
|
|
|
DefaultPort = 6790
|
2017-01-20 09:41:27 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Config struct {
|
2017-06-02 13:44:54 -07:00
|
|
|
Name string
|
|
|
|
|
Cluster *ClusterInfo
|
|
|
|
|
isDaemon bool
|
2017-09-09 17:33:28 +02:00
|
|
|
Port int32
|
2017-06-02 13:44:54 -07:00
|
|
|
}
|
|
|
|
|
|
2017-09-09 17:33:28 +02:00
|
|
|
func NewConfig(name string, cluster *ClusterInfo, isDaemon bool, port int32) *Config {
|
|
|
|
|
return &Config{Name: name, Cluster: cluster, isDaemon: isDaemon, Port: port}
|
2017-01-20 09:41:27 -08:00
|
|
|
}
|
|
|
|
|
|
2017-01-27 08:44:25 -08:00
|
|
|
func FlattenMonEndpoints(mons map[string]*CephMonitorConfig) string {
|
|
|
|
|
endpoints := []string{}
|
|
|
|
|
for _, m := range mons {
|
|
|
|
|
endpoints = append(endpoints, fmt.Sprintf("%s=%s", m.Name, m.Endpoint))
|
|
|
|
|
}
|
|
|
|
|
return strings.Join(endpoints, ",")
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-19 13:31:22 -08:00
|
|
|
func ParseMonEndpoints(input string) map[string]*CephMonitorConfig {
|
2017-01-27 08:44:25 -08:00
|
|
|
logger.Infof("parsing mon endpoints: %s", input)
|
2017-01-19 13:31:22 -08:00
|
|
|
mons := map[string]*CephMonitorConfig{}
|
|
|
|
|
rawMons := strings.Split(input, ",")
|
|
|
|
|
for _, rawMon := range rawMons {
|
|
|
|
|
parts := strings.Split(rawMon, "=")
|
|
|
|
|
if len(parts) != 2 {
|
|
|
|
|
logger.Warningf("ignoring invalid monitor %s", rawMon)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
mons[parts[0]] = &CephMonitorConfig{Name: parts[0], Endpoint: parts[1]}
|
|
|
|
|
}
|
|
|
|
|
return mons
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-09 17:33:28 +02:00
|
|
|
func ToCephMon(name, ip string, port int32) *CephMonitorConfig {
|
|
|
|
|
return &CephMonitorConfig{Name: name, Endpoint: fmt.Sprintf("%s:%d", ip, port)}
|
2017-01-27 08:44:25 -08:00
|
|
|
}
|
|
|
|
|
|
2017-06-02 13:44:54 -07:00
|
|
|
func Run(context *clusterd.Context, config *Config) error {
|
2017-01-20 09:41:27 -08:00
|
|
|
|
|
|
|
|
configFile, monDataDir, err := generateConfigFiles(context, config)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to generate mon config files. %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = startMon(context, config, configFile, monDataDir)
|
|
|
|
|
if err != nil {
|
2017-01-19 13:31:22 -08:00
|
|
|
return fmt.Errorf("failed to run mon. %+v", err)
|
2017-01-20 09:41:27 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-02 13:44:54 -07:00
|
|
|
func generateConfigFiles(context *clusterd.Context, config *Config) (string, string, error) {
|
2017-01-20 09:41:27 -08:00
|
|
|
|
|
|
|
|
// write the keyring to disk
|
2017-06-02 13:44:54 -07:00
|
|
|
if err := writeMonKeyring(context, config.Cluster, config.Name); err != nil {
|
2017-01-20 09:41:27 -08:00
|
|
|
return "", "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// write the config file to disk
|
2017-06-02 13:44:54 -07:00
|
|
|
confFilePath, err := GenerateConnectionConfigFile(context, config.Cluster, getMonRunDirPath(context.ConfigDir, config.Name),
|
2017-01-20 09:41:27 -08:00
|
|
|
"admin", getMonKeyringPath(context.ConfigDir, config.Name))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create monitor data dir
|
|
|
|
|
monDataDir := getMonDataDirPath(context.ConfigDir, config.Name)
|
|
|
|
|
if err := os.MkdirAll(monDataDir, 0744); err != nil {
|
|
|
|
|
logger.Warningf("failed to create monitor data directory at %s: %+v", monDataDir, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// write the kv_backend file to force ceph to use rocksdb for the MON store
|
|
|
|
|
if err := writeBackendFile(monDataDir, "rocksdb"); err != nil {
|
|
|
|
|
return "", "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return confFilePath, monDataDir, nil
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-02 13:44:54 -07:00
|
|
|
func startMon(context *clusterd.Context, config *Config, confFilePath, monDataDir string) error {
|
2017-01-20 09:41:27 -08:00
|
|
|
// call mon --mkfs in a child process
|
|
|
|
|
logger.Infof("initializing mon")
|
|
|
|
|
|
2017-08-01 22:32:31 -07:00
|
|
|
// generate the monmap
|
|
|
|
|
monmapPath, err := generateMonMap(context, config.Cluster, getMonRunDirPath(context.ConfigDir, config.Name))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-02 13:44:54 -07:00
|
|
|
monNameArg := fmt.Sprintf("--name=mon.%s", config.Name)
|
2017-01-20 09:41:27 -08:00
|
|
|
keyringPath := getMonKeyringPath(context.ConfigDir, config.Name)
|
2017-10-26 15:21:53 -07:00
|
|
|
err = context.Executor.ExecuteCommand(
|
|
|
|
|
false,
|
2017-01-20 09:41:27 -08:00
|
|
|
fmt.Sprintf("mkfs-%s", config.Name),
|
2017-06-02 13:44:54 -07:00
|
|
|
"ceph-mon",
|
2017-01-20 09:41:27 -08:00
|
|
|
"--mkfs",
|
2017-06-02 13:44:54 -07:00
|
|
|
monNameArg,
|
2017-01-20 09:41:27 -08:00
|
|
|
fmt.Sprintf("--cluster=%s", config.Cluster.Name),
|
|
|
|
|
fmt.Sprintf("--mon-data=%s", monDataDir),
|
|
|
|
|
fmt.Sprintf("--conf=%s", confFilePath),
|
2017-08-01 22:32:31 -07:00
|
|
|
fmt.Sprintf("--keyring=%s", keyringPath),
|
|
|
|
|
fmt.Sprintf("--monmap=%s", monmapPath))
|
2017-01-20 09:41:27 -08:00
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed mon %s --mkfs: %+v", config.Name, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// start the monitor daemon in the foreground with the given config
|
|
|
|
|
logger.Infof("starting mon")
|
|
|
|
|
|
|
|
|
|
util.WriteFileToLog(logger, confFilePath)
|
|
|
|
|
|
2017-06-02 13:44:54 -07:00
|
|
|
args := []string{
|
2017-01-20 09:41:27 -08:00
|
|
|
"--foreground",
|
2017-06-02 13:44:54 -07:00
|
|
|
monNameArg,
|
2017-01-20 09:41:27 -08:00
|
|
|
fmt.Sprintf("--cluster=%s", config.Cluster.Name),
|
|
|
|
|
fmt.Sprintf("--mon-data=%s", monDataDir),
|
|
|
|
|
fmt.Sprintf("--conf=%s", confFilePath),
|
2017-06-02 13:44:54 -07:00
|
|
|
fmt.Sprintf("--keyring=%s", keyringPath),
|
2017-09-09 17:33:28 +02:00
|
|
|
fmt.Sprintf("--public-addr=%s:%d", context.NetworkInfo.PublicAddrIPv4, config.Port),
|
|
|
|
|
fmt.Sprintf("--public-bind-addr=%s:%d", context.NetworkInfo.ClusterAddrIPv4, config.Port),
|
2017-06-02 13:44:54 -07:00
|
|
|
}
|
2017-10-26 15:21:53 -07:00
|
|
|
if err = context.Executor.ExecuteCommand(false, config.Name, "ceph-mon", args...); err != nil {
|
2017-02-01 11:00:09 -08:00
|
|
|
return fmt.Errorf("failed to start mon: %+v", err)
|
2017-01-20 09:41:27 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|