diff --git a/src/runtime/virtcontainers/sandbox.go b/src/runtime/virtcontainers/sandbox.go index b84174b436..a53003fc67 100644 --- a/src/runtime/virtcontainers/sandbox.go +++ b/src/runtime/virtcontainers/sandbox.go @@ -933,6 +933,17 @@ func (s *Sandbox) createNetwork(ctx context.Context) error { return nil } + // docker container needs the hypervisor process ID to find out the container netns, + // which means that the hypervisor has to support network device hotplug so that docker + // can use the prestart hooks to set up container netns. + caps := s.hypervisor.Capabilities(ctx) + if !caps.IsNetworkDeviceHotplugSupported() { + spec := s.GetPatchedOCISpec() + if utils.IsDockerContainer(spec) { + return errors.New("docker container needs network device hotplug but the configured hypervisor does not support it") + } + } + span, ctx := katatrace.Trace(ctx, s.Logger(), "createNetwork", sandboxTracingTags, map[string]string{"sandbox_id": s.id}) defer span.End() katatrace.AddTags(span, "network", s.network, "NetworkConfig", s.config.NetworkConfig) diff --git a/src/runtime/virtcontainers/utils/utils.go b/src/runtime/virtcontainers/utils/utils.go index bac62e8cfd..735cf3a2f5 100644 --- a/src/runtime/virtcontainers/utils/utils.go +++ b/src/runtime/virtcontainers/utils/utils.go @@ -12,9 +12,11 @@ import ( "os" "os/exec" "path/filepath" + "strings" "syscall" "time" + "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" @@ -494,3 +496,21 @@ func RevertBytes(num uint64) uint64 { } return 1024*RevertBytes(a) + b } + +// IsDockerContainer returns if the container is managed by docker +// This is done by checking the prestart hook for `libnetwork` arguments. +func IsDockerContainer(spec *specs.Spec) bool { + if spec == nil || spec.Hooks == nil { + return false + } + + for _, hook := range spec.Hooks.Prestart { + for _, arg := range hook.Args { + if strings.HasPrefix(arg, "libnetwork") { + return true + } + } + } + + return false +} diff --git a/src/runtime/virtcontainers/utils/utils_test.go b/src/runtime/virtcontainers/utils/utils_test.go index 8f3d0eed26..bae9af8dbd 100644 --- a/src/runtime/virtcontainers/utils/utils_test.go +++ b/src/runtime/virtcontainers/utils/utils_test.go @@ -16,6 +16,7 @@ import ( "syscall" "testing" + "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) @@ -580,3 +581,25 @@ func TestRevertBytes(t *testing.T) { num := RevertBytes(testNum) assert.Equal(expectedNum, num) } + +func TestIsDockerContainer(t *testing.T) { + assert := assert.New(t) + + ociSpec := &specs.Spec{ + Hooks: &specs.Hooks{ + Prestart: []specs.Hook{ + { + Args: []string{ + "haha", + }, + }, + }, + }, + } + assert.False(IsDockerContainer(ociSpec)) + + ociSpec.Hooks.Prestart = append(ociSpec.Hooks.Prestart, specs.Hook{ + Args: []string{"libnetwork-xxx"}, + }) + assert.True(IsDockerContainer(ociSpec)) +}