mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
vendor: update buildkit to master@b49a8873179b
Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
89
vendor/github.com/moby/buildkit/util/testutil/integration/azurite.go
generated
vendored
89
vendor/github.com/moby/buildkit/util/testutil/integration/azurite.go
generated
vendored
@ -1,89 +0,0 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
azuriteBin = "azurite-blob"
|
||||
)
|
||||
|
||||
type AzuriteOpts struct {
|
||||
AccountName string
|
||||
AccountKey string
|
||||
}
|
||||
|
||||
func NewAzuriteServer(t *testing.T, sb Sandbox, opts AzuriteOpts) (address string, cl func() error, err error) {
|
||||
t.Helper()
|
||||
|
||||
if _, err := exec.LookPath(azuriteBin); err != nil {
|
||||
return "", nil, errors.Wrapf(err, "failed to lookup %s binary", azuriteBin)
|
||||
}
|
||||
|
||||
deferF := &multiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
deferF.F()()
|
||||
cl = nil
|
||||
}
|
||||
}()
|
||||
|
||||
l, err := net.Listen("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
addr := l.Addr().String()
|
||||
if err = l.Close(); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
host, port, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
address = fmt.Sprintf("http://%s/%s", addr, opts.AccountName)
|
||||
|
||||
// start server
|
||||
cmd := exec.Command(azuriteBin, "--disableProductStyleUrl", "--blobHost", host, "--blobPort", port, "--location", t.TempDir())
|
||||
cmd.Env = append(os.Environ(), []string{
|
||||
"AZURITE_ACCOUNTS=" + opts.AccountName + ":" + opts.AccountKey,
|
||||
}...)
|
||||
azuriteStop, err := startCmd(cmd, sb.Logs())
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err = waitAzurite(address, 15*time.Second); err != nil {
|
||||
azuriteStop()
|
||||
return "", nil, errors.Wrapf(err, "azurite did not start up: %s", formatLogs(sb.Logs()))
|
||||
}
|
||||
deferF.append(azuriteStop)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func waitAzurite(address string, d time.Duration) error {
|
||||
step := 1 * time.Second
|
||||
i := 0
|
||||
for {
|
||||
if resp, err := http.Get(fmt.Sprintf("%s?comp=list", address)); err == nil {
|
||||
resp.Body.Close()
|
||||
break
|
||||
}
|
||||
i++
|
||||
if time.Duration(i)*step > d {
|
||||
return errors.Errorf("failed dialing: %s", address)
|
||||
}
|
||||
time.Sleep(step)
|
||||
}
|
||||
return nil
|
||||
}
|
116
vendor/github.com/moby/buildkit/util/testutil/integration/minio.go
generated
vendored
116
vendor/github.com/moby/buildkit/util/testutil/integration/minio.go
generated
vendored
@ -1,116 +0,0 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
minioBin = "minio"
|
||||
mcBin = "mc"
|
||||
)
|
||||
|
||||
type MinioOpts struct {
|
||||
Region string
|
||||
AccessKeyID string
|
||||
SecretAccessKey string
|
||||
}
|
||||
|
||||
func NewMinioServer(t *testing.T, sb Sandbox, opts MinioOpts) (address string, bucket string, cl func() error, err error) {
|
||||
t.Helper()
|
||||
bucket = randomString(10)
|
||||
|
||||
if _, err := exec.LookPath(minioBin); err != nil {
|
||||
return "", "", nil, errors.Wrapf(err, "failed to lookup %s binary", minioBin)
|
||||
}
|
||||
if _, err := exec.LookPath(mcBin); err != nil {
|
||||
return "", "", nil, errors.Wrapf(err, "failed to lookup %s binary", mcBin)
|
||||
}
|
||||
|
||||
deferF := &multiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
deferF.F()()
|
||||
cl = nil
|
||||
}
|
||||
}()
|
||||
|
||||
l, err := net.Listen("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
|
||||
addr := l.Addr().String()
|
||||
if err = l.Close(); err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
address = "http://" + addr
|
||||
|
||||
// start server
|
||||
cmd := exec.Command(minioBin, "server", "--json", "--address", addr, t.TempDir())
|
||||
cmd.Env = append(os.Environ(), []string{
|
||||
"MINIO_ROOT_USER=" + opts.AccessKeyID,
|
||||
"MINIO_ROOT_PASSWORD=" + opts.SecretAccessKey,
|
||||
}...)
|
||||
minioStop, err := startCmd(cmd, sb.Logs())
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
if err = waitMinio(address, 15*time.Second); err != nil {
|
||||
minioStop()
|
||||
return "", "", nil, errors.Wrapf(err, "minio did not start up: %s", formatLogs(sb.Logs()))
|
||||
}
|
||||
deferF.append(minioStop)
|
||||
|
||||
// create alias config
|
||||
alias := randomString(10)
|
||||
cmd = exec.Command(mcBin, "alias", "set", alias, address, opts.AccessKeyID, opts.SecretAccessKey)
|
||||
if err := runCmd(cmd, sb.Logs()); err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
deferF.append(func() error {
|
||||
return exec.Command(mcBin, "alias", "rm", alias).Run()
|
||||
})
|
||||
|
||||
// create bucket
|
||||
cmd = exec.Command(mcBin, "mb", "--region", opts.Region, fmt.Sprintf("%s/%s", alias, bucket)) // #nosec G204
|
||||
if err := runCmd(cmd, sb.Logs()); err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
|
||||
// trace
|
||||
cmd = exec.Command(mcBin, "admin", "trace", "--json", alias)
|
||||
traceStop, err := startCmd(cmd, sb.Logs())
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
deferF.append(traceStop)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func waitMinio(address string, d time.Duration) error {
|
||||
step := 1 * time.Second
|
||||
i := 0
|
||||
for {
|
||||
if resp, err := http.Get(fmt.Sprintf("%s/minio/health/live", address)); err == nil {
|
||||
resp.Body.Close()
|
||||
break
|
||||
}
|
||||
i++
|
||||
if time.Duration(i)*step > d {
|
||||
return errors.Errorf("failed dialing: %s", address)
|
||||
}
|
||||
time.Sleep(step)
|
||||
}
|
||||
return nil
|
||||
}
|
15
vendor/github.com/moby/buildkit/util/testutil/integration/pins.go
generated
vendored
15
vendor/github.com/moby/buildkit/util/testutil/integration/pins.go
generated
vendored
@ -1,15 +1,16 @@
|
||||
package integration
|
||||
|
||||
var pins = map[string]map[string]string{
|
||||
// busybox is pinned to 1.35. Newer produces has "illegal instruction" panic on some of Github infra on sha256sum
|
||||
// busybox 1.36
|
||||
"busybox:latest": {
|
||||
"amd64": "sha256:0d5a701f0ca53f38723108687add000e1922f812d4187dea7feaee85d2f5a6c5",
|
||||
"arm64v8": "sha256:ffe38d75e44d8ffac4cd6d09777ffc31e94ea0ded6a0164e825a325dc17a3b68",
|
||||
"library": "sha256:f4ed5f2163110c26d42741fdc92bd1710e118aed4edb19212548e8ca4e5fca22",
|
||||
"amd64": "sha256:023917ec6a886d0e8e15f28fb543515a5fcd8d938edb091e8147db4efed388ee",
|
||||
"arm64v8": "sha256:1fa89c01cd0473cedbd1a470abb8c139eeb80920edf1bc55de87851bfb63ea11",
|
||||
"library": "sha256:3fbc632167424a6d997e74f52b878d7cc478225cffac6bc977eedfe51c7f4e79",
|
||||
},
|
||||
// alpine 3.18
|
||||
"alpine:latest": {
|
||||
"amd64": "sha256:c0d488a800e4127c334ad20d61d7bc21b4097540327217dfab52262adc02380c",
|
||||
"arm64v8": "sha256:af06af3514c44a964d3b905b498cf6493db8f1cde7c10e078213a89c87308ba0",
|
||||
"library": "sha256:8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4",
|
||||
"amd64": "sha256:25fad2a32ad1f6f510e528448ae1ec69a28ef81916a004d3629874104f8a7f70",
|
||||
"arm64v8": "sha256:e3bd82196e98898cae9fe7fbfd6e2436530485974dc4fb3b7ddb69134eda2407",
|
||||
"library": "sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1",
|
||||
},
|
||||
}
|
||||
|
10
vendor/github.com/moby/buildkit/util/testutil/integration/registry.go
generated
vendored
10
vendor/github.com/moby/buildkit/util/testutil/integration/registry.go
generated
vendored
@ -15,11 +15,11 @@ import (
|
||||
)
|
||||
|
||||
func NewRegistry(dir string) (url string, cl func() error, err error) {
|
||||
if err := lookupBinary("registry"); err != nil {
|
||||
if err := LookupBinary("registry"); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
deferF := &multiCloser{}
|
||||
deferF := &MultiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
@ -34,7 +34,7 @@ func NewRegistry(dir string) (url string, cl func() error, err error) {
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
deferF.append(func() error { return os.RemoveAll(tmpdir) })
|
||||
deferF.Append(func() error { return os.RemoveAll(tmpdir) })
|
||||
dir = tmpdir
|
||||
}
|
||||
|
||||
@ -61,11 +61,11 @@ http:
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
stop, err := startCmd(cmd, nil)
|
||||
stop, err := StartCmd(cmd, nil)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
deferF.append(stop)
|
||||
deferF.Append(stop)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
44
vendor/github.com/moby/buildkit/util/testutil/integration/run.go
generated
vendored
44
vendor/github.com/moby/buildkit/util/testutil/integration/run.go
generated
vendored
@ -21,7 +21,6 @@ import (
|
||||
"github.com/moby/buildkit/util/appcontext"
|
||||
"github.com/moby/buildkit/util/contentutil"
|
||||
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
@ -37,8 +36,10 @@ type Backend interface {
|
||||
Address() string
|
||||
DockerAddress() string
|
||||
ContainerdAddress() string
|
||||
|
||||
Rootless() bool
|
||||
Snapshotter() string
|
||||
Supports(feature string) bool
|
||||
}
|
||||
|
||||
type Sandbox interface {
|
||||
@ -422,44 +423,3 @@ func prepareValueMatrix(tc testConf) []matrixValue {
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func runStargzSnapshotter(cfg *BackendConfig) (address string, cl func() error, err error) {
|
||||
binary := "containerd-stargz-grpc"
|
||||
if err := lookupBinary(binary); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
deferF := &multiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
deferF.F()()
|
||||
cl = nil
|
||||
}
|
||||
}()
|
||||
|
||||
tmpStargzDir, err := os.MkdirTemp("", "bktest_containerd_stargz_grpc")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
deferF.append(func() error { return os.RemoveAll(tmpStargzDir) })
|
||||
|
||||
address = filepath.Join(tmpStargzDir, "containerd-stargz-grpc.sock")
|
||||
stargzRootDir := filepath.Join(tmpStargzDir, "root")
|
||||
cmd := exec.Command(binary,
|
||||
"--log-level", "debug",
|
||||
"--address", address,
|
||||
"--root", stargzRootDir)
|
||||
snStop, err := startCmd(cmd, cfg.Logs)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err = waitUnix(address, 10*time.Second, cmd); err != nil {
|
||||
snStop()
|
||||
return "", nil, errors.Wrapf(err, "containerd-stargz-grpc did not start up: %s", formatLogs(cfg.Logs))
|
||||
}
|
||||
deferF.append(snStop)
|
||||
|
||||
return
|
||||
}
|
||||
|
230
vendor/github.com/moby/buildkit/util/testutil/integration/sandbox.go
generated
vendored
230
vendor/github.com/moby/buildkit/util/testutil/integration/sandbox.go
generated
vendored
@ -8,76 +8,20 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/shlex"
|
||||
"github.com/moby/buildkit/util/bklog"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const buildkitdConfigFile = "buildkitd.toml"
|
||||
|
||||
type backend struct {
|
||||
address string
|
||||
dockerAddress string
|
||||
containerdAddress string
|
||||
rootless bool
|
||||
snapshotter string
|
||||
unsupportedFeatures []string
|
||||
isDockerd bool
|
||||
}
|
||||
|
||||
func (b backend) Address() string {
|
||||
return b.address
|
||||
}
|
||||
|
||||
func (b backend) DockerAddress() string {
|
||||
return b.dockerAddress
|
||||
}
|
||||
|
||||
func (b backend) ContainerdAddress() string {
|
||||
return b.containerdAddress
|
||||
}
|
||||
|
||||
func (b backend) Rootless() bool {
|
||||
return b.rootless
|
||||
}
|
||||
|
||||
func (b backend) Snapshotter() string {
|
||||
return b.snapshotter
|
||||
}
|
||||
|
||||
func (b backend) isUnsupportedFeature(feature string) bool {
|
||||
if enabledFeatures := os.Getenv("BUILDKIT_TEST_ENABLE_FEATURES"); enabledFeatures != "" {
|
||||
for _, enabledFeature := range strings.Split(enabledFeatures, ",") {
|
||||
if feature == enabledFeature {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if disabledFeatures := os.Getenv("BUILDKIT_TEST_DISABLE_FEATURES"); disabledFeatures != "" {
|
||||
for _, disabledFeature := range strings.Split(disabledFeatures, ",") {
|
||||
if feature == disabledFeature {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, unsupportedFeature := range b.unsupportedFeatures {
|
||||
if feature == unsupportedFeature {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type sandbox struct {
|
||||
Backend
|
||||
|
||||
logs map[string]*bytes.Buffer
|
||||
cleanup *multiCloser
|
||||
cleanup *MultiCloser
|
||||
mv matrixValue
|
||||
ctx context.Context
|
||||
name string
|
||||
@ -96,7 +40,7 @@ func (sb *sandbox) Logs() map[string]*bytes.Buffer {
|
||||
}
|
||||
|
||||
func (sb *sandbox) PrintLogs(t *testing.T) {
|
||||
printLogs(sb.logs, t.Log)
|
||||
PrintLogs(sb.logs, t.Log)
|
||||
}
|
||||
|
||||
func (sb *sandbox) ClearLogs() {
|
||||
@ -108,7 +52,7 @@ func (sb *sandbox) NewRegistry() (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sb.cleanup.append(cl)
|
||||
sb.cleanup.Append(cl)
|
||||
return url, nil
|
||||
}
|
||||
|
||||
@ -144,7 +88,7 @@ func newSandbox(ctx context.Context, w Worker, mirror string, mv matrixValue) (s
|
||||
upt = append(upt, withMirrorConfig(mirror))
|
||||
}
|
||||
|
||||
deferF := &multiCloser{}
|
||||
deferF := &MultiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
@ -159,7 +103,7 @@ func newSandbox(ctx context.Context, w Worker, mirror string, mv matrixValue) (s
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
deferF.append(func() error {
|
||||
deferF.Append(func() error {
|
||||
return os.RemoveAll(dir)
|
||||
})
|
||||
cfg.ConfigFile = filepath.Join(dir, buildkitdConfigFile)
|
||||
@ -169,7 +113,7 @@ func newSandbox(ctx context.Context, w Worker, mirror string, mv matrixValue) (s
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
deferF.append(closer)
|
||||
deferF.Append(closer)
|
||||
|
||||
return &sandbox{
|
||||
Backend: b,
|
||||
@ -181,95 +125,8 @@ func newSandbox(ctx context.Context, w Worker, mirror string, mv matrixValue) (s
|
||||
}, cl, nil
|
||||
}
|
||||
|
||||
func getBuildkitdAddr(tmpdir string) string {
|
||||
address := "unix://" + filepath.Join(tmpdir, "buildkitd.sock")
|
||||
if runtime.GOOS == "windows" {
|
||||
address = "//./pipe/buildkitd-" + filepath.Base(tmpdir)
|
||||
}
|
||||
return address
|
||||
}
|
||||
|
||||
func runBuildkitd(ctx context.Context, conf *BackendConfig, args []string, logs map[string]*bytes.Buffer, uid, gid int, extraEnv []string) (address string, cl func() error, err error) {
|
||||
deferF := &multiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
deferF.F()()
|
||||
cl = nil
|
||||
}
|
||||
}()
|
||||
|
||||
if conf.ConfigFile != "" {
|
||||
args = append(args, "--config="+conf.ConfigFile)
|
||||
}
|
||||
|
||||
tmpdir, err := os.MkdirTemp("", "bktest_buildkitd")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := os.Chown(tmpdir, uid, gid); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(tmpdir, "tmp"), 0711); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := os.Chown(filepath.Join(tmpdir, "tmp"), uid, gid); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
deferF.append(func() error { return os.RemoveAll(tmpdir) })
|
||||
|
||||
address = getBuildkitdAddr(tmpdir)
|
||||
|
||||
args = append(args, "--root", tmpdir, "--addr", address, "--debug")
|
||||
cmd := exec.Command(args[0], args[1:]...) //nolint:gosec // test utility
|
||||
cmd.Env = append(os.Environ(), "BUILDKIT_DEBUG_EXEC_OUTPUT=1", "BUILDKIT_DEBUG_PANIC_ON_ERROR=1", "TMPDIR="+filepath.Join(tmpdir, "tmp"))
|
||||
cmd.Env = append(cmd.Env, extraEnv...)
|
||||
cmd.SysProcAttr = getSysProcAttr()
|
||||
|
||||
stop, err := startCmd(cmd, logs)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
deferF.append(stop)
|
||||
|
||||
if err := waitUnix(address, 15*time.Second, cmd); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
deferF.append(func() error {
|
||||
f, err := os.Open("/proc/self/mountinfo")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to open mountinfo")
|
||||
}
|
||||
defer f.Close()
|
||||
s := bufio.NewScanner(f)
|
||||
for s.Scan() {
|
||||
if strings.Contains(s.Text(), tmpdir) {
|
||||
return errors.Errorf("leaked mountpoint for %s", tmpdir)
|
||||
}
|
||||
}
|
||||
return s.Err()
|
||||
})
|
||||
|
||||
return address, cl, err
|
||||
}
|
||||
|
||||
func getBackend(sb Sandbox) (*backend, error) {
|
||||
sbx, ok := sb.(*sandbox)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid sandbox type %T", sb)
|
||||
}
|
||||
b, ok := sbx.Backend.(backend)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid backend type %T", b)
|
||||
}
|
||||
return &b, nil
|
||||
}
|
||||
|
||||
func rootlessSupported(uid int) bool {
|
||||
cmd := exec.Command("sudo", "-u", fmt.Sprintf("#%d", uid), "-i", "--", "exec", "unshare", "-U", "true") //nolint:gosec // test utility
|
||||
func RootlessSupported(uid int) bool {
|
||||
cmd := exec.Command("sudo", "-E", "-u", fmt.Sprintf("#%d", uid), "-i", "--", "exec", "unshare", "-U", "true") //nolint:gosec // test utility
|
||||
b, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
bklog.L.Warnf("rootless mode is not supported on this host: %v (%s)", err, string(b))
|
||||
@ -278,7 +135,7 @@ func rootlessSupported(uid int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func printLogs(logs map[string]*bytes.Buffer, f func(args ...interface{})) {
|
||||
func PrintLogs(logs map[string]*bytes.Buffer, f func(args ...interface{})) {
|
||||
for name, l := range logs {
|
||||
f(name)
|
||||
s := bufio.NewScanner(l)
|
||||
@ -288,74 +145,25 @@ func printLogs(logs map[string]*bytes.Buffer, f func(args ...interface{})) {
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
FeatureCacheExport = "cache_export"
|
||||
FeatureCacheImport = "cache_import"
|
||||
FeatureCacheBackendAzblob = "cache_backend_azblob"
|
||||
FeatureCacheBackendGha = "cache_backend_gha"
|
||||
FeatureCacheBackendInline = "cache_backend_inline"
|
||||
FeatureCacheBackendLocal = "cache_backend_local"
|
||||
FeatureCacheBackendRegistry = "cache_backend_registry"
|
||||
FeatureCacheBackendS3 = "cache_backend_s3"
|
||||
FeatureDirectPush = "direct_push"
|
||||
FeatureFrontendOutline = "frontend_outline"
|
||||
FeatureFrontendTargets = "frontend_targets"
|
||||
FeatureImageExporter = "image_exporter"
|
||||
FeatureInfo = "info"
|
||||
FeatureMergeDiff = "merge_diff"
|
||||
FeatureMultiCacheExport = "multi_cache_export"
|
||||
FeatureMultiPlatform = "multi_platform"
|
||||
FeatureOCIExporter = "oci_exporter"
|
||||
FeatureOCILayout = "oci_layout"
|
||||
FeatureProvenance = "provenance"
|
||||
FeatureSBOM = "sbom"
|
||||
FeatureSecurityMode = "security_mode"
|
||||
FeatureSourceDateEpoch = "source_date_epoch"
|
||||
FeatureCNINetwork = "cni_network"
|
||||
)
|
||||
|
||||
var features = map[string]struct{}{
|
||||
FeatureCacheExport: {},
|
||||
FeatureCacheImport: {},
|
||||
FeatureCacheBackendAzblob: {},
|
||||
FeatureCacheBackendGha: {},
|
||||
FeatureCacheBackendInline: {},
|
||||
FeatureCacheBackendLocal: {},
|
||||
FeatureCacheBackendRegistry: {},
|
||||
FeatureCacheBackendS3: {},
|
||||
FeatureDirectPush: {},
|
||||
FeatureFrontendOutline: {},
|
||||
FeatureFrontendTargets: {},
|
||||
FeatureImageExporter: {},
|
||||
FeatureInfo: {},
|
||||
FeatureMergeDiff: {},
|
||||
FeatureMultiCacheExport: {},
|
||||
FeatureMultiPlatform: {},
|
||||
FeatureOCIExporter: {},
|
||||
FeatureOCILayout: {},
|
||||
FeatureProvenance: {},
|
||||
FeatureSBOM: {},
|
||||
FeatureSecurityMode: {},
|
||||
FeatureSourceDateEpoch: {},
|
||||
FeatureCNINetwork: {},
|
||||
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, ",")
|
||||
}
|
||||
|
||||
func CheckFeatureCompat(t *testing.T, sb Sandbox, reason ...string) {
|
||||
func CheckFeatureCompat(t *testing.T, sb Sandbox, features map[string]struct{}, reason ...string) {
|
||||
t.Helper()
|
||||
if len(reason) == 0 {
|
||||
t.Fatal("no reason provided")
|
||||
}
|
||||
b, err := getBackend(sb)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(b.unsupportedFeatures) == 0 {
|
||||
return
|
||||
}
|
||||
var ereasons []string
|
||||
for _, r := range reason {
|
||||
if _, ok := features[r]; ok {
|
||||
if b.isUnsupportedFeature(r) {
|
||||
if !sb.Supports(r) {
|
||||
ereasons = append(ereasons, r)
|
||||
}
|
||||
} else {
|
||||
|
12
vendor/github.com/moby/buildkit/util/testutil/integration/sandbox_unix.go
generated
vendored
12
vendor/github.com/moby/buildkit/util/testutil/integration/sandbox_unix.go
generated
vendored
@ -1,12 +0,0 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package integration
|
||||
|
||||
import "syscall"
|
||||
|
||||
func getSysProcAttr() *syscall.SysProcAttr {
|
||||
return &syscall.SysProcAttr{
|
||||
Setsid: true, // stretch sudo needs this for sigterm
|
||||
}
|
||||
}
|
10
vendor/github.com/moby/buildkit/util/testutil/integration/sandbox_windows.go
generated
vendored
10
vendor/github.com/moby/buildkit/util/testutil/integration/sandbox_windows.go
generated
vendored
@ -1,10 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package integration
|
||||
|
||||
import "syscall"
|
||||
|
||||
func getSysProcAttr() *syscall.SysProcAttr {
|
||||
return &syscall.SysProcAttr{}
|
||||
}
|
108
vendor/github.com/moby/buildkit/util/testutil/integration/util.go
generated
vendored
108
vendor/github.com/moby/buildkit/util/testutil/integration/util.go
generated
vendored
@ -3,7 +3,6 @@ package integration
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@ -21,20 +20,42 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
func runCmd(cmd *exec.Cmd, logs map[string]*bytes.Buffer) error {
|
||||
var ErrRequirements = errors.Errorf("missing requirements")
|
||||
|
||||
func Tmpdir(t *testing.T, appliers ...fstest.Applier) string {
|
||||
t.Helper()
|
||||
|
||||
// We cannot use t.TempDir() to create a temporary directory here because
|
||||
// appliers might contain fstest.CreateSocket. If the test name is too long,
|
||||
// t.TempDir() could return a path that is longer than 108 characters. This
|
||||
// would result in "bind: invalid argument" when we listen on the socket.
|
||||
tmpdir, err := os.MkdirTemp("", "buildkit")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, os.RemoveAll(tmpdir))
|
||||
})
|
||||
|
||||
err = fstest.Apply(appliers...).Apply(tmpdir)
|
||||
require.NoError(t, err)
|
||||
|
||||
return tmpdir
|
||||
}
|
||||
|
||||
func RunCmd(cmd *exec.Cmd, logs map[string]*bytes.Buffer) error {
|
||||
if logs != nil {
|
||||
setCmdLogs(cmd, logs)
|
||||
}
|
||||
fmt.Fprintf(cmd.Stderr, "> runCmd %v %+v\n", time.Now(), cmd.String())
|
||||
fmt.Fprintf(cmd.Stderr, "> RunCmd %v %+v\n", time.Now(), cmd.String())
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func startCmd(cmd *exec.Cmd, logs map[string]*bytes.Buffer) (func() error, error) {
|
||||
func StartCmd(cmd *exec.Cmd, logs map[string]*bytes.Buffer) (func() error, error) {
|
||||
if logs != nil {
|
||||
setCmdLogs(cmd, logs)
|
||||
}
|
||||
|
||||
fmt.Fprintf(cmd.Stderr, "> startCmd %v %+v\n", time.Now(), cmd.String())
|
||||
fmt.Fprintf(cmd.Stderr, "> StartCmd %v %+v\n", time.Now(), cmd.String())
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
@ -79,16 +100,7 @@ func startCmd(cmd *exec.Cmd, logs map[string]*bytes.Buffer) (func() error, error
|
||||
}, nil
|
||||
}
|
||||
|
||||
func setCmdLogs(cmd *exec.Cmd, logs map[string]*bytes.Buffer) {
|
||||
b := new(bytes.Buffer)
|
||||
logs["stdout: "+cmd.String()] = b
|
||||
cmd.Stdout = &lockingWriter{Writer: b}
|
||||
b = new(bytes.Buffer)
|
||||
logs["stderr: "+cmd.String()] = b
|
||||
cmd.Stderr = &lockingWriter{Writer: b}
|
||||
}
|
||||
|
||||
func waitUnix(address string, d time.Duration, cmd *exec.Cmd) error {
|
||||
func WaitUnix(address string, d time.Duration, cmd *exec.Cmd) error {
|
||||
address = strings.TrimPrefix(address, "unix://")
|
||||
addr, err := net.ResolveUnixAddr("unix", address)
|
||||
if err != nil {
|
||||
@ -115,11 +127,19 @@ func waitUnix(address string, d time.Duration, cmd *exec.Cmd) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type multiCloser struct {
|
||||
func LookupBinary(name string) error {
|
||||
_, err := exec.LookPath(name)
|
||||
if err != nil {
|
||||
return errors.Wrapf(ErrRequirements, "failed to lookup %s binary", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MultiCloser struct {
|
||||
fns []func() error
|
||||
}
|
||||
|
||||
func (mc *multiCloser) F() func() error {
|
||||
func (mc *MultiCloser) F() func() error {
|
||||
return func() error {
|
||||
var err error
|
||||
for i := range mc.fns {
|
||||
@ -132,25 +152,17 @@ func (mc *multiCloser) F() func() error {
|
||||
}
|
||||
}
|
||||
|
||||
func (mc *multiCloser) append(f func() error) {
|
||||
func (mc *MultiCloser) Append(f func() error) {
|
||||
mc.fns = append(mc.fns, f)
|
||||
}
|
||||
|
||||
var ErrRequirements = errors.Errorf("missing requirements")
|
||||
|
||||
func lookupBinary(name string) error {
|
||||
_, err := exec.LookPath(name)
|
||||
if err != nil {
|
||||
return errors.Wrapf(ErrRequirements, "failed to lookup %s binary", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func requireRoot() error {
|
||||
if os.Getuid() != 0 {
|
||||
return errors.Wrap(ErrRequirements, "requires root")
|
||||
}
|
||||
return nil
|
||||
func setCmdLogs(cmd *exec.Cmd, logs map[string]*bytes.Buffer) {
|
||||
b := new(bytes.Buffer)
|
||||
logs["stdout: "+cmd.String()] = b
|
||||
cmd.Stdout = &lockingWriter{Writer: b}
|
||||
b = new(bytes.Buffer)
|
||||
logs["stderr: "+cmd.String()] = b
|
||||
cmd.Stderr = &lockingWriter{Writer: b}
|
||||
}
|
||||
|
||||
type lockingWriter struct {
|
||||
@ -164,33 +176,3 @@ func (w *lockingWriter) Write(dt []byte) (int, error) {
|
||||
w.mu.Unlock()
|
||||
return n, err
|
||||
}
|
||||
|
||||
func Tmpdir(t *testing.T, appliers ...fstest.Applier) (string, error) {
|
||||
// We cannot use t.TempDir() to create a temporary directory here because
|
||||
// appliers might contain fstest.CreateSocket. If the test name is too long,
|
||||
// t.TempDir() could return a path that is longer than 108 characters. This
|
||||
// would result in "bind: invalid argument" when we listen on the socket.
|
||||
tmpdir, err := os.MkdirTemp("", "buildkit")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, os.RemoveAll(tmpdir))
|
||||
})
|
||||
|
||||
if err := fstest.Apply(appliers...).Apply(tmpdir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return tmpdir, nil
|
||||
}
|
||||
|
||||
func randomString(n int) string {
|
||||
chars := "abcdefghijklmnopqrstuvwxyz"
|
||||
var b = make([]byte, n)
|
||||
_, _ = rand.Read(b)
|
||||
for k, v := range b {
|
||||
b[k] = chars[v%byte(len(chars))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
59
vendor/github.com/moby/buildkit/util/testutil/workers/backend.go
generated
vendored
Normal file
59
vendor/github.com/moby/buildkit/util/testutil/workers/backend.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type backend struct {
|
||||
address string
|
||||
dockerAddress string
|
||||
containerdAddress string
|
||||
rootless bool
|
||||
snapshotter string
|
||||
unsupportedFeatures []string
|
||||
isDockerd bool
|
||||
}
|
||||
|
||||
func (b backend) Address() string {
|
||||
return b.address
|
||||
}
|
||||
|
||||
func (b backend) DockerAddress() string {
|
||||
return b.dockerAddress
|
||||
}
|
||||
|
||||
func (b backend) ContainerdAddress() string {
|
||||
return b.containerdAddress
|
||||
}
|
||||
|
||||
func (b backend) Rootless() bool {
|
||||
return b.rootless
|
||||
}
|
||||
|
||||
func (b backend) Snapshotter() string {
|
||||
return b.snapshotter
|
||||
}
|
||||
|
||||
func (b backend) Supports(feature string) bool {
|
||||
if enabledFeatures := os.Getenv("BUILDKIT_TEST_ENABLE_FEATURES"); enabledFeatures != "" {
|
||||
for _, enabledFeature := range strings.Split(enabledFeatures, ",") {
|
||||
if feature == enabledFeature {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
if disabledFeatures := os.Getenv("BUILDKIT_TEST_DISABLE_FEATURES"); disabledFeatures != "" {
|
||||
for _, disabledFeature := range strings.Split(disabledFeatures, ",") {
|
||||
if feature == disabledFeature {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, unsupportedFeature := range b.unsupportedFeatures {
|
||||
if feature == unsupportedFeature {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package integration
|
||||
package workers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
@ -14,11 +13,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/moby/buildkit/util/bklog"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func InitContainerdWorker() {
|
||||
Register(&Containerd{
|
||||
integration.Register(&Containerd{
|
||||
ID: "containerd",
|
||||
Containerd: "containerd",
|
||||
})
|
||||
@ -32,7 +32,7 @@ func InitContainerdWorker() {
|
||||
panic(errors.Errorf("unexpected BUILDKIT_INTEGRATION_CONTAINERD_EXTRA: %q", s))
|
||||
}
|
||||
name, bin := pair[0], pair[1]
|
||||
Register(&Containerd{
|
||||
integration.Register(&Containerd{
|
||||
ID: name,
|
||||
Containerd: filepath.Join(bin, "containerd"),
|
||||
// override PATH to make sure that the expected version of the shim binary is used
|
||||
@ -47,8 +47,8 @@ func InitContainerdWorker() {
|
||||
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{
|
||||
if integration.RootlessSupported(uid) {
|
||||
integration.Register(&Containerd{
|
||||
ID: "containerd-rootless",
|
||||
Containerd: "containerd",
|
||||
UID: uid,
|
||||
@ -59,7 +59,7 @@ func InitContainerdWorker() {
|
||||
}
|
||||
|
||||
if s := os.Getenv("BUILDKIT_INTEGRATION_SNAPSHOTTER"); s != "" {
|
||||
Register(&Containerd{
|
||||
integration.Register(&Containerd{
|
||||
ID: fmt.Sprintf("containerd-snapshotter-%s", s),
|
||||
Containerd: "containerd",
|
||||
Snapshotter: s,
|
||||
@ -84,18 +84,18 @@ 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 {
|
||||
func (c *Containerd) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
||||
if err := integration.LookupBinary(c.Containerd); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := lookupBinary("buildkitd"); err != nil {
|
||||
if err := integration.LookupBinary("buildkitd"); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := requireRoot(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
deferF := &multiCloser{}
|
||||
deferF := &integration.MultiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
@ -123,7 +123,7 @@ func (c *Containerd) New(ctx context.Context, cfg *BackendConfig) (b Backend, cl
|
||||
}
|
||||
}
|
||||
|
||||
deferF.append(func() error { return os.RemoveAll(tmpdir) })
|
||||
deferF.Append(func() error { return os.RemoveAll(tmpdir) })
|
||||
|
||||
address := filepath.Join(tmpdir, "containerd.sock")
|
||||
config := fmt.Sprintf(`root = %q
|
||||
@ -149,7 +149,7 @@ disabled_plugins = ["cri"]
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
deferF.append(snCl)
|
||||
deferF.Append(snCl)
|
||||
config = fmt.Sprintf(`%s
|
||||
|
||||
[proxy_plugins]
|
||||
@ -168,7 +168,7 @@ disabled_plugins = ["cri"]
|
||||
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",
|
||||
containerdArgs = append(append([]string{"sudo", "-E", "-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
|
||||
@ -181,15 +181,15 @@ disabled_plugins = ["cri"]
|
||||
cmd := exec.Command(containerdArgs[0], containerdArgs[1:]...) //nolint:gosec // test utility
|
||||
cmd.Env = append(os.Environ(), c.ExtraEnv...)
|
||||
|
||||
ctdStop, err := startCmd(cmd, cfg.Logs)
|
||||
ctdStop, err := integration.StartCmd(cmd, cfg.Logs)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := waitUnix(address, 10*time.Second, cmd); err != nil {
|
||||
if err := integration.WaitUnix(address, 10*time.Second, cmd); err != nil {
|
||||
ctdStop()
|
||||
return nil, nil, errors.Wrapf(err, "containerd did not start up: %s", formatLogs(cfg.Logs))
|
||||
return nil, nil, errors.Wrapf(err, "containerd did not start up: %s", integration.FormatLogs(cfg.Logs))
|
||||
}
|
||||
deferF.append(ctdStop)
|
||||
deferF.Append(ctdStop)
|
||||
|
||||
buildkitdArgs := append([]string{"buildkitd",
|
||||
"--oci-worker=false",
|
||||
@ -211,16 +211,16 @@ disabled_plugins = ["cri"]
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
buildkitdArgs = append([]string{"sudo", "-u", fmt.Sprintf("#%d", c.UID), "-i", "--", "exec",
|
||||
buildkitdArgs = append([]string{"sudo", "-E", "-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)
|
||||
integration.PrintLogs(cfg.Logs, log.Println)
|
||||
return nil, nil, err
|
||||
}
|
||||
deferF.append(stop)
|
||||
deferF.Append(stop)
|
||||
|
||||
return backend{
|
||||
address: buildkitdSock,
|
||||
@ -234,12 +234,43 @@ func (c *Containerd) Close() error {
|
||||
return 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()))
|
||||
}
|
||||
func runStargzSnapshotter(cfg *integration.BackendConfig) (address string, cl func() error, err error) {
|
||||
binary := "containerd-stargz-grpc"
|
||||
if err := integration.LookupBinary(binary); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return strings.Join(ss, ",")
|
||||
|
||||
deferF := &integration.MultiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
deferF.F()()
|
||||
cl = nil
|
||||
}
|
||||
}()
|
||||
|
||||
tmpStargzDir, err := os.MkdirTemp("", "bktest_containerd_stargz_grpc")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
deferF.Append(func() error { return os.RemoveAll(tmpStargzDir) })
|
||||
|
||||
address = filepath.Join(tmpStargzDir, "containerd-stargz-grpc.sock")
|
||||
stargzRootDir := filepath.Join(tmpStargzDir, "root")
|
||||
cmd := exec.Command(binary,
|
||||
"--log-level", "debug",
|
||||
"--address", address,
|
||||
"--root", stargzRootDir)
|
||||
snStop, err := integration.StartCmd(cmd, cfg.Logs)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err = integration.WaitUnix(address, 10*time.Second, cmd); err != nil {
|
||||
snStop()
|
||||
return "", nil, errors.Wrapf(err, "containerd-stargz-grpc did not start up: %s", integration.FormatLogs(cfg.Logs))
|
||||
}
|
||||
deferF.Append(snStop)
|
||||
|
||||
return
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package integration
|
||||
package workers
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -13,13 +13,14 @@ import (
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/moby/buildkit/cmd/buildkitd/config"
|
||||
"github.com/moby/buildkit/util/testutil/dockerd"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// InitDockerdWorker registers a dockerd worker with the global registry.
|
||||
func InitDockerdWorker() {
|
||||
Register(&Moby{
|
||||
integration.Register(&Moby{
|
||||
ID: "dockerd",
|
||||
IsRootless: false,
|
||||
Unsupported: []string{
|
||||
@ -42,7 +43,7 @@ func InitDockerdWorker() {
|
||||
FeatureCNINetwork,
|
||||
},
|
||||
})
|
||||
Register(&Moby{
|
||||
integration.Register(&Moby{
|
||||
ID: "dockerd-containerd",
|
||||
IsRootless: false,
|
||||
ContainerdSnapshotter: true,
|
||||
@ -70,7 +71,7 @@ func (c Moby) Rootless() bool {
|
||||
return c.IsRootless
|
||||
}
|
||||
|
||||
func (c Moby) New(ctx context.Context, cfg *BackendConfig) (b Backend, cl func() error, err error) {
|
||||
func (c Moby) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
||||
if err := requireRoot(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -106,7 +107,7 @@ func (c Moby) New(ctx context.Context, cfg *BackendConfig) (b Backend, cl func()
|
||||
return nil, nil, errors.Wrapf(err, "failed to marshal dockerd config")
|
||||
}
|
||||
|
||||
deferF := &multiCloser{}
|
||||
deferF := &integration.MultiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
@ -117,7 +118,7 @@ func (c Moby) New(ctx context.Context, cfg *BackendConfig) (b Backend, cl func()
|
||||
}()
|
||||
|
||||
var proxyGroup errgroup.Group
|
||||
deferF.append(proxyGroup.Wait)
|
||||
deferF.Append(proxyGroup.Wait)
|
||||
|
||||
workDir, err := os.MkdirTemp("", "integration")
|
||||
if err != nil {
|
||||
@ -126,7 +127,7 @@ func (c Moby) New(ctx context.Context, cfg *BackendConfig) (b Backend, cl func()
|
||||
|
||||
d, err := dockerd.NewDaemon(workDir)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Errorf("new daemon error: %q, %s", err, formatLogs(cfg.Logs))
|
||||
return nil, nil, errors.Errorf("new daemon error: %q, %s", err, integration.FormatLogs(cfg.Logs))
|
||||
}
|
||||
|
||||
dockerdConfigFile := filepath.Join(workDir, "daemon.json")
|
||||
@ -148,21 +149,21 @@ func (c Moby) New(ctx context.Context, cfg *BackendConfig) (b Backend, cl func()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
deferF.append(d.StopWithError)
|
||||
deferF.Append(d.StopWithError)
|
||||
|
||||
if err := waitUnix(d.Sock(), 5*time.Second, nil); err != nil {
|
||||
return nil, nil, errors.Errorf("dockerd did not start up: %q, %s", err, formatLogs(cfg.Logs))
|
||||
if err := integration.WaitUnix(d.Sock(), 5*time.Second, nil); err != nil {
|
||||
return nil, nil, errors.Errorf("dockerd did not start up: %q, %s", err, integration.FormatLogs(cfg.Logs))
|
||||
}
|
||||
|
||||
dockerAPI, err := client.NewClientWithOpts(client.WithHost(d.Sock()))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
deferF.append(dockerAPI.Close)
|
||||
deferF.Append(dockerAPI.Close)
|
||||
|
||||
err = waitForAPI(ctx, dockerAPI, 5*time.Second)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "dockerd client api timed out: %s", formatLogs(cfg.Logs))
|
||||
return nil, nil, errors.Wrapf(err, "dockerd client api timed out: %s", integration.FormatLogs(cfg.Logs))
|
||||
}
|
||||
|
||||
// Create a file descriptor to be used as a Unix domain socket.
|
||||
@ -178,9 +179,9 @@ func (c Moby) New(ctx context.Context, cfg *BackendConfig) (b Backend, cl func()
|
||||
|
||||
listener, err := net.Listen("unix", localPath)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "dockerd listener error: %s", formatLogs(cfg.Logs))
|
||||
return nil, nil, errors.Wrapf(err, "dockerd listener error: %s", integration.FormatLogs(cfg.Logs))
|
||||
}
|
||||
deferF.append(listener.Close)
|
||||
deferF.Append(listener.Close)
|
||||
|
||||
proxyGroup.Go(func() error {
|
||||
for {
|
||||
@ -244,10 +245,6 @@ func IsTestDockerd() bool {
|
||||
return os.Getenv("TEST_DOCKERD") == "1"
|
||||
}
|
||||
|
||||
func IsTestDockerdMoby(sb Sandbox) bool {
|
||||
b, err := getBackend(sb)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return b.isDockerd && sb.Name() == "dockerd"
|
||||
func IsTestDockerdMoby(sb integration.Sandbox) bool {
|
||||
return sb.DockerAddress() != "" && sb.Name() == "dockerd"
|
||||
}
|
63
vendor/github.com/moby/buildkit/util/testutil/workers/features.go
generated
vendored
Normal file
63
vendor/github.com/moby/buildkit/util/testutil/workers/features.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
)
|
||||
|
||||
const (
|
||||
FeatureCacheExport = "cache_export"
|
||||
FeatureCacheImport = "cache_import"
|
||||
FeatureCacheBackendAzblob = "cache_backend_azblob"
|
||||
FeatureCacheBackendGha = "cache_backend_gha"
|
||||
FeatureCacheBackendInline = "cache_backend_inline"
|
||||
FeatureCacheBackendLocal = "cache_backend_local"
|
||||
FeatureCacheBackendRegistry = "cache_backend_registry"
|
||||
FeatureCacheBackendS3 = "cache_backend_s3"
|
||||
FeatureDirectPush = "direct_push"
|
||||
FeatureFrontendOutline = "frontend_outline"
|
||||
FeatureFrontendTargets = "frontend_targets"
|
||||
FeatureImageExporter = "image_exporter"
|
||||
FeatureInfo = "info"
|
||||
FeatureMergeDiff = "merge_diff"
|
||||
FeatureMultiCacheExport = "multi_cache_export"
|
||||
FeatureMultiPlatform = "multi_platform"
|
||||
FeatureOCIExporter = "oci_exporter"
|
||||
FeatureOCILayout = "oci_layout"
|
||||
FeatureProvenance = "provenance"
|
||||
FeatureSBOM = "sbom"
|
||||
FeatureSecurityMode = "security_mode"
|
||||
FeatureSourceDateEpoch = "source_date_epoch"
|
||||
FeatureCNINetwork = "cni_network"
|
||||
)
|
||||
|
||||
var features = map[string]struct{}{
|
||||
FeatureCacheExport: {},
|
||||
FeatureCacheImport: {},
|
||||
FeatureCacheBackendAzblob: {},
|
||||
FeatureCacheBackendGha: {},
|
||||
FeatureCacheBackendInline: {},
|
||||
FeatureCacheBackendLocal: {},
|
||||
FeatureCacheBackendRegistry: {},
|
||||
FeatureCacheBackendS3: {},
|
||||
FeatureDirectPush: {},
|
||||
FeatureFrontendOutline: {},
|
||||
FeatureFrontendTargets: {},
|
||||
FeatureImageExporter: {},
|
||||
FeatureInfo: {},
|
||||
FeatureMergeDiff: {},
|
||||
FeatureMultiCacheExport: {},
|
||||
FeatureMultiPlatform: {},
|
||||
FeatureOCIExporter: {},
|
||||
FeatureOCILayout: {},
|
||||
FeatureProvenance: {},
|
||||
FeatureSBOM: {},
|
||||
FeatureSecurityMode: {},
|
||||
FeatureSourceDateEpoch: {},
|
||||
FeatureCNINetwork: {},
|
||||
}
|
||||
|
||||
func CheckFeatureCompat(t *testing.T, sb integration.Sandbox, reason ...string) {
|
||||
integration.CheckFeatureCompat(t, sb, features, reason...)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package integration
|
||||
package workers
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -8,11 +8,12 @@ import (
|
||||
"runtime"
|
||||
|
||||
"github.com/moby/buildkit/util/bklog"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func InitOCIWorker() {
|
||||
Register(&OCI{ID: "oci"})
|
||||
integration.Register(&OCI{ID: "oci"})
|
||||
|
||||
// the rootless uid is defined in Dockerfile
|
||||
if s := os.Getenv("BUILDKIT_INTEGRATION_ROOTLESS_IDPAIR"); s != "" {
|
||||
@ -20,13 +21,13 @@ func InitOCIWorker() {
|
||||
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(&OCI{ID: "oci-rootless", UID: uid, GID: gid})
|
||||
if integration.RootlessSupported(uid) {
|
||||
integration.Register(&OCI{ID: "oci-rootless", UID: uid, GID: gid})
|
||||
}
|
||||
}
|
||||
|
||||
if s := os.Getenv("BUILDKIT_INTEGRATION_SNAPSHOTTER"); s != "" {
|
||||
Register(&OCI{ID: "oci-snapshotter-" + s, Snapshotter: s})
|
||||
integration.Register(&OCI{ID: "oci-snapshotter-" + s, Snapshotter: s})
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,8 +46,8 @@ func (s *OCI) Rootless() bool {
|
||||
return s.UID != 0
|
||||
}
|
||||
|
||||
func (s *OCI) New(ctx context.Context, cfg *BackendConfig) (Backend, func() error, error) {
|
||||
if err := lookupBinary("buildkitd"); err != nil {
|
||||
func (s *OCI) New(ctx context.Context, cfg *integration.BackendConfig) (integration.Backend, func() error, error) {
|
||||
if err := integration.LookupBinary("buildkitd"); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := requireRoot(); err != nil {
|
||||
@ -65,7 +66,7 @@ func (s *OCI) New(ctx context.Context, cfg *BackendConfig) (Backend, func() erro
|
||||
return nil, nil, errors.Errorf("unsupported id pair: uid=%d, gid=%d", s.UID, s.GID)
|
||||
}
|
||||
// TODO: make sure the user exists and subuid/subgid are configured.
|
||||
buildkitdArgs = append([]string{"sudo", "-u", fmt.Sprintf("#%d", s.UID), "-i", "--", "exec", "rootlesskit"}, buildkitdArgs...)
|
||||
buildkitdArgs = append([]string{"sudo", "-E", "-u", fmt.Sprintf("#%d", s.UID), "-i", "--", "exec", "rootlesskit"}, buildkitdArgs...)
|
||||
}
|
||||
|
||||
var extraEnv []string
|
||||
@ -74,7 +75,7 @@ func (s *OCI) New(ctx context.Context, cfg *BackendConfig) (Backend, func() erro
|
||||
}
|
||||
buildkitdSock, stop, err := runBuildkitd(ctx, cfg, buildkitdArgs, cfg.Logs, s.UID, s.GID, extraEnv)
|
||||
if err != nil {
|
||||
printLogs(cfg.Logs, log.Println)
|
||||
integration.PrintLogs(cfg.Logs, log.Println)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
23
vendor/github.com/moby/buildkit/util/testutil/workers/sysprocattr_unix.go
generated
vendored
Normal file
23
vendor/github.com/moby/buildkit/util/testutil/workers/sysprocattr_unix.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package workers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func getSysProcAttr() *syscall.SysProcAttr {
|
||||
return &syscall.SysProcAttr{
|
||||
Setsid: true, // stretch sudo needs this for sigterm
|
||||
}
|
||||
}
|
||||
|
||||
func getBuildkitdAddr(tmpdir string) string {
|
||||
return "unix://" + filepath.Join(tmpdir, "buildkitd.sock")
|
||||
}
|
||||
|
||||
func getTraceSocketPath(tmpdir string) string {
|
||||
return filepath.Join(tmpdir, "otel-grpc.sock")
|
||||
}
|
21
vendor/github.com/moby/buildkit/util/testutil/workers/sysprocattr_windows.go
generated
vendored
Normal file
21
vendor/github.com/moby/buildkit/util/testutil/workers/sysprocattr_windows.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package workers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func getSysProcAttr() *syscall.SysProcAttr {
|
||||
return &syscall.SysProcAttr{}
|
||||
}
|
||||
|
||||
func getBuildkitdAddr(tmpdir string) string {
|
||||
return "//./pipe/buildkitd-" + filepath.Base(tmpdir)
|
||||
}
|
||||
|
||||
func getTraceSocketPath(tmpdir string) string {
|
||||
return `\\.\pipe\buildkit-otel-grpc-` + filepath.Base(tmpdir)
|
||||
}
|
89
vendor/github.com/moby/buildkit/util/testutil/workers/util.go
generated
vendored
Normal file
89
vendor/github.com/moby/buildkit/util/testutil/workers/util.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func requireRoot() error {
|
||||
if os.Getuid() != 0 {
|
||||
return errors.Wrap(integration.ErrRequirements, "requires root")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runBuildkitd(ctx context.Context, conf *integration.BackendConfig, args []string, logs map[string]*bytes.Buffer, uid, gid int, extraEnv []string) (address string, cl func() error, err error) {
|
||||
deferF := &integration.MultiCloser{}
|
||||
cl = deferF.F()
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
deferF.F()()
|
||||
cl = nil
|
||||
}
|
||||
}()
|
||||
|
||||
if conf.ConfigFile != "" {
|
||||
args = append(args, "--config="+conf.ConfigFile)
|
||||
}
|
||||
|
||||
tmpdir, err := os.MkdirTemp("", "bktest_buildkitd")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := os.Chown(tmpdir, uid, gid); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(tmpdir, "tmp"), 0711); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := os.Chown(filepath.Join(tmpdir, "tmp"), uid, gid); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
deferF.Append(func() error { return os.RemoveAll(tmpdir) })
|
||||
|
||||
address = getBuildkitdAddr(tmpdir)
|
||||
|
||||
args = append(args, "--root", tmpdir, "--addr", address, "--debug")
|
||||
cmd := exec.Command(args[0], args[1:]...) //nolint:gosec // test utility
|
||||
cmd.Env = append(os.Environ(), "BUILDKIT_DEBUG_EXEC_OUTPUT=1", "BUILDKIT_DEBUG_PANIC_ON_ERROR=1", "BUILDKIT_TRACE_SOCKET="+getTraceSocketPath(tmpdir), "TMPDIR="+filepath.Join(tmpdir, "tmp"))
|
||||
cmd.Env = append(cmd.Env, extraEnv...)
|
||||
cmd.SysProcAttr = getSysProcAttr()
|
||||
|
||||
stop, err := integration.StartCmd(cmd, logs)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
deferF.Append(stop)
|
||||
|
||||
if err := integration.WaitUnix(address, 15*time.Second, cmd); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
deferF.Append(func() error {
|
||||
f, err := os.Open("/proc/self/mountinfo")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to open mountinfo")
|
||||
}
|
||||
defer f.Close()
|
||||
s := bufio.NewScanner(f)
|
||||
for s.Scan() {
|
||||
if strings.Contains(s.Text(), tmpdir) {
|
||||
return errors.Errorf("leaked mountpoint for %s", tmpdir)
|
||||
}
|
||||
}
|
||||
return s.Err()
|
||||
})
|
||||
|
||||
return address, cl, err
|
||||
}
|
Reference in New Issue
Block a user