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) }
devicesCgroupPath = filepath.Join(fakeCgroupDir, "foo", "devices") Expect(os.MkdirAll(devicesCgroupPath, 0700)).To(Succeed()) Expect(ioutil.WriteFile(filepath.Join(devicesCgroupPath, "cgroup.procs"), []byte(`1 3 5 9`), 0700)).To(Succeed()) fakeCgroupResolver.ResolveStub = func(name string, subsystem string) (string, error) { return filepath.Join(fakeCgroupDir, name, subsystem), nil } fakeRetrier.RunStub = func(fn func() error) error { return fn() } subject = stopper.New(fakeCgroupResolver, fakeKiller, fakeRetrier) }) AfterEach(func() { os.RemoveAll(fakeCgroupDir) }) It("does not send any signal to processes in the exceptions list", func() { Expect(subject.StopAll(lagertest.NewTestLogger("test"), "foo", []int{3, 5}, false)).To(Succeed()) Expect(fakeKiller).To(HaveKilled(0, syscall.SIGTERM, 1, 9)) Expect(fakeKiller).To(HaveKilled(1, syscall.SIGKILL, 1, 9)) }) Context("when the kill flag is true", func() { It("sends a KILL to all processes found in the cgroup", func() { Expect(subject.StopAll(lagertest.NewTestLogger("test"), "foo", nil, true)).To(Succeed())