The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/2416

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
This is an ongoing work to enable port forwarding for LXD through its own channel. It's been slow as I study networking in Go after Python, and some concepts need more time to settle down.

 * [x] teleport command
 * [x] passing teleport parameters
   * [ ] parsing and setting port number
 * [x] client-side command handler
   * [x] accepting local connections
   * [ ] getting back result 
   * [ ] handle errors
   * [ ] handle multiple connections simultaneously (or limit them)
   * [ ] wrap request over websocket to the server side
    * [ ] create websocket tunnel
    * [ ] forward request over websocket and listen for reply
   * [ ] write tests
 * [ ] server-side handler
  * [ ] check that port on container is open
    * [ ] wait or no wait
  * [ ] accept connection over the websocket
  * [ ] read from container port
    * [ ] send reply stream through websocket
  * [ ] handle errors, what to do (and how to pass errrors)
   * [ ] port is closed
   * [ ] port doesn't accept connections
   * [ ] wrapped connection is reset
   * [ ] client connection is reset
   * [ ] some websocket error
 * [ ] draw diagram how it is wrapped

Right now the stumbling block is the server side - how can I debug it without packaging and reinstalling the daemon every time?
From 628df5a03e37055115f7f142758b25f6bde6a081 Mon Sep 17 00:00:00 2001
From: anatoly techtonik <techto...@gmail.com>
Date: Wed, 29 Jun 2016 17:38:02 +0300
Subject: [PATCH 1/8] Add new command - teleport - non-tested draft for now

https://github.com/lxc/lxd/issues/1363#issuecomment-226946534

Signed-off-by: anatoly techtonik <techto...@gmail.com>
---
 lxc/teleport.go | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 lxc/teleport.go

diff --git a/lxc/teleport.go b/lxc/teleport.go
new file mode 100644
index 0000000..7e30af7
--- /dev/null
+++ b/lxc/teleport.go
@@ -0,0 +1,28 @@
+package main
+
+import (
+       "fmt"
+       "strings"
+
+       "github.com/lxc/lxd"
+       "github.com/lxc/lxd/shared"
+       "github.com/lxc/lxd/shared/i18n"
+)
+
+type teleportCmd struct {
+       httpAddr string
+       expanded bool
+}
+
+func (c *teleportCmd) showByDefault() bool {
+       return true
+}
+
+func (c *teleportCmd) usage() string {
+       return i18n.G(
+               `Makes port from inside container available on local interface.
+
+lxd teleport [remote:]container there=:<port> here=<host>:<port>
+`)
+
+}

From c64c9750b0abca5c6f091d3a3b773c79b9c57ecc Mon Sep 17 00:00:00 2001
From: anatoly techtonik <techto...@gmail.com>
Date: Fri, 1 Jul 2016 11:45:30 +0300
Subject: [PATCH 2/8] Add teleport to command line, fix go errors

  *teleportCmd does not implement command (missing flags method)
  *teleportCmd does not implement command (missing run method)
  imported and not used: "fmt"
  imported and not used: "strings"

Signed-off-by: anatoly techtonik <techto...@gmail.com>
---
 lxc/main.go     |  1 +
 lxc/teleport.go | 15 ++++++++++-----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/lxc/main.go b/lxc/main.go
index a3dcc70..c612d6a 100644
--- a/lxc/main.go
+++ b/lxc/main.go
@@ -203,6 +203,7 @@ var commands = map[string]command{
                name:       "stop",
                timeout:    -1,
        },
+       "teleport": &teleportCmd{},
        "version": &versionCmd{},
 }
 
diff --git a/lxc/teleport.go b/lxc/teleport.go
index 7e30af7..c7f6c92 100644
--- a/lxc/teleport.go
+++ b/lxc/teleport.go
@@ -1,11 +1,7 @@
 package main
 
 import (
-       "fmt"
-       "strings"
-
        "github.com/lxc/lxd"
-       "github.com/lxc/lxd/shared"
        "github.com/lxc/lxd/shared/i18n"
 )
 
