实现单体实例安装工具

This commit is contained in:
刘祥超
2024-01-29 17:57:01 +08:00
parent 4d9f404bb0
commit c0cbd7c607
12 changed files with 1333 additions and 18 deletions

View File

@@ -0,0 +1,2 @@
standalone-instance-installer*
prepare.sh

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
OS="${1}"
ARCH="${2}"
TAG="${3}"
if [ -z "$OS" ]; then
echo "usage: build.sh OS ARCH"
exit
fi
if [ -z "$ARCH" ]; then
echo "usage: build.sh OS ARCH"
exit
fi
env GOOS=linux GOARCH="${ARCH}" go build -tags="${TAG}" -trimpath -ldflags="-s -w" -o "standalone-instance-installer-${OS}-${ARCH}" main.go

View File

@@ -0,0 +1,74 @@
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package main
import (
"fmt"
"github.com/TeaOSLab/EdgeAPI/internal/instances"
_ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/lists"
"os"
"strings"
)
func main() {
dbPasswordData, err := os.ReadFile("/usr/local/mysql/generated-password.txt")
if err != nil {
fmt.Println("[ERROR]read mysql password failed: " + err.Error())
return
}
var dbPassword = strings.TrimSpace(string(dbPasswordData))
var isTesting = lists.ContainsString(os.Args, "-test") || lists.ContainsString(os.Args, "--test")
if isTesting {
fmt.Println("testing mode ...")
}
var instance = instances.NewInstance(instances.Options{
IsTesting: isTesting,
Verbose: lists.ContainsString(os.Args, "-v"),
Cacheable: true,
WorkDir: "",
SrcDir: "/usr/local/goedge/src",
DB: struct {
Host string
Port int
Username string
Password string
Name string
}{
Host: "127.0.0.1",
Port: 3306,
Username: "root",
Password: dbPassword,
Name: "edges",
},
AdminNode: struct {
Port int
}{
Port: 7788,
},
APINode: struct {
HTTPPort int
RestHTTPPort int
}{
HTTPPort: 8001,
RestHTTPPort: 8002,
},
Node: struct{ HTTPPort int }{
HTTPPort: 8080,
},
UserNode: struct {
HTTPPort int
}{
HTTPPort: 7799,
},
})
err = instance.SetupAll()
if err != nil {
fmt.Println("[ERROR]setup failed: " + err.Error())
return
}
fmt.Println("ok")
}

View File

@@ -5,7 +5,6 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/go-sql-driver/mysql"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -759,10 +758,5 @@ func (this *MetricStatDAO) canIgnore(err error) bool {
}
// 忽略 Error 1213: Deadlock found 错误
mysqlErr, ok := err.(*mysql.MySQLError)
if ok && mysqlErr.Number == 1213 {
return true
}
return false
return CheckSQLErrCode(err, 1213)
}

View File

@@ -4,7 +4,6 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/go-sql-driver/mysql"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -289,10 +288,5 @@ func (this *MetricSumStatDAO) canIgnore(err error) bool {
}
// 忽略 Error 1213: Deadlock found 错误
mysqlErr, ok := err.(*mysql.MySQLError)
if ok && mysqlErr.Number == 1213 {
return true
}
return false
return CheckSQLErrCode(err, 1213)
}

View File

