Skip to content

Commit

Permalink
feature: add exec timeout support
Browse files Browse the repository at this point in the history
Signed-off-by: zhangyue <zy675793960@yeah.net>
  • Loading branch information
zhangyue committed Jul 11, 2019
1 parent e254431 commit 14fac8c
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 34 deletions.
19 changes: 10 additions & 9 deletions cri/v1alpha2/cri.go
Original file line number Diff line number Diff line change
Expand Up @@ -1146,15 +1146,6 @@ func (c *CriManager) ReopenContainerLog(ctx context.Context, r *runtime.ReopenCo
func (c *CriManager) ExecSync(ctx context.Context, r *runtime.ExecSyncRequest) (*runtime.ExecSyncResponse, error) {
id := r.GetContainerId()

timeout := time.Duration(r.GetTimeout()) * time.Second
var cancel context.CancelFunc
if timeout == 0 {
ctx, cancel = context.WithCancel(ctx)
} else {
ctx, cancel = context.WithTimeout(ctx, timeout)
}
defer cancel()

createConfig := &apitypes.ExecCreateConfig{
Cmd: r.GetCmd(),
}
Expand All @@ -1170,6 +1161,16 @@ func (c *CriManager) ExecSync(ctx context.Context, r *runtime.ExecSyncRequest) (
UseStderr: true,
Stderr: stderrBuf,
}

timeout := time.Duration(r.GetTimeout()) * time.Second
var cancel context.CancelFunc
if timeout == 0 {
ctx, cancel = context.WithCancel(ctx)
} else {
ctx, cancel = context.WithTimeout(ctx, timeout)
}
defer cancel()

if err := c.ContainerMgr.StartExec(ctx, execid, attachCfg); err != nil {
return nil, fmt.Errorf("failed to start exec for container %q: %v", id, err)
}
Expand Down
64 changes: 40 additions & 24 deletions ctrd/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ func (c *Client) execContainer(ctx context.Context, process *Process) error {
errCh := make(chan error, 1)
defer close(errCh)

// start the exec process
if err := execProcess.Start(ctx); err != nil {
errCh <- err
return errors.Wrapf(err, "failed to start exec, exec id %s", execID)
}

go func() {
var msg *Message

Expand All @@ -149,38 +155,48 @@ func (c *Client) execContainer(ctx context.Context, process *Process) error {
exitCode: 126,
exitTime: time.Now().UTC(),
}
}

// success to start which means the cmd is valid and wait
// for process.
if msg == nil {
status := <-exitStatus
msg = &Message{
err: status.Error(),
exitCode: status.ExitCode(),
exitTime: status.ExitTime(),
} else {
select {
case status := <-exitStatus:
msg = &Message{
err: status.Error(),
exitCode: status.ExitCode(),
exitTime: status.ExitTime(),
}
case <-ctx.Done():
// Ignore the not found error because the process may exit itself before kill
if err := execProcess.Kill(ctx, syscall.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
//try to force kill the exec process
if err := execProcess.Kill(ctx, syscall.SIGTERM); err != nil && !errdefs.IsNotFound(err) {
logrus.Errorf("failed to kill the exec process, %v", err)
}
}
// Wait for process to be killed
status := <-exitStatus
msg = &Message{
err: errors.Wrapf(status.Error(), "failed to exec process %s, timeout", execID),
exitCode: status.ExitCode(),
exitTime: status.ExitTime(),
}
}
}

// XXX: if exec process get run, io should be closed in this function,
for _, hook := range c.hooks {
if err := hook(process.ExecID, msg); err != nil {
logrus.Errorf("failed to execute the exec exit hooks: %v", err)
break
if msg != nil {
// XXX: if exec process get run, io should be closed in this function,
for _, hook := range c.hooks {
if err := hook(process.ExecID, msg); err != nil {
logrus.Errorf("failed to execute the exec exit hooks: %v", err)
break
}
}
}

// delete the finished exec process in containerd
if _, err := execProcess.Delete(context.TODO()); err != nil {
logrus.Warnf("failed to delete exec process %s: %s", process.ExecID, err)
// delete the finished exec process in containerd
if _, err := execProcess.Delete(context.TODO()); err != nil {
logrus.Warnf("failed to delete exec process %s: %s", process.ExecID, err)
}
}
}()

// start the exec process
if err := execProcess.Start(ctx); err != nil {
errCh <- err
return err
}
return nil
}

Expand Down
1 change: 0 additions & 1 deletion hack/testing/run_daemon_cri_integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export PATH="${GOPATH}/bin:${PATH}"

# CRI_SKIP skips the test to skip.
DEFAULT_CRI_SKIP="should error on create with wrong options"
DEFAULT_CRI_SKIP+="|runtime should support execSync with timeout"
CRI_SKIP="${CRI_SKIP:-"${DEFAULT_CRI_SKIP}"}"

# CRI_FOCUS focuses the test to run.
Expand Down

0 comments on commit 14fac8c

Please sign in to comment.