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>
100 lines
2.1 KiB
Go
100 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
"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 worker struct {
|
|
id int
|
|
wg *sync.WaitGroup
|
|
count int
|
|
failures int
|
|
|
|
client *containerd.Client
|
|
image containerd.Image
|
|
spec *specs.Spec
|
|
commit string
|
|
}
|
|
|
|
func (w *worker) run(ctx, tctx context.Context) {
|
|
defer func() {
|
|
w.wg.Done()
|
|
logrus.Infof("worker %d finished", w.id)
|
|
}()
|
|
for {
|
|
select {
|
|
case <-tctx.Done():
|
|
return
|
|
default:
|
|
}
|
|
|
|
w.count++
|
|
id := w.getID()
|
|
logrus.Debugf("starting container %s", id)
|
|
start := time.Now()
|
|
if err := w.runContainer(ctx, id); err != nil {
|
|
if err != context.DeadlineExceeded ||
|
|
!strings.Contains(err.Error(), context.DeadlineExceeded.Error()) {
|
|
w.failures++
|
|
logrus.WithError(err).Errorf("running container %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
|
|
ct.WithValues(w.commit).UpdateSince(start)
|
|
}
|
|
}
|
|
|
|
func (w *worker) runContainer(ctx context.Context, id string) error {
|
|
// fix up cgroups path for a default config
|
|
w.spec.Linux.CgroupsPath = filepath.Join("/", "stress", id)
|
|
c, err := w.client.NewContainer(ctx, id,
|
|
containerd.WithNewSnapshot(id, w.image),
|
|
containerd.WithSpec(w.spec, oci.WithUsername("games")),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer c.Delete(ctx, containerd.WithSnapshotCleanup)
|
|
|
|
task, err := c.NewTask(ctx, cio.NullIO)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer task.Delete(ctx, containerd.WithProcessKill)
|
|
|
|
statusC, err := task.Wait(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := task.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
|
|
}
|
|
|
|
func (w *worker) getID() string {
|
|
return fmt.Sprintf("%d-%d", w.id, w.count)
|
|
}
|