From 702311f3fbd52497cce00b861651f0ca3a7eb894 Mon Sep 17 00:00:00 2001 From: Erkan Durmus Date: Fri, 4 May 2018 17:14:14 +0300 Subject: [PATCH 1/9] added support to update service template --- README.md | 9 +++++++++ daemon.go | 5 +++++ daemon_darwin.go | 11 +++++++++++ daemon_freebsd.go | 11 +++++++++++ daemon_linux_systemd.go | 11 +++++++++++ daemon_linux_systemv.go | 11 +++++++++++ daemon_linux_upstart.go | 11 +++++++++++ daemon_windows.go | 14 ++++++++++++-- 8 files changed, 81 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9c24e9f..f1fc3a5 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,15 @@ func main() { } ``` +### Service config file + +Service config file can be retrieved or updated by calling +`GetTemplate() string` and `SetTemplate(string)` methods(except MS +Windows). Template will be a default Go Template(`"text/template"`). + +If `SetTemplate` is not called, default template content will be used +while creating service. + ### Cron example See `examples/cron/cron_job.go` diff --git a/daemon.go b/daemon.go index 45f69a4..73011c3 100644 --- a/daemon.go +++ b/daemon.go @@ -159,6 +159,11 @@ import "strings" // Daemon interface has a standard set of methods/commands type Daemon interface { + // GetTemplate - gets service config template + GetTemplate() string + + // SetTemplate - sets service config template + SetTemplate(string) error // Install the service into the system Install(args ...string) (string, error) diff --git a/daemon_darwin.go b/daemon_darwin.go index e639f3c..8443a80 100644 --- a/daemon_darwin.go +++ b/daemon_darwin.go @@ -193,6 +193,17 @@ func (darwin *darwinRecord) Run(e Executable) (string, error) { return runAction + " completed.", nil } +// GetTemplate - gets service config template +func (linux *darwinRecord) GetTemplate() string { + return propertyList +} + +// SetTemplate - sets service config template +func (linux *darwinRecord) SetTemplate(tplStr string) error { + propertyList = tplStr + return nil +} + var propertyList = ` diff --git a/daemon_freebsd.go b/daemon_freebsd.go index 5bf6403..18ff209 100644 --- a/daemon_freebsd.go +++ b/daemon_freebsd.go @@ -234,6 +234,17 @@ func (bsd *bsdRecord) Run(e Executable) (string, error) { return runAction + " completed.", nil } +// GetTemplate - gets service config template +func (linux *bsdRecord) GetTemplate() string { + return bsdConfig +} + +// SetTemplate - sets service config template +func (linux *bsdRecord) SetTemplate(tplStr string) error { + bsdConfig = tplStr + return nil +} + var bsdConfig = `#!/bin/sh # # PROVIDE: {{.Name}} diff --git a/daemon_linux_systemd.go b/daemon_linux_systemd.go index bfd928b..2021ba4 100644 --- a/daemon_linux_systemd.go +++ b/daemon_linux_systemd.go @@ -199,6 +199,17 @@ func (linux *systemDRecord) Run(e Executable) (string, error) { return runAction + " completed.", nil } +// GetTemplate - gets service config template +func (linux *systemDRecord) GetTemplate() string { + return systemDConfig +} + +// SetTemplate - sets service config template +func (linux *systemDRecord) SetTemplate(tplStr string) error { + systemDConfig = tplStr + return nil +} + var systemDConfig = `[Unit] Description={{.Description}} Requires={{.Dependencies}} diff --git a/daemon_linux_systemv.go b/daemon_linux_systemv.go index ba2d158..a8e3f1c 100644 --- a/daemon_linux_systemv.go +++ b/daemon_linux_systemv.go @@ -207,6 +207,17 @@ func (linux *systemVRecord) Run(e Executable) (string, error) { return runAction + " completed.", nil } +// GetTemplate - gets service config template +func (linux *systemVRecord) GetTemplate() string { + return systemVConfig +} + +// SetTemplate - sets service config template +func (linux *systemVRecord) SetTemplate(tplStr string) error { + systemVConfig = tplStr + return nil +} + var systemVConfig = `#! /bin/sh # # /etc/rc.d/init.d/{{.Name}} diff --git a/daemon_linux_upstart.go b/daemon_linux_upstart.go index b5f6728..2aa0a7f 100644 --- a/daemon_linux_upstart.go +++ b/daemon_linux_upstart.go @@ -185,6 +185,17 @@ func (linux *upstartRecord) Run(e Executable) (string, error) { return runAction + " completed.", nil } +// GetTemplate - gets service config template +func (linux *upstartRecord) GetTemplate() string { + return upstatConfig +} + +// SetTemplate - sets service config template +func (linux *upstartRecord) SetTemplate(tplStr string) error { + upstatConfig = tplStr + return nil +} + var upstatConfig = `# {{.Name}} {{.Description}} description "{{.Description}}" diff --git a/daemon_windows.go b/daemon_windows.go index 1ed5e86..5b50900 100644 --- a/daemon_windows.go +++ b/daemon_windows.go @@ -254,7 +254,7 @@ type serviceHandler struct { executable Executable } -func (sh *serviceHandler) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) { +func (sh *serviceHandler) Execute(args []string, r <-chan svc.ChangeRequest, changes chan <- svc.Status) (ssec bool, errno uint32) { const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue changes <- svc.Status{State: svc.StartPending} @@ -265,7 +265,7 @@ func (sh *serviceHandler) Execute(args []string, r <-chan svc.ChangeRequest, cha sh.executable.Start() changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} -loop: + loop: for { select { case <-tick: @@ -318,3 +318,13 @@ func (windows *windowsRecord) Run(e Executable) (string, error) { return runAction + " completed.", nil } + +// GetTemplate - gets service config template +func (linux *windowsRecord) GetTemplate() string { + return "" +} + +// SetTemplate - sets service config template +func (linux *windowsRecord) SetTemplate(tplStr string) error { + return errors.New(fmt.Sprintf("templating is not supported for windows")) +} \ No newline at end of file From 83a63fe2e8b6700ee2edbae128833b254e8f3ca7 Mon Sep 17 00:00:00 2001 From: Erkan Durmus Date: Fri, 4 May 2018 18:58:07 +0300 Subject: [PATCH 2/9] added template example --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f1fc3a5..8d7ad04 100644 --- a/README.md +++ b/README.md @@ -176,13 +176,39 @@ func main() { ### Service config file -Service config file can be retrieved or updated by calling +Optionally, service config file can be retrieved or updated by calling `GetTemplate() string` and `SetTemplate(string)` methods(except MS Windows). Template will be a default Go Template(`"text/template"`). If `SetTemplate` is not called, default template content will be used while creating service. +|Variable | Description| +|---------|------------| +|Description| Description for service | +|Dependencies|Service dependencies| +|Name|Service name| +|Path|Path of service executable| +|Args|Arguments for service executable| + +Example template(for linux systemv) + +```ini +[Unit] +Description={{.Description}} +Requires={{.Dependencies}} +After={{.Dependencies}} + +[Service] +PIDFile=/var/run/{{.Name}}.pid +ExecStartPre=/bin/rm -f /var/run/{{.Name}}.pid +ExecStart={{.Path}} {{.Args}} +Restart=on-failure + +[Install] +WantedBy=multi-user.target +``` + ### Cron example See `examples/cron/cron_job.go` From f352ab09b39d78ed49643480f21d0a435c9b0285 Mon Sep 17 00:00:00 2001 From: Erkan Durmus Date: Fri, 4 May 2018 18:59:57 +0300 Subject: [PATCH 3/9] added template example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d7ad04..abb8dda 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ while creating service. |Path|Path of service executable| |Args|Arguments for service executable| -Example template(for linux systemv) +#### Example template(for linux systemv) ```ini [Unit] From 1ff26e02e2dc4127376e11ad68237449170a27a5 Mon Sep 17 00:00:00 2001 From: Wenzhou Zhang Date: Fri, 6 Jul 2018 15:53:02 +0800 Subject: [PATCH 4/9] Fix: return ErrAlreadyRunning on existing windows service --- daemon_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon_windows.go b/daemon_windows.go index 1ed5e86..6e09c63 100644 --- a/daemon_windows.go +++ b/daemon_windows.go @@ -51,7 +51,7 @@ func (windows *windowsRecord) Install(args ...string) (string, error) { s, err := m.OpenService(windows.name) if err == nil { s.Close() - return installAction + failed, err + return installAction + failed, ErrAlreadyRunning } s, err = m.CreateService(windows.name, execp, mgr.Config{ From c04be40db151226497da01b41b4a0e83907f53ba Mon Sep 17 00:00:00 2001 From: Wenzhou Zhang Date: Thu, 12 Jul 2018 18:30:00 +0800 Subject: [PATCH 5/9] Add: set recovery action for windows service --- daemon_windows.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/daemon_windows.go b/daemon_windows.go index 6e09c63..c11709f 100644 --- a/daemon_windows.go +++ b/daemon_windows.go @@ -65,6 +65,30 @@ func (windows *windowsRecord) Install(args ...string) (string, error) { } defer s.Close() + // set recovery action for service + // restart after 5 seconds for the first 3 times + // restart after 1 minute, otherwise + r := []mgr.RecoveryAction{ + mgr.RecoveryAction{ + Type: mgr.ServiceRestart, + Delay: 5000 * time.Millisecond, + }, + mgr.RecoveryAction{ + Type: mgr.ServiceRestart, + Delay: 5000 * time.Millisecond, + }, + mgr.RecoveryAction{ + Type: mgr.ServiceRestart, + Delay: 5000 * time.Millisecond, + }, + mgr.RecoveryAction{ + Type: mgr.ServiceRestart, + Delay: 60000 * time.Millisecond, + }, + } + // set reset period as a day + s.SetRecoveryActions(r, uint32(86400)) + return installAction + " completed.", nil } From f447b7a7f6f9b9f39b07794d470d201b3a5484a2 Mon Sep 17 00:00:00 2001 From: Rustam Gilyazov <16064414+rusq@users.noreply.github.com> Date: Mon, 2 Mar 2020 23:03:16 +1300 Subject: [PATCH 6/9] #87 fix status message --- daemon.go | 5 +++++ daemon_darwin.go | 2 +- daemon_freebsd.go | 2 +- daemon_linux_systemd.go | 2 +- daemon_linux_systemv.go | 2 +- daemon_linux_upstart.go | 2 +- 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/daemon.go b/daemon.go index 45f69a4..17ded65 100644 --- a/daemon.go +++ b/daemon.go @@ -157,6 +157,11 @@ package daemon import "strings" +// Status literals +const ( + statNotInstalled = "Service not installed" +) + // Daemon interface has a standard set of methods/commands type Daemon interface { diff --git a/daemon_darwin.go b/daemon_darwin.go index e639f3c..8015b2d 100644 --- a/daemon_darwin.go +++ b/daemon_darwin.go @@ -178,7 +178,7 @@ func (darwin *darwinRecord) Status() (string, error) { } if !darwin.isInstalled() { - return "Status could not defined", ErrNotInstalled + return statNotInstalled, ErrNotInstalled } statusAction, _ := darwin.checkRunning() diff --git a/daemon_freebsd.go b/daemon_freebsd.go index 5bf6403..e3843bd 100644 --- a/daemon_freebsd.go +++ b/daemon_freebsd.go @@ -219,7 +219,7 @@ func (bsd *bsdRecord) Status() (string, error) { } if !bsd.isInstalled() { - return "Status could not defined", ErrNotInstalled + return statNotInstalled, ErrNotInstalled } statusAction, _ := bsd.checkRunning() diff --git a/daemon_linux_systemd.go b/daemon_linux_systemd.go index bfd928b..18e4201 100644 --- a/daemon_linux_systemd.go +++ b/daemon_linux_systemd.go @@ -184,7 +184,7 @@ func (linux *systemDRecord) Status() (string, error) { } if !linux.isInstalled() { - return "Status could not defined", ErrNotInstalled + return statNotInstalled, ErrNotInstalled } statusAction, _ := linux.checkRunning() diff --git a/daemon_linux_systemv.go b/daemon_linux_systemv.go index ba2d158..c95fee3 100644 --- a/daemon_linux_systemv.go +++ b/daemon_linux_systemv.go @@ -192,7 +192,7 @@ func (linux *systemVRecord) Status() (string, error) { } if !linux.isInstalled() { - return "Status could not defined", ErrNotInstalled + return statNotInstalled, ErrNotInstalled } statusAction, _ := linux.checkRunning() diff --git a/daemon_linux_upstart.go b/daemon_linux_upstart.go index b5f6728..eaf6113 100644 --- a/daemon_linux_upstart.go +++ b/daemon_linux_upstart.go @@ -170,7 +170,7 @@ func (linux *upstartRecord) Status() (string, error) { } if !linux.isInstalled() { - return "Status could not defined", ErrNotInstalled + return statNotInstalled, ErrNotInstalled } statusAction, _ := linux.checkRunning() From 28186b5887c924b41826d366018a7bd9c970b9e5 Mon Sep 17 00:00:00 2001 From: Rustam Gilyazov <16064414+rusq@users.noreply.github.com> Date: Mon, 2 Mar 2020 23:04:28 +1300 Subject: [PATCH 7/9] comment fix --- daemon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon.go b/daemon.go index 17ded65..e9018fc 100644 --- a/daemon.go +++ b/daemon.go @@ -157,7 +157,7 @@ package daemon import "strings" -// Status literals +// Status constants. const ( statNotInstalled = "Service not installed" ) From 54b74c6f9b5301c2a6d2ed6bb463411abf9de92a Mon Sep 17 00:00:00 2001 From: Igor Dolzhikov Date: Wed, 15 Apr 2020 21:31:02 +0200 Subject: [PATCH 8/9] Added go modules --- go.mod | 8 ++++++++ go.sum | 4 ++++ 2 files changed, 12 insertions(+) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7115eba --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/takama/daemon + +go 1.14 + +require ( + github.com/robfig/cron v1.2.0 + golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..282b469 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= +golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY= +golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From 83159fdec986c07c43f0220738faa2c7f256ce1e Mon Sep 17 00:00:00 2001 From: Igor Dolzhikov Date: Wed, 15 Apr 2020 21:33:30 +0200 Subject: [PATCH 9/9] Bumped version number to v0.12.0 --- daemon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon.go b/daemon.go index d72cbf5..229d947 100644 --- a/daemon.go +++ b/daemon.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. /* -Package daemon 0.11.0 for use with Go (golang) services. +Package daemon v0.12.0 for use with Go (golang) services. Package daemon provides primitives for daemonization of golang services. This package is not provide implementation of user daemon,