mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	启动的时候尝试从备份文件中恢复配置
This commit is contained in:
		
							
								
								
									
										2
									
								
								build/configs/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								build/configs/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,4 +1,4 @@
 | 
				
			|||||||
server.yaml
 | 
					server.yaml
 | 
				
			||||||
api_db.yaml
 | 
					api_db.yaml
 | 
				
			||||||
api.yaml
 | 
					api-123.yaml
 | 
				
			||||||
*.pem
 | 
					*.pem
 | 
				
			||||||
							
								
								
									
										6
									
								
								build/configs/api.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								build/configs/api.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					rpc:
 | 
				
			||||||
 | 
					  endpoints:
 | 
				
			||||||
 | 
					  - http://192.168.2.40:8003
 | 
				
			||||||
 | 
					nodeId: H6sjDf779jimnVPnBFSgZxvr6Ca0wQ0z
 | 
				
			||||||
 | 
					secret: hMHjmEng0SIcT3yiA3HIoUjogwAC9cur
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1,9 +1,12 @@
 | 
				
			|||||||
package configs
 | 
					package configs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
 | 
				
			||||||
	"github.com/go-yaml/yaml"
 | 
						"github.com/go-yaml/yaml"
 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// API配置
 | 
					// API配置
 | 
				
			||||||
@@ -17,7 +20,26 @@ type APIConfig struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 加载API配置
 | 
					// 加载API配置
 | 
				
			||||||
