Skip to content

Commit

Permalink
Merge pull request #690 from kongfei605/feature_install
Browse files Browse the repository at this point in the history
service install  support
  • Loading branch information
kongfei605 authored Oct 19, 2023
2 parents ea4ed7a + 15cf97d commit 5dc3e21
Show file tree
Hide file tree
Showing 7 changed files with 460 additions and 2 deletions.
24 changes: 24 additions & 0 deletions agent/install/service_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package install

import (
"github.com/kardianos/service"
)

const (
ServiceName = "categraf"
)

var (
serviceConfig = &service.Config{
// 服务显示名称
Name: ServiceName,
// 服务名称
DisplayName: "categraf",
// 服务描述
Description: "Opensource telemetry collector",
}
)

func ServiceConfig() *service.Config {
return serviceConfig
}
47 changes: 47 additions & 0 deletions agent/install/service_freebsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package install

import (
"github.com/kardianos/service"
)

const (
// freebsd的服务名中间不能有"-"
ServiceName = "categraf"

SysvScript = `#!/bin/sh
#
# PROVIDE: {{.Name}}
# REQUIRE: networking syslog
# KEYWORD:
# Add the following lines to /etc/rc.conf to enable the {{.Name}}:
#
# {{.Name}}_enable="YES"
#
. /etc/rc.subr
name="{{.Name}}"
rcvar="{{.Name}}_enable"
command="{{.Path}}"
pidfile="/var/run/$name.pid"
start_cmd="/opt/categraf/categraf -configs /opt/categraf/conf"
load_rc_config $name
run_rc_command "$1"
`
)

var (
serviceConfig = &service.Config{
// 服务显示名称
Name: ServiceName,
// 服务名称
DisplayName: "categraf",
// 服务描述
Description: "Opensource telemetry collector",
Option: service.KeyValue{
"SysvScript": SysvScript,
},
}
)

func ServiceConfig() *service.Config {
return serviceConfig
}
219 changes: 219 additions & 0 deletions agent/install/service_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package install

import (
"bytes"
"fmt"
"log"
"os/exec"
"strings"
"time"

"github.com/kardianos/service"

"flashcat.cloud/categraf/pkg/cmdx"
)

const (
systemdScript = `[Unit]
Description={{.Description}}
ConditionFileIsExecutable={{.Path|cmdEscape}}
{{range $i, $dep := .Dependencies}}
{{$dep}} {{end}}
[Service]
StandardOutput=journal+console
StandardError=journal+console
StartLimitInterval=3600
StartLimitBurst=10
ExecStart={{.Path|cmdEscape}}{{range .Arguments}} {{.|cmd}}{{end}}
{{if .ChRoot}}RootDirectory={{.ChRoot|cmd}}{{end}}
{{if .WorkingDirectory}}WorkingDirectory={{.WorkingDirectory|cmdEscape}}{{end}}
{{if .UserName}}User={{.UserName}}{{end}}
{{if .ReloadSignal}}ExecReload=/bin/kill -{{.ReloadSignal}} "$MAINPID"{{end}}
{{if .PIDFile}}PIDFile={{.PIDFile|cmd}}{{end}}
{{if and .LogOutput .HasOutputFileSupport -}}
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier={{.Name}}
{{- end}}
{{if gt .LimitNOFILE -1 }}LimitNOFILE={{.LimitNOFILE}}{{end}}
{{if .Restart}}Restart={{.Restart}}{{end}}
{{if .SuccessExitStatus}}SuccessExitStatus={{.SuccessExitStatus}}{{end}}
RestartSec=120
EnvironmentFile=-/etc/sysconfig/{{.Name}}
KillMode=process
[Install]
WantedBy=multi-user.target
`

// NOTE: sysvinit script below is copied from https://github.com/kardianos/service/master/service_sysv_linux.go
// with modification:
// * In chkconfig configuration [default_runlevels start_priority stop_priority],
// runlevels to be started by default is modified which should be consistent
// with LSB init configuration below. And two priorities is also modified
// to be consistent with installing code in library.
// * "Required-Start" part of LSB init configuration is modified according to
// https://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/facilname.html
// for service dependency ordering, like what systemd provides.
// See https://linux.die.net/man/8/chkconfig for more details
sysvScript = `#!/bin/sh
# For RedHat and cousins:
# chkconfig: 2345 50 02
# description: {{.Description}}
# processname: {{.Path}}
### BEGIN INIT INFO
# Provides: {{.Path}}
# Required-Start: $local_fs $network $named $remote_fs
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: {{.DisplayName}}
# Description: {{.Description}}
### END INIT INFO
cmd="{{.Path}}{{range .Arguments}} {{.|cmd}}{{end}}"
name=$(basename $(readlink -f $0))
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"
[ -e /etc/sysconfig/$name ] && . /etc/sysconfig/$name
get_pid() {
cat "$pid_file"
}
is_running() {
[ -f "$pid_file" ] && ps $(get_pid) > /dev/null 2>&1
}
case "$1" in
start)
if is_running; then
echo "Already started"
else
echo "Starting $name"
{{if .WorkingDirectory}}cd '{{.WorkingDirectory}}'{{end}}
$cmd >> "$stdout_log" 2>> "$stderr_log" &
echo $! > "$pid_file"
if ! is_running; then
echo "Unable to start, see $stdout_log and $stderr_log"
exit 1
fi
fi
;;
stop)
if is_running; then
echo -n "Stopping $name.."
kill $(get_pid)
for i in $(seq 1 10)
do
if ! is_running; then
break
fi
echo -n "."
sleep 1
done
echo
if is_running; then
echo "Not stopped; may still be shutting down or shutdown may have failed"
exit 1
else
echo "Stopped"
if [ -f "$pid_file" ]; then
rm "$pid_file"
fi
fi
else
echo "Not running"
fi
;;
restart)
$0 stop
if is_running; then
echo "Unable to stop, will not attempt to start"
exit 1
fi
$0 start
;;
status)
if is_running; then
echo "Running"
else
echo "Stopped"
exit 1
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
`
)

