github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zutil/daemon/daemon.go (about) 1 // Package daemon program is installed as a system service to achieve process daemon 2 package daemon 3 4 import ( 5 "context" 6 "errors" 7 ) 8 9 const ( 10 optionKeepAlive = "KeepAlive" 11 optionKeepAliveDefault = true 12 optionRunAtLoad = "RunAtLoad" 13 optionRunAtLoadDefault = true 14 optionUserService = "UserService" 15 optionUserServiceDefault = false 16 optionSessionCreate = "SessionCreate" 17 optionSessionCreateDefault = false 18 optionRunWait = "RunWait" 19 ) 20 21 type ( 22 // ServiceIface represents a service that can be run or controlled 23 ServiceIface interface { 24 Run() error 25 Start() error 26 Stop() error 27 Restart() error 28 Install() error 29 Uninstall() error 30 Status() string 31 String() string 32 } 33 Iface interface { 34 Start(s ServiceIface) error 35 Stop(s ServiceIface) error 36 } 37 SystemIface interface { 38 String() string 39 Interactive() bool 40 Detect() bool 41 New(i Iface, c *Config) (ServiceIface, error) 42 } 43 // Config provides the setup for a ServiceIface. The Name field is required. 44 Config struct { 45 Options map[string]interface{} 46 Name string 47 DisplayName string 48 Description string 49 UserName string 50 Executable string 51 WorkingDir string 52 RootDir string 53 Arguments []string 54 Context context.Context 55 } 56 ) 57 58 var ( 59 system SystemIface 60 systemRegistry []SystemIface 61 ErrNameFieldRequired = errors.New("config.name field is required") 62 ErrNoServiceSystemDetected = errors.New("no service system detected") 63 ErrNotAnRootUser = errors.New("need to execute with sudo permission") 64 ErrNotAnAdministrator = errors.New("please operate with administrator rights") 65 ) 66 67 // New creates a new service based on a service interface and configuration 68 func New(i Iface, c *Config) (ServiceIface, error) { 69 if len(c.Name) == 0 { 70 return nil, ErrNameFieldRequired 71 } 72 if system == nil { 73 return nil, ErrNoServiceSystemDetected 74 } 75 return system.New(i, c) 76 } 77 78 func newSystem() SystemIface { 79 for _, choice := range systemRegistry { 80 if !choice.Detect() { 81 continue 82 } 83 return choice 84 } 85 return nil 86 } 87 88 func chooseSystem(a ...SystemIface) { 89 systemRegistry = a 90 system = newSystem() 91 }