Add containerd & gVisor support

This adds containerd, CNI, gVisor and all the necessary shims
and supporting infrastructure. It also enables all relevant features in
the Linux kernel. containerd is designed as a simple supervisor.Runnable.
It is not being started yet, this will happen in D497.

Split out from feature/kubelet.

Test Plan:
Has been tested in conjunction with the rest of D497, will be
covered by a K8s E2E test there.

X-Origin-Diff: phab/D509
GitOrigin-RevId: 92523516b7e361a30da330eb187787e6045bfd17
diff --git a/core/cmd/init/switchroot.go b/core/cmd/init/switchroot.go
index 0e68b06..d51b1fa 100644
--- a/core/cmd/init/switchroot.go
+++ b/core/cmd/init/switchroot.go
@@ -19,6 +19,7 @@
 import (
 	"fmt"
 	"io"
+	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -154,6 +155,40 @@
 		}
 	}
 
+	// Mount all available CGroups for v1 (v2 uses a single unified hierarchy and is not supported by our runtimes yet)
+	if unix.Mount("tmpfs", "/mnt/sys/fs/cgroup", "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
+		panic(err)
+	}
+	cgroupsRaw, err := ioutil.ReadFile("/mnt/proc/cgroups")
+	if err != nil {
+		panic(err)
+	}
+
+	cgroupLines := strings.Split(string(cgroupsRaw), "\n")
+	for _, cgroupLine := range cgroupLines {
+		if cgroupLine == "" || strings.HasPrefix(cgroupLine, "#") {
+			continue
+		}
+		cgroupParts := strings.Split(cgroupLine, "\t")
+		cgroupName := cgroupParts[0]
+		if err := os.Mkdir("/mnt/sys/fs/cgroup/"+cgroupName, 0755); err != nil {
+			panic(err)
+		}
+		if err := unix.Mount("cgroup", "/mnt/sys/fs/cgroup/"+cgroupName, "cgroup", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, cgroupName); err != nil {
+			panic(err)
+		}
+	}
+
+	// Enable hierarchical memory accounting
+	useMemoryHierarchy, err := os.OpenFile("/mnt/sys/fs/cgroup/memory/memory.use_hierarchy", os.O_RDWR, 0)
+	if err != nil {
+		panic(err)
+	}
+	if _, err := useMemoryHierarchy.WriteString("1"); err != nil {
+		panic(err)
+	}
+	useMemoryHierarchy.Close()
+
 	// Chroot to new root.
 	// This is adapted from util-linux's switch_root.
 	err = os.Chdir("/mnt")