Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve skywire-cli proxy command #1680

1 change: 1 addition & 0 deletions cmd/skywire-cli/commands/config/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ var genConfigCmd = &cobra.Command{
Binary: visorconfig.SkysocksClientName,
AutoStart: false,
Port: routing.Port(visorconfig.SkysocksClientPort),
Args: []string{"-addr", visorconfig.SkysocksClientAddr},
},
{
Name: visorconfig.VPNServerName,
Expand Down
138 changes: 116 additions & 22 deletions cmd/skywire-cli/commands/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package skysocksc

import (
"bytes"
"context"
"encoding/json"
"fmt"
"math/rand"
Expand All @@ -12,14 +13,17 @@ import (
"text/tabwriter"
"time"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/skycoin/skywire-utilities/pkg/buildinfo"
"github.com/skycoin/skywire-utilities/pkg/cmdutil"
"github.com/skycoin/skywire-utilities/pkg/skyenv"
clirpc "github.com/skycoin/skywire/cmd/skywire-cli/commands/rpc"
"github.com/skycoin/skywire/cmd/skywire-cli/internal"
"github.com/skycoin/skywire/pkg/app/appserver"
"github.com/skycoin/skywire/pkg/routing"
"github.com/skycoin/skywire/pkg/servicedisc"
)

Expand All @@ -36,6 +40,10 @@ func init() {
version = ""
}
startCmd.Flags().StringVarP(&pk, "pk", "k", "", "server public key")
startCmd.Flags().StringVarP(&addr, "addr", "a", "", "address of proxy for use")
startCmd.Flags().StringVarP(&clientName, "name", "n", "", "name of skysocks client")
stopCmd.Flags().BoolVar(&allClients, "all", false, "stop all skysocks client")
stopCmd.Flags().StringVar(&clientName, "name", "", "specific skysocks client that want stop")
listCmd.Flags().StringVarP(&sdURL, "url", "a", "", "service discovery url default:\n"+skyenv.ServiceDiscAddr)
listCmd.Flags().BoolVarP(&directQuery, "direct", "b", false, "query service discovery directly")
listCmd.Flags().StringVarP(&pk, "pk", "k", "", "check "+serviceType+" service discovery for public key")
Expand All @@ -50,25 +58,81 @@ var startCmd = &cobra.Command{
Use: "start",
Short: "start the " + serviceType + " client",
Run: func(cmd *cobra.Command, args []string) {
//check that a valid public key is provided
err := pubkey.Set(pk)

rpcClient, err := clirpc.Client(cmd.Flags())
if err != nil {
if len(args) > 0 {
err := pubkey.Set(args[0])
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("unable to create RPC client: %w", err))
}

if clientName != "" && pk != "" && addr != "" {
// add new app with -srv and -addr args, and if app was there just change -srv and -addr args and run it
err := pubkey.Set(pk)
if err != nil {
if len(args) > 0 {
err := pubkey.Set(args[0])
if err != nil {
internal.PrintFatalError(cmd.Flags(), err)
}
} else {
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("Invalid or missing public key"))
}
}

arguments := map[string]string{}
arguments["srv"] = pubkey.String()
arguments["addr"] = addr

_, err = rpcClient.App(clientName)
if err == nil {
err = rpcClient.DoCustomSetting(clientName, arguments)
if err != nil {
internal.PrintFatalError(cmd.Flags(), err)
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("Error occurs during set args to custom skysocks client"))
}
} else {
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("Invalid or missing public key"))
err = rpcClient.AddApp(clientName, "skysocks-client")
if err != nil {
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("Error during add new app"))
}
err = rpcClient.DoCustomSetting(clientName, arguments)
if err != nil {
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("Error occurs during set args to custom skysocks client"))
}
}
internal.Catch(cmd.Flags(), rpcClient.StartApp(clientName))
internal.PrintOutput(cmd.Flags(), nil, "Starting.")
} else if clientName != "" && pk == "" && addr == "" {
internal.Catch(cmd.Flags(), rpcClient.StartApp(clientName))
internal.PrintOutput(cmd.Flags(), nil, "Starting.")
} else if pk != "" && clientName == "" && addr == "" {
err := pubkey.Set(pk)
if err != nil {
if len(args) > 0 {
err := pubkey.Set(args[0])
if err != nil {
internal.PrintFatalError(cmd.Flags(), err)
}
} else {
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("Invalid or missing public key"))
}
}
internal.Catch(cmd.Flags(), rpcClient.StartSkysocksClient(pubkey.String()))
internal.PrintOutput(cmd.Flags(), nil, "Starting.")
clientName = "skysocks-client"
// change defaul skysocks-proxy app -srv arg and run it
} else {
// error
return
}
rpcClient, err := clirpc.Client(cmd.Flags())
if err != nil {
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("unable to create RPC client: %w", err))
}
//TODO: implement operational timeout
internal.Catch(cmd.Flags(), rpcClient.StartSkysocksClient(pubkey.String()))
internal.PrintOutput(cmd.Flags(), nil, "Starting.")

