From 91d3f2d006ea1c5854bf340f1daba8fd22b6e74d Mon Sep 17 00:00:00 2001 From: Mihail Slobodyanuk Date: Fri, 9 Dec 2022 19:21:17 +0200 Subject: [PATCH] Embedded meshctl calls inside mesh-ui --- contrib/ui/mesh-ui/webview.go | 149 +++++++++++++++++++++----- contrib/ui/mesh-ui/webview_other.go | 32 ------ contrib/ui/mesh-ui/webview_windows.go | 35 ------ 3 files changed, 124 insertions(+), 92 deletions(-) delete mode 100644 contrib/ui/mesh-ui/webview_other.go delete mode 100755 contrib/ui/mesh-ui/webview_windows.go diff --git a/contrib/ui/mesh-ui/webview.go b/contrib/ui/mesh-ui/webview.go index 001aade6..e76dad2f 100755 --- a/contrib/ui/mesh-ui/webview.go +++ b/contrib/ui/mesh-ui/webview.go @@ -1,7 +1,9 @@ package main import ( + "bytes" "encoding/json" + "errors" "fmt" "io/ioutil" "log" @@ -9,15 +11,16 @@ import ( "net/url" "os" "path/filepath" - "runtime" "strconv" "strings" "time" "github.com/hjson/hjson-go" "github.com/webview/webview" + "golang.org/x/text/encoding/unicode" "github.com/RiV-chain/RiV-mesh/src/admin" + "github.com/RiV-chain/RiV-mesh/src/defaults" ) func main() { @@ -40,7 +43,6 @@ func main() { fmt.Printf("Unable to create folder: %v", err) } mesh_settings_path := filepath.Join(user_home, mesh_folder, mesh_conf) - riv_ctrl_path = get_ctl_path() if _, err := os.Stat(mesh_settings_path); os.IsNotExist(err) { err := ioutil.WriteFile(mesh_settings_path, []byte(""), 0750) if err != nil { @@ -145,36 +147,19 @@ func get_user_home_path() string { } } -func get_ctl_path() string { - if runtime.GOOS == "windows" { - program_path := "programfiles" - path, exists := os.LookupEnv(program_path) - if exists { - fmt.Println("Program path: %s", path) - ctl_path := fmt.Sprintf("%s\\RiV-mesh\\meshctl.exe", path) - return ctl_path - } else { - fmt.Println("could not find Program Files path") - return "" - } - } else { - ctl_path := fmt.Sprintf("/usr/local/bin/meshctl") - return ctl_path - } -} - func run(w webview.WebView) { - if len(riv_ctrl_path) > 0 { - get_self(w) - get_peers(w) - } + get_self(w) + get_peers(w) _ = time.AfterFunc(10*time.Second, func() { run(w) }) } func add_peers(uri string) { - run_command_with_arg("addpeers", "uri="+uri) + _, err := run_command_with_arg("addpeers", "uri="+uri) + if err != nil { + log.Println("Error in the add_peers() call:", err) + } } func remove_peers() { @@ -234,3 +219,117 @@ func setPingValue(p webview.WebView, peer string, value string) { p.Eval("setPingValue('" + peer + "','" + value + "');") }) } + +func run_command(command string) []byte { + data, err := run_command_with_arg(command, "") + if err != nil { + log.Println("Error in the "+command+" call:", err) + } + return data +} + +func run_command_with_arg(command string, arg string) ([]byte, error) { + logbuffer := &bytes.Buffer{} + logger := log.New(logbuffer, "", log.Flags()) + + wrapErr := func(err error) error { + logger.Println("Error:", err) + return errors.New(fmt.Sprintln(logbuffer)) + } + + endpoint := getEndpoint(logger) + + var conn net.Conn + u, err := url.Parse(endpoint) + d := net.Dialer{Timeout: 5000 * time.Millisecond} + if err == nil { + switch strings.ToLower(u.Scheme) { + case "unix": + logger.Println("Connecting to UNIX socket", endpoint[7:]) + conn, err = d.Dial("unix", endpoint[7:]) + case "tcp": + logger.Println("Connecting to TCP socket", u.Host) + conn, err = d.Dial("tcp", u.Host) + default: + logger.Println("Unknown protocol or malformed address - check your endpoint") + err = errors.New("protocol not supported") + } + } else { + logger.Println("Connecting to TCP socket", u.Host) + conn, err = d.Dial("tcp", endpoint) + } + if err != nil { + return nil, wrapErr(err) + } + + logger.Println("Connected") + defer conn.Close() + + decoder := json.NewDecoder(conn) + encoder := json.NewEncoder(conn) + send := &admin.AdminSocketRequest{} + recv := &admin.AdminSocketResponse{} + send.Name = command + args := map[string]string{} + switch { + case len(arg) > 0: + tokens := strings.SplitN(arg, "=", 2) + args[tokens[0]] = tokens[1] + default: + } + + if send.Arguments, err = json.Marshal(args); err != nil { + return nil, err + } + if err := encoder.Encode(&send); err != nil { + return nil, err + } + logger.Printf("Request sent") + //js, _ := json.Marshal(send) + //fmt.Println("sent:", string(js)) + if err := decoder.Decode(&recv); err != nil { + return nil, wrapErr(err) + } + if recv.Status == "error" { + if err := recv.Error; err != "" { + return nil, wrapErr(errors.New("Admin socket returned an error:" + err)) + } else { + return nil, wrapErr(errors.New("Admin socket returned an error but didn't specify any error text")) + } + } + if json, err := json.MarshalIndent(recv.Response, "", " "); err == nil { + return json, nil + } + return nil, wrapErr(err) +} + +func getEndpoint(logger *log.Logger) string { + if config, err := os.ReadFile(defaults.GetDefaults().DefaultConfigFile); err == nil { + if bytes.Equal(config[0:2], []byte{0xFF, 0xFE}) || + bytes.Equal(config[0:2], []byte{0xFE, 0xFF}) { + utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM) + decoder := utf.NewDecoder() + config, err = decoder.Bytes(config) + if err != nil { + return defaults.GetDefaults().DefaultAdminListen + } + } + var dat map[string]interface{} + if err := hjson.Unmarshal(config, &dat); err != nil { + return defaults.GetDefaults().DefaultAdminListen + } + if ep, ok := dat["AdminListen"].(string); ok && (ep != "none" && ep != "") { + logger.Println("Found platform default config file", defaults.GetDefaults().DefaultConfigFile) + logger.Println("Using endpoint", ep, "from AdminListen") + return ep + } else { + logger.Println("Configuration file doesn't contain appropriate AdminListen option") + logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) + return defaults.GetDefaults().DefaultAdminListen + } + } else { + logger.Println("Can't open config file from default location", defaults.GetDefaults().DefaultConfigFile) + logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) + return defaults.GetDefaults().DefaultAdminListen + } +} diff --git a/contrib/ui/mesh-ui/webview_other.go b/contrib/ui/mesh-ui/webview_other.go deleted file mode 100644 index 782e0954..00000000 --- a/contrib/ui/mesh-ui/webview_other.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build !windows -// +build !windows - -package main - -import ( - "os/exec" -) - -var riv_ctrl_path string - -func run_command(command string) []byte { - args := []string{"-json", command} - cmd := exec.Command(riv_ctrl_path, args...) - out, err := cmd.CombinedOutput() - if err != nil { - //log.Fatalf("cmd.Run() failed with %s\n", err) - return []byte(err.Error()) - } - return out -} - -func run_command_with_arg(command string, arg string) []byte { - args := []string{"-json", command, arg} - cmd := exec.Command(riv_ctrl_path, args...) - out, err := cmd.CombinedOutput() - if err != nil { - //log.Fatalf("command failed: %s\n", riv_ctrl_path+" "+strings.Join(args, " ")) - return []byte(err.Error()) - } - return out -} diff --git a/contrib/ui/mesh-ui/webview_windows.go b/contrib/ui/mesh-ui/webview_windows.go deleted file mode 100755 index 2b0fd730..00000000 --- a/contrib/ui/mesh-ui/webview_windows.go +++ /dev/null @@ -1,35 +0,0 @@ -//go:build windows -// +build windows - -package main - -import ( - "os/exec" - "syscall" -) - -var riv_ctrl_path string - -func run_command(command string) []byte { - args := []string{"-json", command} - cmd := exec.Command(riv_ctrl_path, args...) - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - out, err := cmd.CombinedOutput() - if err != nil { - //log.Fatalf("cmd.Run() failed with %s\n", err) - return []byte(err.Error()) - } - return out -} - -func run_command_with_arg(command string, arg string) []byte { - args := []string{"-json", command, arg} - cmd := exec.Command(riv_ctrl_path, args...) - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - out, err := cmd.CombinedOutput() - if err != nil { - //log.Fatalf("command failed: %s\n", riv_ctrl_path+" "+strings.Join(args, " ")) - return []byte(err.Error()) - } - return out -}