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  }