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"))
			})
		})
	})
})
Esempio n. 2
0
// 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)
	}
}