func LoadAPIConfig() (*APIConfig, error) {
 | 
					func LoadAPIConfig() (*APIConfig, error) {
 | 
				
			||||||
	data, err := ioutil.ReadFile(Tea.ConfigFile("api.yaml"))
 | 
						// 候选文件
 | 
				
			||||||
 | 
						localFile := Tea.ConfigFile("api.yaml")
 | 
				
			||||||
 | 
						isFromLocal := false
 | 
				
			||||||
 | 
						paths := []string{localFile}
 | 
				
			||||||
 | 
						homeDir, err := os.UserHomeDir()
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							paths = append(paths, homeDir+"/."+teaconst.ProcessName+"/api.yaml")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						paths = append(paths, "/etc/"+teaconst.ProcessName+"/api.yaml")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var data []byte
 | 
				
			||||||
 | 
						for _, path := range paths {
 | 
				
			||||||
 | 
							data, err = ioutil.ReadFile(path)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								if path == localFile {
 | 
				
			||||||
 | 
									isFromLocal = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -28,6 +50,11 @@ func LoadAPIConfig() (*APIConfig, error) {
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !isFromLocal {
 | 
				
			||||||
 | 
							// 恢复文件
 | 
				
			||||||
 | 
							_ = ioutil.WriteFile(localFile, data, 0666)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return config, nil
 | 
						return config, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -37,5 +64,38 @@ func (this *APIConfig) WriteFile(path string) error {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ioutil.WriteFile(path, data, 0666)
 | 
						err = ioutil.WriteFile(path, data, 0666)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 写入 ~/ 和 /etc/ 目录,因为是备份需要,所以不需要提示错误信息
 | 
				
			||||||
 | 
						// 写入 ~/.edge-admin/
 | 
				
			||||||
 | 
						filename := filepath.Base(path)
 | 
				
			||||||
 | 
						homeDir, err := os.UserHomeDir()
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							dir := homeDir + "/." + teaconst.ProcessName
 | 
				
			||||||
 | 
							stat, err := os.Stat(dir)
 | 
				
			||||||
 | 
							if err == nil && stat.IsDir() {
 | 
				
			||||||
 | 
								_ = ioutil.WriteFile(dir+"/"+filename, data, 0666)
 | 
				
			||||||
 | 
							} else if err != nil && os.IsNotExist(err) {
 | 
				
			||||||
 | 
								err = os.Mkdir(dir, 0777)
 | 
				
			||||||
 | 
								if err == nil {
 | 
				
			||||||
 | 
									_ = ioutil.WriteFile(dir+"/"+filename, data, 0666)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 写入 /etc/.edge-admin
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							dir := "/etc/" + teaconst.ProcessName
 | 
				
			||||||
 | 
							stat, err := os.Stat(dir)
 | 
				
			||||||
 | 
							if err == nil && stat.IsDir() {
 | 
				
			||||||
 | 
								_ = ioutil.WriteFile(dir+"/"+filename, data, 0666)
 | 
				
			||||||
 | 
							} else if err != nil && os.IsNotExist(err) {
 | 
				
			||||||
 | 
								err = os.Mkdir(dir, 0777)
 | 
				
			||||||
 | 
								if err == nil {
 | 
				
			||||||
 | 
									_ = ioutil.WriteFile(dir+"/"+filename, data, 0666)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,3 +12,18 @@ func TestLoadAPIConfig(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	t.Log(config)
 | 
						t.Log(config)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestAPIConfig_WriteFile(t *testing.T) {
 | 
				
			||||||
 | 
						config := &APIConfig{
 | 
				
			||||||
 | 
							RPC: struct {
 | 
				
			||||||
 | 
								Endpoints []string `yaml:"endpoints"`
 | 
				
			||||||
 | 
							}{},
 | 
				
			||||||
 | 
							NodeId: "1",
 | 
				
			||||||
 | 
							Secret: "2",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := config.WriteFile("/tmp/api_config.yaml")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,8 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var SharedAdminNode *AdminNode = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AdminNode struct {
 | 
					type AdminNode struct {
 | 
				
			||||||
	subPIDs []int
 | 
						subPIDs []int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -31,6 +33,8 @@ func NewAdminNode() *AdminNode {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *AdminNode) Run() {
 | 
					func (this *AdminNode) Run() {
 | 
				
			||||||
 | 
						SharedAdminNode = this
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 启动管理界面
 | 
						// 启动管理界面
 | 
				
			||||||
	secret := this.genSecret()
 | 
						secret := this.genSecret()
 | 
				
			||||||
	configs.Secret = secret
 | 
						configs.Secret = secret
 | 
				
			||||||
@@ -145,6 +149,11 @@ func (this *AdminNode) InstallSystemService() error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 添加子PID
 | 
				
			||||||
 | 
					func (this *AdminNode) AddSubPID(pid int) {
 | 
				
			||||||
 | 
						this.subPIDs = append(this.subPIDs, pid)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 检查Server配置
 | 
					// 检查Server配置
 | 
				
			||||||
func (this *AdminNode) checkServer() error {
 | 
					func (this *AdminNode) checkServer() error {
 | 
				
			||||||
	configFile := Tea.ConfigFile("server.yaml")
 | 
						configFile := Tea.ConfigFile("server.yaml")
 | 
				
			||||||
@@ -192,8 +201,61 @@ https:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 启动API节点
 | 
					// 启动API节点
 | 
				
			||||||
func (this *AdminNode) startAPINode() {
 | 
					func (this *AdminNode) startAPINode() {
 | 
				
			||||||
	_, err := os.Stat(Tea.Root + "/edge-api/configs/api.yaml")
 | 
						configPath := Tea.Root + "/edge-api/configs/api.yaml"
 | 
				
			||||||
 | 
						_, err := os.Stat(configPath)
 | 
				
			||||||
 | 
						canStart := false
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
 | 
							canStart = true
 | 
				
			||||||
 | 
						} else if err != nil && os.IsNotExist(err) {
 | 
				
			||||||
 | 
							// 尝试恢复api.yaml
 | 
				
			||||||
 | 
							homeDir, _ := os.UserHomeDir()
 | 
				
			||||||
 | 
							paths := []string{}
 | 
				
			||||||
 | 
							if len(homeDir) > 0 {
 | 
				
			||||||
 | 
								paths = append(paths, homeDir+"/.edge-api/api.yaml")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							paths = append(paths, "/etc/edge-api/api.yaml")
 | 
				
			||||||
 | 
							for _, path := range paths {
 | 
				
			||||||
 | 
								_, err = os.Stat(path)
 | 
				
			||||||
 | 
								if err == nil {
 | 
				
			||||||
 | 
									data, err := ioutil.ReadFile(path)
 | 
				
			||||||
 | 
									if err == nil {
 | 
				
			||||||
 | 
										err = ioutil.WriteFile(configPath, data, 0666)
 | 
				
			||||||
 | 
										if err == nil {
 | 
				
			||||||
 | 
											logs.Println("[NODE]recover 'edge-api/configs/api.yaml' from '" + path + "'")
 | 
				
			||||||
 | 
											canStart = true
 | 
				
			||||||
 | 
											break
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dbPath := Tea.Root + "/edge-api/configs/db.yaml"
 | 
				
			||||||
 | 
						_, err = os.Stat(dbPath)
 | 
				
			||||||
 | 
						if err != nil && os.IsNotExist(err) {
 | 
				
			||||||
 | 
							// 尝试恢复db.yaml
 | 
				
			||||||
 | 
							homeDir, _ := os.UserHomeDir()
 | 
				
			||||||
 | 
							paths := []string{}
 | 
				
			||||||
 | 
							if len(homeDir) > 0 {
 | 
				
			||||||
 | 
								paths = append(paths, homeDir+"/.edge-api/db.yaml")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							paths = append(paths, "/etc/edge-api/db.yaml")
 | 
				
			||||||
 | 
							for _, path := range paths {
 | 
				
			||||||
 | 
								_, err = os.Stat(path)
 | 
				
			||||||
 | 
								if err == nil {
 | 
				
			||||||
 | 
									data, err := ioutil.ReadFile(path)
 | 
				
			||||||
 | 
									if err == nil {
 | 
				
			||||||
 | 
										err = ioutil.WriteFile(dbPath, data, 0666)
 | 
				
			||||||
 | 
										if err == nil {
 | 
				
			||||||
 | 
											logs.Println("[NODE]recover 'edge-api/configs/db.yaml' from '" + path + "'")
 | 
				
			||||||
 | 
											break
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if canStart {
 | 
				
			||||||
		logs.Println("start edge-api")
 | 
							logs.Println("start edge-api")
 | 
				
			||||||
		cmd := exec.Command(Tea.Root + "/edge-api/bin/edge-api")
 | 
							cmd := exec.Command(Tea.Root + "/edge-api/bin/edge-api")
 | 
				
			||||||
		err = cmd.Start()
 | 
							err = cmd.Start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/configs"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/configs"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/nodes"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
@@ -91,11 +92,46 @@ func (this *InstallAction) RunPost(params struct {
 | 
				
			|||||||
			this.Fail("保存数据库配置失败:" + err.Error())
 | 
								this.Fail("保存数据库配置失败:" + err.Error())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 生成备份文件
 | 
				
			||||||
 | 
							homeDir, _ := os.UserHomeDir()
 | 
				
			||||||
 | 
							backupDirs := []string{"/etc/edge-api"}
 | 
				
			||||||
 | 
							if len(homeDir) > 0 {
 | 
				
			||||||
 | 
								backupDirs = append(backupDirs, homeDir+"/.edge-api")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, backupDir := range backupDirs {
 | 
				
			||||||
 | 
								stat, err := os.Stat(backupDir)
 | 
				
			||||||
 | 
								if err == nil && stat.IsDir() {
 | 
				
			||||||
 | 
									_ = ioutil.WriteFile(backupDir+"/db.yaml", dbConfigData, 0666)
 | 
				
			||||||
 | 
								} else if err != nil && os.IsNotExist(err) {
 | 
				
			||||||
 | 
									err = os.Mkdir(backupDir, 0777)
 | 
				
			||||||
 | 
									if err == nil {
 | 
				
			||||||
 | 
										_ = ioutil.WriteFile(backupDir+"/db.yaml", dbConfigData, 0666)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err = ioutil.WriteFile(Tea.ConfigFile("/api_db.yaml"), dbConfigData, 0666)
 | 
							err = ioutil.WriteFile(Tea.ConfigFile("/api_db.yaml"), dbConfigData, 0666)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			this.Fail("保存数据库配置失败:" + err.Error())
 | 
								this.Fail("保存数据库配置失败:" + err.Error())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 生成备份文件
 | 
				
			||||||
 | 
							backupDirs = []string{"/etc/edge-admin"}
 | 
				
			||||||
 | 
							if len(homeDir) > 0 {
 | 
				
			||||||
 | 
								backupDirs = append(backupDirs, homeDir+"/.edge-admin")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, backupDir := range backupDirs {
 | 
				
			||||||
 | 
								stat, err := os.Stat(backupDir)
 | 
				
			||||||
 | 
								if err == nil && stat.IsDir() {
 | 
				
			||||||
 | 
									_ = ioutil.WriteFile(backupDir+"/api_db.yaml", dbConfigData, 0666)
 | 
				
			||||||
 | 
								} else if err != nil && os.IsNotExist(err) {
 | 
				
			||||||
 | 
									err = os.Mkdir(backupDir, 0777)
 | 
				
			||||||
 | 
									if err == nil {
 | 
				
			||||||
 | 
										_ = ioutil.WriteFile(backupDir+"/api_db.yaml", dbConfigData, 0666)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// 开始安装
 | 
							// 开始安装
 | 
				
			||||||
		var resultMap = maps.Map{}
 | 
							var resultMap = maps.Map{}
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -125,6 +161,9 @@ func (this *InstallAction) RunPost(params struct {
 | 
				
			|||||||
				this.Fail("API节点启动失败:" + err.Error())
 | 
									this.Fail("API节点启动失败:" + err.Error())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// 记录子PID方便退出的时候一起退出
 | 
				
			||||||
 | 
								nodes.SharedAdminNode.AddSubPID(cmd.Process.Pid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// 等待API节点初始化完成
 | 
								// 等待API节点初始化完成
 | 
				
			||||||
			time.Sleep(2 * time.Second)
 | 
								time.Sleep(2 * time.Second)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user