ExecSync should block unless client context is canceled

A call to ExecSync should only return if the client context was canceled or
exceeded. The Timeout parameter to ExecSyncRequest is now used to send SIGKILL
if the exec'd process does not exit within Timeout but all paths wait for the
exec to exit.

Signed-off-by: Justin Terry (VM) <juterry@microsoft.com>
This commit is contained in:
Justin Terry (VM) 2019-05-21 13:57:42 -07:00
parent 71cecedc44
commit 7b0c78bacd

View File

@ -164,16 +164,15 @@ func (c *criService) execInContainer(ctx context.Context, id string, opts execOp
}, },
}) })
var timeoutCh <-chan time.Time execCtx := ctx
if opts.timeout == 0 { if opts.timeout > 0 {
// Do not set timeout if it's 0. var execCtxCancel context.CancelFunc
timeoutCh = make(chan time.Time) execCtx, execCtxCancel = context.WithTimeout(ctx, opts.timeout)
} else { defer execCtxCancel()
timeoutCh = time.After(opts.timeout)
} }
select { select {
case <-timeoutCh: case <-execCtx.Done():
//TODO(Abhi) Use context.WithDeadline instead of timeout.
// Ignore the not found error because the process may exit itself before killing. // Ignore the not found error because the process may exit itself before killing.
if err := process.Kill(ctx, syscall.SIGKILL); err != nil && !errdefs.IsNotFound(err) { if err := process.Kill(ctx, syscall.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
return nil, errors.Wrapf(err, "failed to kill exec %q", execID) return nil, errors.Wrapf(err, "failed to kill exec %q", execID)
@ -184,7 +183,7 @@ func (c *criService) execInContainer(ctx context.Context, id string, opts execOp
execID, exitRes.ExitCode(), exitRes.Error()) execID, exitRes.ExitCode(), exitRes.Error())
<-attachDone <-attachDone
logrus.Debugf("Stream pipe for exec process %q done", execID) logrus.Debugf("Stream pipe for exec process %q done", execID)
return nil, errors.Errorf("timeout %v exceeded", opts.timeout) return nil, errors.Wrapf(execCtx.Err(), "timeout %v exceeded", opts.timeout)
case exitRes := <-exitCh: case exitRes := <-exitCh:
code, _, err := exitRes.Result() code, _, err := exitRes.Result()
logrus.Infof("Exec process %q exits with exit code %d and error %v", execID, code, err) logrus.Infof("Exec process %q exits with exit code %d and error %v", execID, code, err)