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

Connect hypervisor and visor over dmsg #124

Merged
merged 11 commits into from
Jan 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions cmd/hypervisor/commands/gen-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var (
output string
replace bool
configLocType = pathutil.WorkingDirLoc
testenv bool
)

// nolint:gochecknoinits
Expand All @@ -24,6 +25,10 @@ func init() {
configLocTypeUsage := fmt.Sprintf("config generation mode. Valid values: %v", pathutil.AllConfigLocationTypes())

rootCmd.AddCommand(genConfigCmd)
genConfigCmd.Flags().StringVarP(&output, "output", "o", "", "path of output config file. Uses default of 'type' flag if unspecified.")
genConfigCmd.Flags().BoolVarP(&replace, "replace", "r", false, "whether to allow rewrite of a file that already exists.")
genConfigCmd.Flags().VarP(&configLocType, "type", "m", fmt.Sprintf("config generation mode. Valid values: %v", pathutil.AllConfigLocationTypes()))
genConfigCmd.Flags().BoolVarP(&testenv, "testing-environment", "t", false, "whether to use production or test deployment service.")
genConfigCmd.Flags().StringVarP(&output, "output", "o", "", outputUsage)
genConfigCmd.Flags().BoolVarP(&replace, "replace", "r", false, replaceUsage)
genConfigCmd.Flags().VarP(&configLocType, "type", "m", configLocTypeUsage)
Expand All @@ -47,11 +52,11 @@ var genConfigCmd = &cobra.Command{
var conf hypervisor.Config
switch configLocType {
case pathutil.WorkingDirLoc:
conf = hypervisor.GenerateWorkDirConfig()
conf = hypervisor.GenerateWorkDirConfig(testenv)
case pathutil.HomeLoc:
conf = hypervisor.GenerateHomeConfig()
conf = hypervisor.GenerateHomeConfig(testenv)
case pathutil.LocalLoc:
conf = hypervisor.GenerateLocalConfig()
conf = hypervisor.GenerateLocalConfig(testenv)
default:
log.Fatalln("invalid config type:", configLocType)
}
Expand Down
15 changes: 13 additions & 2 deletions cmd/hypervisor/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package commands

import (
"fmt"
"net"
"net/http"

"github.com/SkycoinProject/dmsg"
"github.com/SkycoinProject/dmsg/disc"

"github.com/SkycoinProject/skycoin/src/util/logging"
"github.com/spf13/cobra"

Expand Down Expand Up @@ -65,10 +67,19 @@ var rootCmd = &cobra.Command{

log.Infof("serving RPC on '%s'", rpcAddr)
go func() {
l, err := net.Listen("tcp", rpcAddr)
_, rpcPort, err := config.Interfaces.SplitRPCAddr()
if err != nil {
log.Fatalln("Failed to parse rpc port from rpc address:", err)
}

dmsgC := dmsg.NewClient(config.PK, config.SK, disc.NewHTTP(config.DmsgDiscovery), dmsg.DefaultConfig())
go dmsgC.Serve()

l, err := dmsgC.Listen(rpcPort)
if err != nil {
log.Fatalln("Failed to bind tcp port:", err)
}

if err := m.ServeRPC(l); err != nil {
log.Fatalln("Failed to serve RPC:", err)
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
golang.org/x/crypto v0.0.0-20191106202628-ed6320f186d4
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect
golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a
golang.org/x/tools v0.0.0-20200124021010-5c352bb417e0 // indirect
)

//replace github.com/SkycoinProject/dmsg => ../dmsg
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,14 @@ golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200110213125-a7a6caa82ab2 h1:V9r/14uGBqLgNlHRYWdVqjMdWkcOHnE2KG8DwVqQSEc=
golang.org/x/tools v0.0.0-20200110213125-a7a6caa82ab2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200115044656-831fdb1e1868/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200116062425-473961ec044c h1:D0OxfnjPaEGt7AluXNompYUYGhoY3u6+bValgqfd1vE=
golang.org/x/tools v0.0.0-20200116062425-473961ec044c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200123162537-45e69182d161 h1:96UK0Rx+sC4aQeuLGFxtAiCxAWzUu0OA4hhWlg4YvPQ=
golang.org/x/tools v0.0.0-20200123162537-45e69182d161/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200123220707-24841a4f5f7d h1:KTOebTDPx6KUWl0wm5bjotr4ceAFMsScfXJderPyZ2c=
golang.org/x/tools v0.0.0-20200123220707-24841a4f5f7d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200124021010-5c352bb417e0 h1:G9K47VwP2wDdADV683EnkOYQHhb20LSa80C4AE+Gskw=
golang.org/x/tools v0.0.0-20200124021010-5c352bb417e0/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
Expand Down
13 changes: 13 additions & 0 deletions pkg/httputil/httputil.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"io"
"net"
"net/http"
"strconv"
"strings"

"github.com/SkycoinProject/skycoin/src/util/logging"
"github.com/gorilla/handlers"
Expand Down Expand Up @@ -71,3 +73,14 @@ func WriteLog(writer io.Writer, params handlers.LogFormatterParams) {
log.WithError(err).Warn("Failed to write log")
}
}

// SplitRPCAddr returns host and port and whatever error results from parsing the rpc address interface
func SplitRPCAddr(rpcAddr string) (host string, port uint16, err error) {
addrToken := strings.Split(rpcAddr, ":")
uint64port, err := strconv.ParseUint(addrToken[1], 10, 16)
if err != nil {
return
}

return addrToken[0], uint16(uint64port), nil
}
42 changes: 28 additions & 14 deletions pkg/hypervisor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (

"github.com/SkycoinProject/dmsg/cipher"

"github.com/SkycoinProject/skywire-mainnet/internal/skyenv"
"github.com/SkycoinProject/skywire-mainnet/pkg/httputil"
"github.com/SkycoinProject/skywire-mainnet/pkg/util/pathutil"
)

Expand Down Expand Up @@ -42,20 +44,28 @@ func (hk *Key) UnmarshalText(text []byte) error {

// Config configures the hypervisor.
type Config struct {
Cookies CookieConfig `json:"cookies"` // Configures cookies (for session management).
Interfaces InterfaceConfig `json:"interfaces"` // Configures exposed interfaces.
DBPath string `json:"db_path"` // Path to store database file.
EnableAuth bool `json:"enable_auth"` // Whether to enable user management.
PK cipher.PubKey `json:"public_key"`
SK cipher.SecKey `json:"secret_key"`
PK cipher.PubKey `json:"public_key"`
SK cipher.SecKey `json:"secret_key"`
DBPath string `json:"db_path"` // Path to store database file.
EnableAuth bool `json:"enable_auth"` // Whether to enable user management.
Cookies CookieConfig `json:"cookies"` // Configures cookies (for session management).
Interfaces InterfaceConfig `json:"interfaces"` // Configures exposed interfaces.
DmsgDiscovery string `json:"dmsg_discovery"` // DmsgDiscovery address for dmsg usage
}

func makeConfig() Config {
func makeConfig(testenv bool) Config {
var c Config

pk, sk := cipher.GenerateKeyPair()
c.PK = pk
c.SK = sk

if testenv {
c.DmsgDiscovery = skyenv.TestDmsgDiscAddr
} else {
c.DmsgDiscovery = skyenv.DefaultDmsgDiscAddr
}

c.EnableAuth = true
c.Cookies.HashKey = cipher.RandByte(hashKeyLen)
c.Cookies.BlockKey = cipher.RandByte(blockKeyLen)
Expand All @@ -66,29 +76,28 @@ func makeConfig() Config {
}

// GenerateWorkDirConfig generates a config with default values and uses db from current working directory.
func GenerateWorkDirConfig() Config {
func GenerateWorkDirConfig(testenv bool) Config {
dir, err := os.Getwd()
if err != nil {
log.Fatalf("failed to generate WD config: %s", dir)
}

c := makeConfig()
c := makeConfig(testenv)
c.DBPath = filepath.Join(dir, "users.db")

return c
}

// GenerateHomeConfig generates a config with default values and uses db from user's home folder.
func GenerateHomeConfig() Config {
c := makeConfig()
func GenerateHomeConfig(testenv bool) Config {
c := makeConfig(testenv)
c.DBPath = filepath.Join(pathutil.HomeDir(), ".skycoin/hypervisor/users.db")

return c
}

// GenerateLocalConfig generates a config with default values and uses db from shared folder.
func GenerateLocalConfig() Config {
c := makeConfig()
func GenerateLocalConfig(testenv bool) Config {
c := makeConfig(testenv)
c.DBPath = "/usr/local/SkycoinProject/hypervisor/users.db"

return c
Expand Down Expand Up @@ -155,3 +164,8 @@ func (c *InterfaceConfig) FillDefaults() {
c.HTTPAddr = ":8080"
c.RPCAddr = ":7080"
}

// SplitRPCAddr returns host and port and whatever error results from parsing the rpc address interface
func (c *InterfaceConfig) SplitRPCAddr() (host string, port uint16, err error) {
return httputil.SplitRPCAddr(c.RPCAddr)
}
40 changes: 18 additions & 22 deletions pkg/hypervisor/hypervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import (
"fmt"
"io"
"math/rand"
"net"
"net/http"
"net/rpc"
"strconv"
"strings"
"sync"
"time"

"github.com/SkycoinProject/dmsg"
"github.com/SkycoinProject/dmsg/cipher"
"github.com/SkycoinProject/dmsg/noise"
"github.com/SkycoinProject/skycoin/src/util/logging"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
Expand All @@ -42,7 +42,7 @@ var (
)

type appNodeConn struct {
Addr *noise.Addr
Addr dmsg.Addr
Client visor.RPCClient
}

Expand Down Expand Up @@ -72,15 +72,15 @@ func NewNode(config Config) (*Node, error) {
}

// ServeRPC serves RPC of a Node.
func (m *Node) ServeRPC(lis net.Listener) error {
func (m *Node) ServeRPC(lis *dmsg.Listener) error {
for {
conn, err := noise.WrapListener(lis, m.c.PK, m.c.SK, false, noise.HandshakeXK).Accept()
conn, err := lis.Accept()
if err != nil {
return err
}

addr := conn.RemoteAddr().(*noise.Addr)

addr := conn.RemoteAddr().(dmsg.Addr)
log.Infoln("accepted: ", addr.PK)
m.mu.Lock()
m.nodes[addr.PK] = appNodeConn{
Addr: addr,
Expand All @@ -90,11 +90,6 @@ func (m *Node) ServeRPC(lis net.Listener) error {
}
}

type mockAddr string

func (mockAddr) Network() string { return "mock" }
func (a mockAddr) String() string { return string(a) }

// MockConfig configures how mock data is to be added.
type MockConfig struct {
Nodes int
Expand All @@ -115,9 +110,9 @@ func (m *Node) AddMockData(config MockConfig) error {

m.mu.Lock()
m.nodes[pk] = appNodeConn{
Addr: &noise.Addr{
Addr: dmsg.Addr{
PK: pk,
Addr: mockAddr(fmt.Sprintf("0.0.0.0:%d", i)),
Port: uint16(i),
},
Client: client,
}
Expand Down Expand Up @@ -284,7 +279,7 @@ func (m *Node) getNodes() http.HandlerFunc {
}

summaries = append(summaries, summaryResp{
TCPAddr: c.Addr.Addr.String(),
TCPAddr: c.Addr.String(),
Online: err == nil,
Summary: summary,
})
Expand All @@ -305,7 +300,7 @@ func (m *Node) getNode() http.HandlerFunc {
}

httputil.WriteJSON(w, r, http.StatusOK, summaryResp{
TCPAddr: ctx.Addr.Addr.String(),
TCPAddr: ctx.Addr.String(),
Summary: summary,
})
})
Expand Down Expand Up @@ -412,6 +407,7 @@ type LogsRes struct {
func (m *Node) appLogsSince() http.HandlerFunc {
return m.withCtx(m.appCtx, func(w http.ResponseWriter, r *http.Request, ctx *httpCtx) {
since := r.URL.Query().Get("since")
since = strings.Replace(since, " ", "+", 1) // we need to put '+' again that was replaced in the query string

// if time is not parsable or empty default to return all logs
t, err := time.Parse(time.RFC3339Nano, since)
Expand Down Expand Up @@ -696,7 +692,7 @@ func (m *Node) restart() http.HandlerFunc {
<<< Helper functions >>>
*/

func (m *Node) client(pk cipher.PubKey) (*noise.Addr, visor.RPCClient, bool) {
func (m *Node) client(pk cipher.PubKey) (dmsg.Addr, visor.RPCClient, bool) {
m.mu.RLock()
conn, ok := m.nodes[pk]
m.mu.RUnlock()
Expand All @@ -705,6 +701,11 @@ func (m *Node) client(pk cipher.PubKey) (*noise.Addr, visor.RPCClient, bool) {
}

type httpCtx struct {
// Node
PK cipher.PubKey
Addr dmsg.Addr
RPC visor.RPCClient

// App
App *visor.AppState

Expand All @@ -713,11 +714,6 @@ type httpCtx struct {

// Route
RtKey routing.RouteID

// Node
PK cipher.PubKey
Addr *noise.Addr
RPC visor.RPCClient
}

type (
Expand Down
2 changes: 1 addition & 1 deletion pkg/hypervisor/hypervisor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const (
)

func TestNewNode(t *testing.T) {
config := makeConfig()
config := makeConfig(false)

confDir, err := ioutil.TempDir(os.TempDir(), "SWHV")
require.NoError(t, err)
Expand Down
Loading