2017-12-15 07:00:13 +00:00
|
|
|
// +build linux,no_containerd_worker
|
2017-05-27 05:10:26 +00:00
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
package runc
|
2017-05-26 22:15:20 +00:00
|
|
|
|
|
|
|
import (
|
2017-06-02 00:30:02 +00:00
|
|
|
"bytes"
|
2017-07-11 06:55:04 +00:00
|
|
|
"io"
|
2017-05-26 22:15:20 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
2017-11-27 22:24:29 +00:00
|
|
|
"os/exec"
|
2017-05-26 22:15:20 +00:00
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
|
2017-06-13 23:01:47 +00:00
|
|
|
"github.com/containerd/containerd/namespaces"
|
2017-07-25 22:14:46 +00:00
|
|
|
"github.com/moby/buildkit/client"
|
2017-11-21 08:08:36 +00:00
|
|
|
"github.com/moby/buildkit/executor"
|
|
|
|
"github.com/moby/buildkit/session"
|
2017-06-22 20:15:46 +00:00
|
|
|
"github.com/moby/buildkit/snapshot"
|
|
|
|
"github.com/moby/buildkit/source"
|
2017-12-15 08:06:54 +00:00
|
|
|
"github.com/moby/buildkit/worker/base"
|
2017-12-12 18:44:12 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2017-06-13 23:01:47 +00:00
|
|
|
"golang.org/x/net/context"
|
2017-05-26 22:15:20 +00:00
|
|
|
)
|
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
func TestRuncWorker(t *testing.T) {
|
2017-12-09 02:19:08 +00:00
|
|
|
t.Parallel()
|
2017-11-27 22:24:29 +00:00
|
|
|
if os.Getuid() != 0 {
|
|
|
|
t.Skip("requires root")
|
|
|
|
}
|
|
|
|
if _, err := exec.LookPath("runc"); err != nil {
|
|
|
|
t.Skipf("no runc found: %s", err.Error())
|
|
|
|
}
|
|
|
|
|
2017-06-13 23:01:47 +00:00
|
|
|
ctx := namespaces.WithNamespace(context.Background(), "buildkit-test")
|
|
|
|
|
2017-05-30 21:17:04 +00:00
|
|
|
// this should be an example or e2e test
|
2017-11-21 08:08:36 +00:00
|
|
|
tmpdir, err := ioutil.TempDir("", "workertest")
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-30 21:17:04 +00:00
|
|
|
defer os.RemoveAll(tmpdir)
|
2017-05-27 05:10:26 +00:00
|
|
|
|
2018-02-19 05:33:49 +00:00
|
|
|
workerOpt, err := NewWorkerOpt(tmpdir, nil, "overlayfs")
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-27 05:10:26 +00:00
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
workerOpt.SessionManager, err = session.NewManager()
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-07-05 02:00:27 +00:00
|
|
|
|
2017-12-15 08:06:54 +00:00
|
|
|
w, err := base.NewWorker(workerOpt)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-31 22:05:22 +00:00
|
|
|
|
2017-06-01 22:24:23 +00:00
|
|
|
img, err := source.NewImageIdentifier("docker.io/library/busybox:latest")
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-27 05:10:26 +00:00
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
src, err := w.SourceManager.Resolve(ctx, img)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-07-06 20:15:54 +00:00
|
|
|
|
|
|
|
snap, err := src.Snapshot(ctx)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-27 05:10:26 +00:00
|
|
|
|
2017-07-18 06:08:22 +00:00
|
|
|
mounts, err := snap.Mount(ctx, false)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-30 21:17:04 +00:00
|
|
|
|
|
|
|
lm := snapshot.LocalMounter(mounts)
|
|
|
|
|
|
|
|
target, err := lm.Mount()
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-30 21:17:04 +00:00
|
|
|
|
|
|
|
f, err := os.Open(target)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-30 21:17:04 +00:00
|
|
|
|
|
|
|
names, err := f.Readdirnames(-1)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.True(t, len(names) > 5)
|
2017-05-30 21:17:04 +00:00
|
|
|
|
|
|
|
err = f.Close()
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-30 21:17:04 +00:00
|
|
|
|
|
|
|
lm.Unmount()
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-30 21:17:04 +00:00
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
du, err := w.CacheManager.DiskUsage(ctx, client.DiskUsageInfo{})
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-31 23:45:04 +00:00
|
|
|
|
|
|
|
// for _, d := range du {
|
2017-05-31 23:52:53 +00:00
|
|
|
// fmt.Printf("du: %+v\n", d)
|
2017-05-31 23:45:04 +00:00
|
|
|
// }
|
|
|
|
|
2017-06-01 22:24:23 +00:00
|
|
|
for _, d := range du {
|
2017-12-12 18:44:12 +00:00
|
|
|
require.True(t, d.Size >= 8192)
|
2017-06-01 22:24:23 +00:00
|
|
|
}
|
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
meta := executor.Meta{
|
2017-06-01 22:24:23 +00:00
|
|
|
Args: []string{"/bin/sh", "-c", "echo \"foo\" > /bar"},
|
2017-06-02 00:30:02 +00:00
|
|
|
Cwd: "/",
|
2017-06-01 22:24:23 +00:00
|
|
|
}
|
|
|
|
|
2017-06-02 00:30:02 +00:00
|
|
|
stderr := bytes.NewBuffer(nil)
|
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
err = w.Executor.Exec(ctx, meta, snap, nil, nil, nil, &nopCloser{stderr})
|
2017-12-12 18:44:12 +00:00
|
|
|
require.Error(t, err) // Read-only root
|
2017-09-09 09:49:48 +00:00
|
|
|
// typical error is like `mkdir /.../rootfs/proc: read-only file system`.
|
|
|
|
// make sure the error is caused before running `echo foo > /bar`.
|
2017-12-12 18:44:12 +00:00
|
|
|
require.Contains(t, stderr.String(), "read-only file system")
|
2017-06-01 22:24:23 +00:00
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
root, err := w.CacheManager.New(ctx, snap)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-06-01 22:24:23 +00:00
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
err = w.Executor.Exec(ctx, meta, root, nil, nil, nil, nil)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-06-01 22:24:23 +00:00
|
|
|
|
2017-07-14 18:59:31 +00:00
|
|
|
rf, err := root.Commit(ctx)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-06-01 22:24:23 +00:00
|
|
|
|
2017-07-18 06:08:22 +00:00
|
|
|
mounts, err = rf.Mount(ctx, false)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-06-01 22:24:23 +00:00
|
|
|
|
|
|
|
lm = snapshot.LocalMounter(mounts)
|
|
|
|
|
|
|
|
target, err = lm.Mount()
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-06-01 22:24:23 +00:00
|
|
|
|
|
|
|
dt, err := ioutil.ReadFile(filepath.Join(target, "bar"))
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, string(dt), "foo\n")
|
2017-06-01 22:24:23 +00:00
|
|
|
|
|
|
|
lm.Unmount()
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-06-01 22:24:23 +00:00
|
|
|
|
2017-06-13 23:01:47 +00:00
|
|
|
err = rf.Release(ctx)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-06-01 22:24:23 +00:00
|
|
|
|
2017-06-13 23:01:47 +00:00
|
|
|
err = snap.Release(ctx)
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-31 23:45:04 +00:00
|
|
|
|
2017-11-21 08:08:36 +00:00
|
|
|
du2, err := w.CacheManager.DiskUsage(ctx, client.DiskUsageInfo{})
|
2017-12-12 18:44:12 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 1, len(du2)-len(du))
|
2017-05-31 23:45:04 +00:00
|
|
|
|
2017-05-26 22:15:20 +00:00
|
|
|
}
|
2017-07-11 06:55:04 +00:00
|
|
|
|
|
|
|
type nopCloser struct {
|
|
|
|
io.Writer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *nopCloser) Close() error {
|
|
|
|
return nil
|
|
|
|
}
|