Skip to content

Commit 6abfa6d

Browse files
committed
support busyBox and sysV, for openWrt, fix ehang-io#419, change update url
1 parent f6063e0 commit 6abfa6d

File tree

3 files changed

+188
-59
lines changed

3 files changed

+188
-59
lines changed

cmd/npc/npc.go

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/ccding/go-stun/stun"
1414
"github.com/kardianos/service"
1515
"os"
16+
"os/exec"
1617
"runtime"
1718
"strings"
1819
"sync"
@@ -37,31 +38,6 @@ var (
3738
pprofAddr = flag.String("pprof", "", "PProf debug addr (ip:port)")
3839
)
3940

40-
const systemdScript = `[Unit]
41-
Description={{.Description}}
42-
ConditionFileIsExecutable={{.Path|cmdEscape}}
43-
{{range $i, $dep := .Dependencies}}
44-
{{$dep}} {{end}}
45-
[Service]
46-
LimitNOFILE=65536
47-
StartLimitInterval=5
48-
StartLimitBurst=10
49-
ExecStart={{.Path|cmdEscape}}{{range .Arguments}} {{.|cmd}}{{end}}
50-
{{if .ChRoot}}RootDirectory={{.ChRoot|cmd}}{{end}}
51-
{{if .WorkingDirectory}}WorkingDirectory={{.WorkingDirectory|cmdEscape}}{{end}}
52-
{{if .UserName}}User={{.UserName}}{{end}}
53-
{{if .ReloadSignal}}ExecReload=/bin/kill -{{.ReloadSignal}} "$MAINPID"{{end}}
54-
{{if .PIDFile}}PIDFile={{.PIDFile|cmd}}{{end}}
55-
{{if and .LogOutput .HasOutputFileSupport -}}
56-
StandardOutput=file:/var/log/{{.Name}}.out
57-
StandardError=file:/var/log/{{.Name}}.err
58-
{{- end}}
59-
Restart=always
60-
RestartSec=120
61-
[Install]
62-
WantedBy=multi-user.target
63-
`
64-
6541
func main() {
6642
flag.Parse()
6743
logs.Reset()
@@ -91,7 +67,8 @@ func main() {
9167
svcConfig.Dependencies = []string{
9268
"Requires=network.target",
9369
"After=network-online.target syslog.target"}
94-
svcConfig.Option["SystemdScript"] = systemdScript
70+
svcConfig.Option["SystemdScript"] = install.SystemdScript
71+
svcConfig.Option["SysvScript"] = install.SysvScript
9572
}
9673
for _, v := range os.Args[1:] {
9774
switch v {
@@ -137,16 +114,47 @@ func main() {
137114
}
138115
fmt.Printf("nat type: %s \npublic address: %s\n", nat.String(), host.String())
139116
os.Exit(0)
140-
case "install", "start", "stop", "uninstall", "restart":
141-
if os.Args[1] == "install" {
142-
service.Control(s, "stop")
143-
service.Control(s, "uninstall")
144-
install.InstallNpc()
117+
case "start", "stop", "restart":
118+
// support busyBox and sysV, for openWrt
119+
if service.Platform() == "unix-systemv" {
120+
logs.Info("unix-systemv service")
121+
cmd := exec.Command("/etc/init.d/"+svcConfig.Name, os.Args[1])
122+
err := cmd.Run()
123+
if err != nil {
124+
logs.Error(err)
125+
}
126+
return
127+
}
128+
err := service.Control(s, os.Args[1])
129+
if err != nil {
130+
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
145131
}
132+
return
133+
case "install":
134+
service.Control(s, "stop")
135+
service.Control(s, "uninstall")
136+
install.InstallNpc()
146137
err := service.Control(s, os.Args[1])
147138
if err != nil {
148139
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
149140
}
141+
if service.Platform() == "unix-systemv" {
142+
logs.Info("unix-systemv service")
143+
confPath := "/etc/init.d/" + svcConfig.Name
144+
os.Symlink(confPath, "/etc/rc.d/S90"+svcConfig.Name)
145+
os.Symlink(confPath, "/etc/rc.d/K02"+svcConfig.Name)
146+
}
147+
return
148+
case "uninstall":
149+
err := service.Control(s, os.Args[1])
150+
if err != nil {
151+
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
152+
}
153+
if service.Platform() == "unix-systemv" {
154+
logs.Info("unix-systemv service")
155+
os.Remove("/etc/rc.d/S90" + svcConfig.Name)
156+
os.Remove("/etc/rc.d/K02" + svcConfig.Name)
157+
}
150158
return
151159
}
152160
}

cmd/nps/nps.go

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"flag"
1313
"log"
1414
"os"
15+
"os/exec"
1516
"path/filepath"
1617
"runtime"
1718
"strings"
@@ -29,31 +30,6 @@ var (
2930
level string
3031
)
3132

32-
const systemdScript = `[Unit]
33-
Description={{.Description}}
34-
ConditionFileIsExecutable={{.Path|cmdEscape}}
35-
{{range $i, $dep := .Dependencies}}
36-
{{$dep}} {{end}}
37-
[Service]
38-
LimitNOFILE=65536
39-
StartLimitInterval=5
40-
StartLimitBurst=10
41-
ExecStart={{.Path|cmdEscape}}{{range .Arguments}} {{.|cmd}}{{end}}
42-
{{if .ChRoot}}RootDirectory={{.ChRoot|cmd}}{{end}}
43-
{{if .WorkingDirectory}}WorkingDirectory={{.WorkingDirectory|cmdEscape}}{{end}}
44-
{{if .UserName}}User={{.UserName}}{{end}}
45-
{{if .ReloadSignal}}ExecReload=/bin/kill -{{.ReloadSignal}} "$MAINPID"{{end}}
46-
{{if .PIDFile}}PIDFile={{.PIDFile|cmd}}{{end}}
47-
{{if and .LogOutput .HasOutputFileSupport -}}
48-
StandardOutput=file:/var/log/{{.Name}}.out
49-
StandardError=file:/var/log/{{.Name}}.err
50-
{{- end}}
51-
Restart=always
52-
RestartSec=120
53-
[Install]
54-
WantedBy=multi-user.target
55-
`
56-
5733
func main() {
5834
flag.Parse()
5935
// init log
@@ -92,7 +68,8 @@ func main() {
9268
svcConfig.Dependencies = []string{
9369
"Requires=network.target",
9470
"After=network-online.target syslog.target"}
95-
svcConfig.Option["SystemdScript"] = systemdScript
71+
svcConfig.Option["SystemdScript"] = install.SystemdScript
72+
svcConfig.Option["SysvScript"] = install.SysvScript
9673
}
9774
prg := &nps{}
9875
prg.exit = make(chan struct{})
@@ -127,12 +104,38 @@ func main() {
127104
if err != nil {
128105
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
129106
}
107+
if service.Platform() == "unix-systemv" {
108+
logs.Info("unix-systemv service")
109+
confPath := "/etc/init.d/" + svcConfig.Name
110+
os.Symlink(confPath, "/etc/rc.d/S90"+svcConfig.Name)
111+
os.Symlink(confPath, "/etc/rc.d/K02"+svcConfig.Name)
112+
}
113+
return
114+
case "start", "restart", "stop":
115+
if service.Platform() == "unix-systemv" {
116+
logs.Info("unix-systemv service")
117+
cmd := exec.Command("/etc/init.d/"+svcConfig.Name, os.Args[1])
118+
err := cmd.Run()
119+
if err != nil {
120+
logs.Error(err)
121+
}
122+
return
123+
}
124+
err := service.Control(s, os.Args[1])
125+
if err != nil {
126+
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
127+
}
130128
return
131-
case "start", "restart", "stop", "uninstall":
129+
case "uninstall":
132130
err := service.Control(s, os.Args[1])
133131
if err != nil {
134132
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
135133
}
134+
if service.Platform() == "unix-systemv" {
135+
logs.Info("unix-systemv service")
136+
os.Remove("/etc/rc.d/S90" + svcConfig.Name)
137+
os.Remove("/etc/rc.d/K02" + svcConfig.Name)
138+
}
136139
return
137140
case "update":
138141
install.UpdateNps()

lib/install/install.go

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,124 @@ import (
1616
"strings"
1717
)
1818

19+
// Keep it in sync with the template from service_sysv_linux.go file
20+
// Use "ps | grep -v grep | grep $(get_pid)" because "ps PID" may not work on OpenWrt
21+
const SysvScript = `#!/bin/sh
22+
# For RedHat and cousins:
23+
# chkconfig: - 99 01
24+
# description: {{.Description}}
25+
# processname: {{.Path}}
26+
### BEGIN INIT INFO
27+
# Provides: {{.Path}}
28+
# Required-Start:
29+
# Required-Stop:
30+
# Default-Start: 2 3 4 5
31+
# Default-Stop: 0 1 6
32+
# Short-Description: {{.DisplayName}}
33+
# Description: {{.Description}}
34+
### END INIT INFO
35+
cmd="{{.Path}}{{range .Arguments}} {{.|cmd}}{{end}}"
36+
name=$(basename $(readlink -f $0))
37+
pid_file="/var/run/$name.pid"
38+
stdout_log="/var/log/$name.log"
39+
stderr_log="/var/log/$name.err"
40+
[ -e /etc/sysconfig/$name ] && . /etc/sysconfig/$name
41+
get_pid() {
42+
cat "$pid_file"
43+
}
44+
is_running() {
45+
[ -f "$pid_file" ] && ps | grep -v grep | grep $(get_pid) > /dev/null 2>&1
46+
}
47+
case "$1" in
48+
start)
49+
if is_running; then
50+
echo "Already started"
51+
else
52+
echo "Starting $name"
53+
{{if .WorkingDirectory}}cd '{{.WorkingDirectory}}'{{end}}
54+
$cmd >> "$stdout_log" 2>> "$stderr_log" &
55+
echo $! > "$pid_file"
56+
if ! is_running; then
57+
echo "Unable to start, see $stdout_log and $stderr_log"
58+
exit 1
59+
fi
60+
fi
61+
;;
62+
stop)
63+
if is_running; then
64+
echo -n "Stopping $name.."
65+
kill $(get_pid)
66+
for i in $(seq 1 10)
67+
do
68+
if ! is_running; then
69+
break
70+
fi
71+
echo -n "."
72+
sleep 1
73+
done
74+
echo
75+
if is_running; then
76+
echo "Not stopped; may still be shutting down or shutdown may have failed"
77+
exit 1
78+
else
79+
echo "Stopped"
80+
if [ -f "$pid_file" ]; then
81+
rm "$pid_file"
82+
fi
83+
fi
84+
else
85+
echo "Not running"
86+
fi
87+
;;
88+
restart)
89+
$0 stop
90+
if is_running; then
91+
echo "Unable to stop, will not attempt to start"
92+
exit 1
93+
fi
94+
$0 start
95+
;;
96+
status)
97+
if is_running; then
98+
echo "Running"
99+
else
100+
echo "Stopped"
101+
exit 1
102+
fi
103+
;;
104+
*)
105+
echo "Usage: $0 {start|stop|restart|status}"
106+
exit 1
107+
;;
108+
esac
109+
exit 0
110+
`
111+
112+
const SystemdScript = `[Unit]
113+
Description={{.Description}}
114+
ConditionFileIsExecutable={{.Path|cmdEscape}}
115+
{{range $i, $dep := .Dependencies}}
116+
{{$dep}} {{end}}
117+
[Service]
118+
LimitNOFILE=65536
119+
StartLimitInterval=5
120+
StartLimitBurst=10
121+
ExecStart={{.Path|cmdEscape}}{{range .Arguments}} {{.|cmd}}{{end}}
122+
{{if .ChRoot}}RootDirectory={{.ChRoot|cmd}}{{end}}
123+
{{if .WorkingDirectory}}WorkingDirectory={{.WorkingDirectory|cmdEscape}}{{end}}
124+
{{if .UserName}}User={{.UserName}}{{end}}
125+
{{if .ReloadSignal}}ExecReload=/bin/kill -{{.ReloadSignal}} "$MAINPID"{{end}}
126+
{{if .PIDFile}}PIDFile={{.PIDFile|cmd}}{{end}}
127+
{{if and .LogOutput .HasOutputFileSupport -}}
128+
StandardOutput=file:/var/log/{{.Name}}.out
129+
StandardError=file:/var/log/{{.Name}}.err
130+
{{- end}}
131+
Restart=always
132+
RestartSec=120
133+
[Install]
134+
WantedBy=multi-user.target
135+
`
136+
19137
func UpdateNps() {
20138
destPath := downloadLatest("server")
21139
//复制文件到对应目录
@@ -36,7 +154,7 @@ type release struct {
36154

37155
func downloadLatest(bin string) string {
38156
// get version
39-
data, err := http.Get("https://api.github.com/repos/cnlh/nps/releases/latest")
157+
data, err := http.Get("https://api.github.com/repos/ehang-io/nps/releases/latest")
40158
if err != nil {
41159
log.Fatal(err.Error())
42160
}

0 commit comments

Comments
 (0)