summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/container.go4
-rw-r--r--libpod/container_internal.go6
-rw-r--r--libpod/networking_linux.go38
-rw-r--r--libpod/networking_unsupported.go4
-rw-r--r--libpod/oci.go10
-rw-r--r--pkg/spec/createconfig.go8
6 files changed, 65 insertions, 5 deletions
diff --git a/libpod/container.go b/libpod/container.go
index 456fc412d..77c94c7df 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -3,6 +3,7 @@ package libpod
import (
"fmt"
"net"
+ "os"
"path/filepath"
"time"
@@ -106,6 +107,9 @@ type Container struct {
valid bool
lock storage.Locker
runtime *Runtime
+
+ rootlessSlirpSyncR *os.File
+ rootlessSlirpSyncW *os.File
}
// containerState contains the current state of the container
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 8a96af0ab..2f258d007 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -524,12 +524,12 @@ func (c *Container) completeNetworkSetup() error {
if !c.config.PostConfigureNetNS {
return nil
}
- if rootless.IsRootless() {
- return nil
- }
if err := c.syncContainer(); err != nil {
return err
}
+ if rootless.IsRootless() {
+ return c.runtime.setupRootlessNetNS(c)
+ }
return c.runtime.setupNetNS(c)
}
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index dbc68e04b..2186b4ac9 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -6,9 +6,11 @@ import (
"crypto/rand"
"fmt"
"os"
+ "os/exec"
"path/filepath"
"strconv"
"strings"
+ "syscall"
cnitypes "github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/plugins/pkg/ns"
@@ -93,6 +95,42 @@ func (r *Runtime) createNetNS(ctr *Container) (err error) {
return r.configureNetNS(ctr, ctrNS)
}
+// Configure the network namespace for a rootless container
+func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
+ defer ctr.rootlessSlirpSyncR.Close()
+ defer ctr.rootlessSlirpSyncW.Close()
+
+ path, err := exec.LookPath("slirp4netns")
+ if err != nil {
+ logrus.Errorf("could not find slirp4netns, the network namespace won't be configured: %v", err)
+ return nil
+ }
+
+ syncR, syncW, err := os.Pipe()
+ if err != nil {
+ return errors.Wrapf(err, "failed to open pipe")
+ }
+ defer syncR.Close()
+ defer syncW.Close()
+
+ cmd := exec.Command(path, "-c", "-e", "3", "-r", "4", fmt.Sprintf("%d", ctr.state.PID), "tap0")
+
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Setpgid: true,
+ }
+ cmd.ExtraFiles = append(cmd.ExtraFiles, ctr.rootlessSlirpSyncR, syncW)
+
+ if err := cmd.Start(); err != nil {
+ return errors.Wrapf(err, "failed to start process")
+ }
+
+ b := make([]byte, 16)
+ if _, err := syncR.Read(b); err != nil {
+ return errors.Wrapf(err, "failed to read from sync pipe")
+ }
+ return nil
+}
+
// Configure the network namespace using the container process
func (r *Runtime) setupNetNS(ctr *Container) (err error) {
nsProcess := fmt.Sprintf("/proc/%d/ns/net", ctr.state.PID)
diff --git a/libpod/networking_unsupported.go b/libpod/networking_unsupported.go
index e4c668f88..070985c47 100644
--- a/libpod/networking_unsupported.go
+++ b/libpod/networking_unsupported.go
@@ -6,6 +6,10 @@ import (
"github.com/projectatomic/libpod/pkg/inspect"
)
+func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
+ return ErrNotImplemented
+}
+
func (r *Runtime) setupNetNS(ctr *Container) (err error) {
return ErrNotImplemented
}
diff --git a/libpod/oci.go b/libpod/oci.go
index 0483c0d53..5ae3406ac 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -22,6 +22,7 @@ import (
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/projectatomic/libpod/pkg/ctime"
+ "github.com/projectatomic/libpod/pkg/rootless"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
kwait "k8s.io/apimachinery/pkg/util/wait"
@@ -317,6 +318,15 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string) (er
// process cannot use them.
cmd.ExtraFiles = append(cmd.ExtraFiles, ports...)
+ if rootless.IsRootless() {
+ ctr.rootlessSlirpSyncR, ctr.rootlessSlirpSyncW, err = os.Pipe()
+ if err != nil {
+ return errors.Wrapf(err, "failed to create rootless network sync pipe")
+ }
+ // Leak one end in conmon, the other one will be leaked into slirp4netns
+ cmd.ExtraFiles = append(cmd.ExtraFiles, ctr.rootlessSlirpSyncW)
+ }
+
if notify, ok := os.LookupEnv("NOTIFY_SOCKET"); ok {
cmd.Env = append(cmd.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", notify))
}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 0bd6c6d1c..fb45f042b 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -381,8 +381,12 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
return nil, errors.Wrapf(err, "container %q not found", c.NetMode.ConnectedContainer())
}
options = append(options, libpod.WithNetNSFrom(connectedCtr))
- } else if !rootless.IsRootless() && !c.NetMode.IsHost() && !c.NetMode.IsNone() {
- postConfigureNetNS := (len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0) && !c.UsernsMode.IsHost()
+ } else if !c.NetMode.IsHost() && !c.NetMode.IsNone() {
+ isRootless := rootless.IsRootless()
+ postConfigureNetNS := isRootless || (len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0) && !c.UsernsMode.IsHost()
+ if isRootless && len(portBindings) > 0 {
+ return nil, errors.New("port bindings are not yet supported by rootless containers")
+ }
options = append(options, libpod.WithNetNS(portBindings, postConfigureNetNS, networks))
}