From 2f34e7255e5e023c599c99b3a15237a50612df90 Mon Sep 17 00:00:00 2001 From: krysennn Date: Sat, 17 Mar 2018 11:51:27 +0100 Subject: [PATCH 1/3] User can set service exec path --- daemon.go | 4 ++-- daemon_darwin.go | 29 ++++++++++++++++++----------- daemon_freebsd.go | 29 ++++++++++++++++++----------- daemon_linux.go | 8 ++++---- daemon_linux_systemd.go | 26 +++++++++++++++++--------- daemon_linux_systemv.go | 26 +++++++++++++++++--------- daemon_linux_upstart.go | 26 +++++++++++++++++--------- daemon_windows.go | 23 ++++++++++++++++------- helper.go | 3 +++ 9 files changed, 112 insertions(+), 62 deletions(-) diff --git a/daemon.go b/daemon.go index 96e31b5..ea9d161 100644 --- a/daemon.go +++ b/daemon.go @@ -181,6 +181,6 @@ type Daemon interface { // name: name of the service // // description: any explanation, what is the service, its purpose -func New(name, description string, dependencies ...string) (Daemon, error) { - return newDaemon(strings.Join(strings.Fields(name), "_"), description, dependencies) +func New(name, description, execStartPath string, dependencies ...string) (Daemon, error) { + return newDaemon(strings.Join(strings.Fields(name), "_"), description, execStartPath, dependencies) } diff --git a/daemon_darwin.go b/daemon_darwin.go index 5fb016c..f36cdad 100644 --- a/daemon_darwin.go +++ b/daemon_darwin.go @@ -15,14 +15,15 @@ import ( // darwinRecord - standard record (struct) for darwin version of daemon package type darwinRecord struct { - name string - description string - dependencies []string + name string + description string + execStartPath string + dependencies []string } -func newDaemon(name, description string, dependencies []string) (Daemon, error) { +func newDaemon(name, description, execStartPath string, dependencies []string) (Daemon, error) { - return &darwinRecord{name, description, dependencies}, nil + return &darwinRecord{name, description, execStartPath,dependencies}, nil } // Standard service path for system daemons @@ -76,16 +77,22 @@ func (darwin *darwinRecord) Install(args ...string) (string, error) { return installAction + failed, ErrAlreadyInstalled } - file, err := os.Create(srvPath) - if err != nil { - return installAction + failed, err + if darwin.execStartPath == "" { + darwin.execStartPath, err = executablePath(darwin.name) + if err != nil { + return installAction + failed, err + } } - defer file.Close() - execPatch, err := executablePath(darwin.name) + if stat, err := os.Stat(darwin.execStartPath); os.IsNotExist(err) || stat.IsDir() { + return installAction + failed, ErrIncorrectExecStartPath + } + + file, err := os.Create(srvPath) if err != nil { return installAction + failed, err } + defer file.Close() templ, err := template.New("propertyList").Parse(propertyList) if err != nil { @@ -97,7 +104,7 @@ func (darwin *darwinRecord) Install(args ...string) (string, error) { &struct { Name, Path string Args []string - }{darwin.name, execPatch, args}, + }{darwin.name, darwin.execStartPath, args}, ); err != nil { return installAction + failed, err } diff --git a/daemon_freebsd.go b/daemon_freebsd.go index 9451c4e..bcc8d08 100644 --- a/daemon_freebsd.go +++ b/daemon_freebsd.go @@ -13,9 +13,10 @@ import ( // systemVRecord - standard record (struct) for linux systemV version of daemon package type bsdRecord struct { - name string - description string - dependencies []string + name string + description string + execStartPath string + dependencies []string } // Standard service path for systemV daemons @@ -66,8 +67,8 @@ func (bsd *bsdRecord) getCmd(cmd string) string { } // Get the daemon properly -func newDaemon(name, description string, dependencies []string) (Daemon, error) { - return &bsdRecord{name, description, dependencies}, nil +func newDaemon(name, description, execStartPath string, dependencies []string) (Daemon, error) { + return &bsdRecord{name, description, execStartPath,dependencies}, nil } func execPath() (name string, err error) { @@ -114,16 +115,22 @@ func (bsd *bsdRecord) Install(args ...string) (string, error) { return installAction + failed, ErrAlreadyInstalled } - file, err := os.Create(srvPath) - if err != nil { - return installAction + failed, err + if bsd.execStartPath == "" { + bsd.execStartPath, err = executablePath(bsd.name) + if err != nil { + return installAction + failed, err + } } - defer file.Close() - execPatch, err := executablePath(bsd.name) + if stat, err := os.Stat(bsd.execStartPath); os.IsNotExist(err) || stat.IsDir() { + return installAction + failed, ErrIncorrectExecStartPath + } + + file, err := os.Create(srvPath) if err != nil { return installAction + failed, err } + defer file.Close() templ, err := template.New("bsdConfig").Parse(bsdConfig) if err != nil { @@ -134,7 +141,7 @@ func (bsd *bsdRecord) Install(args ...string) (string, error) { file, &struct { Name, Description, Path, Args string - }{bsd.name, bsd.description, execPatch, strings.Join(args, " ")}, + }{bsd.name, bsd.description, bsd.execStartPath, strings.Join(args, " ")}, ); err != nil { return installAction + failed, err } diff --git a/daemon_linux.go b/daemon_linux.go index 633f20c..00bacd3 100644 --- a/daemon_linux.go +++ b/daemon_linux.go @@ -10,15 +10,15 @@ import ( ) // Get the daemon properly -func newDaemon(name, description string, dependencies []string) (Daemon, error) { +func newDaemon(name, description, execStartPath string, dependencies []string) (Daemon, error) { // newer subsystem must be checked first if _, err := os.Stat("/run/systemd/system"); err == nil { - return &systemDRecord{name, description, dependencies}, nil + return &systemDRecord{name, description, execStartPath, dependencies}, nil } if _, err := os.Stat("/sbin/initctl"); err == nil { - return &upstartRecord{name, description, dependencies}, nil + return &upstartRecord{name, description, execStartPath, dependencies}, nil } - return &systemVRecord{name, description, dependencies}, nil + return &systemVRecord{name, description, execStartPath, dependencies}, nil } // Get executable path diff --git a/daemon_linux_systemd.go b/daemon_linux_systemd.go index 299b8c4..1660d7c 100644 --- a/daemon_linux_systemd.go +++ b/daemon_linux_systemd.go @@ -14,9 +14,10 @@ import ( // systemDRecord - standard record (struct) for linux systemD version of daemon package type systemDRecord struct { - name string - description string - dependencies []string + name string + description string + execStartPath string + dependencies []string } // Standard service path for systemD daemons @@ -55,6 +56,7 @@ func (linux *systemDRecord) checkRunning() (string, bool) { func (linux *systemDRecord) Install(args ...string) (string, error) { installAction := "Install " + linux.description + ":" + var err error if ok, err := checkPrivileges(); !ok { return installAction + failed, err } @@ -65,16 +67,22 @@ func (linux *systemDRecord) Install(args ...string) (string, error) { return installAction + failed, ErrAlreadyInstalled } - file, err := os.Create(srvPath) - if err != nil { - return installAction + failed, err + if linux.execStartPath == "" { + linux.execStartPath, err = executablePath(linux.name) + if err != nil { + return installAction + failed, err + } } - defer file.Close() - execPatch, err := executablePath(linux.name) + if stat, err := os.Stat(linux.execStartPath); os.IsNotExist(err) || stat.IsDir() { + return installAction + failed, ErrIncorrectExecStartPath + } + + file, err := os.Create(srvPath) if err != nil { return installAction + failed, err } + defer file.Close() templ, err := template.New("systemDConfig").Parse(systemDConfig) if err != nil { @@ -89,7 +97,7 @@ func (linux *systemDRecord) Install(args ...string) (string, error) { linux.name, linux.description, strings.Join(linux.dependencies, " "), - execPatch, + linux.execStartPath, strings.Join(args, " "), }, ); err != nil { diff --git a/daemon_linux_systemv.go b/daemon_linux_systemv.go index 810e74c..1e3c223 100644 --- a/daemon_linux_systemv.go +++ b/daemon_linux_systemv.go @@ -14,9 +14,10 @@ import ( // systemVRecord - standard record (struct) for linux systemV version of daemon package type systemVRecord struct { - name string - description string - dependencies []string + name string + description string + execStartPath string + dependencies []string } // Standard service path for systemV daemons @@ -55,6 +56,7 @@ func (linux *systemVRecord) checkRunning() (string, bool) { func (linux *systemVRecord) Install(args ...string) (string, error) { installAction := "Install " + linux.description + ":" + var err error if ok, err := checkPrivileges(); !ok { return installAction + failed, err } @@ -65,16 +67,22 @@ func (linux *systemVRecord) Install(args ...string) (string, error) { return installAction + failed, ErrAlreadyInstalled } - file, err := os.Create(srvPath) - if err != nil { - return installAction + failed, err + if linux.execStartPath == "" { + linux.execStartPath, err = executablePath(linux.name) + if err != nil { + return installAction + failed, err + } } - defer file.Close() - execPatch, err := executablePath(linux.name) + if stat, err := os.Stat(linux.execStartPath); os.IsNotExist(err) || stat.IsDir() { + return installAction + failed, ErrIncorrectExecStartPath + } + + file, err := os.Create(srvPath) if err != nil { return installAction + failed, err } + defer file.Close() templ, err := template.New("systemVConfig").Parse(systemVConfig) if err != nil { @@ -85,7 +93,7 @@ func (linux *systemVRecord) Install(args ...string) (string, error) { file, &struct { Name, Description, Path, Args string - }{linux.name, linux.description, execPatch, strings.Join(args, " ")}, + }{linux.name, linux.description, linux.execStartPath, strings.Join(args, " ")}, ); err != nil { return installAction + failed, err } diff --git a/daemon_linux_upstart.go b/daemon_linux_upstart.go index 899653b..407b9cf 100644 --- a/daemon_linux_upstart.go +++ b/daemon_linux_upstart.go @@ -14,9 +14,10 @@ import ( // upstartRecord - standard record (struct) for linux upstart version of daemon package type upstartRecord struct { - name string - description string - dependencies []string + name string + description string + execStartPath string + dependencies []string } // Standard service path for systemV daemons @@ -55,6 +56,7 @@ func (linux *upstartRecord) checkRunning() (string, bool) { func (linux *upstartRecord) Install(args ...string) (string, error) { installAction := "Install " + linux.description + ":" + var err error if ok, err := checkPrivileges(); !ok { return installAction + failed, err } @@ -65,16 +67,22 @@ func (linux *upstartRecord) Install(args ...string) (string, error) { return installAction + failed, ErrAlreadyInstalled } - file, err := os.Create(srvPath) - if err != nil { - return installAction + failed, err + if linux.execStartPath == "" { + linux.execStartPath, err = executablePath(linux.name) + if err != nil { + return installAction + failed, err + } } - defer file.Close() - execPatch, err := executablePath(linux.name) + if stat, err := os.Stat(linux.execStartPath); os.IsNotExist(err) || stat.IsDir() { + return installAction + failed, ErrIncorrectExecStartPath + } + + file, err := os.Create(srvPath) if err != nil { return installAction + failed, err } + defer file.Close() templ, err := template.New("upstatConfig").Parse(upstatConfig) if err != nil { @@ -85,7 +93,7 @@ func (linux *upstartRecord) Install(args ...string) (string, error) { file, &struct { Name, Description, Path, Args string - }{linux.name, linux.description, execPatch, strings.Join(args, " ")}, + }{linux.name, linux.description, linux.execStartPath, strings.Join(args, " ")}, ); err != nil { return installAction + failed, err } diff --git a/daemon_windows.go b/daemon_windows.go index 54ca1f0..d5812ec 100644 --- a/daemon_windows.go +++ b/daemon_windows.go @@ -13,31 +13,40 @@ import ( "syscall" "unicode/utf16" "unsafe" + "os" ) // windowsRecord - standard record (struct) for windows version of daemon package type windowsRecord struct { - name string - description string - dependencies []string + name string + description string + execStartPath string + dependencies []string } -func newDaemon(name, description string, dependencies []string) (Daemon, error) { +func newDaemon(name, description, execStartPath string, dependencies []string) (Daemon, error) { - return &windowsRecord{name, description, dependencies}, nil + return &windowsRecord{name, description, execStartPath, dependencies}, nil } // Install the service func (windows *windowsRecord) Install(args ...string) (string, error) { installAction := "Install " + windows.description + ":" - execp, err := execPath() + var err error + if windows.execStartPath == "" { + windows.execStartPath, err = execPath() + } if err != nil { return installAction + failed, err } - cmdArgs := []string{"create", windows.name, "start=auto", "binPath=" + execp} + if stat, err := os.Stat(windows.execStartPath); os.IsNotExist(err) || stat.IsDir() { + return installAction + failed, ErrIncorrectExecStartPath + } + + cmdArgs := []string{"create", windows.name, "start=auto", "binPath=" + windows.execStartPath} cmdArgs = append(cmdArgs, args...) cmd := exec.Command("sc", cmdArgs...) diff --git a/helper.go b/helper.go index 35981fb..ca13d58 100644 --- a/helper.go +++ b/helper.go @@ -38,6 +38,9 @@ var ( // ErrAlreadyStopped appears if try to stop already stopped service ErrAlreadyStopped = errors.New("Service has already been stopped") + + // ErrIncorrectExecStartPath appears if try to path folder or incorrect exec path start for service + ErrIncorrectExecStartPath = errors.New("Incorrect exec start path") ) // ExecPath tries to get executable path From 9d9a289c35b6f0a32a9e1e5a666c44c3ae56c27f Mon Sep 17 00:00:00 2001 From: Alexis Camilleri Date: Mon, 19 Mar 2018 10:36:29 +0100 Subject: [PATCH 2/3] Update daemon_darwin.go Fix undefined err --- daemon_darwin.go | 1 + 1 file changed, 1 insertion(+) diff --git a/daemon_darwin.go b/daemon_darwin.go index f36cdad..c69cacc 100644 --- a/daemon_darwin.go +++ b/daemon_darwin.go @@ -67,6 +67,7 @@ func (darwin *darwinRecord) checkRunning() (string, bool) { func (darwin *darwinRecord) Install(args ...string) (string, error) { installAction := "Install " + darwin.description + ":" + var err error if ok, err := checkPrivileges(); !ok { return installAction + failed, err } From 61dee160e2febe876887618f695400bb0ec7d40d Mon Sep 17 00:00:00 2001 From: Alexis Camilleri Date: Thu, 5 Apr 2018 15:30:54 +0200 Subject: [PATCH 3/3] Fix undefined execp --- daemon_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon_windows.go b/daemon_windows.go index a96c95a..ae0fdeb 100644 --- a/daemon_windows.go +++ b/daemon_windows.go @@ -57,7 +57,7 @@ func (windows *windowsRecord) Install(args ...string) (string, error) { return installAction + failed, err } - s, err = m.CreateService(windows.name, execp, mgr.Config{ + s, err = m.CreateService(windows.name, windows.execStartPath, mgr.Config{ DisplayName: windows.name, Description: windows.description, StartType: mgr.StartAutomatic,