waiter = &fake_waiter.FakeWaiter{} cz = &containerizer.Containerizer{ RootfsPath: "", ContainerInitializer: initializer, Signaller: signaller, Waiter: waiter, } }) AfterEach(func() { Expect(os.Chdir(workingDirectory)).To(Succeed()) }) It("initializes the container", func() { Expect(cz.Init()).To(Succeed()) Expect(initializer.InitCallCount()).To(Equal(1)) }) Context("when container initialization fails", func() { BeforeEach(func() { initializer.InitReturns(errors.New("Bing")) }) It("returns an error", func() { err := cz.Init() Expect(err).To(MatchError("containerizer: initializing the container: Bing")) }) }) }) })
// initc initializes a newly created container and then execs to become // the init process func main() { if reexec.Init() { return } defer func() { if r := recover(); r != nil { fmt.Fprintf(os.Stderr, "initc: panicked: %s\n", r) os.Exit(4) } }() rootFsPath := flag.String("root", "", "Path for the root file system directory") configFilePath := flag.String("config", "./etc/config", "Path for the configuration file") title := flag.String("title", "", "") cf_lager.AddFlags(flag.CommandLine) flag.Parse() if *rootFsPath == "" { missing("--root") } syncReader := os.NewFile(uintptr(3), "/dev/a") defer syncReader.Close() syncWriter := os.NewFile(uintptr(4), "/dev/d") defer syncWriter.Close() sync := &containerizer.PipeSynchronizer{ Reader: syncReader, Writer: syncWriter, } if err := sync.Wait(2 * time.Minute); err != nil { fail(fmt.Sprintf("initc: wait for host: %s", err), 8) } env, err := process.EnvFromFile(*configFilePath) if err != nil { fmt.Fprintf(os.Stderr, "initc: failed to get env from config file: %s\n", err) os.Exit(3) } dropCapabilities := env["root_uid"] != "0" procMountFlags := syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_NOEXEC sysMountFlags := syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_NOEXEC | syscall.MS_RDONLY if dropCapabilities { procMountFlags = procMountFlags | syscall.MS_RDONLY } initializer := &system.Initializer{ Steps: []system.StepRunner{ &containerizer.FuncStep{system.Mount{ Type: system.Tmpfs, Flags: syscall.MS_NODEV, TargetPath: "/dev/shm", }.Mount}, &containerizer.FuncStep{system.Mount{ Type: system.Proc, Flags: procMountFlags, TargetPath: "/proc", }.Mount}, &containerizer.FuncStep{system.Mount{ Type: system.Sys, Flags: sysMountFlags, TargetPath: "/sys", }.Mount}, &containerizer.FuncStep{system.Mount{ Type: system.Devpts, TargetPath: "/dev/pts", Data: "newinstance,ptmxmode=0666", }.Mount}, &containerizer.FuncStep{system.Unmount{ Dir: "/tmp/garden-host", }.Unmount}, &containerizer.FuncStep{func() error { return setupNetwork(env) }}, &containerizer.CapabilitiesStep{ Drop: dropCapabilities, Capabilities: &sys.ProcessCapabilities{Pid: os.Getpid()}, }, }, } containerizer := containerizer.Containerizer{ RootfsPath: *rootFsPath, ContainerInitializer: initializer, Waiter: sync, Signaller: sync, } if err := containerizer.Init(); err != nil { fail(fmt.Sprintf("failed to init containerizer: %s", err), 2) } syscall.RawSyscall(syscall.SYS_FCNTL, uintptr(4), syscall.F_SETFD, 0) syscall.RawSyscall(syscall.SYS_FCNTL, uintptr(5), syscall.F_SETFD, 0) if err := syscall.Exec("/proc/self/exe", []string{"initd", fmt.Sprintf("-dropCapabilities=%t", dropCapabilities), fmt.Sprintf("-title=\"%s\"", *title)}, os.Environ()); err != nil { fail(fmt.Sprintf("failed to reexec: %s", err), 3) } }