gitee.com/quant1x/gox@v1.21.2/daemon/daemon_linux_upstart.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by
     3  // license that can be found in the LICENSE file.
     4  
     5  package daemon
     6  
     7  import (
     8  	"os"
     9  	"os/exec"
    10  	"regexp"
    11  	"strings"
    12  	"text/template"
    13  )
    14  
    15  // upstartRecord - standard record (struct) for linux upstart version of daemon package
    16  type upstartRecord struct {
    17  	name         string
    18  	description  string
    19  	kind         Kind
    20  	dependencies []string
    21  }
    22  
    23  // Standard service path for systemV daemons
    24  func (linux *upstartRecord) servicePath() string {
    25  	return "/etc/init/" + linux.name + ".conf"
    26  }
    27  
    28  // Is a service installed
    29  func (linux *upstartRecord) isInstalled() bool {
    30  
    31  	if _, err := os.Stat(linux.servicePath()); err == nil {
    32  		return true
    33  	}
    34  
    35  	return false
    36  }
    37  
    38  // Check service is running
    39  func (linux *upstartRecord) checkRunning() (string, bool) {
    40  	output, err := exec.Command("status", linux.name).Output()
    41  	if err == nil {
    42  		if matched, err := regexp.MatchString(linux.name+" start/running", string(output)); err == nil && matched {
    43  			reg := regexp.MustCompile("process ([0-9]+)")
    44  			data := reg.FindStringSubmatch(string(output))
    45  			if len(data) > 1 {
    46  				return "Service (pid  " + data[1] + ") is running...", true
    47  			}
    48  			return "Service is running...", true
    49  		}
    50  	}
    51  
    52  	return "Service is stopped", false
    53  }
    54  
    55  // Install the service
    56  func (linux *upstartRecord) Install(args ...string) (string, error) {
    57  	installAction := "Install " + linux.description + ":"
    58  
    59  	if ok, err := checkPrivileges(); !ok {
    60  		return installAction + failed, err
    61  	}
    62  
    63  	srvPath := linux.servicePath()
    64  
    65  	if linux.isInstalled() {
    66  		return installAction + failed, ErrAlreadyInstalled
    67  	}
    68  
    69  	file, err := os.Create(srvPath)
    70  	if err != nil {
    71  		return installAction + failed, err
    72  	}
    73  	defer file.Close()
    74  
    75  	execPatch, err := executablePath(linux.name)
    76  	if err != nil {
    77  		return installAction + failed, err
    78  	}
    79  
    80  	templ, err := template.New("upstatConfig").Parse(upstatConfig)
    81  	if err != nil {
    82  		return installAction + failed, err
    83  	}
    84  
    85  	if err := templ.Execute(
    86  		file,
    87  		&struct {
    88  			Name, Description, Path, Args string
    89  		}{linux.name, linux.description, execPatch, strings.Join(args, " ")},
    90  	); err != nil {
    91  		return installAction + failed, err
    92  	}
    93  
    94  	if err := os.Chmod(srvPath, 0755); err != nil {
    95  		return installAction + failed, err
    96  	}
    97  
    98  	return installAction + success, nil
    99  }
   100  
   101  // Remove the service
   102  func (linux *upstartRecord) Remove() (string, error) {
   103  	removeAction := "Removing " + linux.description + ":"
   104  
   105  	if ok, err := checkPrivileges(); !ok {
   106  		return removeAction + failed, err
   107  	}
   108  
   109  	if !linux.isInstalled() {
   110  		return removeAction + failed, ErrNotInstalled
   111  	}
   112  
   113  	if err := os.Remove(linux.servicePath()); err != nil {
   114  		return removeAction + failed, err
   115  	}
   116  
   117  	return removeAction + success, nil
   118  }
   119  
   120  // Start the service
   121  func (linux *upstartRecord) Start() (string, error) {
   122  	startAction := "Starting " + linux.description + ":"
   123  
   124  	if ok, err := checkPrivileges(); !ok {
   125  		return startAction + failed, err
   126  	}
   127  
   128  	if !linux.isInstalled() {
   129  		return startAction + failed, ErrNotInstalled
   130  	}
   131  
   132  	if _, ok := linux.checkRunning(); ok {
   133  		return startAction + failed, ErrAlreadyRunning
   134  	}
   135  
   136  	if err := exec.Command("start", linux.name).Run(); err != nil {
   137  		return startAction + failed, err
   138  	}
   139  
   140  	return startAction + success, nil
   141  }
   142  
   143  // Stop the service
   144  func (linux *upstartRecord) Stop() (string, error) {
   145  	stopAction := "Stopping " + linux.description + ":"
   146  
   147  	if ok, err := checkPrivileges(); !ok {
   148  		return stopAction + failed, err
   149  	}
   150  
   151  	if !linux.isInstalled() {
   152  		return stopAction + failed, ErrNotInstalled
   153  	}
   154  
   155  	if _, ok := linux.checkRunning(); !ok {
   156  		return stopAction + failed, ErrAlreadyStopped
   157  	}
   158  
   159  	if err := exec.Command("stop", linux.name).Run(); err != nil {
   160  		return stopAction + failed, err
   161  	}
   162  
   163  	return stopAction + success, nil
   164  }
   165  
   166  // Status - Get service status
   167  func (linux *upstartRecord) Status() (string, error) {
   168  
   169  	if ok, err := checkPrivileges(); !ok {
   170  		return "", err
   171  	}
   172  
   173  	if !linux.isInstalled() {
   174  		return statNotInstalled, ErrNotInstalled
   175  	}
   176  
   177  	statusAction, _ := linux.checkRunning()
   178  
   179  	return statusAction, nil
   180  }
   181  
   182  // Run - Run service
   183  func (linux *upstartRecord) Run(e Executable) (string, error) {
   184  	runAction := "Running " + linux.description + ":"
   185  	e.Run()
   186  	return runAction + " completed.", nil
   187  }
   188  
   189  // GetTemplate - gets service config template
   190  func (linux *upstartRecord) GetTemplate() string {
   191  	return upstatConfig
   192  }
   193  
   194  // SetTemplate - sets service config template
   195  func (linux *upstartRecord) SetTemplate(tplStr string) error {
   196  	upstatConfig = tplStr
   197  	return nil
   198  }
   199  
   200  var upstatConfig = `# {{.Name}} {{.Description}}
   201  
   202  description     "{{.Description}}"
   203  author          "Pichu Chen <pichu@tih.tw>"
   204  
   205  start on runlevel [2345]
   206  stop on runlevel [016]
   207  
   208  respawn
   209  #kill timeout 5
   210  
   211  exec {{.Path}} {{.Args}} >> /var/log/{{.Name}}.log 2>> /var/log/{{.Name}}.err
   212  `