Skip to content

Commit

Permalink
Merge pull request #111 from nkryuchkov/feature/persistent-settings
Browse files Browse the repository at this point in the history
Improve app configurability via hypervisor and make it persistent
  • Loading branch information
nkryuchkov authored Jan 22, 2020
2 parents 9b6d140 + 1f10e36 commit 6dd75b9
Show file tree
Hide file tree
Showing 31 changed files with 634 additions and 239 deletions.
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

0 comments on commit 6dd75b9

Please sign in to comment.