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 app configurability via hypervisor and make it persistent #111

Merged
merged 18 commits into from
Jan 22, 2020
Merged
Show file tree
Hide file tree
Changes from 15 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
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: go
go:
# - "1.11.x" At minimum the code should run make check on the latest two go versions in the default linux environment provided by Travis.
- "1.12.x"
# - "1.13.x" At minimum the code should run make check on the latest two go versions in the default linux environment provided by Travis.
- "1.13.x"

dist: xenial

Expand All @@ -15,7 +15,7 @@ matrix:

install:
- go get -u github.com/FiloSottile/vendorcheck
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin v1.17.1
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin v1.22.2

before_script:
- ci_scripts/create-ip-aliases.sh
Expand Down
25 changes: 21 additions & 4 deletions cmd/apps/skysocks/skysocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package main
import (
"flag"
"fmt"
"os"
"os/signal"

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

Expand All @@ -16,16 +18,17 @@ import (
)

const (
appName = "skysocks"
netType = appnet.TypeSkynet
port = routing.Port(3)
appName = "skysocks"
netType = appnet.TypeSkynet
port routing.Port = 3
)

func main() {
log := app.NewLogger(appName)
skysocks.Log = log.PackageLogger("skysocks")

var passcode = flag.String("passcode", "", "Authorize user against this passcode")

flag.Parse()

config, err := app.ClientConfigFromEnv()
Expand All @@ -37,6 +40,7 @@ func main() {
if err != nil {
log.Fatal("Setup failure: ", err)
}

defer func() {
socksApp.Close()
}()
Expand All @@ -53,5 +57,18 @@ func main() {

log.Infoln("Starting serving proxy server")

log.Fatal(srv.Serve(l))
termCh := make(chan os.Signal, 1)
signal.Notify(termCh, os.Interrupt)

go func() {
<-termCh

if err := srv.Close(); err != nil {
log.Fatalf("Failed to close server: %v", err)
}
}()

if err := srv.Serve(l); err != nil {
log.Fatal(err)
}
}
32 changes: 29 additions & 3 deletions cmd/skywire-visor/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type runCfg struct {
port string
startDelay string
args []string
configPath *string

profileStop func()
logger *logging.Logger
Expand Down Expand Up @@ -90,6 +91,7 @@ func Execute() {

func (cfg *runCfg) startProfiler() *runCfg {
var option func(*profile.Profile)

switch cfg.profileMode {
case "none":
cfg.profileStop = func() {}
Expand All @@ -98,7 +100,9 @@ func (cfg *runCfg) startProfiler() *runCfg {
go func() {
log.Println(http.ListenAndServe(fmt.Sprintf("localhost:%v", cfg.port), nil))
}()

cfg.profileStop = func() {}

return cfg
case "cpu":
option = profile.CPUProfile
Expand All @@ -111,7 +115,9 @@ func (cfg *runCfg) startProfiler() *runCfg {
case "trace":
option = profile.TraceProfile
}

cfg.profileStop = profile.Start(profile.ProfilePath("./logs/"+cfg.tag), option).Stop

return cfg
}

Expand All @@ -128,18 +134,31 @@ func (cfg *runCfg) startLogger() *runCfg {
cfg.masterLogger.Out = ioutil.Discard
}
}

return cfg
}

func (cfg *runCfg) readConfig() *runCfg {
var rdr io.Reader
var err error

if !cfg.cfgFromStdin {
configPath := pathutil.FindConfigPath(cfg.args, 0, configEnv, pathutil.NodeDefaults())
rdr, err = os.Open(filepath.Clean(configPath))

file, err := os.Open(filepath.Clean(configPath))
if err != nil {
cfg.logger.Fatalf("Failed to open config: %s", err)
}

defer func() {
if err := file.Close(); err != nil {
cfg.logger.Warnf("Failed to close config file: %v", err)
}
}()

cfg.logger.Info("Reading config from %v", configPath)

rdr = file
cfg.configPath = &configPath
} else {
cfg.logger.Info("Reading config from STDIN")
rdr = bufio.NewReader(os.Stdin)
Expand All @@ -149,14 +168,17 @@ func (cfg *runCfg) readConfig() *runCfg {
if err := json.NewDecoder(rdr).Decode(&cfg.conf); err != nil {
cfg.logger.Fatalf("Failed to decode %s: %s", rdr, err)
}

fmt.Println("TCP Factory conf:", cfg.conf.STCP)

return cfg
}

func (cfg *runCfg) runNode() *runCfg {
startDelay, err := time.ParseDuration(cfg.startDelay)
if err != nil {
cfg.logger.Warnf("Using no visor start delay due to parsing failure: %v", err)

startDelay = time.Duration(0)
}

Expand All @@ -176,7 +198,7 @@ func (cfg *runCfg) runNode() *runCfg {
cfg.logger.Fatal("failed to unlink socket files: ", err)
}

node, err := visor.NewNode(&cfg.conf, cfg.masterLogger, cfg.restartCtx)
node, err := visor.NewNode(&cfg.conf, cfg.masterLogger, cfg.restartCtx, cfg.configPath)
if err != nil {
cfg.logger.Fatal("Failed to initialize node: ", err)
}
Expand Down Expand Up @@ -216,18 +238,21 @@ func (cfg *runCfg) runNode() *runCfg {

func (cfg *runCfg) stopNode() *runCfg {
defer cfg.profileStop()

if err := cfg.node.Close(); err != nil {
if !strings.Contains(err.Error(), "closed") {
cfg.logger.Fatal("Failed to close node: ", err)
}
}

return cfg
}

func (cfg *runCfg) waitOsSignals() *runCfg {
ch := make(chan os.Signal, 2)
signal.Notify(ch, []os.Signal{syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT}...)
<-ch

go func() {
select {
case <-time.After(time.Duration(cfg.conf.ShutdownTimeout)):
Expand All @@ -236,5 +261,6 @@ func (cfg *runCfg) waitOsSignals() *runCfg {
cfg.logger.Fatalf("Received signal %s: terminating", s)
}
}()

return cfg
}
79 changes: 45 additions & 34 deletions internal/skysocks/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

// Log is skysocks package level logger, it can be replaced with a different one from outside the package
var Log = logging.MustGetLogger("skysocks")
var Log = logging.MustGetLogger("skysocks") // nolint: gochecknoglobals

// Client implement multiplexing proxy client using yamux.
type Client struct {
Expand All @@ -19,20 +19,22 @@ type Client struct {
}

// NewClient constructs a new Client.
func NewClient(conn net.Conn) (*Client, error) {
func NewClient(conn io.ReadWriteCloser) (*Client, error) {
session, err := yamux.Client(conn, nil)
if err != nil {
return nil, fmt.Errorf("error creating client: yamux: %s", err)
}

return &Client{session: session}, nil
c := &Client{
session: session,
}

return c, nil
}

// ListenAndServe start tcp listener on addr and proxies incoming
// connection to a remote proxy server.
func (c *Client) ListenAndServe(addr string) error {
var err error

l, err := net.Listen("tcp", addr)
if err != nil {
return fmt.Errorf("listen: %s", err)
Expand All @@ -41,6 +43,7 @@ func (c *Client) ListenAndServe(addr string) error {
Log.Printf("Listening skysocks client on %s", addr)

c.listener = l

for {
conn, err := l.Accept()
if err != nil {
Expand All @@ -49,59 +52,67 @@ func (c *Client) ListenAndServe(addr string) error {
}

Log.Println("Accepted skysocks client")

stream, err := c.session.Open()
if err != nil {
return fmt.Errorf("error on `ListenAndServe`: yamux: %s", err)
}

Log.Println("Opened session skysocks client")

go func() {
errCh := make(chan error, 2)
go c.handleStream(conn, stream)
}
}

go func() {
_, err := io.Copy(stream, conn)
errCh <- err
}()
func (c *Client) handleStream(conn, stream net.Conn) {
const errorCount = 2

go func() {
_, err := io.Copy(conn, stream)
errCh <- err
}()
errCh := make(chan error, errorCount)

var connClosed, streamClosed bool
for err := range errCh {
if !connClosed {
if err := conn.Close(); err != nil {
Log.WithError(err).Warn("Failed to close connection")
}
go func() {
_, err := io.Copy(stream, conn)
errCh <- err
}()

connClosed = true
}
go func() {
_, err := io.Copy(conn, stream)
errCh <- err
}()

if !streamClosed {
if err := stream.Close(); err != nil {
Log.WithError(err).Warn("Failed to close stream")
}
var connClosed, streamClosed bool

streamClosed = true
}
for err := range errCh {
if !connClosed {
if err := conn.Close(); err != nil {
Log.WithError(err).Warn("Failed to close connection")
}

if err != nil {
Log.Error("Copy error:", err)
}
connClosed = true
}

if !streamClosed {
if err := stream.Close(); err != nil {
Log.WithError(err).Warn("Failed to close stream")
}

close(errCh)
}()
streamClosed = true
}

if err != nil {
Log.Error("Copy error:", err)
}
}

close(errCh)
}

// Close implement io.Closer.
func (c *Client) Close() error {
Log.Infoln("Closing proxy client")

if c == nil {
return nil
}

return c.listener.Close()
}
Loading