mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-11-17 18:06:15 -05:00
commit
bb441a6eb1
@ -4,6 +4,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/platform"
|
"v2ray.com/core/common/platform"
|
||||||
@ -35,14 +36,14 @@ func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
|
|||||||
if err := cmd.Wait(); err != nil {
|
if err := cmd.Wait(); err != nil {
|
||||||
msg := "failed to execute v2ctl"
|
msg := "failed to execute v2ctl"
|
||||||
if errBuffer.Len() > 0 {
|
if errBuffer.Len() > 0 {
|
||||||
msg += ": " + errBuffer.MultiBuffer.String()
|
msg += ": \n" + strings.TrimSpace(errBuffer.MultiBuffer.String())
|
||||||
}
|
}
|
||||||
return nil, newError(msg).Base(err)
|
return nil, newError(msg).Base(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log stderr, info message
|
// log stderr, info message
|
||||||
if !errBuffer.IsEmpty() {
|
if !errBuffer.IsEmpty() {
|
||||||
newError("v2ctl > \n", errBuffer.MultiBuffer.String()).AtInfo().WriteToLog()
|
newError("<v2ctl message> \n", strings.TrimSpace(errBuffer.MultiBuffer.String())).AtInfo().WriteToLog()
|
||||||
}
|
}
|
||||||
|
|
||||||
return outBuffer.MultiBuffer, nil
|
return outBuffer.MultiBuffer, nil
|
||||||
|
@ -83,3 +83,10 @@ func GetConfigurationPath() string {
|
|||||||
configPath := NewEnvFlag(name).GetValue(getExecutableDir)
|
configPath := NewEnvFlag(name).GetValue(getExecutableDir)
|
||||||
return filepath.Join(configPath, "config.json")
|
return filepath.Join(configPath, "config.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetConfDirPath reads "v2ray.location.confdir"
|
||||||
|
func GetConfDirPath() string {
|
||||||
|
const name = "v2ray.location.confdir"
|
||||||
|
configPath := NewEnvFlag(name).GetValue(func() string { return "" })
|
||||||
|
return configPath
|
||||||
|
}
|
||||||
|
@ -2,6 +2,8 @@ package conf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"v2ray.com/core"
|
"v2ray.com/core"
|
||||||
@ -31,6 +33,8 @@ var (
|
|||||||
"mtproto": func() interface{} { return new(MTProtoClientConfig) },
|
"mtproto": func() interface{} { return new(MTProtoClientConfig) },
|
||||||
"dns": func() interface{} { return new(DnsOutboundConfig) },
|
"dns": func() interface{} { return new(DnsOutboundConfig) },
|
||||||
}, "protocol", "settings")
|
}, "protocol", "settings")
|
||||||
|
|
||||||
|
ctllog = log.New(os.Stderr, "v2ctl> ", 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
func toProtocolList(s []string) ([]proxyman.KnownProtocols, error) {
|
func toProtocolList(s []string) ([]proxyman.KnownProtocols, error) {
|
||||||
@ -361,10 +365,10 @@ func (c *Config) Override(o *Config, fn string) {
|
|||||||
if len(c.InboundConfigs) > 0 && len(o.InboundConfigs) == 1 {
|
if len(c.InboundConfigs) > 0 && len(o.InboundConfigs) == 1 {
|
||||||
if idx := c.findInboundTag(o.InboundConfigs[0].Tag); idx > -1 {
|
if idx := c.findInboundTag(o.InboundConfigs[0].Tag); idx > -1 {
|
||||||
c.InboundConfigs[idx] = o.InboundConfigs[0]
|
c.InboundConfigs[idx] = o.InboundConfigs[0]
|
||||||
newError("<", fn, "> updated inbound with tag: ", o.InboundConfigs[0].Tag).AtInfo().WriteToLog()
|
ctllog.Println("[", fn, "] updated inbound with tag: ", o.InboundConfigs[0].Tag)
|
||||||
} else {
|
} else {
|
||||||
c.InboundConfigs = append(c.InboundConfigs, o.InboundConfigs[0])
|
c.InboundConfigs = append(c.InboundConfigs, o.InboundConfigs[0])
|
||||||
newError("<", fn, "> appended inbound with tag: ", o.InboundConfigs[0].Tag).AtInfo().WriteToLog()
|
ctllog.Println("[", fn, "] appended inbound with tag: ", o.InboundConfigs[0].Tag)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.InboundConfigs = o.InboundConfigs
|
c.InboundConfigs = o.InboundConfigs
|
||||||
@ -376,14 +380,14 @@ func (c *Config) Override(o *Config, fn string) {
|
|||||||
if len(c.OutboundConfigs) > 0 && len(o.OutboundConfigs) == 1 {
|
if len(c.OutboundConfigs) > 0 && len(o.OutboundConfigs) == 1 {
|
||||||
if idx := c.findOutboundTag(o.OutboundConfigs[0].Tag); idx > -1 {
|
if idx := c.findOutboundTag(o.OutboundConfigs[0].Tag); idx > -1 {
|
||||||
c.OutboundConfigs[idx] = o.OutboundConfigs[0]
|
c.OutboundConfigs[idx] = o.OutboundConfigs[0]
|
||||||
newError("<", fn, "> updated outbound with tag: ", o.OutboundConfigs[0].Tag).AtInfo().WriteToLog()
|
ctllog.Println("[", fn, "] updated outbound with tag: ", o.OutboundConfigs[0].Tag)
|
||||||
} else {
|
} else {
|
||||||
if strings.Contains(strings.ToLower(fn), "tail") {
|
if strings.Contains(strings.ToLower(fn), "tail") {
|
||||||
c.OutboundConfigs = append(c.OutboundConfigs, o.OutboundConfigs[0])
|
c.OutboundConfigs = append(c.OutboundConfigs, o.OutboundConfigs[0])
|
||||||
newError("<", fn, "> appended outbound with tag: ", o.OutboundConfigs[0].Tag).AtInfo().WriteToLog()
|
ctllog.Println("[", fn, "] appended outbound with tag: ", o.OutboundConfigs[0].Tag)
|
||||||
} else {
|
} else {
|
||||||
c.OutboundConfigs = append(o.OutboundConfigs, c.OutboundConfigs...)
|
c.OutboundConfigs = append(o.OutboundConfigs, c.OutboundConfigs...)
|
||||||
newError("<", fn, "> prepended outbound with tag: ", o.OutboundConfigs[0].Tag).AtInfo().WriteToLog()
|
ctllog.Println("[", fn, "] prepended outbound with tag: ", o.OutboundConfigs[0].Tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,6 +2,8 @@ package control
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,6 +20,7 @@ type Command interface {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
commandRegistry = make(map[string]Command)
|
commandRegistry = make(map[string]Command)
|
||||||
|
ctllog = log.New(os.Stderr, "v2ctl> ", 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterCommand(cmd Command) error {
|
func RegisterCommand(cmd Command) error {
|
||||||
|
@ -37,11 +37,13 @@ func (c *ConfigCommand) Execute(args []string) error {
|
|||||||
|
|
||||||
conf := &conf.Config{}
|
conf := &conf.Config{}
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
newError("Reading config: ", arg).AtInfo().WriteToLog()
|
ctllog.Println("Read config: ", arg)
|
||||||
r, err := c.LoadArg(arg)
|
r, err := c.LoadArg(arg)
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
c, err := serial.DecodeJSONConfig(r)
|
c, err := serial.DecodeJSONConfig(r)
|
||||||
common.Must(err)
|
if err != nil {
|
||||||
|
ctllog.Fatalln(err)
|
||||||
|
}
|
||||||
conf.Override(c, arg)
|
conf.Override(c, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
main/main.go
44
main/main.go
@ -5,8 +5,11 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
@ -20,10 +23,10 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
configFiles cmdarg.Arg // "Config file for V2Ray.", the option is customed type, parse in main
|
configFiles cmdarg.Arg // "Config file for V2Ray.", the option is customed type, parse in main
|
||||||
|
configDir string
|
||||||
version = flag.Bool("version", false, "Show current version of V2Ray.")
|
version = flag.Bool("version", false, "Show current version of V2Ray.")
|
||||||
test = flag.Bool("test", false, "Test config file only, without launching V2Ray server.")
|
test = flag.Bool("test", false, "Test config file only, without launching V2Ray server.")
|
||||||
format = flag.String("format", "json", "Format of input file.")
|
format = flag.String("format", "json", "Format of input file.")
|
||||||
errNoConfig = newError("no valid config")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func fileExists(file string) bool {
|
func fileExists(file string) bool {
|
||||||
@ -31,7 +34,27 @@ func fileExists(file string) bool {
|
|||||||
return err == nil && !info.IsDir()
|
return err == nil && !info.IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func dirExists(file string) bool {
|
||||||
|
info, err := os.Stat(file)
|
||||||
|
return err == nil && info.IsDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
func readConfDir(dirPath string) {
|
||||||
|
confs, err := ioutil.ReadDir(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
for _, f := range confs {
|
||||||
|
if strings.HasSuffix(f.Name(), ".json") {
|
||||||
|
configFiles.Set(path.Join(dirPath, f.Name()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getConfigFilePath() (cmdarg.Arg, error) {
|
func getConfigFilePath() (cmdarg.Arg, error) {
|
||||||
|
if dirExists(configDir) {
|
||||||
|
readConfDir(configDir)
|
||||||
|
}
|
||||||
if len(configFiles) > 0 {
|
if len(configFiles) > 0 {
|
||||||
return configFiles, nil
|
return configFiles, nil
|
||||||
}
|
}
|
||||||
@ -39,14 +62,25 @@ func getConfigFilePath() (cmdarg.Arg, error) {
|
|||||||
if workingDir, err := os.Getwd(); err == nil {
|
if workingDir, err := os.Getwd(); err == nil {
|
||||||
configFile := filepath.Join(workingDir, "config.json")
|
configFile := filepath.Join(workingDir, "config.json")
|
||||||
if fileExists(configFile) {
|
if fileExists(configFile) {
|
||||||
|
log.Println("Using default config: ", configFile)
|
||||||
return cmdarg.Arg{configFile}, nil
|
return cmdarg.Arg{configFile}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if configFile := platform.GetConfigurationPath(); fileExists(configFile) {
|
if configFile := platform.GetConfigurationPath(); fileExists(configFile) {
|
||||||
|
log.Println("Using config from env: ", configFile)
|
||||||
return cmdarg.Arg{configFile}, nil
|
return cmdarg.Arg{configFile}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if envConfDir := platform.GetConfDirPath(); dirExists(envConfDir) {
|
||||||
|
log.Println("Using confdir from env: ", envConfDir)
|
||||||
|
readConfDir(envConfDir)
|
||||||
|
if len(configFiles) > 0 {
|
||||||
|
return configFiles, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Using config from STDIN")
|
||||||
return cmdarg.Arg{"stdin:"}, nil
|
return cmdarg.Arg{"stdin:"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +121,8 @@ func printVersion() {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Var(&configFiles, "config", "Config file for V2Ray. Multiple assign is accepted (only json). Latter ones overrides the former ones.")
|
flag.Var(&configFiles, "config", "Config file for V2Ray. Multiple assign is accepted (only json). Latter ones overrides the former ones.")
|
||||||
flag.Var(&configFiles, "c", "short alias of -config")
|
flag.Var(&configFiles, "c", "Short alias of -config")
|
||||||
|
flag.StringVar(&configDir, "confdir", "", "A dir with multiple json config")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
printVersion()
|
printVersion()
|
||||||
@ -98,11 +133,8 @@ func main() {
|
|||||||
|
|
||||||
server, err := startV2Ray()
|
server, err := startV2Ray()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err)
|
||||||
// Configuration error. Exit with a special value to prevent systemd from restarting.
|
// Configuration error. Exit with a special value to prevent systemd from restarting.
|
||||||
if err == errNoConfig {
|
|
||||||
flag.PrintDefaults()
|
|
||||||
}
|
|
||||||
os.Exit(23)
|
os.Exit(23)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user