Skip to content

Commit

Permalink
enable detach-netns by upgrading rootlesskit to v2
Browse files Browse the repository at this point in the history
Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>
  • Loading branch information
fahedouch committed Sep 28, 2023
1 parent 1f92536 commit 42adb17
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 5 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ jobs:
- ubuntu: 22.04
containerd: v1.7.3
target: test-integration-rootless
- ubuntu: 22.04
containerd: v1.7.3
target: test-integration-rootless
rootlesskit: v2.0.0-alpha.0
- ubuntu: 22.04
containerd: main
target: test-integration-rootless
Expand All @@ -139,6 +143,7 @@ jobs:
env:
UBUNTU_VERSION: "${{ matrix.ubuntu }}"
CONTAINERD_VERSION: "${{ matrix.containerd }}"
ROOTLESSKIT_VERSION: "${{ matrix.rootlesskit }}"
TEST_TARGET: "${{ matrix.target }}"
steps:
- uses: actions/checkout@v4.0.0
Expand All @@ -147,7 +152,7 @@ jobs:
- name: "Register QEMU (tonistiigi/binfmt)"
run: docker run --privileged --rm tonistiigi/binfmt --install all
- name: "Prepare (network driver=slirp4netns, port driver=builtin)"
run: DOCKER_BUILDKIT=1 docker build -t ${TEST_TARGET} --target ${TEST_TARGET} --build-arg UBUNTU_VERSION=${UBUNTU_VERSION} --build-arg CONTAINERD_VERSION=${CONTAINERD_VERSION} .
run: DOCKER_BUILDKIT=1 docker build -t ${TEST_TARGET} --target ${TEST_TARGET} --build-arg UBUNTU_VERSION=${UBUNTU_VERSION} --build-arg CONTAINERD_VERSION=${CONTAINERD_VERSION} --build-arg ROOTLESSKIT_VERSION=${ROOTLESSKIT_VERSION} .
- name: "Test (network driver=slirp4netns, port driver=builtin)"
run: docker run -t --rm --privileged -e WORKAROUND_ISSUE_622=1 ${TEST_TARGET}

Expand Down
6 changes: 6 additions & 0 deletions Dockerfile.d/SHA256SUMS.d/rootlesskit-v2.0.0-alpha.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
74baab4363ff68d060c788605f5bc5979d3c662f0351b033ae874a3a72e6ebce rootlesskit-aarch64.tar.gz
630dce1a26263d6a7a9461656f3e004c63386b7d4ca71fdaaa37cd075e0f677c rootlesskit-armv7l.tar.gz
4377eb874bb202b7a00354b0924898de81d818753ac730cee8d16262eadd5617 rootlesskit-ppc64le.tar.gz
92861409fa4db5e8344a1b5409ea4e5cb47fa7db706b4647ff627e15bc806ffc rootlesskit-riscv64.tar.gz
5ea02fba90e5656660aa7eca66aece2b5c3207e01d147495da2f55cfb4726663 rootlesskit-s390x.tar.gz
3db2ac3022efc7d030f48fb60a0d568e9dcf8700bb3e0c926e02a4b080caa629 rootlesskit-x86_64.tar.gz
12 changes: 12 additions & 0 deletions extras/rootless/containerd-rootless.sh
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ if [ -z $_CONTAINERD_ROOTLESS_CHILD ]; then
export _CONTAINERD_ROOTLESS_SELINUX
fi
fi

detachNetns=
if command -v rootlesskit >/dev/null 2>&1; then
# If --detach-netns is present in --help, rootlesskit is >= v2.0.0.
if rootlesskit --help | grep -qw -- --detach-netns; then
detachNetns="--detach-netns"
else
echo "rootlesskit found but seems older than v2.0.0. Network namespace will kept attached."
fi
fi

