Skip to content

Commit efe0e6a

Browse files
committed
feat: silent start, stop and restart
1 parent 00de9bf commit efe0e6a

File tree

5 files changed

+192
-0
lines changed

5 files changed

+192
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ bin/*
2525
data/
2626
log/
2727
lang/
28+
daemon/
2829
public/dist/*
2930
!public/dist/README.md

cmd/common.go

+30
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package cmd
22

33
import (
4+
"os"
5+
"path/filepath"
6+
"strconv"
7+
48
"github.com/alist-org/alist/v3/internal/bootstrap"
59
"github.com/alist-org/alist/v3/internal/bootstrap/data"
10+
"github.com/alist-org/alist/v3/pkg/utils"
11+
log "github.com/sirupsen/logrus"
612
)
713

814
func Init() {
@@ -11,3 +17,27 @@ func Init() {
1117
bootstrap.InitDB()
1218
data.InitData()
1319
}
20+
21+
var pid = -1
22+
var pidFile string
23+
24+
func initDaemon() {
25+
ex, err := os.Executable()
26+
if err != nil {
27+
log.Fatal(err)
28+
}
29+
exPath := filepath.Dir(ex)
30+
_ = os.MkdirAll(filepath.Join(exPath, "daemon"), 0700)
31+
pidFile = filepath.Join(exPath, "daemon/pid")
32+
if utils.Exists(pidFile) {
33+
bytes, err := os.ReadFile(pidFile)
34+
if err != nil {
35+
log.Fatal("failed to read pid file", err)
36+
}
37+
id, err := strconv.Atoi(string(bytes))
38+
if err != nil {
39+
log.Fatal("failed to parse pid data", err)
40+
}
41+
pid = id
42+
}
43+
}

cmd/restart.go

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
3+
*/
4+
package cmd
5+
6+
import (
7+
"github.com/spf13/cobra"
8+
)
9+
10+
// restartCmd represents the restart command
11+
var restartCmd = &cobra.Command{
12+
Use: "restart",
13+
Short: "Restart alist server by daemon/pid file",
14+
Run: func(cmd *cobra.Command, args []string) {
15+
stop()
16+
start()
17+
},
18+
}
19+
20+
func init() {
21+
rootCmd.AddCommand(restartCmd)
22+
23+
// Here you will define your flags and configuration settings.
24+
25+
// Cobra supports Persistent Flags which will work for this command
26+
// and all subcommands, e.g.:
27+
// restartCmd.PersistentFlags().String("foo", "", "A help for foo")
28+
29+
// Cobra supports local flags which will only run when this command
30+
// is called directly, e.g.:
31+
// restartCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
32+
}

cmd/start.go

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
3+
*/
4+
package cmd
5+
6+
import (
7+
"os"
8+
"os/exec"
9+
"path/filepath"
10+
"strconv"
11+
12+
log "github.com/sirupsen/logrus"
13+
"github.com/spf13/cobra"
14+
)
15+
16+
// startCmd represents the start command
17+
var startCmd = &cobra.Command{
18+
Use: "start",
19+
Short: "Silent start alist server with `--force-bin-dir`",
20+
Run: func(cmd *cobra.Command, args []string) {
21+
start()
22+
},
23+
}
24+
25+
func start() {
26+
initDaemon()
27+
if pid != -1 {
28+
_, err := os.FindProcess(pid)
29+
if err == nil {
30+
log.Info("alist already started, pid ", pid)
31+
return
32+
}
33+
}
34+
args := os.Args
35+
args[1] = "server"
36+
args = append(args, "--force-bin-dir")
37+
cmd := &exec.Cmd{
38+
Path: args[0],
39+
Args: args,
40+
Env: os.Environ(),
41+
}
42+
stdout, err := os.OpenFile(filepath.Join(filepath.Dir(pidFile), "start.log"), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
43+
if err != nil {
44+
log.Fatal(os.Getpid(), ": failed to open start log file:", err)
45+
}
46+
cmd.Stderr = stdout
47+
cmd.Stdout = stdout
48+
err = cmd.Start()
49+
if err != nil {
50+
log.Fatal("failed to start children process: ", err)
51+
}
52+
log.Infof("success start pid: %d", cmd.Process.Pid)
53+
err = os.WriteFile(pidFile, []byte(strconv.Itoa(cmd.Process.Pid)), 0666)
54+
if err != nil {
55+
log.Warn("failed to record pid, you may not be able to stop the program with `./alist stop`")
56+
}
57+
}
58+
59+
func init() {
60+
rootCmd.AddCommand(startCmd)
61+
62+
// Here you will define your flags and configuration settings.
63+
64+
// Cobra supports Persistent Flags which will work for this command
65+
// and all subcommands, e.g.:
66+
// startCmd.PersistentFlags().String("foo", "", "A help for foo")
67+
68+
// Cobra supports local flags which will only run when this command
69+
// is called directly, e.g.:
70+
// startCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
71+
}

cmd/stop.go

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
3+
*/
4+
package cmd
5+
6+
import (
7+
"os"
8+
9+
log "github.com/sirupsen/logrus"
10+
"github.com/spf13/cobra"
11+
)
12+
13+
// stopCmd represents the stop command
14+
var stopCmd = &cobra.Command{
15+
Use: "stop",
16+
Short: "Stop alist server by daemon/pid file",
17+
Run: func(cmd *cobra.Command, args []string) {
18+
stop()
19+
},
20+
}
21+
22+
func stop() {
23+
initDaemon()
24+
if pid == -1 {
25+
log.Info("Seems not have been started. Try use `alist start` to start server.")
26+
return
27+
}
28+
process, err := os.FindProcess(pid)
29+
if err != nil {
30+
log.Errorf("failed to find process by pid: %d, reason: %v", pid, process)
31+
return
32+
}
33+
err = process.Kill()
34+
if err != nil {
35+
log.Errorf("failed to kill process %d: %v", pid, err)
36+
} else {
37+
log.Info("killed process: ", pid)
38+
}
39+
err = os.Remove(pidFile)
40+
if err != nil {
41+
log.Errorf("failed to remove pid file")
42+
}
43+
pid = -1
44+
}
45+
46+
func init() {
47+
rootCmd.AddCommand(stopCmd)
48+
49+
// Here you will define your flags and configuration settings.
50+
51+
// Cobra supports Persistent Flags which will work for this command
52+
// and all subcommands, e.g.:
53+
// stopCmd.PersistentFlags().String("foo", "", "A help for foo")
54+
55+
// Cobra supports local flags which will only run when this command
56+
// is called directly, e.g.:
57+
// stopCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
58+
}

0 commit comments

Comments
 (0)