mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-11 01:36:37 +08:00
实现代理节点功能,包括主程序入口、配置加载、心跳检测和状态管理,添加相关服务和API响应结构
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package nginx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type Executor interface {
|
||||
Test(ctx context.Context) error
|
||||
Reload(ctx context.Context) error
|
||||
}
|
||||
|
||||
type ShellExecutor struct {
|
||||
Binary string
|
||||
}
|
||||
|
||||
func (e *ShellExecutor) Test(ctx context.Context) error {
|
||||
cmd := exec.CommandContext(ctx, e.Binary, "-t")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("nginx -t failed: %w: %s", err, string(output))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *ShellExecutor) Reload(ctx context.Context) error {
|
||||
cmd := exec.CommandContext(ctx, e.Binary, "-s", "reload")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("nginx reload failed: %w: %s", err, string(output))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
RouteConfigPath string
|
||||
Executor Executor
|
||||
}
|
||||
|
||||
func (m *Manager) Apply(ctx context.Context, content string) error {
|
||||
backupPath, hadExisting, err := m.backup()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = os.WriteFile(m.RouteConfigPath, []byte(content), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = m.Executor.Test(ctx); err != nil {
|
||||
_ = m.restore(backupPath, hadExisting)
|
||||
return err
|
||||
}
|
||||
if err = m.Executor.Reload(ctx); err != nil {
|
||||
_ = m.restore(backupPath, hadExisting)
|
||||
return err
|
||||
}
|
||||
if backupPath != "" {
|
||||
_ = os.Remove(backupPath)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) backup() (string, bool, error) {
|
||||
if m.RouteConfigPath == "" {
|
||||
return "", false, errors.New("route config path 不能为空")
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(m.RouteConfigPath), 0o755); err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
data, err := os.ReadFile(m.RouteConfigPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return "", false, nil
|
||||
}
|
||||
return "", false, err
|
||||
}
|
||||
backupPath := m.RouteConfigPath + ".bak"
|
||||
if err = os.WriteFile(backupPath, data, 0o644); err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
return backupPath, true, nil
|
||||
}
|
||||
|
||||
func (m *Manager) restore(backupPath string, hadExisting bool) error {
|
||||
if hadExisting {
|
||||
data, err := os.ReadFile(backupPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(m.RouteConfigPath, data, 0o644)
|
||||
}
|
||||
if err := os.Remove(m.RouteConfigPath); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user