github.com/v2fly/v2ray-core/v4@v4.45.2/infra/control/config.go (about)

     1  package control
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/golang/protobuf/proto"
    10  
    11  	"github.com/v2fly/v2ray-core/v4/common"
    12  	"github.com/v2fly/v2ray-core/v4/infra/conf"
    13  	"github.com/v2fly/v2ray-core/v4/infra/conf/serial"
    14  )
    15  
    16  // ConfigCommand is the json to pb convert struct
    17  type ConfigCommand struct{}
    18  
    19  // Name for cmd usage
    20  func (c *ConfigCommand) Name() string {
    21  	return "config"
    22  }
    23  
    24  // Description for help usage
    25  func (c *ConfigCommand) Description() Description {
    26  	return Description{
    27  		Short: "merge multiple json config",
    28  		Usage: []string{"v2ctl config config.json c1.json c2.json <url>.json"},
    29  	}
    30  }
    31  
    32  // Execute real work here.
    33  func (c *ConfigCommand) Execute(args []string) error {
    34  	if len(args) < 1 {
    35  		return newError("empty config list")
    36  	}
    37  
    38  	conf := &conf.Config{}
    39  	for _, arg := range args {
    40  		ctllog.Println("Read config: ", arg)
    41  		r, err := c.LoadArg(arg)
    42  		common.Must(err)
    43  		c, err := serial.DecodeJSONConfig(r)
    44  		if err != nil {
    45  			ctllog.Fatalln(err)
    46  		}
    47  		conf.Override(c, arg)
    48  	}
    49  
    50  	pbConfig, err := conf.Build()
    51  	if err != nil {
    52  		return err
    53  	}
    54  
    55  	bytesConfig, err := proto.Marshal(pbConfig)
    56  	if err != nil {
    57  		return newError("failed to marshal proto config").Base(err)
    58  	}
    59  
    60  	if _, err := os.Stdout.Write(bytesConfig); err != nil {
    61  		return newError("failed to write proto config").Base(err)
    62  	}
    63  
    64  	return nil
    65  }
    66  
    67  // LoadArg loads one arg, maybe an remote url, or local file path
    68  func (c *ConfigCommand) LoadArg(arg string) (out io.Reader, err error) {
    69  	var data []byte
    70  	switch {
    71  	case strings.HasPrefix(arg, "http://"), strings.HasPrefix(arg, "https://"):
    72  		data, err = FetchHTTPContent(arg)
    73  
    74  	case arg == "stdin:":
    75  		data, err = io.ReadAll(os.Stdin)
    76  
    77  	default:
    78  		data, err = os.ReadFile(arg)
    79  	}
    80  
    81  	if err != nil {
    82  		return
    83  	}
    84  	out = bytes.NewBuffer(data)
    85  	return
    86  }
    87  
    88  func init() {
    89  	common.Must(RegisterCommand(&ConfigCommand{}))
    90  }