diff --git a/cmd/skywire-cli/commands/visor/gen-config.go b/cmd/skywire-cli/commands/visor/gen-config.go index 0f10905500..15772ef56e 100644 --- a/cmd/skywire-cli/commands/visor/gen-config.go +++ b/cmd/skywire-cli/commands/visor/gen-config.go @@ -2,17 +2,14 @@ package visor import ( "encoding/json" - "errors" "fmt" "io/ioutil" - "net" "path" "path/filepath" - "time" - - "github.com/SkycoinProject/skywire-mainnet/pkg/app/appcommon" "github.com/SkycoinProject/skywire-mainnet/internal/skyenv" + "github.com/SkycoinProject/skywire-mainnet/pkg/app/appcommon" + "github.com/SkycoinProject/skywire-mainnet/pkg/restart" "github.com/SkycoinProject/skywire-mainnet/pkg/routing" "github.com/SkycoinProject/dmsg/cipher" @@ -87,8 +84,8 @@ func fillInOldKeys(confPath string, conf *visor.Config) error { return fmt.Errorf("invalid old configuration file: %w", err) } - conf.Visor.StaticPubKey = oldConf.Visor.StaticPubKey - conf.Visor.StaticSecKey = oldConf.Visor.StaticSecKey + conf.KeyPair.StaticPubKey = oldConf.KeyPair.StaticPubKey + conf.KeyPair.StaticSecKey = oldConf.KeyPair.StaticSecKey return nil } @@ -109,25 +106,17 @@ func localConfig() *visor.Config { func defaultConfig() *visor.Config { conf := &visor.Config{} - conf.Version = "1.0" - pk, sk := cipher.GenerateKeyPair() - conf.Visor.StaticPubKey = pk - conf.Visor.StaticSecKey = sk + conf.KeyPair = visor.NewKeyPair() - lIPaddr, err := getLocalIPAddress() + stcp, err := visor.DefaultSTCPConfig() if err != nil { logger.Warn(err) - } - - conf.STCP.LocalAddr = lIPaddr - - if testenv { - conf.Dmsg.Discovery = skyenv.TestDmsgDiscAddr } else { - conf.Dmsg.Discovery = skyenv.DefaultDmsgDiscAddr + conf.STCP = stcp } - conf.Dmsg.SessionsCount = 1 + + conf.Dmsg = visor.DefaultDmsgConfig() ptyConf := defaultDmsgPtyConfig() conf.DmsgPty = &ptyConf @@ -139,44 +128,34 @@ func defaultConfig() *visor.Config { defaultSkysocksConfig(""), defaultSkysocksClientConfig(), } - conf.TrustedVisors = []cipher.PubKey{} - if testenv { - conf.Transport.Discovery = skyenv.TestTpDiscAddr - } else { - conf.Transport.Discovery = skyenv.DefaultTpDiscAddr - } + conf.TrustedVisors = []cipher.PubKey{} - conf.Transport.LogStore.Type = "file" - conf.Transport.LogStore.Location = "./skywire/transport_logs" + conf.Transport = visor.DefaultTransportConfig() + conf.Routing = visor.DefaultRoutingConfig() if testenv { + conf.Dmsg.Discovery = skyenv.TestDmsgDiscAddr + conf.Transport.Discovery = skyenv.TestTpDiscAddr conf.Routing.RouteFinder = skyenv.TestRouteFinderAddr - } else { - conf.Routing.RouteFinder = skyenv.DefaultRouteFinderAddr - } - - var sPK cipher.PubKey - if err := sPK.UnmarshalText([]byte(skyenv.DefaultSetupPK)); err != nil { - logger.WithError(err).Warnf("Failed to unmarshal default setup-node public key %s", skyenv.DefaultSetupPK) } - conf.Routing.SetupNodes = []cipher.PubKey{sPK} - conf.Routing.RouteFinderTimeout = visor.Duration(10 * time.Second) conf.Hypervisors = []visor.HypervisorConfig{} - conf.Uptime.Tracker = "uptime-tracker.skywire.skycoin.com" - - conf.AppsPath = "./apps" - conf.LocalPath = "./local" + conf.UptimeTracker = visor.DefaultUptimeTrackerConfig() - conf.LogLevel = "info" + conf.AppsPath = visor.DefaultAppsPath + conf.LocalPath = visor.DefaultLocalPath - conf.ShutdownTimeout = visor.Duration(10 * time.Second) + conf.LogLevel = visor.DefaultLogLevel + conf.ShutdownTimeout = visor.DefaultTimeout - conf.Interfaces.RPCAddress = "localhost:3435" + conf.Interfaces = &visor.InterfaceConfig{ + RPCAddress: "localhost:3435", + } conf.AppServerAddr = appcommon.DefaultServerAddr + conf.RestartCheckDelay = restart.DefaultCheckDelay.String() return conf } @@ -219,19 +198,3 @@ func defaultSkysocksClientConfig() visor.AppConfig { Port: routing.Port(skyenv.SkysocksClientPort), } } - -func getLocalIPAddress() (string, error) { - addrs, err := net.InterfaceAddrs() - if err != nil { - return "", err - } - - for _, a := range addrs { - if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To4() != nil { - return ipnet.IP.String() + ":7777", nil - } - } - } - return "", errors.New("could not find local IP address") -} diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 7c63c9854a..7e1fd9ea8e 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -176,8 +176,6 @@ func (cfg *runCfg) readConfig() *runCfg { cfg.logger.Fatalf("Failed to decode %s: %s", rdr, err) } - fmt.Println("TCP Factory conf:", cfg.conf.STCP) - return cfg } @@ -206,8 +204,8 @@ func (cfg *runCfg) runVisor() *runCfg { cfg.logger.Fatal("Failed to initialize visor: ", err) } - if cfg.conf.Uptime.Tracker != "" { - uptimeTracker, err := utclient.NewHTTP(cfg.conf.Uptime.Tracker, cfg.conf.Visor.StaticPubKey, cfg.conf.Visor.StaticSecKey) + if cfg.conf.UptimeTracker != nil { + uptimeTracker, err := utclient.NewHTTP(cfg.conf.UptimeTracker.Addr, cfg.conf.Keys().StaticPubKey, cfg.conf.Keys().StaticSecKey) if err != nil { cfg.logger.Error("Failed to connect to uptime tracker: ", err) } else { diff --git a/internal/skyenv/const.go b/internal/skyenv/values.go similarity index 60% rename from internal/skyenv/const.go rename to internal/skyenv/values.go index 2c99851eb0..85a1a8a009 100644 --- a/internal/skyenv/const.go +++ b/internal/skyenv/values.go @@ -1,13 +1,28 @@ package skyenv +import ( + "github.com/SkycoinProject/dmsg/cipher" +) + // Constants for default services. const ( - DefaultTpDiscAddr = "http://transport.discovery.skywire.skycoin.com" - DefaultDmsgDiscAddr = "http://dmsg.discovery.skywire.skycoin.com" - DefaultRouteFinderAddr = "http://routefinder.skywire.skycoin.com" - DefaultSetupPK = "026c5a07de617c5c488195b76e8671bf9e7ee654d0633933e202af9e111ffa358d" + DefaultTpDiscAddr = "http://transport.discovery.skywire.skycoin.com" + DefaultDmsgDiscAddr = "http://dmsg.discovery.skywire.skycoin.com" + DefaultRouteFinderAddr = "http://routefinder.skywire.skycoin.com" + DefaultUptimeTrackerAddr = "http://uptime-tracker.skywire.skycoin.com" + DefaultSetupPK = "026c5a07de617c5c488195b76e8671bf9e7ee654d0633933e202af9e111ffa358d" ) +// MustDefaultSetupPK returns DefaultSetupPK as cipher.PubKey. It panics if unmarshaling fails. +func MustDefaultSetupPK() cipher.PubKey { + var sPK cipher.PubKey + if err := sPK.UnmarshalText([]byte(DefaultSetupPK)); err != nil { + panic(err) + } + + return sPK +} + // Constants for testing deployment. const ( TestTpDiscAddr = "http://transport.discovery.skywire.cc" diff --git a/pkg/app/appserver/mock_proc_manager.go b/pkg/app/appserver/mock_proc_manager.go index adba5cf0a1..483cde0e91 100644 --- a/pkg/app/appserver/mock_proc_manager.go +++ b/pkg/app/appserver/mock_proc_manager.go @@ -5,10 +5,11 @@ package appserver import ( io "io" + appcommon "github.com/SkycoinProject/skywire-mainnet/pkg/app/appcommon" + logging "github.com/SkycoinProject/skycoin/src/util/logging" - mock "github.com/stretchr/testify/mock" - appcommon "github.com/SkycoinProject/skywire-mainnet/pkg/app/appcommon" + mock "github.com/stretchr/testify/mock" ) // MockProcManager is an autogenerated mock type for the ProcManager type diff --git a/pkg/app/mock_rpc_client.go b/pkg/app/mock_rpc_client.go index 5e3dc70007..f3c62f3238 100644 --- a/pkg/app/mock_rpc_client.go +++ b/pkg/app/mock_rpc_client.go @@ -143,7 +143,7 @@ func (_m *MockRPCClient) Read(connID uint16, b []byte) (int, error) { return r0, r1 } -// SetDeadline provides a mock function with given fields: id, t +// SetDeadline provides a mock function with given fields: connID, d func (_m *MockRPCClient) SetDeadline(connID uint16, d time.Time) error { ret := _m.Called(connID, d) @@ -157,7 +157,7 @@ func (_m *MockRPCClient) SetDeadline(connID uint16, d time.Time) error { return r0 } -// SetReadDeadline provides a mock function with given fields: id, t +// SetReadDeadline provides a mock function with given fields: connID, d func (_m *MockRPCClient) SetReadDeadline(connID uint16, d time.Time) error { ret := _m.Called(connID, d) @@ -171,7 +171,7 @@ func (_m *MockRPCClient) SetReadDeadline(connID uint16, d time.Time) error { return r0 } -// SetWriteDeadline provides a mock function with given fields: id, t +// SetWriteDeadline provides a mock function with given fields: connID, d func (_m *MockRPCClient) SetWriteDeadline(connID uint16, d time.Time) error { ret := _m.Called(connID, d) diff --git a/pkg/snet/network.go b/pkg/snet/network.go index 6d4286a154..01400ed612 100644 --- a/pkg/snet/network.go +++ b/pkg/snet/network.go @@ -29,7 +29,7 @@ const ( // Network types. const ( DmsgType = dmsg.Type - STcpType = stcp.Type + STCPType = stcp.Type ) var ( @@ -37,51 +37,88 @@ var ( ErrUnknownNetwork = errors.New("unknown network type") ) -// Config represents a network configuration. -type Config struct { - PubKey cipher.PubKey - SecKey cipher.SecKey - TpNetworks []string // networks to be used with transports +// NetworkConfig is a common interface for network configs. +type NetworkConfig interface { + Type() string +} + +// DmsgConfig defines config for Dmsg network. +type DmsgConfig struct { + Discovery string `json:"discovery"` + SessionsCount int `json:"sessions_count"` +} - DmsgDiscAddr string - DmsgMinSessions int +// Type returns DmsgType. +func (c *DmsgConfig) Type() string { + return DmsgType +} + +// STCPConfig defines config for STCP network. +type STCPConfig struct { + LocalAddr string `json:"local_address"` + PubKeyTable map[cipher.PubKey]string `json:"pk_table"` +} - STCPLocalAddr string // if empty, don't listen. - STCPTable map[cipher.PubKey]string +// Type returns STCPType. +func (c *STCPConfig) Type() string { + return STCPType +} + +// Config represents a network configuration. +type Config struct { + PubKey cipher.PubKey + SecKey cipher.SecKey + Dmsg *DmsgConfig + STCP *STCPConfig } // Network represents a network between nodes in Skywire. type Network struct { - conf Config - dmsgC *dmsg.Client - stcpC *stcp.Client + conf Config + networks []string // networks to be used with transports + dmsgC *dmsg.Client + stcpC *stcp.Client } // New creates a network from a config. func New(conf Config) *Network { - dmsgC := dmsg.NewClient( - conf.PubKey, - conf.SecKey, - disc.NewHTTP(conf.DmsgDiscAddr), &dmsg.Config{ - MinSessions: conf.DmsgMinSessions, - }) - dmsgC.SetLogger(logging.MustGetLogger("snet.dmsgC")) - - stcpC := stcp.NewClient( - logging.MustGetLogger("snet.stcpC"), - conf.PubKey, - conf.SecKey, - stcp.NewTable(conf.STCPTable)) + var dmsgC *dmsg.Client + var stcpC *stcp.Client + + if conf.Dmsg != nil { + c := &dmsg.Config{ + MinSessions: conf.Dmsg.SessionsCount, + } + + dmsgC = dmsg.NewClient(conf.PubKey, conf.SecKey, disc.NewHTTP(conf.Dmsg.Discovery), c) + dmsgC.SetLogger(logging.MustGetLogger("snet.dmsgC")) + } + + if conf.STCP != nil { + stcpC = stcp.NewClient(conf.PubKey, conf.SecKey, stcp.NewTable(conf.STCP.PubKeyTable)) + stcpC.SetLogger(logging.MustGetLogger("snet.stcpC")) + } return NewRaw(conf, dmsgC, stcpC) } // NewRaw creates a network from a config and a dmsg client. func NewRaw(conf Config, dmsgC *dmsg.Client, stcpC *stcp.Client) *Network { + networks := make([]string, 0) + + if dmsgC != nil { + networks = append(networks, DmsgType) + } + + if stcpC != nil { + networks = append(networks, STCPType) + } + return &Network{ - conf: conf, - dmsgC: dmsgC, - stcpC: stcpC, + conf: conf, + networks: networks, + dmsgC: dmsgC, + stcpC: stcpC, } } @@ -93,9 +130,9 @@ func (n *Network) Init(_ context.Context) error { time.Sleep(200 * time.Millisecond) } - if n.stcpC != nil { - if n.conf.STCPLocalAddr != "" { - if err := n.stcpC.Serve(n.conf.STCPLocalAddr); err != nil { + if n.conf.STCP != nil { + if n.stcpC != nil && n.conf.STCP.LocalAddr != "" { + if err := n.stcpC.Serve(n.conf.STCP.LocalAddr); err != nil { return fmt.Errorf("failed to initiate 'stcp': %v", err) } } else { @@ -141,7 +178,7 @@ func (n *Network) LocalPK() cipher.PubKey { return n.conf.PubKey } func (n *Network) LocalSK() cipher.SecKey { return n.conf.SecKey } // TransportNetworks returns network types that are used for transports. -func (n *Network) TransportNetworks() []string { return n.conf.TpNetworks } +func (n *Network) TransportNetworks() []string { return n.networks } // Dmsg returns underlying dmsg client. func (n *Network) Dmsg() *dmsg.Client { return n.dmsgC } @@ -170,7 +207,7 @@ func (n *Network) Dial(ctx context.Context, network string, pk cipher.PubKey, po } return makeConn(conn, network), nil - case STcpType: + case STCPType: conn, err := n.stcpC.Dial(ctx, pk, port) if err != nil { return nil, err @@ -192,7 +229,7 @@ func (n *Network) Listen(network string, port uint16) (*Listener, error) { } return makeListener(lis, network), nil - case STcpType: + case STCPType: lis, err := n.stcpC.Listen(port) if err != nil { return nil, err diff --git a/pkg/snet/snettest/env.go b/pkg/snet/snettest/env.go index f4477416a5..65be604db5 100644 --- a/pkg/snet/snettest/env.go +++ b/pkg/snet/snettest/env.go @@ -5,12 +5,10 @@ import ( "strconv" "testing" - "github.com/SkycoinProject/skycoin/src/util/logging" - "github.com/stretchr/testify/assert" - "github.com/SkycoinProject/dmsg" "github.com/SkycoinProject/dmsg/cipher" "github.com/SkycoinProject/dmsg/disc" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/net/nettest" @@ -89,17 +87,20 @@ func NewEnv(t *testing.T, keys []KeyPair, networks []string) *Env { } if hasStcp { - stcpClient = stcp.NewClient(logging.MustGetLogger("stcp"), pairs.PK, pairs.SK, table) + stcpClient = stcp.NewClient(pairs.PK, pairs.SK, table) } port := 7033 n := snet.NewRaw( snet.Config{ - PubKey: pairs.PK, - SecKey: pairs.SK, - TpNetworks: networks, - DmsgMinSessions: 1, - STCPLocalAddr: "127.0.0.1:" + strconv.Itoa(port+i), + PubKey: pairs.PK, + SecKey: pairs.SK, + Dmsg: &snet.DmsgConfig{ + SessionsCount: 1, + }, + STCP: &snet.STCPConfig{ + LocalAddr: "127.0.0.1:" + strconv.Itoa(port+i), + }, }, dmsgClient, stcpClient, diff --git a/pkg/snet/stcp/client.go b/pkg/snet/stcp/client.go index 48a4fd95be..bf2e004ae9 100644 --- a/pkg/snet/stcp/client.go +++ b/pkg/snet/stcp/client.go @@ -140,12 +140,9 @@ type Client struct { } // NewClient creates a net Client. -func NewClient(log *logging.Logger, pk cipher.PubKey, sk cipher.SecKey, t PKTable) *Client { - if log == nil { - log = logging.MustGetLogger(Type) - } +func NewClient(pk cipher.PubKey, sk cipher.SecKey, t PKTable) *Client { return &Client{ - log: log, + log: logging.MustGetLogger(Type), lPK: pk, lSK: sk, t: t, @@ -155,6 +152,11 @@ func NewClient(log *logging.Logger, pk cipher.PubKey, sk cipher.SecKey, t PKTabl } } +// SetLogger sets a logger for Client. +func (c *Client) SetLogger(log *logging.Logger) { + c.log = log +} + // Serve serves the listening portion of the client. func (c *Client) Serve(tcpAddr string) error { if c.lTCP != nil { diff --git a/pkg/visor/config.go b/pkg/visor/config.go index bbb2c20e6f..98d3e591e8 100644 --- a/pkg/visor/config.go +++ b/pkg/visor/config.go @@ -1,63 +1,49 @@ package visor import ( - "encoding/json" "errors" "fmt" + "net" "os" "path/filepath" "time" "github.com/SkycoinProject/dmsg" "github.com/SkycoinProject/dmsg/cipher" - "github.com/SkycoinProject/dmsg/disc" "github.com/SkycoinProject/dmsg/dmsgpty" + "github.com/SkycoinProject/skywire-mainnet/internal/skyenv" + "github.com/SkycoinProject/skywire-mainnet/pkg/app/appcommon" "github.com/SkycoinProject/skywire-mainnet/pkg/routing" + "github.com/SkycoinProject/skywire-mainnet/pkg/snet" "github.com/SkycoinProject/skywire-mainnet/pkg/transport" trClient "github.com/SkycoinProject/skywire-mainnet/pkg/transport-discovery/client" ) +const ( + // DefaultTimeout is used for default config generation and if it is not set in config. + DefaultTimeout = Duration(10 * time.Second) + // DefaultLocalPath is used for default config generation and if it is not set in config. + DefaultLocalPath = "./local" + // DefaultAppsPath is used for default config generation and if it is not set in config. + DefaultAppsPath = "./apps" + // DefaultLogLevel is used for default config generation and if it is not set in config. + DefaultLogLevel = "info" + // DefaultSTCPPort ??? + // TODO: Define above or remove below. + DefaultSTCPPort = 7777 +) + // Config defines configuration parameters for Visor. -// TODO(evanlinjin): Instead of having nested structs, make separate types for each field. -// TODO(evanlinjin): Use pointers to allow nil-configs for non-crucial fields. type Config struct { - Version string `json:"version"` - - Visor struct { - StaticPubKey cipher.PubKey `json:"static_public_key"` - StaticSecKey cipher.SecKey `json:"static_secret_key"` - } `json:"visor"` - - STCP struct { - PubKeyTable map[cipher.PubKey]string `json:"pk_table"` - LocalAddr string `json:"local_address"` - } `json:"stcp"` - - Dmsg struct { - Discovery string `json:"discovery"` - SessionsCount int `json:"sessions_count"` - } `json:"dmsg"` - - DmsgPty *DmsgPtyConfig `json:"dmsg_pty,omitempty"` - - Transport struct { - Discovery string `json:"discovery"` - LogStore struct { - Type string `json:"type"` - Location string `json:"location"` - } `json:"log_store"` - } `json:"transport"` - - Routing struct { - SetupNodes []cipher.PubKey `json:"setup_nodes"` - RouteFinder string `json:"route_finder"` - RouteFinderTimeout Duration `json:"route_finder_timeout,omitempty"` - } `json:"routing"` - - Uptime struct { - Tracker string `json:"tracker"` - } `json:"uptime"` + Version string `json:"version"` + KeyPair *KeyPair `json:"key_pair"` + STCP *snet.STCPConfig `json:"stcp"` + Dmsg *snet.DmsgConfig `json:"dmsg"` + DmsgPty *DmsgPtyConfig `json:"dmsg_pty,omitempty"` + Transport *TransportConfig `json:"transport"` + Routing *RoutingConfig `json:"routing"` + UptimeTracker *UptimeTrackerConfig `json:"uptime_tracker"` Apps []AppConfig `json:"apps"` @@ -70,34 +56,28 @@ type Config struct { LogLevel string `json:"log_level"` ShutdownTimeout Duration `json:"shutdown_timeout,omitempty"` // time value, examples: 10s, 1m, etc - Interfaces InterfaceConfig `json:"interfaces"` + Interfaces *InterfaceConfig `json:"interfaces"` AppServerAddr string `json:"app_server_addr"` RestartCheckDelay string `json:"restart_check_delay,omitempty"` } -// DmsgConfig returns config for dmsg client. -func (c *Config) DmsgConfig() (*DmsgConfig, error) { - dmsgConfig := c.Dmsg - - if dmsgConfig.Discovery == "" { - return nil, errors.New("empty discovery") +// Keys returns visor public and secret keys extracted from config. +// If they are not found, new keys are generated. +func (c *Config) Keys() *KeyPair { + if c.KeyPair == nil || c.KeyPair.StaticPubKey.Null() || c.KeyPair.StaticSecKey.Null() { + c.KeyPair = NewKeyPair() } - return &DmsgConfig{ - PubKey: c.Visor.StaticPubKey, - SecKey: c.Visor.StaticSecKey, - Discovery: disc.NewHTTP(dmsgConfig.Discovery), - Retries: 5, - RetryDelay: time.Second, - }, nil + return c.KeyPair } -// DmsgPtyHost instantiates a host from the dmsgpty config. +// DmsgPtyHost extracts DmsgPtyConfig and returns *dmsgpty.Host based on the config. +// If DmsgPtyConfig is not found, DefaultDmsgPtyConfig() is used. func (c *Config) DmsgPtyHost(dmsgC *dmsg.Client) (*dmsgpty.Host, error) { if c.DmsgPty == nil { - return nil, errors.New("'dmsg_pty' config field not defined") + c.DmsgPty = DefaultDmsgPtyConfig() } var wl dmsgpty.Whitelist @@ -117,28 +97,47 @@ func (c *Config) DmsgPtyHost(dmsgC *dmsg.Client) (*dmsgpty.Host, error) { return nil, fmt.Errorf("failed to add hypervisor PK to whitelist: %v", err) } } + host := dmsgpty.NewHost(dmsgC, dmsgpty.NewCombinedWhitelist(0, wl, hypervisorWL)) return host, nil } -// TransportDiscovery returns transport discovery client. +// TransportDiscovery extracts TransportConfig and returns transport.DiscoveryClient based on the config. +// If TransportConfig is not found, DefaultTransportConfig() is used. func (c *Config) TransportDiscovery() (transport.DiscoveryClient, error) { - if c.Transport.Discovery == "" { - return nil, errors.New("empty transport_discovery") + if c.Transport == nil { + c.Transport = DefaultTransportConfig() } - return trClient.NewHTTP(c.Transport.Discovery, c.Visor.StaticPubKey, c.Visor.StaticSecKey) + return trClient.NewHTTP(c.Transport.Discovery, c.Keys().StaticPubKey, c.Keys().StaticSecKey) } -// TransportLogStore returns configure transport.LogStore. +// TransportLogStore extracts LogStoreConfig and returns transport.LogStore based on the config. +// If LogStoreConfig is not found, DefaultLogStoreConfig() is used. func (c *Config) TransportLogStore() (transport.LogStore, error) { - if c.Transport.LogStore.Type == "file" { + if c.Transport == nil { + c.Transport = DefaultTransportConfig() + } else if c.Transport.LogStore == nil { + c.Transport.LogStore = DefaultLogStoreConfig() + } + + if c.Transport.LogStore.Type == LogStoreFile { return transport.FileTransportLogStore(c.Transport.LogStore.Location) } return transport.InMemoryTransportLogStore(), nil } +// RoutingConfig extracts and returns RoutingConfig from Visor Config. +// If it is not found, it sets DefaultRoutingConfig() as RoutingConfig and returns it. +func (c *Config) RoutingConfig() *RoutingConfig { + if c.Routing == nil { + c.Routing = DefaultRoutingConfig() + } + + return c.Routing +} + // AppsConfig decodes AppsConfig from a local json config file. func (c *Config) AppsConfig() (map[string]AppConfig, error) { apps := make(map[string]AppConfig) @@ -149,26 +148,38 @@ func (c *Config) AppsConfig() (map[string]AppConfig, error) { return apps, nil } -// AppsDir returns absolute path for directory with application -// binaries. Directory will be created if necessary. +// AppsDir returns absolute path for directory with application binaries. +// Directory will be created if necessary. +// If it is not set in config, DefaultAppsPath is used. func (c *Config) AppsDir() (string, error) { if c.AppsPath == "" { - return "", errors.New("empty AppsPath") + c.AppsPath = DefaultAppsPath } return ensureDir(c.AppsPath) } -// LocalDir returns absolute path for app work directory. Directory -// will be created if necessary. +// LocalDir returns absolute path for app work directory. +// Directory will be created if necessary. +// If it is not set in config, DefaultLocalPath is used. func (c *Config) LocalDir() (string, error) { if c.LocalPath == "" { - return "", errors.New("empty LocalPath") + c.LocalPath = DefaultLocalPath } return ensureDir(c.LocalPath) } +// AppServerAddress extracts and returns AppServerAddr from Visor Config. +// If it is not found, it sets appcommon.DefaultServerAddr as AppServerAddr and returns it. +func (c *Config) AppServerAddress() string { + if c.AppServerAddr == "" { + c.AppServerAddr = appcommon.DefaultServerAddr + } + + return c.AppServerAddr +} + func ensureDir(path string) (string, error) { absPath, err := filepath.Abs(path) if err != nil { @@ -186,19 +197,42 @@ func ensureDir(path string) (string, error) { return absPath, nil } -// HypervisorConfig represents hypervisor configuration. -type HypervisorConfig struct { - PubKey cipher.PubKey `json:"public_key"` - Addr string `json:"address"` +// KeyPair defines Visor public and secret key pair. +type KeyPair struct { + StaticPubKey cipher.PubKey `json:"static_public_key"` + StaticSecKey cipher.SecKey `json:"static_secret_key"` +} + +// NewKeyPair returns a new public and secret key pair. +func NewKeyPair() *KeyPair { + pk, sk := cipher.GenerateKeyPair() + + return &KeyPair{ + StaticPubKey: pk, + StaticSecKey: sk, + } +} + +// DefaultSTCPConfig returns default STCP config. +func DefaultSTCPConfig() (*snet.STCPConfig, error) { + lIPaddr, err := getLocalIPAddress() + if err != nil { + return nil, err + } + + c := &snet.STCPConfig{ + LocalAddr: lIPaddr, + } + + return c, nil } -// DmsgConfig represents dmsg configuration. -type DmsgConfig struct { - PubKey cipher.PubKey - SecKey cipher.SecKey - Discovery disc.APIClient - Retries int - RetryDelay time.Duration +// DefaultDmsgConfig returns default Dmsg config. +func DefaultDmsgConfig() *snet.DmsgConfig { + return &snet.DmsgConfig{ + Discovery: skyenv.DefaultDmsgDiscAddr, + SessionsCount: 1, + } } // DmsgPtyConfig configures the dmsgpty-host. @@ -209,6 +243,88 @@ type DmsgPtyConfig struct { CLIAddr string `json:"cli_address"` } +// DefaultDmsgPtyConfig returns default DmsgPty config. +func DefaultDmsgPtyConfig() *DmsgPtyConfig { + return &DmsgPtyConfig{ + Port: skyenv.DmsgPtyPort, + AuthFile: "./skywire/dmsgpty/whitelist.json", + CLINet: skyenv.DefaultDmsgPtyCLINet, + CLIAddr: skyenv.DefaultDmsgPtyCLIAddr, + } +} + +// TransportConfig defines a transport config. +type TransportConfig struct { + Discovery string `json:"discovery"` + LogStore *LogStoreConfig `json:"log_store"` +} + +// DefaultTransportConfig returns default transport config. +func DefaultTransportConfig() *TransportConfig { + return &TransportConfig{ + Discovery: skyenv.DefaultTpDiscAddr, + LogStore: DefaultLogStoreConfig(), + } +} + +// LogStoreType defines a type for LogStore. It may be either file or memory. +type LogStoreType string + +const ( + // LogStoreFile tells LogStore to use a file for storage. + LogStoreFile = "file" + // LogStoreMemory tells LogStore to use memory for storage. + LogStoreMemory = "memory" +) + +// LogStoreConfig configures a LogStore. +type LogStoreConfig struct { + Type LogStoreType `json:"type"` + Location string `json:"location"` +} + +// DefaultLogStoreConfig returns default LogStore config. +func DefaultLogStoreConfig() *LogStoreConfig { + return &LogStoreConfig{ + Type: LogStoreFile, + Location: "./skywire/transport_logs", + } +} + +// RoutingConfig configures routing. +type RoutingConfig struct { + SetupNodes []cipher.PubKey `json:"setup_nodes"` + RouteFinder string `json:"route_finder"` + RouteFinderTimeout Duration `json:"route_finder_timeout,omitempty"` +} + +// DefaultRoutingConfig returns default routing config. +func DefaultRoutingConfig() *RoutingConfig { + return &RoutingConfig{ + SetupNodes: []cipher.PubKey{skyenv.MustDefaultSetupPK()}, + RouteFinder: skyenv.DefaultRouteFinderAddr, + RouteFinderTimeout: DefaultTimeout, + } +} + +// UptimeTrackerConfig configures uptime tracker. +type UptimeTrackerConfig struct { + Addr string `json:"addr"` +} + +// DefaultUptimeTrackerConfig returns default uptime tracker config. +func DefaultUptimeTrackerConfig() *UptimeTrackerConfig { + return &UptimeTrackerConfig{ + Addr: skyenv.DefaultUptimeTrackerAddr, + } +} + +// HypervisorConfig represents hypervisor configuration. +type HypervisorConfig struct { + PubKey cipher.PubKey `json:"public_key"` + Addr string `json:"address"` +} + // AppConfig defines app startup parameters. type AppConfig struct { App string `json:"app"` @@ -222,32 +338,25 @@ type InterfaceConfig struct { RPCAddress string `json:"rpc"` // RPC address and port for command-line interface (leave blank to disable RPC interface). } -// Duration wraps around time.Duration to allow parsing from and to JSON -type Duration time.Duration - -// MarshalJSON implements json marshaling -func (d Duration) MarshalJSON() ([]byte, error) { - return json.Marshal(time.Duration(d).String()) +// DefaultInterfaceConfig returns default server interface config. +func DefaultInterfaceConfig() *InterfaceConfig { + return &InterfaceConfig{ + RPCAddress: "localhost:3435", + } } -// UnmarshalJSON implements unmarshal from json -func (d *Duration) UnmarshalJSON(b []byte) error { - var v interface{} - if err := json.Unmarshal(b, &v); err != nil { - return err +func getLocalIPAddress() (string, error) { + addrs, err := net.InterfaceAddrs() + if err != nil { + return "", err } - switch value := v.(type) { - case float64: - *d = Duration(time.Duration(value)) - return nil - case string: - tmp, err := time.ParseDuration(value) - if err != nil { - return err + + for _, a := range addrs { + if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + return fmt.Sprintf("%s:%d", ipnet.IP.String(), DefaultSTCPPort), nil + } } - *d = Duration(tmp) - return nil - default: - return errors.New("invalid duration") } + return "", errors.New("could not find local IP address") } diff --git a/pkg/visor/config_test.go b/pkg/visor/config_test.go index beb9f6626a..bbb5ba7dd4 100644 --- a/pkg/visor/config_test.go +++ b/pkg/visor/config_test.go @@ -7,7 +7,6 @@ import ( "os" "path/filepath" "testing" - "time" "github.com/SkycoinProject/dmsg/cipher" "github.com/stretchr/testify/assert" @@ -17,24 +16,6 @@ import ( "github.com/SkycoinProject/skywire-mainnet/pkg/routing" ) -func TestDmsgDiscovery(t *testing.T) { - pk, sk := cipher.GenerateKeyPair() - conf := Config{} - conf.Visor.StaticPubKey = pk - conf.Visor.StaticSecKey = sk - conf.Dmsg.Discovery = "skywire.skycoin.net:8001" - conf.Dmsg.SessionsCount = 10 - - c, err := conf.DmsgConfig() - require.NoError(t, err) - - assert.NotNil(t, c.Discovery) - assert.False(t, c.PubKey.Null()) - assert.False(t, c.SecKey.Null()) - assert.Equal(t, 5, c.Retries) - assert.Equal(t, time.Second, c.RetryDelay) -} - func TestTransportDiscovery(t *testing.T) { pk, _ := cipher.GenerateKeyPair() srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -43,8 +24,11 @@ func TestTransportDiscovery(t *testing.T) { defer srv.Close() - conf := Config{} - conf.Transport.Discovery = srv.URL + conf := Config{ + Transport: &TransportConfig{ + Discovery: srv.URL, + }, + } discovery, err := conf.TransportDiscovery() require.NoError(t, err) @@ -59,25 +43,33 @@ func TestTransportLogStore(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - conf := Config{} - conf.Transport.LogStore.Type = "file" - conf.Transport.LogStore.Location = dir + conf := Config{ + Transport: &TransportConfig{ + LogStore: &LogStoreConfig{ + Type: LogStoreFile, + Location: dir, + }, + }, + } + ls, err := conf.TransportLogStore() require.NoError(t, err) require.NotNil(t, ls) - conf.Transport.LogStore.Type = "memory" + conf.Transport.LogStore.Type = LogStoreMemory conf.Transport.LogStore.Location = "" + ls, err = conf.TransportLogStore() require.NoError(t, err) require.NotNil(t, ls) } func TestAppsConfig(t *testing.T) { - conf := Config{Version: "1.0"} - conf.Apps = []AppConfig{ - {App: "foo", Port: 1}, - {App: "bar", AutoStart: true, Port: 2}, + conf := Config{ + Apps: []AppConfig{ + {App: "foo", Port: 1}, + {App: "bar", AutoStart: true, Port: 2}, + }, } appsConf, err := conf.AppsConfig() @@ -96,6 +88,7 @@ func TestAppsConfig(t *testing.T) { func TestAppsDir(t *testing.T) { conf := Config{AppsPath: "apps"} + dir, err := conf.AppsDir() require.NoError(t, err) diff --git a/pkg/visor/duration.go b/pkg/visor/duration.go new file mode 100644 index 0000000000..4ac6eeca04 --- /dev/null +++ b/pkg/visor/duration.go @@ -0,0 +1,37 @@ +package visor + +import ( + "encoding/json" + "errors" + "time" +) + +// Duration wraps around time.Duration to allow parsing from and to JSON +type Duration time.Duration + +// MarshalJSON implements json marshaling +func (d Duration) MarshalJSON() ([]byte, error) { + return json.Marshal(time.Duration(d).String()) +} + +// UnmarshalJSON implements unmarshal from json +func (d *Duration) UnmarshalJSON(b []byte) error { + var v interface{} + if err := json.Unmarshal(b, &v); err != nil { + return err + } + switch value := v.(type) { + case float64: + *d = Duration(time.Duration(value)) + return nil + case string: + tmp, err := time.ParseDuration(value) + if err != nil { + return err + } + *d = Duration(tmp) + return nil + default: + return errors.New("invalid duration") + } +} diff --git a/pkg/visor/rpc.go b/pkg/visor/rpc.go index 6e06f50e2c..6e7c629901 100644 --- a/pkg/visor/rpc.go +++ b/pkg/visor/rpc.go @@ -81,11 +81,11 @@ func (r *RPC) Health(_ *struct{}, out *HealthInfo) (err error) { out.TransportDiscovery = http.StatusNotFound } - if r.visor.conf.Routing.RouteFinder == "" { + if r.visor.conf.RoutingConfig().RouteFinder == "" { out.RouteFinder = http.StatusNotFound } - if len(r.visor.conf.Routing.SetupNodes) == 0 { + if len(r.visor.conf.RoutingConfig().SetupNodes) == 0 { out.SetupNode = http.StatusNotFound } @@ -98,7 +98,7 @@ func (r *RPC) Health(_ *struct{}, out *HealthInfo) (err error) { // Uptime returns for how long the visor has been running in seconds func (r *RPC) Uptime(_ *struct{}, out *float64) (err error) { - defer rpcutil.LogCall(r.log, "Uptime", nil)(out, &err) + defer rpcutil.LogCall(r.log, "UptimeTracker", nil)(out, &err) *out = time.Since(r.visor.startedAt).Seconds() return nil @@ -184,7 +184,7 @@ func (r *RPC) Summary(_ *struct{}, out *Summary) (err error) { return true }) *out = Summary{ - PubKey: r.visor.conf.Visor.StaticPubKey, + PubKey: r.visor.conf.Keys().StaticPubKey, BuildInfo: buildinfo.Get(), AppProtoVersion: supportedProtocolVersion, Apps: r.visor.Apps(), diff --git a/pkg/visor/rpc_client.go b/pkg/visor/rpc_client.go index 49f11be974..4b1d6c3824 100644 --- a/pkg/visor/rpc_client.go +++ b/pkg/visor/rpc_client.go @@ -97,10 +97,10 @@ func (rc *rpcClient) Health() (*HealthInfo, error) { return hi, err } -// Uptime calls Uptime +// UptimeTracker calls UptimeTracker func (rc *rpcClient) Uptime() (float64, error) { var out float64 - err := rc.Call("Uptime", &struct{}{}, &out) + err := rc.Call("UptimeTracker", &struct{}{}, &out) return out, err } @@ -410,7 +410,7 @@ func (mc *mockRPCClient) Health() (*HealthInfo, error) { return hi, nil } -// Uptime implements RPCClient +// UptimeTracker implements RPCClient func (mc *mockRPCClient) Uptime() (float64, error) { return time.Since(mc.startedAt).Seconds(), nil } diff --git a/pkg/visor/rpc_test.go b/pkg/visor/rpc_test.go index b9d9098b44..d99b3d4254 100644 --- a/pkg/visor/rpc_test.go +++ b/pkg/visor/rpc_test.go @@ -25,14 +25,17 @@ import ( ) func TestHealth(t *testing.T) { - sPK, sSK := cipher.GenerateKeyPair() + c := &Config{ + KeyPair: NewKeyPair(), + Transport: &TransportConfig{ + Discovery: "foo", + }, + Routing: &RoutingConfig{ + RouteFinder: "foo", + }, + } - c := &Config{} - c.Visor.StaticPubKey = sPK - c.Visor.StaticSecKey = sSK - c.Transport.Discovery = "foo" - c.Routing.SetupNodes = []cipher.PubKey{sPK} - c.Routing.RouteFinder = "foo" + c.Routing.SetupNodes = []cipher.PubKey{c.KeyPair.StaticPubKey} t.Run("Report all the services as available", func(t *testing.T) { rpc := &RPC{visor: &Visor{conf: c}, log: logrus.New()} @@ -46,7 +49,11 @@ func TestHealth(t *testing.T) { }) t.Run("Report as unavailable", func(t *testing.T) { - rpc := &RPC{visor: &Visor{conf: &Config{}}, log: logrus.New()} + conf := &Config{ + Routing: &RoutingConfig{}, + } + + rpc := &RPC{visor: &Visor{conf: conf}, log: logrus.New()} h := &HealthInfo{} err := rpc.Health(nil, h) require.NoError(t, err) @@ -59,6 +66,7 @@ func TestHealth(t *testing.T) { func TestUptime(t *testing.T) { rpc := &RPC{visor: &Visor{startedAt: time.Now()}, log: logrus.New()} time.Sleep(time.Second) + var res float64 err := rpc.Uptime(nil, &res) require.NoError(t, err) @@ -124,7 +132,6 @@ func TestStartStopApp(t *testing.T) { require.NoError(t, err) defer func() { require.NoError(t, os.RemoveAll(tempDir)) }() - pk, _ := cipher.GenerateKeyPair() r := &router.MockRouter{} r.On("Serve", mock.Anything /* context */).Return(testhelpers.NoErr) r.On("Close").Return(testhelpers.NoErr) @@ -147,10 +154,12 @@ func TestStartStopApp(t *testing.T) { unknownApp := "bar" app := apps["foo"].App + keyPair := NewKeyPair() + visorCfg := Config{ + KeyPair: keyPair, AppServerAddr: appcommon.DefaultServerAddr, } - visorCfg.Visor.StaticPubKey = pk visor := &Visor{ router: r, @@ -168,7 +177,7 @@ func TestStartStopApp(t *testing.T) { appCfg1 := appcommon.Config{ Name: app, ServerAddr: appcommon.DefaultServerAddr, - VisorPK: visorCfg.Visor.StaticPubKey.Hex(), + VisorPK: visorCfg.Keys().StaticPubKey.Hex(), WorkDir: filepath.Join("", app), } diff --git a/pkg/visor/visor.go b/pkg/visor/visor.go index 2f92cc8348..587e2c7c1d 100644 --- a/pkg/visor/visor.go +++ b/pkg/visor/visor.go @@ -117,6 +117,11 @@ func NewVisor(cfg *Config, logger *logging.MasterLogger, restartCtx *restart.Con visor.Logger = logger visor.logger = visor.Logger.PackageLogger("skywire") + pk := cfg.Keys().StaticPubKey + sk := cfg.Keys().StaticSecKey + + logger.WithField("PK", pk).Infof("Starting visor") + restartCheckDelay, err := time.ParseDuration(cfg.RestartCheckDelay) if err == nil { restartCtx.SetCheckDelay(restartCheckDelay) @@ -126,18 +131,11 @@ func NewVisor(cfg *Config, logger *logging.MasterLogger, restartCtx *restart.Con visor.restartCtx = restartCtx - pk := cfg.Visor.StaticPubKey - sk := cfg.Visor.StaticSecKey - - fmt.Println("min sessions:", cfg.Dmsg.SessionsCount) visor.n = snet.New(snet.Config{ - PubKey: pk, - SecKey: sk, - TpNetworks: []string{dmsg.Type, snet.STcpType}, // TODO: Have some way to configure this. - DmsgDiscAddr: cfg.Dmsg.Discovery, - DmsgMinSessions: cfg.Dmsg.SessionsCount, - STCPLocalAddr: cfg.STCP.LocalAddr, - STCPTable: cfg.STCP.PubKeyTable, + PubKey: pk, + SecKey: sk, + Dmsg: cfg.Dmsg, + STCP: cfg.STCP, }) if err := visor.n.Init(ctx); err != nil { return nil, fmt.Errorf("failed to init network: %v", err) @@ -157,10 +155,12 @@ func NewVisor(cfg *Config, logger *logging.MasterLogger, restartCtx *restart.Con if err != nil { return nil, fmt.Errorf("invalid transport discovery config: %s", err) } + logStore, err := cfg.TransportLogStore() if err != nil { return nil, fmt.Errorf("invalid TransportLogStore: %s", err) } + tmConfig := &transport.ManagerConfig{ PubKey: pk, SecKey: sk, @@ -168,6 +168,7 @@ func NewVisor(cfg *Config, logger *logging.MasterLogger, restartCtx *restart.Con DiscoveryClient: trDiscovery, LogStore: logStore, } + visor.tm, err = transport.NewManager(visor.n, tmConfig) if err != nil { return nil, fmt.Errorf("transport manager: %s", err) @@ -178,8 +179,8 @@ func NewVisor(cfg *Config, logger *logging.MasterLogger, restartCtx *restart.Con PubKey: pk, SecKey: sk, TransportManager: visor.tm, - RouteFinder: rfclient.NewHTTP(cfg.Routing.RouteFinder, time.Duration(cfg.Routing.RouteFinderTimeout)), - SetupNodes: cfg.Routing.SetupNodes, + RouteFinder: rfclient.NewHTTP(cfg.RoutingConfig().RouteFinder, time.Duration(cfg.RoutingConfig().RouteFinderTimeout)), + SetupNodes: cfg.RoutingConfig().SetupNodes, } r, err := router.New(visor.n, rConfig) @@ -207,11 +208,12 @@ func NewVisor(cfg *Config, logger *logging.MasterLogger, restartCtx *restart.Con visor.Logger.SetLevel(lvl) } - if cfg.Interfaces.RPCAddress != "" { + if cfg.Interfaces != nil { l, err := net.Listen("tcp", cfg.Interfaces.RPCAddress) if err != nil { return nil, fmt.Errorf("failed to setup RPC listener: %s", err) } + visor.cliLis = l } @@ -386,7 +388,7 @@ func (visor *Visor) startRPC(ctx context.Context) { } func (visor *Visor) dir() string { - return pathutil.VisorDir(visor.conf.Visor.StaticPubKey.String()) + return pathutil.VisorDir(visor.conf.Keys().StaticPubKey.String()) } func (visor *Visor) pidFile() (*os.File, error) { @@ -561,7 +563,7 @@ func (visor *Visor) SpawnApp(config *AppConfig, startCh chan<- struct{}) (err er appCfg := appcommon.Config{ Name: config.App, ServerAddr: visor.conf.AppServerAddr, - VisorPK: visor.conf.Visor.StaticPubKey.Hex(), + VisorPK: visor.conf.Keys().StaticPubKey.Hex(), BinaryDir: visor.appsPath, WorkDir: filepath.Join(visor.localPath, config.App), } diff --git a/pkg/visor/visor_test.go b/pkg/visor/visor_test.go index c884b5145f..055d9f7935 100644 --- a/pkg/visor/visor_test.go +++ b/pkg/visor/visor_test.go @@ -103,27 +103,26 @@ func TestVisorStartClose(t *testing.T) { require.NoError(t, os.RemoveAll("skychat")) }() - var ( - visorCfg = Config{ - AppServerAddr: appcommon.DefaultServerAddr, - } - logger = logging.MustGetLogger("test") - server = appserver.New(logger, visorCfg.AppServerAddr) - ) + visorCfg := Config{ + KeyPair: NewKeyPair(), + AppServerAddr: appcommon.DefaultServerAddr, + } + + logger := logging.MustGetLogger("test") visor := &Visor{ conf: &visorCfg, router: r, appsConf: apps, logger: logger, - appRPCServer: server, + appRPCServer: appserver.New(logger, visorCfg.AppServerAddr), } pm := &appserver.MockProcManager{} appCfg1 := appcommon.Config{ Name: apps["skychat"].App, ServerAddr: appcommon.DefaultServerAddr, - VisorPK: visorCfg.Visor.StaticPubKey.Hex(), + VisorPK: visorCfg.Keys().StaticPubKey.Hex(), WorkDir: filepath.Join("", apps["skychat"].App), } appArgs1 := append([]string{filepath.Join(visor.dir(), apps["skychat"].App)}, apps["skychat"].Args...) @@ -139,13 +138,7 @@ func TestVisorStartClose(t *testing.T) { dmsgC := dmsg.NewClient(cipher.PubKey{}, cipher.SecKey{}, disc.NewMock(), nil) go dmsgC.Serve() - netConf := snet.Config{ - PubKey: cipher.PubKey{}, - SecKey: cipher.SecKey{}, - TpNetworks: nil, - DmsgDiscAddr: "", - DmsgMinSessions: 0, - } + var netConf snet.Config network := snet.NewRaw(netConf, dmsgC, nil) tmConf := &transport.ManagerConfig{ @@ -168,7 +161,6 @@ func TestVisorStartClose(t *testing.T) { } func TestVisorSpawnApp(t *testing.T) { - pk, _ := cipher.GenerateKeyPair() r := &router.MockRouter{} r.On("Serve", mock.Anything /* context */).Return(testhelpers.NoErr) r.On("Close").Return(testhelpers.NoErr) @@ -188,9 +180,9 @@ func TestVisorSpawnApp(t *testing.T) { apps["skychat"] = app visorCfg := Config{ + KeyPair: NewKeyPair(), AppServerAddr: appcommon.DefaultServerAddr, } - visorCfg.Visor.StaticPubKey = pk visor := &Visor{ router: r, @@ -208,7 +200,7 @@ func TestVisorSpawnApp(t *testing.T) { appCfg := appcommon.Config{ Name: app.App, ServerAddr: appcommon.DefaultServerAddr, - VisorPK: visorCfg.Visor.StaticPubKey.Hex(), + VisorPK: visorCfg.Keys().StaticPubKey.Hex(), WorkDir: filepath.Join("", app.App), } @@ -233,7 +225,6 @@ func TestVisorSpawnApp(t *testing.T) { } func TestVisorSpawnAppValidations(t *testing.T) { - pk, _ := cipher.GenerateKeyPair() r := &router.MockRouter{} r.On("Serve", mock.Anything /* context */).Return(testhelpers.NoErr) r.On("Close").Return(testhelpers.NoErr) @@ -243,9 +234,9 @@ func TestVisorSpawnAppValidations(t *testing.T) { }() c := &Config{ + KeyPair: NewKeyPair(), AppServerAddr: appcommon.DefaultServerAddr, } - c.Visor.StaticPubKey = pk visor := &Visor{ router: r, @@ -268,7 +259,7 @@ func TestVisorSpawnAppValidations(t *testing.T) { appCfg := appcommon.Config{ Name: app.App, ServerAddr: appcommon.DefaultServerAddr, - VisorPK: c.Visor.StaticPubKey.Hex(), + VisorPK: c.Keys().StaticPubKey.Hex(), WorkDir: filepath.Join("", app.App), } @@ -307,7 +298,7 @@ func TestVisorSpawnAppValidations(t *testing.T) { appCfg := appcommon.Config{ Name: app.App, ServerAddr: appcommon.DefaultServerAddr, - VisorPK: c.Visor.StaticPubKey.Hex(), + VisorPK: c.Keys().StaticPubKey.Hex(), WorkDir: filepath.Join("", app.App), } appArgs := append([]string{filepath.Join(visor.dir(), app.App)}, app.Args...)