ctx, cancel := cmdutil.SignalContext(context.Background(), &logrus.Logger{})
defer cancel()
go func() {
<-ctx.Done()
cancel()
rpcClient.StopApp(clientName) //nolint
os.Exit(1)
}()

startProcess := true
for startProcess {
time.Sleep(time.Second * 1)
Expand Down Expand Up @@ -107,8 +171,19 @@ var stopCmd = &cobra.Command{
if err != nil {
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("unable to create RPC client: %w", err))
}
internal.Catch(cmd.Flags(), rpcClient.StopSkysocksClient())
internal.PrintOutput(cmd.Flags(), "OK", fmt.Sprintln("OK"))
if allClients && clientName != "" {
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("cannot use both --all and --name flag in together"))
}
if !allClients && clientName == "" {
internal.PrintFatalError(cmd.Flags(), fmt.Errorf("you should use one of flags, --all or --name"))
}
if allClients {
internal.Catch(cmd.Flags(), rpcClient.StopSkysocksClients())
internal.PrintOutput(cmd.Flags(), "all skysocks client stopped", fmt.Sprintln("all skysocks clients stopped"))
return
}
internal.Catch(cmd.Flags(), rpcClient.StopApp(clientName))
internal.PrintOutput(cmd.Flags(), fmt.Sprintf("skysocks client %s stopped", clientName), fmt.Sprintf("skysocks client %s stopped\n", clientName))
},
}

