diff --git a/cmd/qpty/main.go b/cmd/qpty/main.go index e5d4078..45af680 100644 --- a/cmd/qpty/main.go +++ b/cmd/qpty/main.go @@ -25,27 +25,23 @@ func main() { if err != nil { log.Fatal(err) } - machine := qpty.New(client, containerId) + proc, err := qpty.New(client, containerId, &pty.Winsize{Rows: 14, Cols: 11}) if err != nil { log.Fatal(err) } - exec, err := machine.Exec(&pty.Winsize{Rows: 14, Cols: 11}) - if err != nil { - return - } go func() { time.Sleep(5 * time.Second) - milliType(exec, []byte(cmd+"\n"), 500*time.Millisecond) + milliType(proc, []byte(cmd+"\n"), 500*time.Millisecond) }() - err = exec.Run(shell) + err = proc.Run(shell) if err != nil { log.Fatal(err) } } -func milliType(exec *qpty.Exec, p []byte, gap time.Duration) { +func milliType(exec *qpty.Qpty, p []byte, gap time.Duration) { for _, i := range p { exec.Send([]byte{i}) time.Sleep(gap) diff --git a/qpty.go b/qpty.go index 3440616..73dfd53 100644 --- a/qpty.go +++ b/qpty.go @@ -12,57 +12,45 @@ import ( type Qpty struct { dock *docker.Client container string + pty, tty *os.File + ir, or *io.PipeReader + iw, ow *io.PipeWriter } -func New(client *docker.Client, container string) *Qpty { - return &Qpty{ - dock: client, - container: container, - } -} - -func (q *Qpty) Exec(size *pty.Winsize) (*Exec, error) { - iPty, _, err := pty.Open() +func New(client *docker.Client, container string, size *pty.Winsize) (*Qpty, error) { + iPty, iTty, err := pty.Open() if err != nil { return nil, err } - e := &Exec{ - q: q, - pty: iPty, + q := &Qpty{ + dock: client, + container: container, + pty: iPty, tty: iTty, } - if err := e.SetSize(size); err != nil { + if err := q.SetSize(size); err != nil { return nil, err } - - e.ir, e.iw = io.Pipe() - e.or, e.ow = io.Pipe() - - return e, nil + q.ir, q.iw = io.Pipe() + q.or, q.ow = io.Pipe() + return q, nil } -type Exec struct { - q *Qpty - pty *os.File - ir, or *io.PipeReader - iw, ow *io.PipeWriter +func (q *Qpty) Pty() *os.File { + return q.pty } -func (e *Exec) Pty() *os.File { - return e.pty +func (q *Qpty) SetSize(winsize *pty.Winsize) error { + return pty.Setsize(q.pty, winsize) } -func (e *Exec) SetSize(winsize *pty.Winsize) error { - return pty.Setsize(e.pty, winsize) +func (q *Qpty) Send(p []byte) (int, error) { + return q.iw.Write(p) } -func (e *Exec) Send(p []byte) (int, error) { - return e.iw.Write(p) -} - -func (e *Exec) Run(shell string) error { - execInst, err := e.q.dock.CreateExec(docker.CreateExecOptions{ +func (q *Qpty) Run(shell string) error { + execInst, err := q.dock.CreateExec(docker.CreateExecOptions{ Cmd: []string{shell}, - Container: e.q.container, + Container: q.container, User: "root", WorkingDir: "/", Context: context.Background(), @@ -75,18 +63,20 @@ func (e *Exec) Run(shell string) error { } go func() { - _, _ = io.Copy(e.pty, e.or) + _, _ = io.Copy(q.tty, q.or) }() go func() { r, w := io.Pipe() - go io.Copy(hex.NewEncoder(w), e.pty) - io.Copy(os.Stdout, r) + go func() { + _, _ = io.Copy(hex.NewEncoder(w), q.pty) + }() + _, _ = io.Copy(os.Stdout, r) }() - return e.q.dock.StartExec(execInst.ID, docker.StartExecOptions{ - InputStream: e.ir, - OutputStream: e.ow, + return q.dock.StartExec(execInst.ID, docker.StartExecOptions{ + InputStream: q.ir, + OutputStream: q.ow, ErrorStream: nil, Tty: true, RawTerminal: true,