Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // client.go
- package main
- import (
- "log"
- "io"
- "net"
- "os"
- "github.com/docker/libchan"
- "github.com/docker/libchan/spdy"
- )
- type RemoteCommand struct {
- Cmd string
- Args []string
- Stdin io.Writer
- Stdout io.Reader
- Stderr io.Reader
- StatusChan libchan.Sender
- }
- type CommandResponse struct {
- Status int
- }
- func main() {
- var client net.Conn
- client, err := net.Dial("tcp", "127.0.0.1:9323")
- if err != nil {
- log.Fatal(err)
- }
- p, err := spdy.NewSpdyStreamProvider(client, false)
- transport := spdy.NewTransport(p)
- sender, err := transport.NewSendChannel()
- if err != nil {
- log.Fatal(err)
- }
- receiver, remoteSender := libchan.Pipe()
- command := &RemoteCommand{
- Cmd: os.Args[1],
- Args: os.Args[2:],
- Stdin: os.Stdin,
- Stdout: os.Stdout,
- Stderr: os.Stderr,
- StatusChan: remoteSender,
- }
- err = sender.Send(command)
- if err != nil {
- log.Fatal(err)
- }
- response := &CommandResponse{}
- err = receiver.Receive(response)
- if err != nil {
- log.Fatal(err)
- }
- os.Exit(response.Status)
- }
- // server.go
- package main
- import (
- "log"
- "net"
- "io"
- "os/exec"
- "syscall"
- "github.com/docker/libchan"
- "github.com/docker/libchan/spdy"
- )
- type RemoteReceivedCommand struct {
- Cmd string
- Args []string
- Stdin io.Reader
- Stdout io.WriteCloser
- Stderr io.WriteCloser
- StatusChan libchan.Sender
- }
- type CommandResponse struct {
- Status int
- }
- func main() {
- var listener net.Listener
- var err error
- listener, err = net.Listen("tcp", "localhost:9323")
- if err != nil {
- log.Fatal(err)
- }
- for {
- c, err := listener.Accept()
- if err != nil {
- log.Print("listener accept error")
- log.Print(err)
- break
- }
- p, err := spdy.NewSpdyStreamProvider(c, true)
- if err != nil {
- log.Print("spdy stream error")
- log.Print(err)
- break
- }
- t := spdy.NewTransport(p)
- go func() {
- for {
- receiver, err := t.WaitReceiveChannel()
- if err != nil {
- log.Print("receiver error")
- log.Print(err)
- break
- }
- log.Print("about to spawn receive proc")
- go func() {
- for {
- command := &RemoteReceivedCommand{}
- err := receiver.Receive(command)
- log.Print("received command")
- log.Print(command)
- if err != nil {
- log.Print("command error")
- log.Print(err)
- break
- }
- cmd := exec.Command(command.Cmd, command.Args...)
- cmd.Stdout = command.Stdout
- cmd.Stderr = command.Stderr
- stdin, err := cmd.StdinPipe()
- if err != nil {
- log.Print("stdin error")
- log.Print(err)
- break
- }
- go func() {
- io.Copy(stdin, command.Stdin)
- stdin.Close()
- }()
- log.Print("about to run the command")
- res := cmd.Run()
- command.Stdout.Close()
- command.Stderr.Close()
- returnResult := &CommandResponse{}
- if res != nil {
- if exiterr, ok := res.(*exec.ExitError); ok {
- returnResult.Status = exiterr.Sys().(syscall.WaitStatus).ExitStatus()
- } else {
- log.Print("res")
- log.Print(res)
- returnResult.Status = 10
- }
- }
- err = command.StatusChan.Send(returnResult)
- if err != nil {
- log.Print(err)
- }
- }
- }()
- }
- }()
- }
- }
- $ ./client /bin/echo "hello"
- 2018/06/18 23:13:56 about to spawn receive proc
- 2018/06/18 23:13:56 received command
- 2018/06/18 23:13:56 &{/bin/echo [hello] 0xc4201201b0 0xc42023c030 0xc42023c090 0xc420186080}
- 2018/06/18 23:13:56 about to run the command
- 2018/06/18 23:13:56 received command
- 2018/06/18 23:13:56 &{ [] <nil> <nil> <nil> <nil>}
- 2018/06/18 23:13:56 command error
- 2018/06/18 23:13:56 EOF
Add Comment
Please, Sign In to add comment