fix bugs use chan transport log and use env for installNodeShellPath

This commit is contained in:
凡羊羊 2019-08-07 11:05:57 +08:00
parent eb2d2e6b46
commit 7d83add0f0
3 changed files with 86 additions and 28 deletions

View File

@ -25,6 +25,7 @@ import (
"os"
"strconv"
"strings"
"sync"
"github.com/fatih/color"
@ -636,12 +637,21 @@ func installNode(node *client.HostNode) {
KeyPath: node.KeyPath,
NodeID: node.ID,
Stdin: os.Stdin,
Stderr: os.Stderr,
}
err := coreutil.RunNodeInstallCmd(option, func(line string) {
// run log func
fmt.Fprint(os.Stdout, line) // write log to os.Stdout
})
logChan := make(chan string, 10)
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
// write log
for line := range logChan {
fmt.Fprint(os.Stdout, line) // write log to os.Stdout
}
wg.Done()
}()
err := coreutil.RunNodeInstallCmd(option, logChan)
if err != nil {
logrus.Errorf("Error executing shell script %s", err.Error())
if _, err := clients.RegionClient.Nodes().UpdateNodeStatus(node.ID, client.InstallFailed); err != nil {
@ -650,6 +660,9 @@ func installNode(node *client.HostNode) {
return
}
// wait log write finish
wg.Wait()
// node status success
if _, err := clients.RegionClient.Nodes().UpdateNodeStatus(node.ID, client.InstallSuccess); err != nil {
logrus.Errorf("update node %s status failure %s", node.ID, err.Error())

View File

@ -24,6 +24,7 @@ import (
"os"
"sort"
"strconv"
"sync"
"time"
"github.com/goodrain/rainbond/event"
@ -210,21 +211,30 @@ func (n *NodeService) AsynchronousInstall(node *client.HostNode) {
KeyPath: node.KeyPath,
NodeID: node.ID,
Stdin: nil,
Stderr: f,
}
// write log to event log
logger := event.GetManager().GetLogger(node.ID + "-insatll")
err = coreutil.RunNodeInstallCmd(option, func(line string) {
// run log func
logger.Info(line, map[string]string{"step": "node-install", "status": "installing"}) // write log to eventLog
_, err = f.WriteString(line) // write log to file
if err != nil {
logrus.Error(err)
return
logChan := make(chan string, 10)
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
// write log
for line := range logChan {
logger.Info(line, map[string]string{"step": "node-install", "status": "installing"}) // write log to eventLog
_, err = f.WriteString(line) // write log to file
if err != nil {
logrus.Error(err)
return
}
// fmt.Fprint(os.Stdout, line) //write os.Stdout
}
// fmt.Fprint(os.Stdout, line) //write os.Stdout
})
wg.Done()
}()
err = coreutil.RunNodeInstallCmd(option, logChan)
if err != nil {
if _, err := f.Write([]byte(err.Error())); err != nil {
logrus.Errorf("Error write file %s", err.Error())
@ -236,6 +246,9 @@ func (n *NodeService) AsynchronousInstall(node *client.HostNode) {
return
}
// wait log write finish
wg.Wait()
logrus.Infof("Install node %s successful", node.ID)
node.Status = client.InstallSuccess

View File

@ -25,6 +25,7 @@ import (
"os"
"os/exec"
"strings"
"sync"
"github.com/Sirupsen/logrus"
)
@ -38,12 +39,16 @@ type NodeInstallOption struct {
KeyPath string
NodeID string
Stdin *os.File
Stderr *os.File
}
func RunNodeInstallCmd(option NodeInstallOption, runLog func(line string)) (err error) {
func RunNodeInstallCmd(option NodeInstallOption, logChan chan string) (err error) {
installNodeShellPath := os.Getenv("INSTALL_NODE_SHELL_PATH")
if installNodeShellPath == "" {
installNodeShellPath = "/opt/rainbond/rainbond-ansible/scripts/node.sh"
}
// ansible file must exists
if ok, _ := FileExists("/opt/rainbond/rainbond-ansible/scripts/node.sh"); !ok {
if ok, _ := FileExists(installNodeShellPath); !ok {
err = fmt.Errorf("install node scripts is not found")
logrus.Error(err)
return err
@ -54,21 +59,28 @@ func RunNodeInstallCmd(option NodeInstallOption, runLog func(line string)) (err
return
}
line := fmt.Sprintf("/opt/rainbond/rainbond-ansible/scripts/node.sh %s %s %s %s %s %s %s",
line := fmt.Sprintf(installNodeShellPath+" %s %s %s %s %s %s %s",
option.HostRole, option.HostName, option.InternalIP, option.LinkModel, option.RootPass, option.KeyPath, option.NodeID)
cmd := exec.Command("bash", "-c", line)
cmd.Stderr = option.Stderr
cmd.Stdin = option.Stdin
stderr, err := cmd.StderrPipe()
if err != nil {
logrus.Errorf("install node failed")
return err
}
stdout, err := cmd.StdoutPipe()
if err != nil {
logrus.Errorf("install node failed")
return err
}
wg := sync.WaitGroup{}
// for another log
reader := bufio.NewReader(stdout)
wg.Add(1)
go func() {
for {
line, err := reader.ReadString('\n')
@ -80,10 +92,26 @@ func RunNodeInstallCmd(option NodeInstallOption, runLog func(line string)) (err
return
}
if runLog != nil {
runLog(line)
}
logChan <- line
}
wg.Done()
}()
readerStderr := bufio.NewReader(stderr)
wg.Add(1)
go func() {
for {
line, err := readerStderr.ReadString('\n')
if err == io.EOF {
break
}
if err != nil {
logrus.Error("install node failed")
return
}
logChan <- line
}
wg.Done()
}()
err = cmd.Start()
@ -96,6 +124,9 @@ func RunNodeInstallCmd(option NodeInstallOption, runLog func(line string)) (err
if err != nil {
logrus.Errorf("install node finished with error : %v", err.Error())
}
// wait clse logChan
wg.Wait()
close(logChan)
return
}
@ -126,11 +157,12 @@ func preCheckNodeInstall(option NodeInstallOption) (err error) {
logrus.Error(err)
return
}
if strings.TrimSpace(option.KeyPath) == "" {
err = fmt.Errorf("install node failed, install scripts needs param keyPath")
logrus.Error(err)
return
}
// if rootPass is not empty then keyPath can be empty
// if strings.TrimSpace(option.KeyPath) == "" {
// err = fmt.Errorf("install node failed, install scripts needs param keyPath")
// logrus.Error(err)
// return
// }
if strings.TrimSpace(option.NodeID) == "" {
err = fmt.Errorf("install node failed, install scripts needs param nodeID")
logrus.Error(err)