mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
test: add basic integration tests
Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
241
vendor/github.com/moby/buildkit/util/testutil/integration/containerd.go
generated
vendored
Normal file
241
vendor/github.com/moby/buildkit/util/testutil/integration/containerd.go
generated
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/moby/buildkit/util/bklog"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func InitContainerdWorker() {
|
||||
Register(&Containerd{
|
||||
ID: "containerd",
|
||||
Containerd: "containerd",
|
||||
})
|
||||
// defined in Dockerfile
|
||||
// e.g. `containerd-1.1=/opt/containerd-1.1/bin,containerd-42.0=/opt/containerd-42.0/bin`
|
||||
if s := os.Getenv("BUILDKIT_INTEGRATION_CONTAINERD_EXTRA"); s != "" {
|
||||
entries := strings.Split(s, ",")
|
||||
for _, entry := range entries {
|
||||
pair := strings.Split(strings.TrimSpace(entry), "=")
|
||||
if len(pair) != 2 {
|
||||
panic(errors.Errorf("unexpected BUILDKIT_INTEGRATION_CONTAINERD_EXTRA: %q", s))
|
||||
}
|
||||
name, bin := pair[0], pair[1]
|
||||
Register(&Containerd{
|
||||
ID: name,
|
||||
Containerd: filepath.Join(bin, "containerd"),
|
||||
// override PATH to make sure that the expected version of the shim binary is used
|
||||
ExtraEnv: []string{fmt.Sprintf("PATH=%s:%s", bin, os.Getenv("PATH"))},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// the rootless uid is defined in Dockerfile
|
||||
if s := os.Getenv("BUILDKIT_INTEGRATION_ROOTLESS_IDPAIR"); s != "" {
|
||||
var uid, gid int
|
||||
if _, err := fmt.Sscanf(s, "%d:%d", &uid, &gid); err != nil {
|
||||
bklog.L.Fatalf("unexpected BUILDKIT_INTEGRATION_ROOTLESS_IDPAIR: %q", s)
|
||||
}
|
||||
if rootlessSupported(uid) {
|
||||
Register(&Containerd{
|
||||
ID: "containerd-rootless",
|
||||
Containerd: "containerd",
|
||||
UID: uid,
|
||||
GID: gid,
|
||||
Snapshotter: "native", // TODO: test with fuse-overlayfs as well, or automatically determine snapshotter
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if s := os.Getenv("BUILDKIT_INTEGRATION_SNAPSHOTTER"); s != "" {
|
||||
Register(&Containerd{
|
||||
ID: fmt.Sprintf("containerd-snapshotter-%s", s),
|
||||
Containerd: "containerd",
|
||||
Snapshotter: s,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type Containerd struct {
|
||||
ID string
|
||||
Containerd string
|
||||
Snapshotter string
|
||||
UID int
|
||||
GID int
|
||||
ExtraEnv []string // e.g. "PATH=/opt/containerd-1.4/bin:/usr/bin:..."
|
||||
}
|
||||
|
||||
func (c *Containerd) Name() string {
|
||||
return c.ID
|
||||
}
|
||||
|
||||
func (c *Containerd) Rootless() bool {
|
||||
return c.UID != 0
|
||||
}
|
||||
|
||||
func (c *Containerd) New(ctx context.Context, cfg *BackendConfig) (b Backend, cl func() error, err error) {
|
||||
if err := lookupBinary(c.Containerd); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := lookupBinary("buildkitd"); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := requireRoot(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
deferF := &multiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
deferF.F()()
|
||||
cl = nil
|
||||
}
|
||||
}()
|
||||
|
||||
rootless := false
|
||||
if c.UID != 0 {
|
||||
if c.GID == 0 {
|
||||
return nil, nil, errors.Errorf("unsupported id pair: uid=%d, gid=%d", c.UID, c.GID)
|
||||
}
|
||||
rootless = true
|
||||
}
|
||||
|
||||
tmpdir, err := os.MkdirTemp("", "bktest_containerd")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if rootless {
|
||||
if err := os.Chown(tmpdir, c.UID, c.GID); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
deferF.append(func() error { return os.RemoveAll(tmpdir) })
|
||||
|
||||
address := filepath.Join(tmpdir, "containerd.sock")
|
||||
config := fmt.Sprintf(`root = %q
|
||||
state = %q
|
||||
# CRI plugins listens on 10010/tcp for stream server.
|
||||
# We disable CRI plugin so that multiple instance can run simultaneously.
|
||||
disabled_plugins = ["cri"]
|
||||
|
||||
[grpc]
|
||||
address = %q
|
||||
|
||||
[debug]
|
||||
level = "debug"
|
||||
address = %q
|
||||
`, filepath.Join(tmpdir, "root"), filepath.Join(tmpdir, "state"), address, filepath.Join(tmpdir, "debug.sock"))
|
||||
|
||||
var snBuildkitdArgs []string
|
||||
if c.Snapshotter != "" {
|
||||
snBuildkitdArgs = append(snBuildkitdArgs,
|
||||
fmt.Sprintf("--containerd-worker-snapshotter=%s", c.Snapshotter))
|
||||
if c.Snapshotter == "stargz" {
|
||||
snPath, snCl, err := runStargzSnapshotter(cfg)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
deferF.append(snCl)
|
||||
config = fmt.Sprintf(`%s
|
||||
|
||||
[proxy_plugins]
|
||||
[proxy_plugins.stargz]
|
||||
type = "snapshot"
|
||||
address = %q
|
||||
`, config, snPath)
|
||||
}
|
||||
}
|
||||
|
||||
configFile := filepath.Join(tmpdir, "config.toml")
|
||||
if err := os.WriteFile(configFile, []byte(config), 0644); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
containerdArgs := []string{c.Containerd, "--config", configFile}
|
||||
rootlessKitState := filepath.Join(tmpdir, "rootlesskit-containerd")
|
||||
if rootless {
|
||||
containerdArgs = append(append([]string{"sudo", "-u", fmt.Sprintf("#%d", c.UID), "-i",
|
||||
fmt.Sprintf("CONTAINERD_ROOTLESS_ROOTLESSKIT_STATE_DIR=%s", rootlessKitState),
|
||||
// Integration test requires the access to localhost of the host network namespace.
|
||||
// TODO: remove these configurations
|
||||
"CONTAINERD_ROOTLESS_ROOTLESSKIT_NET=host",
|
||||
"CONTAINERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=none",
|
||||
"CONTAINERD_ROOTLESS_ROOTLESSKIT_FLAGS=--mtu=0",
|
||||
}, c.ExtraEnv...), "containerd-rootless.sh", "-c", configFile)
|
||||
}
|
||||
|
||||
cmd := exec.Command(containerdArgs[0], containerdArgs[1:]...) //nolint:gosec // test utility
|
||||
cmd.Env = append(os.Environ(), c.ExtraEnv...)
|
||||
|
||||
ctdStop, err := startCmd(cmd, cfg.Logs)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := waitUnix(address, 10*time.Second, cmd); err != nil {
|
||||
ctdStop()
|
||||
return nil, nil, errors.Wrapf(err, "containerd did not start up: %s", formatLogs(cfg.Logs))
|
||||
}
|
||||
deferF.append(ctdStop)
|
||||
|
||||
buildkitdArgs := append([]string{"buildkitd",
|
||||
"--oci-worker=false",
|
||||
"--containerd-worker-gc=false",
|
||||
"--containerd-worker=true",
|
||||
"--containerd-worker-addr", address,
|
||||
"--containerd-worker-labels=org.mobyproject.buildkit.worker.sandbox=true", // Include use of --containerd-worker-labels to trigger https://github.com/moby/buildkit/pull/603
|
||||
}, snBuildkitdArgs...)
|
||||
|
||||
if runtime.GOOS != "windows" && c.Snapshotter != "native" {
|
||||
c.ExtraEnv = append(c.ExtraEnv, "BUILDKIT_DEBUG_FORCE_OVERLAY_DIFF=true")
|
||||
}
|
||||
if rootless {
|
||||
pidStr, err := os.ReadFile(filepath.Join(rootlessKitState, "child_pid"))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
pid, err := strconv.ParseInt(string(pidStr), 10, 64)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
buildkitdArgs = append([]string{"sudo", "-u", fmt.Sprintf("#%d", c.UID), "-i", "--", "exec",
|
||||
"nsenter", "-U", "--preserve-credentials", "-m", "-t", fmt.Sprintf("%d", pid)},
|
||||
append(buildkitdArgs, "--containerd-worker-snapshotter=native")...)
|
||||
}
|
||||
buildkitdSock, stop, err := runBuildkitd(ctx, cfg, buildkitdArgs, cfg.Logs, c.UID, c.GID, c.ExtraEnv)
|
||||
if err != nil {
|
||||
printLogs(cfg.Logs, log.Println)
|
||||
return nil, nil, err
|
||||
}
|
||||
deferF.append(stop)
|
||||
|
||||
return backend{
|
||||
address: buildkitdSock,
|
||||
containerdAddress: address,
|
||||
rootless: rootless,
|
||||
snapshotter: c.Snapshotter,
|
||||
}, cl, nil
|
||||
}
|
||||
|
||||
func formatLogs(m map[string]*bytes.Buffer) string {
|
||||
var ss []string
|
||||
for k, b := range m {
|
||||
if b != nil {
|
||||
ss = append(ss, fmt.Sprintf("%q:%q", k, b.String()))
|
||||
}
|
||||
}
|
||||
return strings.Join(ss, ",")
|
||||
}
|
Reference in New Issue
Block a user