func isSystemd() bool {
var stdout bytes.Buffer
var stderr bytes.Buffer

cmd := exec.Command("ls", "-l", "/sbin/init") //nolint:gosec
cmd.Stdout = &stdout
cmd.Stderr = &stderr

err, timeout := cmdx.RunTimeout(cmd, time.Second*2)
if timeout {
log.Printf("E! run command: %s timeout", cmd)
return false
}

if err != nil {
fmt.Errorf("failed to run command: %s | error: %v | stdout: %s | stderr: %s",
cmd, err, stdout.String(), stderr.String())
return false
}

if strings.Contains(stdout.String(), "systemd") {
return true
}
return false
}

func ServiceConfig() *service.Config {
ServiceName := "categraf"
depends := []string{}
option := make(service.KeyValue)
if isSystemd() {
ServiceName = "categraf"
// Official doc https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/
// suggests both After= and Wants= configuration to delay a service after
// network is up. Need validation on ALL distros and releases.
depends = append(depends, "After=network-online.target")
depends = append(depends, "Wants=network-online.target")
option["SystemdScript"] = systemdScript
option["Restart"] = "on-failure"

// REMEMBER: Explicit disable LogOutput option of kardianos/service, and
// use StandardOutput/StandardError settings manually written above.
option["LogOutput"] = false
} else {
ServiceName = "categraf"
option["SysvScript"] = sysvScript
option["LogOutput"] = true
}

return &service.Config{
// 服务显示名称
Name: ServiceName,
// 服务名称
DisplayName: ServiceName,
// 服务描述
Description: "Opensource telemetry collector",
// TODO: Use symbolic link for shorter path needs more adaption
// Executable: "/opt/categraf/categraf",
Dependencies: depends, //
Option: option,
}
}
24 changes: 24 additions & 0 deletions agent/install/service_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package install

import (
"github.com/kardianos/service"
)

const (
ServiceName = "categraf"
)

var (
serviceConfig = &service.Config{
// 服务显示名称
Name: ServiceName,
// 服务名称
DisplayName: "categraf",
// 服务描述
Description: "Opensource telemetry collector",
}
)

func ServiceConfig() *service.Config {
return serviceConfig
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sts v1.18.3
github.com/bmatcuk/doublestar/v3 v3.0.0
github.com/coreos/go-systemd/v22 v22.3.2
github.com/kardianos/service v1.2.2
github.com/karrick/godirwalk v1.10.3
github.com/likexian/whois v1.15.0
github.com/likexian/whois-parser v1.24.8
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60=
github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3 h1:lOpSw2vJP0y5eLBW906QwKsUK/fe/QDyoqM5rnnuPDY=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
Expand Down Expand Up @@ -1683,6 +1685,7 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
Loading

0 comments on commit 5dc3e21

Please sign in to comment.