Implement Pty and CloseStdin for windows runtime

Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
Kenfe-Mickael Laventure 2017-04-10 13:18:55 -07:00
parent 22a051c88e
commit 918a3ee4a1
7 changed files with 124 additions and 41 deletions

View File

@ -5,11 +5,8 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
"os/signal"
"runtime" "runtime"
"golang.org/x/sys/unix"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
@ -192,39 +189,3 @@ var runCommand = cli.Command{
return nil return nil
}, },
} }
func handleConsoleResize(ctx gocontext.Context, service execution.ContainerServiceClient, id string, pid uint32, con console.Console) error {
// do an initial resize of the console
size, err := con.Size()
if err != nil {
return err
}
if _, err := service.Pty(ctx, &execution.PtyRequest{
ID: id,
Pid: pid,
Width: uint32(size.Width),
Height: uint32(size.Height),
}); err != nil {
return err
}
s := make(chan os.Signal, 16)
signal.Notify(s, unix.SIGWINCH)
go func() {
for range s {
size, err := con.Size()
if err != nil {
logrus.WithError(err).Error("get pty size")
continue
}
if _, err := service.Pty(ctx, &execution.PtyRequest{
ID: id,
Pid: pid,
Width: uint32(size.Width),
Height: uint32(size.Height),
}); err != nil {
logrus.WithError(err).Error("resize pty")
}
}
}()
return nil
}

View File

@ -3,16 +3,22 @@
package main package main
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os"
"os/signal"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"golang.org/x/sys/unix"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/containerd/containerd/api/services/execution" "github.com/containerd/containerd/api/services/execution"
"github.com/crosbymichael/console"
protobuf "github.com/gogo/protobuf/types" protobuf "github.com/gogo/protobuf/types"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
@ -262,3 +268,39 @@ func newCreateRequest(context *cli.Context, imageConfig *ocispec.ImageConfig, id
return create, nil return create, nil
} }
func handleConsoleResize(ctx context.Context, service execution.ContainerServiceClient, id string, pid uint32, con console.Console) error {
// do an initial resize of the console
size, err := con.Size()
if err != nil {
return err
}
if _, err := service.Pty(ctx, &execution.PtyRequest{
ID: id,
Pid: pid,
Width: uint32(size.Width),
Height: uint32(size.Height),
}); err != nil {
return err
}
s := make(chan os.Signal, 16)
signal.Notify(s, unix.SIGWINCH)
go func() {
for range s {
size, err := con.Size()
if err != nil {
logrus.WithError(err).Error("get pty size")
continue
}
if _, err := service.Pty(ctx, &execution.PtyRequest{
ID: id,
Pid: pid,
Width: uint32(size.Width),
Height: uint32(size.Height),
}); err != nil {
logrus.WithError(err).Error("resize pty")
}
}
}()
return nil
}

View File

@ -1,15 +1,19 @@
package main package main
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"runtime" "runtime"
"time"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/containerd/containerd/api/services/execution" "github.com/containerd/containerd/api/services/execution"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/windows" "github.com/containerd/containerd/windows"
"github.com/containerd/containerd/windows/hcs" "github.com/containerd/containerd/windows/hcs"
"github.com/crosbymichael/console"
protobuf "github.com/gogo/protobuf/types" protobuf "github.com/gogo/protobuf/types"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
@ -148,3 +152,36 @@ func newCreateRequest(context *cli.Context, imageConfig *ocispec.ImageConfig, id
return create, nil return create, nil
} }
func handleConsoleResize(ctx context.Context, service execution.ContainerServiceClient, id string, pid uint32, con console.Console) error {
// do an initial resize of the console
size, err := con.Size()
if err != nil {
return err
}
go func() {
prevSize := size
for {
time.Sleep(time.Millisecond * 250)
size, err := con.Size()
if err != nil {
log.G(ctx).WithError(err).Error("get pty size")
continue
}
if size.Width != prevSize.Width || size.Height != prevSize.Height {
if _, err := service.Pty(ctx, &execution.PtyRequest{
ID: id,
Pid: pid,
Width: uint32(size.Width),
Height: uint32(size.Height),
}); err != nil {
log.G(ctx).WithError(err).Error("resize pty")
}
prevSize = size
}
}
}()
return nil
}

View File

@ -1,5 +1,5 @@
github.com/crosbymichael/go-runc 65847bfc51952703ca24b564d10de50d3f2db6e7 github.com/crosbymichael/go-runc 65847bfc51952703ca24b564d10de50d3f2db6e7
github.com/crosbymichael/console 3e9d1bd6d181492458dbc171150185c14139fd46 github.com/crosbymichael/console f13f890e20a94bdec6c328cdf9410b7158f0cfa4
github.com/crosbymichael/cgroups a692a19766b072b86d89620c97a7916b2e2de3e7 github.com/crosbymichael/cgroups a692a19766b072b86d89620c97a7916b2e2de3e7
github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87 github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87
github.com/prometheus/client_golang v0.8.0 github.com/prometheus/client_golang v0.8.0

View File

@ -105,7 +105,7 @@ func (m *master) Reset() error {
} }
func (m *master) Size() (WinSize, error) { func (m *master) Size() (WinSize, error) {
info, err := winterm.GetConsoleScreenBufferInfo(m.in) info, err := winterm.GetConsoleScreenBufferInfo(m.out)
if err != nil { if err != nil {
return WinSize{}, errors.Wrap(err, "unable to get console info") return WinSize{}, errors.Wrap(err, "unable to get console info")
} }

View File

@ -142,6 +142,14 @@ func (c *container) Exec(ctx context.Context, opts containerd.ExecOpts) (contain
return &process{p}, nil return &process{p}, nil
} }
func (c *container) CloseStdin(ctx context.Context, pid uint32) error {
return c.ctr.CloseStdin(ctx, pid)
}
func (c *container) Pty(ctx context.Context, pid uint32, size containerd.ConsoleSize) error {
return c.ctr.Pty(ctx, pid, size)
}
func (c *container) Status() containerd.Status { func (c *container) Status() containerd.Status {
return c.getStatus() return c.getStatus()
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/containerd/containerd"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/windows/pid" "github.com/containerd/containerd/windows/pid"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
@ -194,6 +195,40 @@ func (c *Container) Stop(ctx context.Context) error {
return nil return nil
} }
func (c *Container) CloseStdin(ctx context.Context, pid uint32) error {
var proc *Process
c.Lock()
for _, p := range c.processes {
if p.Pid() == pid {
proc = p
break
}
}
c.Unlock()
if proc == nil {
return errors.Errorf("no such process %v", pid)
}
return proc.CloseStdin()
}
func (c *Container) Pty(ctx context.Context, pid uint32, size containerd.ConsoleSize) error {
var proc *Process
c.Lock()
for _, p := range c.processes {
if p.Pid() == pid {
proc = p
break
}
}
c.Unlock()
if proc == nil {
return errors.Errorf("no such process %v", pid)
}
return proc.ResizeConsole(uint16(size.Width), uint16(size.Height))
}
func (c *Container) Delete(ctx context.Context) { func (c *Container) Delete(ctx context.Context) {
defer func() { defer func() {
if err := c.Stop(ctx); err != nil { if err := c.Stop(ctx); err != nil {