Files
containerd/cmd/containerd-stress/exec_worker.go
Michael Crosby 94602aea63 Add execs to stress tests
This improves the exec support so that they can run along with the
normal stress tests.  You don't have to pick exec stres or container
stress.  They both run at the same time and report the different values.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
2018-01-19 13:44:54 -05:00

111 lines
2.6 KiB
Go

package main
import (
"context"
"path/filepath"
"strings"
"syscall"
"time"
"github.com/containerd/containerd"
"github.com/containerd/containerd/cio"
"github.com/containerd/containerd/oci"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
)
type execWorker struct {
worker
}
func (w *execWorker) exec(ctx, tctx context.Context) {
defer func() {
w.wg.Done()
logrus.Infof("worker %d finished", w.id)
}()
// create and start the exec container
w.spec.Linux.CgroupsPath = filepath.Join("/", "stress", "exec-container")
w.spec.Process.Args = []string{
"sleep", "30d",
}
c, err := w.client.NewContainer(ctx, "exec-container",
containerd.WithNewSnapshot("exec-container", w.image),
containerd.WithSpec(w.spec, oci.WithUsername("games")),
)
if err != nil {
logrus.WithError(err).Error("create exec container")
return
}
defer c.Delete(ctx, containerd.WithSnapshotCleanup)
task, err := c.NewTask(ctx, cio.NullIO)
if err != nil {
logrus.WithError(err).Error("create exec container's task")
return
}
defer task.Delete(ctx, containerd.WithProcessKill)
statusC, err := task.Wait(ctx)
if err != nil {
logrus.WithError(err).Error("wait exec container's task")
return
}
pspec := w.spec.Process
pspec.Args = []string{"true"}
for {
select {
case <-tctx.Done():
if err := task.Kill(ctx, syscall.SIGKILL); err != nil {
logrus.WithError(err).Error("kill exec container's task")
}
<-statusC
return
default:
}
w.count++
id := w.getID()
logrus.Debugf("starting exec %s", id)
start := time.Now()
if err := w.runExec(ctx, task, id, pspec); err != nil {
if err != context.DeadlineExceeded ||
!strings.Contains(err.Error(), context.DeadlineExceeded.Error()) {
w.failures++
logrus.WithError(err).Errorf("running exec %s", id)
errCounter.WithValues(err.Error()).Inc()
}
continue
}
// only log times are success so we don't scew the results from failures that go really fast
execTimer.WithValues(w.commit).UpdateSince(start)
}
}
func (w *execWorker) runExec(ctx context.Context, task containerd.Task, id string, spec *specs.Process) error {
process, err := task.Exec(ctx, id, spec, cio.NullIO)
if err != nil {
return err
}
defer process.Delete(ctx, containerd.WithProcessKill)
statusC, err := process.Wait(ctx)
if err != nil {
return err
}
if err := process.Start(ctx); err != nil {
return err
}
status := <-statusC
_, _, err = status.Result()
if err != nil {
if err == context.DeadlineExceeded || err == context.Canceled {
return nil
}
w.failures++
}
return nil
}