# Re-exec the script via RootlessKit, so as to create unprivileged {user,mount,network} namespaces.
#
# --copy-up allows removing/creating files in the directories by creating tmpfs and symlinks
Expand All @@ -116,6 +127,7 @@ if [ -z $_CONTAINERD_ROOTLESS_CHILD ]; then
# * /run: copy-up is required so that we can create /run/containerd (hardcoded) in our namespace
# * /var/lib: copy-up is required so that we can create /var/lib/containerd in our namespace
exec rootlesskit \
$detachNetns \
--state-dir=$CONTAINERD_ROOTLESS_ROOTLESSKIT_STATE_DIR \
--net=$net --mtu=$mtu \
--slirp4netns-sandbox=$CONTAINERD_ROOTLESS_ROOTLESSKIT_SLIRP4NETNS_SANDBOX \
Expand Down
20 changes: 20 additions & 0 deletions pkg/infoutil/infoutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,26 @@ func parseRuncVersion(runcVersionStdout []byte) (*dockercompat.ComponentVersion,
}, nil
}

func DetectBinaryFeature(binary, feature string) (bool, error) {
if binary == "" {
return false, fmt.Errorf("got empty %s binary", binary)
}
realBinary, err := exec.LookPath(binary)
if err != nil {
return false, fmt.Errorf("binary %q is not installed: %w", binary, err)
}
cmd := exec.Command(realBinary, "--help")
cmd.Env = os.Environ()
b, err := cmd.CombinedOutput()
if err != nil {
return false, fmt.Errorf("command \"%s --help\" failed, --help is not supported: %w", realBinary, err)
}
if !strings.Contains(string(b), feature) {
return false, nil
}
return true, nil
}

// BlockIOWeight return whether Block IO weight is supported or not
func BlockIOWeight(cgroupManager string) bool {
var info dockercompat.Info
Expand Down
26 changes: 22 additions & 4 deletions pkg/ocihook/ocihook.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,18 @@ import (
gocni "github.com/containerd/go-cni"
"github.com/containerd/nerdctl/pkg/bypass4netnsutil"
"github.com/containerd/nerdctl/pkg/dnsutil/hostsstore"
"github.com/containerd/nerdctl/pkg/infoutil"
"github.com/containerd/nerdctl/pkg/labels"
"github.com/containerd/nerdctl/pkg/namestore"
"github.com/containerd/nerdctl/pkg/netutil"
"github.com/containerd/nerdctl/pkg/netutil/nettype"
"github.com/containerd/nerdctl/pkg/rootlessutil"
types100 "github.com/containernetworking/cni/pkg/types/100"
"github.com/opencontainers/runtime-spec/specs-go"

b4nndclient "github.com/rootless-containers/bypass4netns/pkg/api/daemon/client"
rlkclient "github.com/rootless-containers/rootlesskit/pkg/api/client"
"github.com/sirupsen/logrus"
"github.com/vishvananda/netns"
)

const (
Expand Down Expand Up @@ -86,6 +87,24 @@ func Run(stdin io.Reader, stderr io.Writer, event, dataStore, cniPath, cniNetcon
return err
}

detachNetNs, err := infoutil.DetectBinaryFeature("rootlesskit", "--detach-netns")
if err != nil {
return err
}
if rootlessutil.IsRootlessChild() && detachNetNs {
stateDir, err := rootlessutil.RootlessKitStateDir()
if err != nil {
return err
}
ns, err := netns.GetFromPath(filepath.Join(stateDir, "netns"))
if err != nil {
return err
}
if err = netns.Set(ns); err != nil {
return fmt.Errorf("switch to detached netns: %w", err)
}
}

switch event {
case "createRuntime":
return onCreateRuntime(opts)
Expand Down Expand Up @@ -268,16 +287,15 @@ func getExtraHosts(state *specs.State) (map[string]string, error) {

func getNetNSPath(state *specs.State) (string, error) {
// If we have a network-namespace annotation we use it over the passed Pid.
netNsPath, netNsFound := state.Annotations[NetworkNamespace]
if netNsFound {
if netNsPath, netNsFound := state.Annotations[NetworkNamespace]; netNsFound {
if _, err := os.Stat(netNsPath); err != nil {
return "", err
}

return netNsPath, nil
}

if state.Pid == 0 && !netNsFound {
if state.Pid == 0 {
return "", errors.New("both state.Pid and the netNs annotation are unset")
}

Expand Down
1 change: 1 addition & 0 deletions pkg/rootlessutil/parent_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func ParentMain(hostGatewayIP string) error {
if err != nil {
return err
}

// args are compatible with both util-linux nsenter and busybox nsenter
args := []string{
"-r/", // root dir (busybox nsenter wants this to be explicitly specified),
Expand Down

0 comments on commit 42adb17

Please sign in to comment.