forked from XrayR-project/XrayR
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroot.go
121 lines (99 loc) · 2.6 KB
/
root.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package cmd
import (
"fmt"
"os"
"os/signal"
"path"
"runtime"
"strings"
"syscall"
"time"
log "github.com/sirupsen/logrus"
"github.com/fsnotify/fsnotify"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/XrayR-project/XrayR/panel"
)
var (
cfgFile string
rootCmd = &cobra.Command{
Use: "XrayR",
Run: func(cmd *cobra.Command, args []string) {
if err := run(); err != nil {
log.Fatal(err)
}
},
}
)
func init() {
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "Config file for XrayR.")
}
func getConfig() *viper.Viper {
config := viper.New()
// Set custom path and name
if cfgFile != "" {
configName := path.Base(cfgFile)
configFileExt := path.Ext(cfgFile)
configNameOnly := strings.TrimSuffix(configName, configFileExt)
configPath := path.Dir(cfgFile)
config.SetConfigName(configNameOnly)
config.SetConfigType(strings.TrimPrefix(configFileExt, "."))
config.AddConfigPath(configPath)
// Set ASSET Path and Config Path for XrayR
os.Setenv("XRAY_LOCATION_ASSET", configPath)
os.Setenv("XRAY_LOCATION_CONFIG", configPath)
} else {
// Set default config path
config.SetConfigName("config")
config.SetConfigType("yml")
config.AddConfigPath(".")
}
if err := config.ReadInConfig(); err != nil {
log.Panicf("Config file error: %s \n", err)
}
config.WatchConfig() // Watch the config
return config
}
func run() error {
showVersion()
config := getConfig()
panelConfig := &panel.Config{}
if err := config.Unmarshal(panelConfig); err != nil {
return fmt.Errorf("Parse config file %v failed: %s \n", cfgFile, err)
}
if panelConfig.LogConfig.Level == "debug" {
log.SetReportCaller(true)
}
p := panel.New(panelConfig)
lastTime := time.Now()
config.OnConfigChange(func(e fsnotify.Event) {
// Discarding event received within a short period of time after receiving an event.
if time.Now().After(lastTime.Add(3 * time.Second)) {
// Hot reload function
fmt.Println("Config file changed:", e.Name)
p.Close()
// Delete old instance and trigger GC
runtime.GC()
if err := config.Unmarshal(panelConfig); err != nil {
log.Panicf("Parse config file %v failed: %s \n", cfgFile, err)
}
if panelConfig.LogConfig.Level == "debug" {
log.SetReportCaller(true)
}
p.Start()
lastTime = time.Now()
}
})
p.Start()
defer p.Close()
// Explicitly triggering GC to remove garbage from config loading.
runtime.GC()
// Running backend
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM)
<-osSignals
return nil
}
func Execute() error {
return rootCmd.Execute()
}