Expand All @@ -128,26 +203,45 @@ var statusCmd = &cobra.Command{
w := tabwriter.NewWriter(&b, 0, 0, 5, ' ', tabwriter.TabIndent)
internal.Catch(cmd.Flags(), err)
type appState struct {
Status string `json:"status"`
Name string `json:"name"`
Status string `json:"status"`
AutoStart bool `json:"autostart"`
Args []string `json:"args"`
AppPort routing.Port `json:"app_port"`
}
var jsonAppStatus appState
var jsonAppStatus []appState
fmt.Fprintf(w, "---- All Proxy List -----------------------------------------------------\n\n")
for _, state := range states {
if state.Name == stateName {

if state.AppConfig.Binary == binaryName {
status := "stopped"
if state.Status == appserver.AppStatusRunning {
status = "running"
}
if state.Status == appserver.AppStatusErrored {
status = "errored"
}
jsonAppStatus = appState{
Status: status,
jsonAppStatus = append(jsonAppStatus, appState{
Name: state.Name,
Status: status,
AutoStart: state.AutoStart,
Args: state.Args,
AppPort: state.Port,
})
var tmpAddr string
var tmpSrv string
for idx, arg := range state.Args {
if arg == "-srv" {
tmpSrv = state.Args[idx+1]
}
if arg == "-addr" {
tmpAddr = "127.0.0.1" + state.Args[idx+1]
}
}
_, err = fmt.Fprintf(w, "%s\n", status)
_, err = fmt.Fprintf(w, "Name: %s\nStatus: %s\nServer: %s\nAddress: %s\nAppPort: %d\nAutoStart: %t\n\n", state.Name, status, tmpSrv, tmpAddr, state.Port, state.AutoStart)
internal.Catch(cmd.Flags(), err)
}
}
fmt.Fprintf(w, "-------------------------------------------------------------------------\n")
internal.Catch(cmd.Flags(), w.Flush())
internal.PrintOutput(cmd.Flags(), jsonAppStatus, b.String())
},
Expand Down
4 changes: 4 additions & 0 deletions cmd/skywire-cli/commands/proxy/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

var (
binaryName = "skysocks-client"
stateName = "skysocks-client"
serviceType = servicedisc.ServiceTypeProxy
servicePort = ":44"
Expand All @@ -22,6 +23,9 @@ var (
sdURL string
directQuery bool
servers []servicedisc.Service
allClients bool
clientName string
addr string
)

// RootCmd contains commands that interact with the skywire-visor
Expand Down
11 changes: 11 additions & 0 deletions cmd/skywire-cli/commands/vpn/vvpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package clivpn

import (
"bytes"
"context"
"encoding/json"
"fmt"
"math/rand"
Expand All @@ -12,10 +13,12 @@ import (
"text/tabwriter"
"time"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/skycoin/skywire-utilities/pkg/buildinfo"
"github.com/skycoin/skywire-utilities/pkg/cmdutil"
"github.com/skycoin/skywire-utilities/pkg/skyenv"
clirpc "github.com/skycoin/skywire/cmd/skywire-cli/commands/rpc"
"github.com/skycoin/skywire/cmd/skywire-cli/internal"
Expand Down Expand Up @@ -80,6 +83,14 @@ var startCmd = &cobra.Command{
}
internal.Catch(cmd.Flags(), rpcClient.StartVPNClient(pubkey))
internal.PrintOutput(cmd.Flags(), nil, "Starting.")
ctx, cancel := cmdutil.SignalContext(context.Background(), &logrus.Logger{})
defer cancel()
go func() {
<-ctx.Done()
cancel()
rpcClient.StopVPNClient("vpn-client") //nolint
os.Exit(1)
}()
startProcess := true
for startProcess {
time.Sleep(time.Second * 1)
Expand Down
24 changes: 19 additions & 5 deletions pkg/visor/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type API interface {
App(appName string) (*appserver.AppState, error)
Apps() ([]*appserver.AppState, error)
StartApp(appName string) error
AddApp(appName, binaryName string) error
RegisterApp(procConf appcommon.ProcConfig) (appcommon.ProcKey, error)
DeregisterApp(procKey appcommon.ProcKey) error
StopApp(appName string) error
Expand Down Expand Up @@ -89,7 +90,7 @@ type API interface {

//skysocks-client controls
StartSkysocksClient(pk string) error
StopSkysocksClient() error
StopSkysocksClients() error
ProxyServers(version, country string) ([]servicedisc.Service, error)

//transports
Expand Down Expand Up @@ -459,6 +460,15 @@ func (v *Visor) StartApp(appName string) error {
return ErrProcNotAvailable
}

// AddApp implement API.
func (v *Visor) AddApp(appName, binaryName string) error {
// check process manager and app launcher availability
if v.appL == nil {
return ErrAppLauncherNotAvailable
}
return v.conf.AddAppConfig(v.appL, appName, binaryName)
}

// RegisterApp implements API.
func (v *Visor) RegisterApp(procConf appcommon.ProcConfig) (appcommon.ProcKey, error) {
// check process manager and app launcher availability
Expand Down Expand Up @@ -598,15 +608,19 @@ func (v *Visor) StartSkysocksClient(serverKey string) error {
return errors.New("no skysocks-client app configuration found")
}

// StopSkysocksClient implements API.
func (v *Visor) StopSkysocksClient() error {
// StopSkysocksClients implements API.
func (v *Visor) StopSkysocksClients() error {
// check process manager and app launcher availability
if v.appL == nil {
return ErrAppLauncherNotAvailable
}
if v.procM != nil {
_, err := v.appL.StopApp(visorconfig.SkysocksClientName) //nolint:errcheck
return err
for _, app := range v.conf.Launcher.Apps {
if app.Binary == visorconfig.SkysocksClientName {
v.appL.StopApp(app.Name) //nolint
}
}
return nil
}
return ErrProcNotAvailable
}
Expand Down
27 changes: 23 additions & 4 deletions pkg/visor/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,25 @@ func (r *RPC) StartApp(name *string, _ *struct{}) (err error) {
return r.visor.StartApp(*name)
}

// SetAppAddIn is input for SetAppAdd.
type SetAppAddIn struct {
AppName string
BinaryName string
}

// AddApp add app to config
func (r *RPC) AddApp(in *SetAppAddIn, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "AddApp", in)(nil, &err)

return r.visor.AddApp(in.AppName, in.BinaryName)
}

// DoCustomSetting set custom setting to apps arguments
func (r *RPC) DoCustomSetting(in *SetAppMapIn, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "DoCustomSetting", in)(nil, &err)
return r.visor.DoCustomSetting(in.AppName, in.Val)
}

// RegisterApp registers a App with provided proc config.
func (r *RPC) RegisterApp(procConf *appcommon.ProcConfig, reply *appcommon.ProcKey) (err error) {
defer rpcutil.LogCall(r.log, "RegisterApp", procConf)(reply, &err)
Expand Down Expand Up @@ -290,11 +309,11 @@ func (r *RPC) StartSkysocksClient(pk string, _ *struct{}) (err error) {
return r.visor.StartSkysocksClient(pk)
}

// StopSkysocksClient stops SkysocksClient App
func (r *RPC) StopSkysocksClient(_ *struct{}, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "StopSkysocksClient", nil)(nil, &err)
// StopSkysocksClients stops all SkysocksClient Apps
func (r *RPC) StopSkysocksClients(_ *struct{}, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "StopSkysocksClients", nil)(nil, &err)

return r.visor.StopSkysocksClient()
return r.visor.StopSkysocksClients()
}

// RestartApp restarts App with provided name.
Expand Down
Loading
Loading