实现API节点远程升级

This commit is contained in:
GoEdgeLab
2023-03-05 12:05:18 +08:00
parent b5cba51456
commit 2ac7f6d14a
12 changed files with 426 additions and 69 deletions

View File

@@ -0,0 +1,30 @@
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package apinodeutils
var SharedManager = NewManager()
type Manager struct {
upgraderMap map[int64]*Upgrader
}
func NewManager() *Manager {
return &Manager{
upgraderMap: map[int64]*Upgrader{},
}
}
func (this *Manager) AddUpgrader(upgrader *Upgrader) {
this.upgraderMap[upgrader.apiNodeId] = upgrader
}
func (this *Manager) FindUpgrader(apiNodeId int64) *Upgrader {
return this.upgraderMap[apiNodeId]
}
func (this *Manager) RemoveUpgrader(upgrader *Upgrader) {
if upgrader == nil {
return
}
delete(this.upgraderMap, upgrader.apiNodeId)
}

View File

@@ -3,7 +3,6 @@
package apinodeutils
import (
"bytes"
"compress/gzip"
"crypto/md5"
"errors"
@@ -16,9 +15,7 @@ import (
stringutil "github.com/iwind/TeaGo/utils/string"
"io"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
)
@@ -27,49 +24,31 @@ type Progress struct {
}
type Upgrader struct {
progress *Progress
apiExe string
progress *Progress
apiExe string
apiNodeId int64
}
func NewUpgrader() *Upgrader {
func NewUpgrader(apiNodeId int64) *Upgrader {
return &Upgrader{
apiExe: Tea.Root + "/edge-api/bin/edge-api",
progress: &Progress{Percent: 0},
apiExe: apiExe(),
progress: &Progress{Percent: 0},
apiNodeId: apiNodeId,
}
}
func (this *Upgrader) CanUpgrade(apiVersion string) (canUpgrade bool, reason string) {
stat, err := os.Stat(this.apiExe)
if err != nil {
return false, "stat error: " + err.Error()
}
if stat.IsDir() {
return false, "is directory"
}
localVersion, err := this.localVersion()
if err != nil {
return false, "lookup version failed: " + err.Error()
}
if stringutil.VersionCompare(localVersion, apiVersion) <= 0 {
return false, "need not upgrade, local '" + localVersion + "' vs remote '" + apiVersion + "'"
}
return true, ""
}
func (this *Upgrader) Upgrade(apiNodeId int64) error {
func (this *Upgrader) Upgrade() error {
sharedClient, err := rpc.SharedRPC()
if err != nil {
return err
}
apiNodeResp, err := sharedClient.APINodeRPC().FindEnabledAPINode(sharedClient.Context(0), &pb.FindEnabledAPINodeRequest{ApiNodeId: apiNodeId})
apiNodeResp, err := sharedClient.APINodeRPC().FindEnabledAPINode(sharedClient.Context(0), &pb.FindEnabledAPINodeRequest{ApiNodeId: this.apiNodeId})
if err != nil {
return err
}
var apiNode = apiNodeResp.ApiNode
if apiNode == nil {
return errors.New("could not find api node with id '" + types.String(apiNodeId) + "'")
return errors.New("could not find api node with id '" + types.String(this.apiNodeId) + "'")
}
apiConfig, err := configs.LoadAPIConfig()
@@ -93,12 +72,12 @@ func (this *Upgrader) Upgrade(apiNodeId int64) error {
}
// 检查本地文件版本
canUpgrade, reason := this.CanUpgrade(versionResp.Version)
canUpgrade, reason := CanUpgrade(versionResp.Version, versionResp.Os, versionResp.Arch)
if !canUpgrade {
return errors.New(reason)
}
localVersion, err := this.localVersion()
localVersion, err := localVersion()
if err != nil {
return errors.New("lookup version failed: " + err.Error())
}
@@ -220,22 +199,3 @@ func (this *Upgrader) Upgrade(apiNodeId int64) error {
func (this *Upgrader) Progress() *Progress {
return this.progress
}
func (this *Upgrader) localVersion() (string, error) {
var cmd = exec.Command(this.apiExe, "-V")
var output = &bytes.Buffer{}
cmd.Stdout = output
err := cmd.Run()
if err != nil {
return "", err
}
var localVersion = output.String()
// 检查版本号
var reg = regexp.MustCompile(`^[\d.]+$`)
if !reg.MatchString(localVersion) {
return "", errors.New("lookup version failed: " + localVersion)
}
return localVersion, nil
}

View File

@@ -5,17 +5,17 @@ package apinodeutils_test
import (
"github.com/TeaOSLab/EdgeAdmin/internal/utils/apinodeutils"
_ "github.com/iwind/TeaGo/bootstrap"
"runtime"
"testing"
)
func TestUpgrader_CanUpgrade(t *testing.T) {
var upgrader = apinodeutils.NewUpgrader()
t.Log(upgrader.CanUpgrade("0.6.3"))
t.Log(apinodeutils.CanUpgrade("0.6.3", runtime.GOOS, runtime.GOARCH))
}
func TestUpgrader_Upgrade(t *testing.T) {
var upgrader = apinodeutils.NewUpgrader()
err := upgrader.Upgrade(1)
var upgrader = apinodeutils.NewUpgrader(1)
err := upgrader.Upgrade()
if err != nil {
t.Fatal(err)
}

View File

@@ -0,0 +1,76 @@
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package apinodeutils
import (
"bytes"
"errors"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/iwind/TeaGo/Tea"
stringutil "github.com/iwind/TeaGo/utils/string"
"os"
"os/exec"
"regexp"
"runtime"
"strings"
)
func CanUpgrade(apiVersion string, osName string, arch string) (canUpgrade bool, reason string) {
if len(apiVersion) == 0 {
return false, "current api version should not be empty"
}
if osName != runtime.GOOS {
return false, "os not match: " + osName
}
if arch != runtime.GOARCH {
return false, "arch not match: " + arch
}
stat, err := os.Stat(apiExe())
if err != nil {
return false, "stat error: " + err.Error()
}
if stat.IsDir() {
return false, "is directory"
}
localVersion, err := localVersion()
if err != nil {
return false, "lookup version failed: " + err.Error()
}
if localVersion != teaconst.APINodeVersion {
return false, "not newest api node"
}
if stringutil.VersionCompare(localVersion, apiVersion) <= 0 {
return false, "need not upgrade, local '" + localVersion + "' vs remote '" + apiVersion + "'"
}
return true, ""
}
func localVersion() (string, error) {
var cmd = exec.Command(apiExe(), "-V")
var output = &bytes.Buffer{}
cmd.Stdout = output
err := cmd.Run()
if err != nil {
return "", err
}
var localVersion = strings.TrimSpace(output.String())
// 检查版本号
var reg = regexp.MustCompile(`^[\d.]+$`)
if !reg.MatchString(localVersion) {
return "", errors.New("lookup version failed: " + localVersion)
}
return localVersion, nil
}
func apiExe() string {
return Tea.Root + "/edge-api/bin/edge-api"
}