diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go index 97bc8e707a..ab5d5b59b3 100644 --- a/daemon/oci_linux.go +++ b/daemon/oci_linux.go @@ -23,7 +23,6 @@ import ( "github.com/docker/docker/oci/caps" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/rootless/specconv" - "github.com/docker/docker/pkg/stringid" volumemounts "github.com/docker/docker/volume/mounts" "github.com/moby/sys/mount" "github.com/moby/sys/mountinfo" @@ -61,28 +60,6 @@ func withRlimits(daemon *Daemon, daemonCfg *dconfig.Config, c *container.Contain } } -// withLibnetwork sets the libnetwork hook -func withLibnetwork(daemon *Daemon, daemonCfg *dconfig.Config, c *container.Container) coci.SpecOpts { - return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error { - if c.Config.NetworkDisabled { - return nil - } - for _, ns := range s.Linux.Namespaces { - if ns.Type == specs.NetworkNamespace && ns.Path == "" { - if s.Hooks == nil { - s.Hooks = &specs.Hooks{} - } - shortNetCtlrID := stringid.TruncateID(daemon.netController.ID()) - s.Hooks.Prestart = append(s.Hooks.Prestart, specs.Hook{ - Path: filepath.Join("/proc", strconv.Itoa(os.Getpid()), "exe"), - Args: []string{"libnetwork-setkey", "-exec-root=" + daemonCfg.GetExecRoot(), c.ID, shortNetCtlrID}, - }) - } - } - return nil - } -} - // withRootless sets the spec to the rootless configuration func withRootless(daemon *Daemon, daemonCfg *dconfig.Config) coci.SpecOpts { return func(_ context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error { @@ -1070,7 +1047,6 @@ func (daemon *Daemon) createSpec(ctx context.Context, daemonCfg *configStore, c WithCapabilities(c), WithSeccomp(daemon, c), withMounts(daemon, daemonCfg, c, mounts), - withLibnetwork(daemon, &daemonCfg.Config, c), WithApparmor(c), WithSelinux(c), WithOOMScore(&c.HostConfig.OomScoreAdj), diff --git a/daemon/start.go b/daemon/start.go index 7e6690295d..516c069958 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -236,6 +236,10 @@ func (daemon *Daemon) containerStart(ctx context.Context, daemonCfg *configStore } }() + if err := daemon.initializeCreatedTask(ctx, tsk, container, spec); err != nil { + return err + } + if err := tsk.Start(context.TODO()); err != nil { // passing ctx caused integration tests to be stuck in the cleanup phase return setExitCodeFromError(container.SetExitCode, err) } diff --git a/daemon/start_linux.go b/daemon/start_linux.go new file mode 100644 index 0000000000..f4c0044dbf --- /dev/null +++ b/daemon/start_linux.go @@ -0,0 +1,31 @@ +package daemon // import "github.com/docker/docker/daemon" + +import ( + "context" + "fmt" + + specs "github.com/opencontainers/runtime-spec/specs-go" + + "github.com/docker/docker/container" + "github.com/docker/docker/errdefs" + "github.com/docker/docker/libcontainerd/types" + "github.com/docker/docker/oci" +) + +// initializeCreatedTask performs any initialization that needs to be done to +// prepare a freshly-created task to be started. +func (daemon *Daemon) initializeCreatedTask(ctx context.Context, tsk types.Task, container *container.Container, spec *specs.Spec) error { + if !container.Config.NetworkDisabled { + nspath, ok := oci.NamespacePath(spec, specs.NetworkNamespace) + if ok && nspath == "" { // the runtime has been instructed to create a new network namespace for tsk. + sb, err := daemon.netController.GetSandbox(container.ID) + if err != nil { + return errdefs.System(err) + } + if err := sb.SetKey(fmt.Sprintf("/proc/%d/ns/net", tsk.Pid())); err != nil { + return errdefs.System(err) + } + } + } + return nil +} diff --git a/daemon/start_notlinux.go b/daemon/start_notlinux.go new file mode 100644 index 0000000000..0170e38cca --- /dev/null +++ b/daemon/start_notlinux.go @@ -0,0 +1,17 @@ +//go:build !linux + +package daemon // import "github.com/docker/docker/daemon" + +import ( + "context" + + "github.com/docker/docker/container" + "github.com/docker/docker/libcontainerd/types" + specs "github.com/opencontainers/runtime-spec/specs-go" +) + +// initializeCreatedTask performs any initialization that needs to be done to +// prepare a freshly-created task to be started. +func (daemon *Daemon) initializeCreatedTask(ctx context.Context, tsk types.Task, container *container.Container, spec *specs.Spec) error { + return nil +} diff --git a/libnetwork/osl/namespace_linux.go b/libnetwork/osl/namespace_linux.go index 1ea66b65cb..256dc0d3b7 100644 --- a/libnetwork/osl/namespace_linux.go +++ b/libnetwork/osl/namespace_linux.go @@ -226,7 +226,11 @@ func NewSandbox(key string, osCreate, isRestore bool) (*Namespace, error) { } func mountNetworkNamespace(basePath string, lnPath string) error { - return syscall.Mount(basePath, lnPath, "bind", syscall.MS_BIND, "") + err := syscall.Mount(basePath, lnPath, "bind", syscall.MS_BIND, "") + if err != nil { + return fmt.Errorf("bind-mount %s -> %s: %w", basePath, lnPath, err) + } + return nil } // GetSandboxForExternalKey returns sandbox object for the supplied path diff --git a/oci/namespaces.go b/oci/namespaces.go index 851edd61ef..befcefcc40 100644 --- a/oci/namespaces.go +++ b/oci/namespaces.go @@ -14,3 +14,14 @@ func RemoveNamespace(s *specs.Spec, nsType specs.LinuxNamespaceType) { } } } + +// NamespacePath returns the configured Path of the first namespace in +// s.Linux.Namespaces of type nsType. +func NamespacePath(s *specs.Spec, nsType specs.LinuxNamespaceType) (path string, ok bool) { + for _, n := range s.Linux.Namespaces { + if n.Type == nsType { + return n.Path, true + } + } + return "", false +}