Beispiel #1
0
func main() {
	libPath := flag.String("lib", "./lib", "Directory containing hooks")
	rootFsPath := flag.String("root", "", "Directory that will become root in the new mount namespace")
	runPath := flag.String("run", "./run", "Directory where server socket is placed")
	userNsFlag := flag.String("userns", "enabled", "If specified, use user namespacing")
	title := flag.String("title", "", "")
	flag.Parse()

	if *rootFsPath == "" {
		missing("--root")
	}

	binPath, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: obtain absolute path: %s", err)
		os.Exit(6)
	}

	socketPath := path.Join(*runPath, "wshd.sock")

	privileged := false
	if *userNsFlag == "" || *userNsFlag == "disabled" {
		privileged = true
	}

	containerReader, hostWriter, err := os.Pipe()
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: create pipe: %s", err)
		os.Exit(5)
	}

	hostReader, containerWriter, err := os.Pipe()
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: create pipe: %s", err)
		os.Exit(4)
	}

	sync := &containerizer.PipeSynchronizer{
		Reader: hostReader,
		Writer: hostWriter,
	}

	listener, err := unix_socket.NewListenerFromPath(socketPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: create listener: %s", err)
		os.Exit(8)
	}

	socketFile, err := listener.File()
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: obtain listener file: %s", err)
		os.Exit(9)
	}

	beforeCloneInitializer := &system.Initializer{Steps: []system.StepRunner{
		&containerizer.FuncStep{
			(&container_daemon.RlimitsManager{}).Init,
		},
	}}

	maxUID := sysinfo.Min(sysinfo.MustGetMaxValidUID(), sysinfo.MustGetMaxValidGID())
	cz := containerizer.Containerizer{
		BeforeCloneInitializer: beforeCloneInitializer,
		InitBinPath:            path.Join(binPath, "initc"),
		InitArgs: []string{
			"--root", *rootFsPath,
			"--config", path.Join(*libPath, "../etc/config"),
			"--title", *title,
		},
		Execer: &system.NamespacingExecer{
			CommandRunner: linux_command_runner.New(),
			ExtraFiles:    []*os.File{containerReader, containerWriter, socketFile},
			Privileged:    privileged,
			MaxUID:        maxUID,
		},
		Signaller: sync,
		Waiter:    sync,
		// Temporary until we merge the hook scripts functionality in Golang
		CommandRunner: linux_command_runner.New(),
		LibPath:       *libPath,
		RootfsPath:    *rootFsPath,
	}

	err = cz.Create()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create container: %s", err)
		os.Exit(2)
	}
}
	"github.com/cloudfoundry-incubator/garden-linux/containerizer"
	"github.com/cloudfoundry-incubator/garden-linux/containerizer/fake_container_execer"
	"github.com/cloudfoundry-incubator/garden-linux/containerizer/fake_initializer"
	"github.com/cloudfoundry-incubator/garden-linux/containerizer/fake_signaller"
	"github.com/cloudfoundry-incubator/garden-linux/containerizer/fake_waiter"
	"github.com/cloudfoundry-incubator/garden-linux/hook"
	. "github.com/cloudfoundry/gunk/command_runner/fake_command_runner"
	. "github.com/cloudfoundry/gunk/command_runner/fake_command_runner/matchers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Containerizer", func() {
	Describe("Create", func() {
		var cz *containerizer.Containerizer
		var containerExecer *fake_container_execer.FakeContainerExecer
		var signaller *fake_signaller.FakeSignaller
		var waiter *fake_waiter.FakeWaiter
		var hookCommandRunner *FakeCommandRunner
		var beforeCloneInitializer *fake_initializer.FakeInitializer

		BeforeEach(func() {
			containerExecer = &fake_container_execer.FakeContainerExecer{}
			signaller = &fake_signaller.FakeSignaller{}
			waiter = &fake_waiter.FakeWaiter{}
			hookCommandRunner = &FakeCommandRunner{}
			beforeCloneInitializer = &fake_initializer.FakeInitializer{}

			cz = &containerizer.Containerizer{
				BeforeCloneInitializer: beforeCloneInitializer,
Beispiel #3
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)
	}
}