@@ -11,6 +11,8 @@ import (
1111
1212 "github.com/codegangsta/cli"
1313 "github.com/docker/containerd/api/grpc/types"
14+ "github.com/docker/docker/pkg/term"
15+ "github.com/opencontainers/runc/libcontainer"
1416 netcontext "golang.org/x/net/context"
1517 "google.golang.org/grpc"
1618)
@@ -72,6 +74,10 @@ var StartCommand = cli.Command{
7274 Name : "interactive,i" ,
7375 Usage : "connect to the stdio of the container" ,
7476 },
77+ cli.BoolFlag {
78+ Name : "tty,t" ,
79+ Usage : "allocate a tty for use with the container" ,
80+ },
7581 },
7682 Action : func (context * cli.Context ) {
7783 var (
@@ -84,6 +90,11 @@ var StartCommand = cli.Command{
8490 if id == "" {
8591 fatal ("container id cannot be empty" , 1 )
8692 }
93+ c := getClient ()
94+ events , err := c .Events (netcontext .Background (), & types.EventsRequest {})
95+ if err != nil {
96+ fatal (err .Error (), 1 )
97+ }
8798 r := & types.CreateContainerRequest {
8899 Id : id ,
89100 BundlePath : path ,
@@ -94,17 +105,57 @@ var StartCommand = cli.Command{
94105 fatal (err .Error (), 1 )
95106 }
96107 }
97- c := getClient ()
108+ if context .Bool ("tty" ) {
109+ if err := attachTty (r ); err != nil {
110+ fatal (err .Error (), 1 )
111+ }
112+ }
98113 if _ , err := c .CreateContainer (netcontext .Background (), r ); err != nil {
99114 fatal (err .Error (), 1 )
100115 }
101116 if stdin != nil {
102- io .Copy (stdin , os .Stdin )
117+ go func () {
118+ io .Copy (stdin , os .Stdin )
119+ if state != nil {
120+ term .RestoreTerminal (os .Stdin .Fd (), state )
121+ }
122+ }()
123+ for {
124+ e , err := events .Recv ()
125+ if err != nil {
126+ fatal (err .Error (), 1 )
127+ }
128+ if e .Id == id && e .Type == "exit" {
129+ os .Exit (int (e .Status ))
130+ }
131+ }
103132 }
104133 },
105134}
106135
107- var stdin io.WriteCloser
136+ var (
137+ stdin io.WriteCloser
138+ state * term.State
139+ )
140+
141+ func attachTty (r * types.CreateContainerRequest ) error {
142+ console , err := libcontainer .NewConsole (os .Getuid (), os .Getgid ())
143+ if err != nil {
144+ return err
145+ }
146+ r .Console = console .Path ()
147+ stdin = console
148+ go func () {
149+ io .Copy (os .Stdout , console )
150+ console .Close ()
151+ }()
152+ s , err := term .SetRawTerminal (os .Stdin .Fd ())
153+ if err != nil {
154+ return err
155+ }
156+ state = s
157+ return nil
158+ }
108159
109160func attachStdio (r * types.CreateContainerRequest ) error {
110161 dir , err := ioutil .TempDir ("" , "ctr-" )
0 commit comments