@@ -383,12 +383,13 @@ func (cli *DebugCli) ContainerClean(ctx context.Context, id string) error {
383383}
384384
385385// ExecCreate exec create
386- func (cli * DebugCli ) ExecCreate (options execOptions , container string ) (types.IDResponse , error ) {
386+ func (cli * DebugCli ) ExecCreate (options execOptions , containerStr string ) (types.IDResponse , error ) {
387387 var workDir = options .workDir
388388 if workDir == "" && cli .config .MountDir != "" {
389389 workDir = path .Join (cli .config .MountDir , options .targetDir )
390390 }
391- opt := types.ExecConfig {
391+ h , w := cli .out .GetTtySize ()
392+ opt := container.ExecOptions {
392393 User : options .user ,
393394 Privileged : options .privileged ,
394395 DetachKeys : options .detachKeys ,
@@ -398,34 +399,67 @@ func (cli *DebugCli) ExecCreate(options execOptions, container string) (types.ID
398399 AttachStdout : true ,
399400 WorkingDir : workDir ,
400401 Cmd : options .command ,
402+ ConsoleSize : & [2 ]uint {h , w },
401403 }
402404 ctx , cancel := cli .withContent (cli .config .Timeout )
403405 defer cancel ()
404- resp , err := cli .client .ContainerExecCreate (ctx , container , opt )
406+ resp , err := cli .client .ContainerExecCreate (ctx , containerStr , opt )
405407 return resp , errors .WithStack (err )
406408}
407409
408410// ExecStart exec start
409- func (cli * DebugCli ) ExecStart (_ execOptions , execID string ) error {
410- execConfig := types.ExecStartCheck {
411- Tty : true ,
411+ func (cli * DebugCli ) ExecStart (options execOptions , execID string ) error {
412+ h , w := cli .out .GetTtySize ()
413+ execConfig := container.ExecStartOptions {
414+ Tty : true ,
415+ ConsoleSize : & [2 ]uint {h , w },
412416 }
413417
414418 ctx , cancel := cli .withContent (cli .config .Timeout )
415- response , err := cli .client .ContainerExecAttach (ctx , execID , execConfig )
416419 defer cancel ()
420+ response , err := cli .client .ContainerExecAttach (ctx , execID , execConfig )
417421 if err != nil {
418422 return errors .WithStack (err )
419423 }
420- streamer := tty.HijackedIOStreamer {
421- Streams : cli ,
422- InputStream : cli .in ,
423- OutputStream : cli .out ,
424- ErrorStream : cli .err ,
425- Resp : response ,
426- TTY : true ,
424+ defer response .Close ()
425+ errCh := make (chan error , 1 )
426+ go func () {
427+ defer close (errCh )
428+ streamer := tty.HijackedIOStreamer {
429+ Streams : cli ,
430+ InputStream : cli .in ,
431+ OutputStream : cli .out ,
432+ ErrorStream : cli .err ,
433+ Resp : response ,
434+ TTY : true ,
435+ DetachKeys : options .detachKeys ,
436+ }
437+ errCh <- streamer .Stream (cli .ctx )
438+ }()
439+ if err := tty .MonitorTtySize (cli .ctx , cli .client , cli .out , execID , true ); err != nil {
440+ _ , _ = fmt .Fprintln (cli .err , "Error monitoring TTY size:" , err )
427441 }
428- return streamer .Stream (cli .ctx , cli .config .ReadTimeout )
442+ if err := <- errCh ; err != nil {
443+ logrus .Debugf ("Error hijack: %s" , err )
444+ return err
445+ }
446+ return getExecExitStatus (cli .ctx , cli .client , execID )
447+ }
448+
449+ func getExecExitStatus (ctx context.Context , apiClient client.ContainerAPIClient , execID string ) error {
450+ resp , err := apiClient .ContainerExecInspect (ctx , execID )
451+ if err != nil {
452+ // If we can't connect, then the daemon probably died.
453+ if ! client .IsErrConnectionFailed (err ) {
454+ return err
455+ }
456+ return errors .Errorf ("ExitStatus %d" , - 1 )
457+ }
458+ status := resp .ExitCode
459+ if status != 0 {
460+ return errors .Errorf ("ExitStatus %d" , status )
461+ }
462+ return nil
429463}
430464
431465// FindContainer find container
0 commit comments