func (cmd *GuardianCommand) wireContainerizer(log lager.Logger, depotPath, dadooPath, runcPath, nstarPath, tarPath, defaultRootFSPath, appArmorProfile string, properties gardener.PropertyManager) *rundmc.Containerizer { depot := depot.New(depotPath) commandRunner := linux_command_runner.New() chrootMkdir := bundlerules.ChrootMkdir{ Command: preparerootfs.Command, CommandRunner: commandRunner, } pidFileReader := &dadoo.PidFileReader{ Clock: clock.NewClock(), Timeout: 10 * time.Second, SleepInterval: time.Millisecond * 100, } runcrunner := runrunc.New( commandRunner, runrunc.NewLogRunner(commandRunner, runrunc.LogDir(os.TempDir()).GenerateLogFile), goci.RuncBinary(runcPath), dadooPath, runcPath, runrunc.NewExecPreparer(&goci.BndlLoader{}, runrunc.LookupFunc(runrunc.LookupUser), chrootMkdir, NonRootMaxCaps), dadoo.NewExecRunner( dadooPath, runcPath, cmd.wireUidGenerator(), pidFileReader, linux_command_runner.New()), ) mounts := []specs.Mount{ {Type: "sysfs", Source: "sysfs", Destination: "/sys", Options: []string{"nosuid", "noexec", "nodev", "ro"}}, {Type: "tmpfs", Source: "tmpfs", Destination: "/dev/shm"}, {Type: "devpts", Source: "devpts", Destination: "/dev/pts", Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"}}, {Type: "bind", Source: cmd.Bin.Init.Path(), Destination: "/tmp/garden-init", Options: []string{"bind"}}, } privilegedMounts := append(mounts, specs.Mount{Type: "proc", Source: "proc", Destination: "/proc", Options: []string{"nosuid", "noexec", "nodev"}}, ) unprivilegedMounts := append(mounts, specs.Mount{Type: "proc", Source: "proc", Destination: "/proc", Options: []string{"nosuid", "noexec", "nodev"}}, ) rwm := "rwm" character := "c" var majorMinor = func(i int64) *int64 { return &i } var worldReadWrite os.FileMode = 0666 fuseDevice := specs.LinuxDevice{ Path: "/dev/fuse", Type: "c", Major: 10, Minor: 229, FileMode: &worldReadWrite, } denyAll := specs.LinuxDeviceCgroup{Allow: false, Access: &rwm} allowedDevices := []specs.LinuxDeviceCgroup{ {Access: &rwm, Type: &character, Major: majorMinor(1), Minor: majorMinor(3), Allow: true}, {Access: &rwm, Type: &character, Major: majorMinor(5), Minor: majorMinor(0), Allow: true}, {Access: &rwm, Type: &character, Major: majorMinor(1), Minor: majorMinor(8), Allow: true}, {Access: &rwm, Type: &character, Major: majorMinor(1), Minor: majorMinor(9), Allow: true}, {Access: &rwm, Type: &character, Major: majorMinor(1), Minor: majorMinor(5), Allow: true}, {Access: &rwm, Type: &character, Major: majorMinor(1), Minor: majorMinor(7), Allow: true}, {Access: &rwm, Type: &character, Major: majorMinor(1), Minor: majorMinor(7), Allow: true}, {Access: &rwm, Type: &character, Major: majorMinor(fuseDevice.Major), Minor: majorMinor(fuseDevice.Minor), Allow: true}, } baseProcess := specs.Process{ Capabilities: UnprivilegedMaxCaps, Args: []string{"/tmp/garden-init"}, Cwd: "/", } baseBundle := goci.Bundle(). WithNamespaces(PrivilegedContainerNamespaces...). WithResources(&specs.LinuxResources{Devices: append([]specs.LinuxDeviceCgroup{denyAll}, allowedDevices...)}). WithRootFS(defaultRootFSPath). WithDevices(fuseDevice). WithProcess(baseProcess) unprivilegedBundle := baseBundle. WithNamespace(goci.UserNamespace). WithUIDMappings(idMappings...). WithGIDMappings(idMappings...). WithMounts(unprivilegedMounts...). WithMaskedPaths(defaultMaskedPaths()) unprivilegedBundle.Spec.Linux.Seccomp = seccomp if appArmorProfile != "" { unprivilegedBundle.Spec.Process.ApparmorProfile = appArmorProfile } privilegedBundle := baseBundle. WithMounts(privilegedMounts...). WithCapabilities(PrivilegedMaxCaps...) template := &rundmc.BundleTemplate{ Rules: []rundmc.BundlerRule{ bundlerules.Base{ PrivilegedBase: privilegedBundle, UnprivilegedBase: unprivilegedBundle, }, bundlerules.RootFS{ ContainerRootUID: idMappings.Map(0), ContainerRootGID: idMappings.Map(0), MkdirChown: chrootMkdir, }, bundlerules.Limits{}, bundlerules.BindMounts{}, bundlerules.Env{}, bundlerules.Hostname{}, }, } log.Info("base-bundles", lager.Data{ "privileged": privilegedBundle, "unprivileged": unprivilegedBundle, }) eventStore := rundmc.NewEventStore(properties) stateStore := rundmc.NewStateStore(properties) nstar := rundmc.NewNstarRunner(nstarPath, tarPath, linux_command_runner.New()) stopper := stopper.New(stopper.NewRuncStateCgroupPathResolver("/run/runc"), nil, retrier.New(retrier.ConstantBackoff(10, 1*time.Second), nil)) return rundmc.New(depot, template, runcrunner, &goci.BndlLoader{}, nstar, stopper, eventStore, stateStore) }
users = new(fakes.FakeUserLookupper) mkdirer = new(fakes.FakeMkdirer) var err error bundlePath, err = ioutil.TempDir("", "bundle") Expect(err).NotTo(HaveOccurred()) bundleLoader.LoadStub = func(path string) (goci.Bndl, error) { bndl := goci.Bundle() return bndl, nil } users.LookupReturns(&user.ExecUser{}, nil) Expect(ioutil.WriteFile(filepath.Join(bundlePath, "pidfile"), []byte("999"), 0644)).To(Succeed()) preparer = runrunc.NewExecPreparer(bundleLoader, users, mkdirer, []string{"foo", "bar", "brains"}) }) It("passes a process.json with the correct path and args", func() { spec, err := preparer.Prepare(logger, bundlePath, garden.ProcessSpec{Path: "to enlightenment", Args: []string{"infinity", "and beyond"}}) Expect(err).NotTo(HaveOccurred()) Expect(spec.Args).To(Equal([]string{"to enlightenment", "infinity", "and beyond"})) }) It("returns the HostUID and HostGID in the returned spec", func() { users.LookupReturns(&user.ExecUser{Uid: 234, Gid: 567}, nil) spec, err := preparer.Prepare(logger, bundlePath, garden.ProcessSpec{Path: "to enlightenment", Args: []string{}}) Expect(err).NotTo(HaveOccurred())