@@ -20,9 +16,18 @@ func (c *teleportCmd) showByDefault() bool {
 
 func (c *teleportCmd) usage() string {
        return i18n.G(
-               `Makes port from inside container available on local interface.
+               `Make port from inside container available on local interface.
 
 lxd teleport [remote:]container there=:<port> here=<host>:<port>
 `)
+}
+
+func (c *teleportCmd) flags() {
+}
 
+func (c *teleportCmd) run(config *lxd.Config, args []string) error {
+       if len(args) == 0 {
+               return errArgs
+       }
+       return nil
 }

From 68339bf2264c3897776e0b3eecb15eb58c7444d3 Mon Sep 17 00:00:00 2001
From: anatoly techtonik <techto...@gmail.com>
Date: Fri, 1 Jul 2016 17:11:32 +0300
Subject: [PATCH 3/8] Add argument parsing and client creation

Signed-off-by: anatoly techtonik <techto...@gmail.com>
---
 lxc/teleport.go | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/lxc/teleport.go b/lxc/teleport.go
index c7f6c92..f940c25 100644
--- a/lxc/teleport.go
+++ b/lxc/teleport.go
@@ -1,14 +1,13 @@
 package main
 
 import (
+       "fmt"
+
        "github.com/lxc/lxd"
        "github.com/lxc/lxd/shared/i18n"
 )
 
-type teleportCmd struct {
-       httpAddr string
-       expanded bool
-}
+type teleportCmd struct {}
 
 func (c *teleportCmd) showByDefault() bool {
        return true
@@ -18,7 +17,7 @@ func (c *teleportCmd) usage() string {
        return i18n.G(
                `Make port from inside container available on local interface.
 
-lxd teleport [remote:]container there=:<port> here=<host>:<port>
+lxd teleport [remote:]container [there=:<port> here=<host>:<port>]
 `)
 }
 
@@ -26,8 +25,18 @@ func (c *teleportCmd) flags() {
 }
 
 func (c *teleportCmd) run(config *lxd.Config, args []string) error {
-       if len(args) == 0 {
+       // [ ] param parsing
+       if len(args) < 1 {
                return errArgs
        }
+
+       remote, name := config.ParseRemoteAndContainer(args[0])
+       d, err := lxd.NewClient(config, remote)
+       if err != nil {
+               return err
+       }
+       fmt.Println(`New client: ` + d.Name)
+       fmt.Println("Teleporting: " + name)
+
        return nil
 }

From 4b934f727f46df89b8d3d50758bd7dd7f4d94693 Mon Sep 17 00:00:00 2001
From: anatoly techtonik <techto...@gmail.com>
Date: Sat, 27 Aug 2016 15:16:19 +0300
Subject: [PATCH 4/8] teleport: Listen for local connections on 1337 (for now)

---
 lxc/teleport.go | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/lxc/teleport.go b/lxc/teleport.go
index f940c25..9aa7f86 100644
--- a/lxc/teleport.go
+++ b/lxc/teleport.go
@@ -2,6 +2,7 @@ package main
 
 import (
        "fmt"
+       "net"
 
        "github.com/lxc/lxd"
        "github.com/lxc/lxd/shared/i18n"
@@ -31,12 +32,32 @@ func (c *teleportCmd) run(config *lxd.Config, args 
[]string) error {
        }
 
        remote, name := config.ParseRemoteAndContainer(args[0])
+       // client provides websocket to container
        d, err := lxd.NewClient(config, remote)
        if err != nil {
                return err
        }
        fmt.Println(`New client: ` + d.Name)
-       fmt.Println("Teleporting: " + name)
+       fmt.Println("Connecting to: " + name)
+
+       // creating local server for listening on specified port
+       // [ ] no hardcoded value
+       listenon := "localhost:1337"
+       fmt.Println("Listening on: " + listenon)
+       acceptor, err := net.Listen("tcp", listenon)
+       if err != nil {
+               return err
+       }
+       for {
+               conn, err := acceptor.Accept()
+               if err != nil {
+                       // [ ] doesn't seem to be the right strategy
+                       return err
+               }
+               // [ ] go handle forward request
+               //handle(conn)
+               fmt.Printf("New connection from: %s\n", conn.RemoteAddr())
+       }
 
        return nil
 }

From 3a3e316415a8b6a93fcc44b477008663665aa7d0 Mon Sep 17 00:00:00 2001
From: anatoly techtonik <techto...@gmail.com>
Date: Sat, 27 Aug 2016 16:35:20 +0300
Subject: [PATCH 5/8] teleport: Move connection handler to separate function

---
 lxc/teleport.go | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/lxc/teleport.go b/lxc/teleport.go
index 9aa7f86..80d2b56 100644
--- a/lxc/teleport.go
+++ b/lxc/teleport.go
@@ -25,6 +25,10 @@ lxd teleport [remote:]container [there=:<port> 
here=<host>:<port>]
 func (c *teleportCmd) flags() {
 }
 
+func (c *teleportCmd) forward(conn net.Conn) {
+       fmt.Printf("New connection from: %s\n", conn.RemoteAddr())
+}
+
 func (c *teleportCmd) run(config *lxd.Config, args []string) error {
        // [ ] param parsing
        if len(args) < 1 {
@@ -55,8 +59,7 @@ func (c *teleportCmd) run(config *lxd.Config, args []string) 
error {
                        return err
                }
                // [ ] go handle forward request
-               //handle(conn)
-               fmt.Printf("New connection from: %s\n", conn.RemoteAddr())
+               go c.forward(conn)
        }
 
        return nil

From 950b4b6b77336922f82e51c67ab00539efb6d881 Mon Sep 17 00:00:00 2001
From: anatoly techtonik <techto...@gmail.com>
Date: Sat, 27 Aug 2016 16:53:30 +0300
Subject: [PATCH 6/8] teleport: Write to accepted socket

Firefox recreates connections too many times,
perhaps it expects HTTP response, so it is better
to test it with nc
---
 lxc/teleport.go | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lxc/teleport.go b/lxc/teleport.go
index 80d2b56..7087bc1 100644
--- a/lxc/teleport.go
+++ b/lxc/teleport.go
@@ -27,6 +27,8 @@ func (c *teleportCmd) flags() {
 
 func (c *teleportCmd) forward(conn net.Conn) {
        fmt.Printf("New connection from: %s\n", conn.RemoteAddr())
+       defer conn.Close()
+       conn.Write([]byte("No signal from remote\n"))
 }
 
 func (c *teleportCmd) run(config *lxd.Config, args []string) error {

From 3152f8ee9363f8c7750e7b49ffc35950d99b953b Mon Sep 17 00:00:00 2001
From: anatoly techtonik <techto...@gmail.com>
Date: Sat, 27 Aug 2016 17:51:41 +0300
Subject: [PATCH 7/8] teleport: Pass lxd client pointer to connection handler

---
 lxc/teleport.go | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/lxc/teleport.go b/lxc/teleport.go
index 7087bc1..3f7b19c 100644
--- a/lxc/teleport.go
+++ b/lxc/teleport.go
@@ -25,9 +25,11 @@ lxd teleport [remote:]container [there=:<port> 
here=<host>:<port>]
 func (c *teleportCmd) flags() {
 }
 
-func (c *teleportCmd) forward(conn net.Conn) {
+func (c *teleportCmd) forward(conn net.Conn, client *lxd.Client) {
        fmt.Printf("New connection from: %s\n", conn.RemoteAddr())
        defer conn.Close()
+
+       // [ ] if no signal, write debug message
        conn.Write([]byte("No signal from remote\n"))
 }
 
@@ -38,13 +40,14 @@ func (c *teleportCmd) run(config *lxd.Config, args 
[]string) error {
        }
 
        remote, name := config.ParseRemoteAndContainer(args[0])
-       // client provides websocket to container
+
+       // create new client to get websocket connection
        d, err := lxd.NewClient(config, remote)
        if err != nil {
                return err
        }
        fmt.Println(`New client: ` + d.Name)
-       fmt.Println("Connecting to: " + name)
+       fmt.Println("Container: " + name)
 
        // creating local server for listening on specified port
        // [ ] no hardcoded value
@@ -61,7 +64,7 @@ func (c *teleportCmd) run(config *lxd.Config, args []string) 
error {
                        return err
                }
                // [ ] go handle forward request
-               go c.forward(conn)
+               go c.forward(conn, d)
        }
 
        return nil

From a0a793288678cf9ae2b0242bb2435edd0912281b Mon Sep 17 00:00:00 2001
From: anatoly techtonik <techto...@gmail.com>
Date: Sat, 27 Aug 2016 18:28:20 +0300
Subject: [PATCH 8/8] Move response string output to client code

---
 client.go       | 8 ++++++++
 lxc/teleport.go | 3 ++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/client.go b/client.go
index 0191656..dee7178 100644
--- a/client.go
+++ b/client.go
@@ -2618,3 +2618,11 @@ func (c *Client) ImageFromContainer(cname string, public 
bool, aliases []string,
 
        return fingerprint, nil
 }
+
+func (c *Client) Teleport() (string, error) {
+       if c.Remote.Public {
+               return "", fmt.Errorf("This function isn't supported by public 
remotes.")
+       }
+
+       return "No signal from remote\n", nil
+}
diff --git a/lxc/teleport.go b/lxc/teleport.go
index 3f7b19c..ed9fcca 100644
--- a/lxc/teleport.go
+++ b/lxc/teleport.go
@@ -30,7 +30,8 @@ func (c *teleportCmd) forward(conn net.Conn, client 
*lxd.Client) {
        defer conn.Close()
 
        // [ ] if no signal, write debug message
-       conn.Write([]byte("No signal from remote\n"))
+       out, _ := client.Teleport()
+       conn.Write([]byte(out))
 }
 
 func (c *teleportCmd) run(config *lxd.Config, args []string) error {
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to