mirror of
https://github.com/moby/moby.git
synced 2026-01-11 10:41:43 +00:00
Buildkit fails when userns remapping is enabled and c8d snapshotter is used. As a temporary workaround, disable c8d snapshotter when userns remapping is enabled. This will need a proper fix in the future. Signed-off-by: Albin Kerouanton <albinker@gmail.com>
154 lines
4.6 KiB
Go
154 lines
4.6 KiB
Go
package command
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/moby/moby/v2/daemon/config"
|
|
"github.com/moby/sys/reexec"
|
|
"golang.org/x/sys/unix"
|
|
"gotest.tools/v3/assert"
|
|
)
|
|
|
|
const (
|
|
testListenerNoAddrCmdPhase1 = "test-listener-no-addr1"
|
|
testListenerNoAddrCmdPhase2 = "test-listener-no-addr2"
|
|
)
|
|
|
|
type listenerTestResponse struct {
|
|
Err string
|
|
}
|
|
|
|
func initListenerTestPhase1() {
|
|
os.Setenv("LISTEN_PID", strconv.Itoa(os.Getpid()))
|
|
os.Setenv("LISTEN_FDS", "1")
|
|
|
|
// NOTE: We cannot use O_CLOEXEC here because we need the fd to stay open for the child process.
|
|
_, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0)
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
cmd := reexec.Command(testListenerNoAddrCmdPhase2)
|
|
if err := unix.Exec(cmd.Path, cmd.Args, os.Environ()); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func initListenerTestPhase2() {
|
|
cfg := &config.Config{
|
|
CommonConfig: config.CommonConfig{
|
|
Hosts: []string{"fd://"},
|
|
},
|
|
}
|
|
_, _, err := loadListeners(cfg, nil)
|
|
var resp listenerTestResponse
|
|
if err != nil {
|
|
resp.Err = err.Error()
|
|
}
|
|
|
|
if err := json.NewEncoder(os.Stdout).Encode(resp); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// Test to make sure that the listen specs without an address are handled
|
|
// It requires a 2-phase setup due to how socket activation works (which we are using to test).
|
|
// It requires LISTEN_FDS and LISTEN_PID to be set in the environment.
|
|
//
|
|
// LISTEN_PID is used by socket activation to determine if the process is the one that should be activated.
|
|
// LISTEN_FDS is used by socket activation to determine how many file descriptors are passed to the process.
|
|
//
|
|
// We can sort of fake this without using extra processes, but it ends up not
|
|
// being a true test because that's not how socket activation is expected to
|
|
// work and we'll end up with nil listeners since the test framework has other
|
|
// file descriptors open.
|
|
//
|
|
// This is not currently testing `tcp://` or `unix://` listen specs without an address because those can conflict with the machine running the test.
|
|
// This could be worked around by using linux namespaces, however that would require root privileges which unit tests don't typically have.
|
|
func TestLoadListenerNoAddr(t *testing.T) {
|
|
cmd := reexec.Command(testListenerNoAddrCmdPhase1)
|
|
stdout := bytes.NewBuffer(nil)
|
|
cmd.Stdout = stdout
|
|
stderr := bytes.NewBuffer(nil)
|
|
cmd.Stderr = stderr
|
|
|
|
assert.NilError(t, cmd.Run(), stderr.String())
|
|
|
|
var resp listenerTestResponse
|
|
assert.NilError(t, json.NewDecoder(stdout).Decode(&resp))
|
|
assert.Equal(t, resp.Err, "")
|
|
}
|
|
|
|
func TestC8dSnapshotterWithUsernsRemap(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
cfg *config.Config
|
|
expCfg *config.Config
|
|
expErr string
|
|
}{
|
|
{
|
|
name: "no remap, no snapshotter",
|
|
cfg: &config.Config{},
|
|
expCfg: &config.Config{},
|
|
},
|
|
{
|
|
name: "userns remap, no explicit containerd-snapshotter feature",
|
|
cfg: &config.Config{RemappedRoot: "default"},
|
|
expCfg: &config.Config{
|
|
RemappedRoot: "dockremap:dockremap",
|
|
CommonConfig: config.CommonConfig{
|
|
ContainerdNamespace: "-100000.100000",
|
|
ContainerdPluginNamespace: "-100000.100000",
|
|
Features: map[string]bool{"containerd-snapshotter": false},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "userns remap, explicit containerd-snapshotter feature",
|
|
cfg: &config.Config{
|
|
RemappedRoot: "default",
|
|
CommonConfig: config.CommonConfig{Features: map[string]bool{"containerd-snapshotter": true}},
|
|
},
|
|
expCfg: &config.Config{
|
|
RemappedRoot: "dockremap:dockremap",
|
|
CommonConfig: config.CommonConfig{
|
|
ContainerdNamespace: "-100000.100000",
|
|
ContainerdPluginNamespace: "-100000.100000",
|
|
Features: map[string]bool{"containerd-snapshotter": true},
|
|
},
|
|
},
|
|
expErr: "containerd-snapshotter is explicitly enabled, but is not compatible with userns remapping. Please disable userns remapping or containerd-snapshotter",
|
|
},
|
|
{
|
|
name: "no remap, explicit containerd-snapshotter feature",
|
|
cfg: &config.Config{
|
|
CommonConfig: config.CommonConfig{Features: map[string]bool{"containerd-snapshotter": true}},
|
|
},
|
|
expCfg: &config.Config{
|
|
CommonConfig: config.CommonConfig{Features: map[string]bool{"containerd-snapshotter": true}},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := setPlatformOptions(tc.cfg)
|
|
assert.DeepEqual(t, tc.expCfg, tc.cfg, cmp.AllowUnexported(config.DefaultBridgeConfig{}))
|
|
if tc.expErr != "" {
|
|
assert.Equal(t, tc.expErr, err.Error())
|
|
} else {
|
|
assert.NilError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|