@@ -1,6 +1,7 @@
package models
import (
"errors"
"github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types"
@@ -60,8 +61,8 @@ func CheckSQLErrCode(err error, code uint16) bool {
}
// 快速判断错误方法
mysqlErr, ok := err.(*mysql.MySQLError)
if ok && mysqlErr.Number == code { // Error 1050: Table 'xxx' already exists
var mysqlErr *mysql.MySQLError
if errors.As(err, &mysqlErr) && mysqlErr.Number == code { // Error 1050: Table 'xxx' already exists
return true
}
@@ -86,6 +87,6 @@ func IsMySQLError(err error) bool {
if err == nil {
return false
}
_, ok := err.(*mysql.MySQLError)
return ok
var mysqlErr *mysql.MySQLError
return errors.As(err, &mysqlErr)
}

View File

@@ -0,0 +1,39 @@
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package models_test
import (
"errors"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/iwind/TeaGo/assert"
"github.com/iwind/TeaGo/dbs"
"testing"
)
func TestIsMySQLError(t *testing.T) {
var a = assert.NewAssertion(t)
{
var err error
a.IsFalse(models.IsMySQLError(err))
}
{
var err = errors.New("hello")
a.IsFalse(models.IsMySQLError(err))
}
{
db, err := dbs.Default()
if err != nil {
t.Fatal(err)
}
defer func() {
_ = db.Close()
}()
_, err = db.Exec("SELECT abc")
a.IsTrue(models.IsMySQLError(err))
a.IsTrue(models.CheckSQLErrCode(err, 1054))
a.IsFalse(models.CheckSQLErrCode(err, 1000))
}
}

View File

@@ -0,0 +1,39 @@
# 实例
## 目录结构:
~~~
/opt/cache
/usr/local/goedge/
edge-admin/
configs/
api_admin.yaml
api_db.yaml
server.yaml
edge-api/
configs/api.yaml
configs/db.yaml
api-node/
configs/api_node.yaml
api-user/
configs/api_user.yaml
src/
/usr/bin/
edge-admin -> ...
edge-api -> ...
edge-node -> ...
edge-user -> ...
/usr/local/mysql
~~~
* 其中 `->` 表示软链接。
* `src/` 目录下放置zip格式的待安装压缩包
## 端口
* Admin7788
* API8001
* API HTTP8002
* User: 7799
* Server: 8080
## 数据库
数据库名称为 `edges`

View File

@@ -0,0 +1,16 @@
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package instances
import "gopkg.in/yaml.v3"
type APIConfig struct {
RPCEndpoints []string `yaml:"rpc.endpoints,flow,omitempty" json:"rpc.endpoints"`
RPCDisableUpdate bool `yaml:"rpc.disableUpdate,omitempty" json:"rpc.disableUpdate"`
NodeId string `yaml:"nodeId" json:"nodeId"`
Secret string `yaml:"secret" json:"secret"`
}
func (this *APIConfig) AsYAML() ([]byte, error) {
return yaml.Marshal(this)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package instances_test
import (
"github.com/TeaOSLab/EdgeAPI/internal/instances"
"github.com/iwind/TeaGo/Tea"
_ "github.com/iwind/TeaGo/bootstrap"
"testing"
)
var instance = instances.NewInstance(instances.Options{
Cacheable: true,
WorkDir: Tea.Root + "/standalone-instance",
SrcDir: Tea.Root + "/standalone-instance/src",
DB: struct {
Host string
Port int
Username string
Password string
Name string
}{
Host: "127.0.0.1",
Port: 3306,
Username: "root",
Password: "123456",
Name: "edges2",
},
AdminNode: struct {
Port int
}{
Port: 7788,
},
APINode: struct {
HTTPPort int
RestHTTPPort int
}{
HTTPPort: 8001,
RestHTTPPort: 8002,
},
Node: struct{ HTTPPort int }{
HTTPPort: 8080,
},
UserNode: struct {
HTTPPort int
}{
HTTPPort: 7799,
},
})
func TestInstanceSetupAll(t *testing.T) {
err := instance.SetupAll()
if err != nil {
t.Fatal(err)
}
}
func TestInstance_SetupDB(t *testing.T) {
err := instance.SetupDB()
if err != nil {
t.Fatal(err)
}
}
func TestInstance_SetupAdminNode(t *testing.T) {
err := instance.SetupAdminNode()
if err != nil {
t.Fatal(err)
}
}
func TestInstance_SetupAPINode(t *testing.T) {
err := instance.SetupAPINode()
if err != nil {
t.Fatal(err)
}
}
func TestInstance_SetupUserNode(t *testing.T) {
err := instance.SetupUserNode()
if err != nil {
t.Fatal(err)
}
}
func TestInstance_SetupNode(t *testing.T) {
err := instance.SetupNode()
if err != nil {
t.Fatal(err)
}
}
func TestInstance_Clean(t *testing.T) {
err := instance.Clean()
if err != nil {
t.Fatal(err)
}
}

View File

@@ -0,0 +1,32 @@
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package instances
type Options struct {
IsTesting bool
Verbose bool
Cacheable bool
WorkDir string
SrcDir string
DB struct {
Host string
Port int
Username string
Password string
Name string
}
AdminNode struct {
Port int
}
APINode struct {
HTTPPort int
RestHTTPPort int
}
Node struct {
HTTPPort int
}
UserNode struct {
HTTPPort int
}
}