145 lines
2.7 KiB
Go
145 lines
2.7 KiB
Go
//go:build plus
|
|
|
|
package nodes
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
|
"github.com/TeaOSLab/EdgeNode/internal/events"
|
|
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
|
executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec"
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils/goman"
|
|
"github.com/iwind/TeaGo/Tea"
|
|
"net"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
var sharedTOAManager = NewTOAManager()
|
|
|
|
func init() {
|
|
if !teaconst.IsMain {
|
|
return
|
|
}
|
|
|
|
events.On(events.EventLoaded, func() {
|
|
err := sharedTOAManager.Apply(nodeConfig().TOA)
|
|
if err != nil {
|
|
remotelogs.Error("TOA", err.Error())
|
|
}
|
|
})
|
|
|
|
events.OnClose(func() {
|
|
_ = sharedTOAManager.Quit()
|
|
})
|
|
}
|
|
|
|
type TOAManager struct {
|
|
config *nodeconfigs.TOAConfig
|
|
configJSON []byte
|
|
|
|
pid int
|
|
conn net.Conn
|
|
}
|
|
|
|
func NewTOAManager() *TOAManager {
|
|
return &TOAManager{}
|
|
}
|
|
|
|
func (this *TOAManager) Apply(config *nodeconfigs.TOAConfig) error {
|
|
newConfigJSON, err := json.Marshal(config)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if this.pid > 0 {
|
|
// 检查配置是否已变更
|
|
if bytes.Equal(this.configJSON, newConfigJSON) {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
this.configJSON = newConfigJSON
|
|
|
|
this.config = config
|
|
|
|
if this.pid > 0 {
|
|
remotelogs.Println("TOA", "stopping ...")
|
|
err := this.Quit()
|
|
if err != nil {
|
|
remotelogs.Error("TOA", "quit error: "+err.Error())
|
|
}
|
|
if this.conn != nil {
|
|
_ = this.conn.Close()
|
|
}
|
|
this.conn = nil
|
|
this.pid = 0
|
|
}
|
|
|
|
if !config.IsOn {
|
|
return nil
|
|
}
|
|
|
|
var binPath = Tea.Root + "/edge-toa/edge-toa"
|
|
_, err = os.Stat(binPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
remotelogs.Println("TOA", "starting ...")
|
|
remotelogs.Println("TOA", "args: "+strings.Join(config.AsArgs(), " "))
|
|
var cmd = executils.NewCmd(binPath, config.AsArgs()...).WithStderr()
|
|
err = cmd.Start()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var process = cmd.Process()
|
|
if process == nil {
|
|
return errors.New("start failed")
|
|
}
|
|
this.pid = process.Pid
|
|
|
|
goman.New(func() {
|
|
err = cmd.Wait()
|
|
if err != nil {
|
|
remotelogs.Error("TOA", "start failed: "+cmd.Stderr())
|
|
}
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
func (this *TOAManager) Config() *nodeconfigs.TOAConfig {
|
|
return this.config
|
|
}
|
|
|
|
func (this *TOAManager) Quit() error {
|
|
return this.SendMsg("quit:0")
|
|
}
|
|
|
|
func (this *TOAManager) SendMsg(msg string) error {
|
|
if this.config == nil {
|
|
return nil
|
|
}
|
|
|
|
if this.conn != nil {
|
|
_, err := this.conn.Write([]byte(msg + "\n"))
|
|
if err != nil {
|
|
_ = this.conn.Close()
|
|
this.conn = nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
conn, err := net.DialTimeout("unix", this.config.SockFile(), 1*time.Second)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
this.conn = conn
|
|
_, err = this.conn.Write([]byte(msg + "\n"))
|
|
return err
|
|
}
|