github.com/TeaOSLab/EdgeNode@v1.3.8/internal/nodes/system_services.go (about) 1 package nodes 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "errors" 7 "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" 8 teaconst "github.com/TeaOSLab/EdgeNode/internal/const" 9 "github.com/TeaOSLab/EdgeNode/internal/events" 10 "github.com/TeaOSLab/EdgeNode/internal/goman" 11 "github.com/TeaOSLab/EdgeNode/internal/remotelogs" 12 "github.com/TeaOSLab/EdgeNode/internal/utils" 13 executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" 14 "github.com/iwind/TeaGo/maps" 15 "os" 16 "runtime" 17 "time" 18 ) 19 20 func init() { 21 if !teaconst.IsMain { 22 return 23 } 24 25 var manager = NewSystemServiceManager() 26 events.On(events.EventReload, func() { 27 goman.New(func() { 28 err := manager.Setup() 29 if err != nil { 30 remotelogs.Error("SYSTEM_SERVICE", "setup system services failed: "+err.Error()) 31 } 32 }) 33 }) 34 } 35 36 // SystemServiceManager 系统服务管理 37 type SystemServiceManager struct { 38 lastIsOn int // -1, 0, 1 39 } 40 41 func NewSystemServiceManager() *SystemServiceManager { 42 return &SystemServiceManager{} 43 } 44 45 func (this *SystemServiceManager) Setup() error { 46 if sharedNodeConfig == nil || !sharedNodeConfig.IsOn { 47 return nil 48 } 49 50 if len(sharedNodeConfig.SystemServices) == 0 { 51 return nil 52 } 53 54 systemdParams, ok := sharedNodeConfig.SystemServices[nodeconfigs.SystemServiceTypeSystemd] 55 if ok { 56 err := this.setupSystemd(systemdParams) 57 if err != nil { 58 return err 59 } 60 } 61 62 return nil 63 } 64 65 func (this *SystemServiceManager) setupSystemd(params maps.Map) error { 66 // 只有在Linux下运行 67 if runtime.GOOS != "linux" { 68 return nil 69 } 70 71 if params == nil { 72 params = maps.Map{} 73 } 74 data, err := json.Marshal(params) 75 if err != nil { 76 return err 77 } 78 79 var config = &nodeconfigs.SystemdServiceConfig{} 80 err = json.Unmarshal(data, config) 81 if err != nil { 82 return err 83 } 84 85 // 检查当前的service 86 systemctl, err := executils.LookPath("systemctl") 87 if err != nil { 88 return err 89 } 90 if len(systemctl) == 0 { 91 return errors.New("can not find 'systemctl' on the system") 92 } 93 94 // 记录上次状态 95 var isOnInt int 96 if config.IsOn { 97 isOnInt = 1 98 } else { 99 isOnInt = 0 100 } 101 102 if this.lastIsOn == isOnInt { 103 return nil 104 } 105 defer func() { 106 this.lastIsOn = isOnInt 107 }() 108 109 var shortName = teaconst.SystemdServiceName 110 var cmd = executils.NewTimeoutCmd(10*time.Second, systemctl, "is-enabled", shortName) 111 cmd.WithStdout() 112 err = cmd.Run() 113 var hasInstalled = err == nil 114 if config.IsOn { 115 exe, err := os.Executable() 116 if err != nil { 117 return err 118 } 119 120 // 检查文件路径是否变化 121 if hasInstalled && cmd.Stdout() == "enabled" { 122 data, err := os.ReadFile("/etc/systemd/system/" + teaconst.SystemdServiceName + ".service") 123 if err == nil && bytes.Index(data, []byte(exe)) > 0 { 124 return nil 125 } 126 } 127 128 // 安装服务 129 var manager = utils.NewServiceManager(shortName, teaconst.ProductName) 130 err = manager.Install(exe, []string{}) 131 if err != nil { 132 return err 133 } 134 135 // 启动服务 136 goman.New(func() { 137 time.Sleep(5 * time.Second) 138 _ = executils.NewTimeoutCmd(30*time.Second, systemctl, "start", teaconst.SystemdServiceName).Start() 139 }) 140 } else { 141 if hasInstalled { 142 var manager = utils.NewServiceManager(shortName, teaconst.ProductName) 143 err = manager.Uninstall() 144 if err != nil { 145 return err 146 } 147 } 148 } 149 150 return nil 151 }