Skip to content

Commit

Permalink
skysocksc command (#1455)
Browse files Browse the repository at this point in the history
* fix command of ServiceTypeProxy

* add skysocksc subcommand

* fix SkysocksClientStop issue | fix status of SkysocksClient

* set --pk flag to get skysocks key instead argument

* fix reset app launcher config issue
  • Loading branch information
mrpalide authored Jan 25, 2023
1 parent 64dfb59 commit e45e73d
Show file tree
Hide file tree
Showing 11 changed files with 271 additions and 41 deletions.
3 changes: 2 additions & 1 deletion cmd/apps/skysocks-client/skysocks-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
var r = netutil.NewRetrier(nil, time.Second, netutil.DefaultMaxBackoff, 0, 1)

func dialServer(ctx context.Context, appCl *app.Client, pk cipher.PubKey) (net.Conn, error) {
appCl.SetDetailedStatus(appserver.AppDetailedStatusStarting) //nolint
var conn net.Conn
err := r.Do(ctx, func() error {
var err error
Expand Down Expand Up @@ -89,7 +90,6 @@ func main() {
}

fmt.Printf("Connected to %v\n", pk)

client, err := skysocks.NewClient(conn, appCl)
if err != nil {
print(fmt.Sprintf("Failed to create a new client: %v\n", err))
Expand All @@ -98,6 +98,7 @@ func main() {
}

fmt.Printf("Serving proxy client %v\n", *addr)
setAppStatus(appCl, appserver.AppDetailedStatusRunning)

if err := client.ListenAndServe(*addr); err != nil {
print(fmt.Sprintf("Error serving proxy client: %v\n", err))
Expand Down
2 changes: 2 additions & 0 deletions cmd/skywire-cli/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
clirtfind "github.com/skycoin/skywire/cmd/skywire-cli/commands/rtfind"
cliskyfwd "github.com/skycoin/skywire/cmd/skywire-cli/commands/skyfwd"
cliskyrev "github.com/skycoin/skywire/cmd/skywire-cli/commands/skyrev"
cliskysocksc "github.com/skycoin/skywire/cmd/skywire-cli/commands/skysocksc"
clisurvey "github.com/skycoin/skywire/cmd/skywire-cli/commands/survey"
clivisor "github.com/skycoin/skywire/cmd/skywire-cli/commands/visor"
clivpn "github.com/skycoin/skywire/cmd/skywire-cli/commands/vpn"
Expand Down Expand Up @@ -188,6 +189,7 @@ func init() {
climdisc.RootCmd,
clicompletion.RootCmd,
clilog.RootCmd,
cliskysocksc.RootCmd,
treeCmd,
docCmd,
)
Expand Down
12 changes: 12 additions & 0 deletions cmd/skywire-cli/commands/skysocksc/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Package skysocksc root.go
package skysocksc

import (
"github.com/spf13/cobra"
)

// RootCmd contains commands that interact with the skywire-visor
var RootCmd = &cobra.Command{
Use: "skysocksc",
Short: "controls for Skysocks client",
}
122 changes: 122 additions & 0 deletions cmd/skywire-cli/commands/skysocksc/skysocksc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Package skysocksc cmd/skywire-cli/commands/skysocksc/skysocks.go
package skysocksc

import (
"bytes"
"fmt"
"os"
"text/tabwriter"
"time"

"github.com/spf13/cobra"

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"
)

var pk string

func init() {
RootCmd.PersistentFlags().StringVar(&clirpc.Addr, "rpc", "localhost:3435", "RPC server address")
RootCmd.AddCommand(
skysockscStartCmd,
skysockscStopCmd,
skysockscStatusCmd,
)
skysockscStartCmd.Flags().StringVar(&pk, "pk", "", "skysocks server public key")
}

var skysockscStartCmd = &cobra.Command{
Use: "start",
Short: "start the skysocks-client",
Args: cobra.MinimumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
rpcClient, err := clirpc.Client(cmd.Flags())
if err != nil {
os.Exit(1)
}
internal.Catch(cmd.Flags(), rpcClient.StartSkysocksClient(pk))
internal.PrintOutput(cmd.Flags(), nil, "Starting.")
startProcess := true
for startProcess {
time.Sleep(time.Second * 1)
internal.PrintOutput(cmd.Flags(), nil, ".")
states, err := rpcClient.Apps()
internal.Catch(cmd.Flags(), err)

type output struct {
AppError string `json:"app_error,omitempty"`
}

for _, state := range states {
if state.Name == "skysocks-client" {
if state.Status == appserver.AppStatusRunning {
startProcess = false
internal.PrintOutput(cmd.Flags(), nil, fmt.Sprintln("\nRunning!"))
}
if state.Status == appserver.AppStatusErrored {
startProcess = false
out := output{
AppError: state.DetailedStatus,
}
internal.PrintOutput(cmd.Flags(), out, fmt.Sprintln("\nError! > "+state.DetailedStatus))
}
}
}
}
},
}

var skysockscStopCmd = &cobra.Command{
Use: "stop",
Short: "stop the skysocks-client",
Run: func(cmd *cobra.Command, _ []string) {
rpcClient, err := clirpc.Client(cmd.Flags())
if err != nil {
os.Exit(1)
}
internal.Catch(cmd.Flags(), rpcClient.StopSkysocksClient())
internal.PrintOutput(cmd.Flags(), "OK", fmt.Sprintln("OK"))
},
}

var skysockscStatusCmd = &cobra.Command{
Use: "status",
Short: "skysocks-client status",
Run: func(cmd *cobra.Command, _ []string) {
rpcClient, err := clirpc.Client(cmd.Flags())
if err != nil {
os.Exit(1)
}
states, err := rpcClient.Apps()
internal.Catch(cmd.Flags(), err)

var b bytes.Buffer
w := tabwriter.NewWriter(&b, 0, 0, 5, ' ', tabwriter.TabIndent)
internal.Catch(cmd.Flags(), err)
type appState struct {
Status string `json:"status"`
}
var jsonAppStatus appState
for _, state := range states {
if state.Name == "skysocks-client" {

status := "stopped"
if state.Status == appserver.AppStatusRunning {
status = "running"
}
if state.Status == appserver.AppStatusErrored {
status = "errored"
}
jsonAppStatus = appState{
Status: status,
}
_, err = fmt.Fprintf(w, "%s\n", status)
internal.Catch(cmd.Flags(), err)
}
}
internal.Catch(cmd.Flags(), w.Flush())
internal.PrintOutput(cmd.Flags(), jsonAppStatus, b.String())
},
}
10 changes: 0 additions & 10 deletions internal/skysocks/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/skycoin/yamux"

"github.com/skycoin/skywire/pkg/app"
"github.com/skycoin/skywire/pkg/app/appserver"
"github.com/skycoin/skywire/pkg/router"
"github.com/skycoin/skywire/pkg/skyenv"
)
Expand Down Expand Up @@ -61,9 +60,6 @@ func (c *Client) ListenAndServe(addr string) error {
fmt.Printf("Listening skysocks client on %s", addr)

c.listener = l
if c.appCl != nil {
c.setAppStatus(appserver.AppDetailedStatusRunning)
}

for {
select {
Expand Down Expand Up @@ -174,12 +170,6 @@ func (c *Client) ListenIPC(client *ipc.Client) {
})
}

func (c *Client) setAppStatus(status appserver.AppDetailedStatus) {
if err := c.appCl.SetDetailedStatus(string(status)); err != nil {
print(fmt.Sprintf("Failed to set status %v: %v\n", status, err))
}
}

func (c *Client) setAppError(appErr error) {
if err := c.appCl.SetError(appErr.Error()); err != nil {
print(fmt.Sprintf("Failed to set error %v: %v\n", appErr, err))
Expand Down
3 changes: 1 addition & 2 deletions pkg/servicedisc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import (
const (
// ServiceTypeSkysocks stands for the skysocks discovery.
ServiceTypeSkysocks = "skysocks"
// ServiceTypeProxy stands for the proxy discovery.
// proxy and skysock are same
// ServiceTypeProxy stands for the proxy discovery. Proxy and Skysocks are same
ServiceTypeProxy = "proxy"
// ServiceTypeVPN stands for the VPN discovery.
ServiceTypeVPN = "vpn"
Expand Down
87 changes: 80 additions & 7 deletions pkg/visor/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ type API interface {
StopVPNClient(appName string) error
VPNServers(version, country string) ([]servicedisc.Service, error)

//skysocks-client controls
StartSkysocksClient(pk string) error
StopSkysocksClient() error

//transports
TransportTypes() ([]string, error)
Transports(types []string, pks []cipher.PubKey, logs bool) ([]*TransportSummary, error)
Expand Down Expand Up @@ -511,6 +515,61 @@ func (v *Visor) StopVPNClient(appName string) error {
return ErrProcNotAvailable
}

// StartSkysocksClient implements API.
func (v *Visor) StartSkysocksClient(serverKey string) error {
var envs []string
if v.tpM == nil {
return ErrTrpMangerNotAvailable
}

if len(v.conf.Launcher.Apps) == 0 {
return errors.New("no skysocks-client app configuration found")
}

for index, app := range v.conf.Launcher.Apps {
if app.Name == visorconfig.SkysocksClientName {
if v.GetSkysocksClientAddress() == "" && serverKey == "" {
return errors.New("Skysocks server pub key is missing")
}

if serverKey != "" {
var pk cipher.PubKey
if err := pk.Set(serverKey); err != nil {
return err
}
v.SetAppPK(visorconfig.SkysocksClientName, pk) //nolint
// we set the args in memory and pass it in `v.appL.StartApp`
// unlike the api method `StartApp` where `nil` is passed in `v.appL.StartApp` as args
// but the args are set in the config
v.conf.Launcher.Apps[index].Args = []string{"-srv", pk.Hex()}
} else {
var pk cipher.PubKey
if err := pk.Set(v.GetSkysocksClientAddress()); err != nil {
return err
}
v.conf.Launcher.Apps[index].Args = []string{"-srv", pk.Hex()}
}

// check process manager availability
if v.procM != nil {
return v.appL.StartApp(visorconfig.SkysocksClientName, v.conf.Launcher.Apps[index].Args, envs)
}
return ErrProcNotAvailable
}
}
return errors.New("no skysocks-client app configuration found")
}

// StopSkysocksClient implements API.
func (v *Visor) StopSkysocksClient() error {
// check process manager availability
if v.procM != nil {
_, err := v.appL.StopApp(visorconfig.SkysocksClientName) //nolint:errcheck
return err
}
return ErrProcNotAvailable
}

// SetAppDetailedStatus implements API.
func (v *Visor) SetAppDetailedStatus(appName, status string) error {
proc, ok := v.procM.ProcByName(appName)
Expand Down Expand Up @@ -553,7 +612,7 @@ func (v *Visor) SetAutoStart(appName string, autoStart bool) error {
}

v.log.Infof("Saving auto start = %v for app %v to config", autoStart, appName)
return v.conf.UpdateAppAutostart(appName, autoStart)
return v.conf.UpdateAppAutostart(v.appL, appName, autoStart)
}

// SetAppPassword implements API.
Expand All @@ -578,7 +637,7 @@ func (v *Visor) SetAppPassword(appName, password string) error {
const (
passcodeArgName = "-passcode"
)
if err := v.conf.UpdateAppArg(appName, passcodeArgName, password); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, passcodeArgName, password); err != nil {
return err
}

Expand All @@ -598,7 +657,7 @@ func (v *Visor) SetAppNetworkInterface(appName, netifc string) error {
const (
netifcArgName = "--netifc"
)
if err := v.conf.UpdateAppArg(appName, netifcArgName, netifc); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, netifcArgName, netifc); err != nil {
return err
}

Expand All @@ -618,7 +677,7 @@ func (v *Visor) SetAppKillswitch(appName string, killswitch bool) error {
const (
killSwitchArg = "--killswitch"
)
if err := v.conf.UpdateAppArg(appName, killSwitchArg, killswitch); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, killSwitchArg, killswitch); err != nil {
return err
}

Expand All @@ -638,7 +697,7 @@ func (v *Visor) SetAppSecure(appName string, isSecure bool) error {
const (
secureArgName = "--secure"
)
if err := v.conf.UpdateAppArg(appName, secureArgName, isSecure); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, secureArgName, isSecure); err != nil {
return err
}
v.log.Infof("Updated %v secure state", appName)
Expand Down Expand Up @@ -667,7 +726,7 @@ func (v *Visor) SetAppPK(appName string, pk cipher.PubKey) error {
const (
pkArgName = "-srv"
)
if err := v.conf.UpdateAppArg(appName, pkArgName, pk.String()); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, pkArgName, pk.String()); err != nil {
return err
}

Expand Down Expand Up @@ -697,7 +756,7 @@ func (v *Visor) SetAppDNS(appName string, dnsAddr string) error {
pkArgName = "-dns"
)

if err := v.conf.UpdateAppArg(appName, pkArgName, dnsAddr); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, pkArgName, dnsAddr); err != nil {
return err
}

Expand Down Expand Up @@ -1274,6 +1333,20 @@ func (v *Visor) GetVPNClientAddress() string {
return ""
}

// GetSkysocksClientAddress get PK address of server set on skysocks-client
func (v *Visor) GetSkysocksClientAddress() string {
for _, v := range v.conf.Launcher.Apps {
if v.Name == visorconfig.SkysocksClientAddr {
for index := range v.Args {
if v.Args[index] == "-srv" {
return v.Args[index+1]
}
}
}
}
return ""
}

// IsDMSGClientReady return availability of dsmg client
func (v *Visor) IsDMSGClientReady() (bool, error) {
if v.isDTMReady() {
Expand Down
14 changes: 14 additions & 0 deletions pkg/visor/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,20 @@ func (r *RPC) StopVPNClient(name *string, _ *struct{}) (err error) {
return r.visor.StopVPNClient(*name)
}

// StartSkysocksClient starts SkysocksClient App
func (r *RPC) StartSkysocksClient(pk string, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "StartSkysocksClient", pk)(nil, &err)

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)

return r.visor.StopSkysocksClient()
}

// RestartApp restarts App with provided name.
func (r *RPC) RestartApp(name *string, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "RestartApp", name)(nil, &err)
Expand Down
Loading

0 comments on commit e45e73d

Please sign in to comment.