mirror of
https://gitee.com/rainbond/Rainbond.git
synced 2024-12-02 19:57:42 +08:00
[REV]Improved logic for node installation #342
This commit is contained in:
parent
c815b86204
commit
e86e5e258e
@ -258,7 +258,7 @@ func (r *resourcesTenant) Get() (*model.TenantResource, *util.APIHandleError) {
|
||||
|
||||
func handleAPIResult(code int, res utilhttp.ResponseBody) *util.APIHandleError {
|
||||
if code >= 300 {
|
||||
return util.CreateAPIHandleErrorf(code, res.Msg)
|
||||
return util.CreateAPIHandleErrorf(code, "msg:%s validation_error %+v", res.Msg, res.ValidationError)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ func (a *APIHandleError) Error() string {
|
||||
}
|
||||
|
||||
func (a *APIHandleError) String() string {
|
||||
return fmt.Sprintf("%d:%s", a.Code, a.Err.Error())
|
||||
return fmt.Sprintf("(Code:%d) %s", a.Code, a.Err.Error())
|
||||
}
|
||||
|
||||
//Handle 处理
|
||||
|
@ -47,26 +47,26 @@ func TestAnsibleHostConfig(t *testing.T) {
|
||||
}
|
||||
ansibleConfig := &AnsibleHostConfig{
|
||||
FileName: "/tmp/hosts",
|
||||
GroupList: []*AnsibleHostGroup{
|
||||
&AnsibleHostGroup{
|
||||
GroupList: map[string]*AnsibleHostGroup{
|
||||
"all": &AnsibleHostGroup{
|
||||
Name: "all",
|
||||
HostList: []*AnsibleHost{
|
||||
h1, h2, h3,
|
||||
},
|
||||
},
|
||||
&AnsibleHostGroup{
|
||||
"manage": &AnsibleHostGroup{
|
||||
Name: "manage",
|
||||
HostList: []*AnsibleHost{
|
||||
h1, h2, h3,
|
||||
},
|
||||
},
|
||||
&AnsibleHostGroup{
|
||||
"gateway": &AnsibleHostGroup{
|
||||
Name: "gateway",
|
||||
HostList: []*AnsibleHost{
|
||||
h3,
|
||||
},
|
||||
},
|
||||
&AnsibleHostGroup{
|
||||
"compute": &AnsibleHostGroup{
|
||||
Name: "compute",
|
||||
HostList: []*AnsibleHost{
|
||||
h2,
|
||||
|
@ -26,6 +26,8 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/goodrain/rainbond/node/nodem/client"
|
||||
|
||||
"github.com/goodrain/rainbond/util"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
@ -195,6 +197,10 @@ func NewCmdInit() cli.Command {
|
||||
Usage: "Additional support for the console to configure the database separately",
|
||||
Value: "",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "not-install-ui",
|
||||
Usage: "Whether or not to install the UI, normally no UI is installed when installing a second data center",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "test",
|
||||
Usage: "use test shell",
|
||||
@ -240,7 +246,6 @@ func NewCmdInstallStatus() cli.Command {
|
||||
//Status(v.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -251,8 +256,8 @@ func NewCmdInstallStatus() cli.Command {
|
||||
}
|
||||
return c
|
||||
}
|
||||
func updateConfigFile(path string, config map[string]string) error {
|
||||
initConfig := make(map[string]string)
|
||||
func updateConfigFile(path string, config map[string]interface{}) error {
|
||||
initConfig := make(map[string]interface{})
|
||||
var file *os.File
|
||||
var err error
|
||||
if ok, _ := util.FileExists(path); ok {
|
||||
@ -289,16 +294,23 @@ func updateConfigFile(path string, config map[string]string) error {
|
||||
if k == "" {
|
||||
continue
|
||||
}
|
||||
if v == "" {
|
||||
file.WriteString(fmt.Sprintf("%s=\"\"\n", k))
|
||||
} else {
|
||||
file.WriteString(fmt.Sprintf("%s=\"%s\"\n", k, v))
|
||||
switch v.(type) {
|
||||
case string:
|
||||
if v == "" {
|
||||
file.WriteString(fmt.Sprintf("%s=\"\"\n", k))
|
||||
} else {
|
||||
file.WriteString(fmt.Sprintf("%s=\"%s\"\n", k, v))
|
||||
}
|
||||
case bool:
|
||||
file.WriteString(fmt.Sprintf("%s=%t\n", k, v))
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func getConfig(c *cli.Context) map[string]string {
|
||||
configs := make(map[string]string)
|
||||
func getConfig(c *cli.Context) map[string]interface{} {
|
||||
configs := make(map[string]interface{})
|
||||
configs["ROLE"] = c.String("role")
|
||||
//configs["work_dir"] = c.String("work_dir")
|
||||
configs["IIP"] = c.String("iip")
|
||||
@ -328,6 +340,7 @@ func getConfig(c *cli.Context) map[string]string {
|
||||
configs["EXCSDB_USER"] = c.String("excsdb-user")
|
||||
configs["EXDB_TYPE"] = c.String("exdb-type")
|
||||
configs["INSTALL_SSH_PORT"] = c.String("install_ssh_port")
|
||||
configs["INSTALL_UI"] = !c.Bool("not-install-ui")
|
||||
return configs
|
||||
}
|
||||
func initCluster(c *cli.Context) {
|
||||
@ -338,6 +351,16 @@ func initCluster(c *cli.Context) {
|
||||
println("Rainbond is already installed, if you want reinstall, then please delete the file: /opt/rainbond/.rainbond.success")
|
||||
return
|
||||
}
|
||||
role := c.String("role")
|
||||
roles := client.HostRule(strings.Split(role, ","))
|
||||
if err := roles.Validation(); err != nil {
|
||||
println(err.Error())
|
||||
return
|
||||
}
|
||||
if !roles.HasRule("manage") || !roles.HasRule("gateway") {
|
||||
println("first node must have manage and gateway role")
|
||||
return
|
||||
}
|
||||
// download source code from github if in online model
|
||||
if c.String("install-type") == "online" {
|
||||
fmt.Println("Download the installation configuration file remotely...")
|
||||
@ -353,29 +376,20 @@ func initCluster(c *cli.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := updateConfigFile(c.String("config-file"), getConfig(c)); err != nil {
|
||||
showError("update config file failure " + err.Error())
|
||||
}
|
||||
|
||||
//storage file
|
||||
//fmt.Println("Check storage type")
|
||||
//ioutil.WriteFile("/tmp/.storage.value", []byte(c.String("storage-args")), 0644)
|
||||
|
||||
// start setup script to install rainbond
|
||||
fmt.Println("Initializes the installation of the first node...")
|
||||
cmd := exec.Command("bash", "-c", fmt.Sprintf("cd %s ; ./setup.sh", c.String("work_dir")))
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdin = os.Stdin
|
||||
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ioutil.WriteFile("/opt/rainbond/.rainbond.success", []byte(c.String("rainbond-version")), 0644)
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ import (
|
||||
|
||||
func handleErr(err *util.APIHandleError) {
|
||||
if err != nil && err.Err != nil {
|
||||
fmt.Printf("Code %d, Msg:%v\n", err.Code, err.String())
|
||||
fmt.Printf(err.String())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@ -536,10 +536,15 @@ func NewCmdNode() cli.Command {
|
||||
Usage: "The option is required",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "hosts-file-path,p",
|
||||
Name: "hosts-file-path",
|
||||
Usage: "hosts file path",
|
||||
Value: "/opt/rainbond/rainbond-ansible/inventory/hosts",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "config-file-path",
|
||||
Usage: "ansible global config file path",
|
||||
Value: "/opt/rainbond/rainbond-ansible/scripts/installer/global.sh",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "internal-ip,iip",
|
||||
Usage: "The option is required",
|
||||
@ -587,7 +592,7 @@ func NewCmdNode() cli.Command {
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "config-file-path",
|
||||
Usage: "install config path",
|
||||
Usage: "ansible global config file path",
|
||||
Value: "/opt/rainbond/rainbond-ansible/scripts/installer/global.sh",
|
||||
},
|
||||
},
|
||||
@ -610,28 +615,17 @@ func isNodeReady(node *client.HostNode) bool {
|
||||
}
|
||||
|
||||
func installNode(node *client.HostNode) {
|
||||
linkModel := "pass"
|
||||
if node.KeyPath != "" {
|
||||
linkModel = "key"
|
||||
}
|
||||
// start add node script
|
||||
logrus.Infof("Begin install node %s", node.ID)
|
||||
if ok, _ := coreutil.FileExists("/opt/rainbond/rainbond-ansible/scripts/node.sh"); !ok {
|
||||
logrus.Errorf("install node scripts is not found")
|
||||
return
|
||||
}
|
||||
|
||||
// node stauts: installing
|
||||
if _, err := clients.RegionClient.Nodes().UpdateNodeStatus(node.ID, client.Installing); err != nil {
|
||||
logrus.Errorf("update node %s status failure %s", node.ID, err.Error())
|
||||
}
|
||||
|
||||
// install node
|
||||
option := coreutil.NodeInstallOption{
|
||||
HostRole: node.Role[0],
|
||||
HostRole: node.Role.String(),
|
||||
HostName: node.HostName,
|
||||
InternalIP: node.InternalIP,
|
||||
LinkModel: linkModel,
|
||||
RootPass: node.RootPass,
|
||||
KeyPath: node.KeyPath,
|
||||
NodeID: node.ID,
|
||||
@ -687,7 +681,6 @@ func addNodeCommand(c *cli.Context) error {
|
||||
if err := node.Role.Validation(); err != nil {
|
||||
showError(err.Error())
|
||||
}
|
||||
fmt.Println(node.Role)
|
||||
node.HostName = c.String("hostname")
|
||||
node.RootPass = c.String("root-pass")
|
||||
node.InternalIP = c.String("internal-ip")
|
||||
@ -699,7 +692,10 @@ func addNodeCommand(c *cli.Context) error {
|
||||
renode, err := clients.RegionClient.Nodes().Add(&node)
|
||||
handleErr(err)
|
||||
if c.Bool("install") {
|
||||
nodes, err := clients.RegionClient.Nodes().List()
|
||||
handleErr(err)
|
||||
//write ansible hosts file
|
||||
WriteHostsFile(c.String("hosts-file-path"), c.String("config-file-path"), nodes)
|
||||
installNode(renode)
|
||||
} else {
|
||||
fmt.Printf("success add %s node %s \n you install it by running: grctl node install %s \n", renode.Role, renode.ID, renode.ID)
|
||||
|
@ -172,10 +172,6 @@ func (n *NodeService) AsynchronousInstall(node *client.HostNode) {
|
||||
logrus.Error("write hosts file error ", err.Error())
|
||||
return
|
||||
}
|
||||
linkModel := "pass"
|
||||
if node.KeyPath != "" {
|
||||
linkModel = "key"
|
||||
}
|
||||
if err := event.NewManager(event.EventConfig{
|
||||
DiscoverAddress: n.c.Etcd.Endpoints,
|
||||
}); err != nil {
|
||||
@ -189,10 +185,9 @@ func (n *NodeService) AsynchronousInstall(node *client.HostNode) {
|
||||
logger := event.GetManager().GetLogger(node.ID + "-insatll")
|
||||
|
||||
option := coreutil.NodeInstallOption{
|
||||
HostRole: node.Role[0],
|
||||
HostRole: node.Role.String(),
|
||||
HostName: node.HostName,
|
||||
InternalIP: node.InternalIP,
|
||||
LinkModel: linkModel,
|
||||
RootPass: node.RootPass,
|
||||
KeyPath: node.KeyPath,
|
||||
NodeID: node.ID,
|
||||
|
@ -26,7 +26,7 @@ func WriteHostsFile(filePath, installConfPath string, hosts []*client.HostNode)
|
||||
return config.WriteFile()
|
||||
}
|
||||
|
||||
//AnsibleHost ansible host config
|
||||
//AnsibleHost ansible host config
|
||||
type AnsibleHost struct {
|
||||
AnsibleHostIP net.IP
|
||||
//ssh port
|
||||
@ -77,7 +77,7 @@ func (a *AnsibleHostGroup) String() string {
|
||||
if a.Name == "all" {
|
||||
rebuffer.WriteString(a.HostList[i].String() + "\n")
|
||||
} else if a.Name == "etcd" {
|
||||
rebuffer.WriteString(a.HostList[i].HostID + " NODE_NAME=etcd1" + "\n")
|
||||
rebuffer.WriteString(a.HostList[i].HostID + "\n")
|
||||
} else {
|
||||
rebuffer.WriteString(a.HostList[i].HostID + "\n")
|
||||
}
|
||||
|
71
util/node.go
71
util/node.go
@ -24,15 +24,13 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
//NodeInstallOption node install option
|
||||
type NodeInstallOption struct {
|
||||
HostRole string
|
||||
HostName string
|
||||
InternalIP string
|
||||
LinkModel string
|
||||
RootPass string // ssh login password
|
||||
KeyPath string // ssh login key path
|
||||
NodeID string
|
||||
@ -40,8 +38,10 @@ type NodeInstallOption struct {
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
loginValue string
|
||||
linkModel string
|
||||
}
|
||||
|
||||
//RunNodeInstallCmd install node
|
||||
func RunNodeInstallCmd(option NodeInstallOption) (err error) {
|
||||
installNodeShellPath := os.Getenv("INSTALL_NODE_SHELL_PATH")
|
||||
if installNodeShellPath == "" {
|
||||
@ -50,76 +50,49 @@ func RunNodeInstallCmd(option NodeInstallOption) (err error) {
|
||||
|
||||
// ansible file must exists
|
||||
if ok, _ := FileExists(installNodeShellPath); !ok {
|
||||
err = fmt.Errorf("install node scripts is not found")
|
||||
logrus.Error(err)
|
||||
return fmt.Errorf("install node scripts is not found")
|
||||
}
|
||||
fmt.Println(option)
|
||||
// ansible's param can't send nil nor empty string
|
||||
if err := preCheckNodeInstall(&option); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ansible's param can't send nil nor empty string
|
||||
if err = preCheckNodeInstall(option); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
line := fmt.Sprintf(installNodeShellPath+" %s %s %s %s %s %s",
|
||||
option.HostRole, option.HostName, option.InternalIP, option.LinkModel, option.loginValue, option.NodeID)
|
||||
|
||||
option.HostRole, option.HostName, option.InternalIP, option.linkModel, option.loginValue, option.NodeID)
|
||||
fmt.Println(line)
|
||||
cmd := exec.Command("bash", "-c", line)
|
||||
cmd.Stdin = option.Stdin
|
||||
cmd.Stdout = option.Stdout
|
||||
cmd.Stderr = option.Stderr
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
logrus.Errorf("install node failed")
|
||||
return err
|
||||
}
|
||||
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
logrus.Errorf("install node finished with error : %v", err.Error())
|
||||
}
|
||||
|
||||
return
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// check param
|
||||
func preCheckNodeInstall(option NodeInstallOption) (err error) {
|
||||
func preCheckNodeInstall(option *NodeInstallOption) error {
|
||||
if strings.TrimSpace(option.HostRole) == "" {
|
||||
err = fmt.Errorf("install node failed, install scripts needs param hostRole")
|
||||
logrus.Error(err)
|
||||
return
|
||||
return fmt.Errorf("install node failed, install scripts needs param hostRole")
|
||||
}
|
||||
if strings.TrimSpace(option.HostName) == "" {
|
||||
err = fmt.Errorf("install node failed, install scripts needs param hostName")
|
||||
logrus.Error(err)
|
||||
return
|
||||
return fmt.Errorf("install node failed, install scripts needs param hostName")
|
||||
}
|
||||
if strings.TrimSpace(option.InternalIP) == "" {
|
||||
err = fmt.Errorf("install node failed, install scripts needs param internalIP")
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(option.LinkModel) == "" {
|
||||
err = fmt.Errorf("install node failed, install scripts needs param linkModel")
|
||||
logrus.Error(err)
|
||||
return
|
||||
return fmt.Errorf("install node failed, install scripts needs param internalIP")
|
||||
}
|
||||
|
||||
//login key path first, and then rootPass, so keyPath and RootPass can't all be empty
|
||||
if strings.TrimSpace(option.KeyPath) == "" {
|
||||
if strings.TrimSpace(option.RootPass) == "" {
|
||||
err = fmt.Errorf("install node failed, install scripts needs login key path or login password")
|
||||
logrus.Error(err)
|
||||
return
|
||||
return fmt.Errorf("install node failed, install scripts needs login key path or login password")
|
||||
}
|
||||
option.loginValue = strings.TrimSpace(option.RootPass)
|
||||
option.linkModel = "pass"
|
||||
} else {
|
||||
option.loginValue = strings.TrimSpace(option.KeyPath)
|
||||
option.linkModel = "key"
|
||||
}
|
||||
option.loginValue = strings.TrimSpace(option.KeyPath)
|
||||
|
||||
if strings.TrimSpace(option.NodeID) == "" {
|
||||
err = fmt.Errorf("install node failed, install scripts needs param nodeID")
|
||||
logrus.Error(err)
|
||||
return
|
||||
return fmt.Errorf("install node failed, install scripts needs param nodeID")
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
@ -162,4 +162,5 @@ func (m *Controller) Scrape(ch chan<- prometheus.Metric, scrapeDurationDesc *pro
|
||||
ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, time.Since(scrapeTime).Seconds(), "collect.fs")
|
||||
m.fsUse.Collect(ch)
|
||||
m.memoryUse.Collect(ch)
|
||||
logrus.Infof("success collect app disk and memory used metric")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user