ソースを参照

Simplify namespaces with only nsinit
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)

Michael Crosby 11 年 前
コミット
7bc3c01250

+ 0 - 203
pkg/libcontainer/cli/main.go

@@ -1,203 +0,0 @@
-package main
-
-import (
-	"encoding/json"
-	"flag"
-	"fmt"
-	"github.com/dotcloud/docker/pkg/libcontainer"
-	"github.com/dotcloud/docker/pkg/libcontainer/namespaces"
-	"github.com/dotcloud/docker/pkg/libcontainer/namespaces/nsinit"
-	"github.com/dotcloud/docker/pkg/libcontainer/network"
-	"github.com/dotcloud/docker/pkg/libcontainer/utils"
-	"os"
-	exec_ "os/exec"
-	"path"
-	"path/filepath"
-)
-
-var (
-	displayPid bool
-	newCommand string
-	usrNet     bool
-	masterFd   int
-	console    string
-)
-
-func init() {
-	flag.BoolVar(&displayPid, "pid", false, "display the pid before waiting")
-	flag.StringVar(&newCommand, "cmd", "/bin/bash", "command to run in the existing namespace")
-	flag.BoolVar(&usrNet, "net", false, "user a net namespace")
-	flag.IntVar(&masterFd, "master", 0, "master fd")
-	flag.StringVar(&console, "console", "", "console path")
-	flag.Parse()
-}
-
-func nsinitFunc(container *libcontainer.Container) error {
-	container.Master = uintptr(masterFd)
-	container.Console = console
-	container.LogFile = "/root/logs"
-
-	return nsinit.InitNamespace(container)
-}
-
-func exec(container *libcontainer.Container) error {
-	var (
-		netFile *os.File
-		err     error
-	)
-	container.NetNsFd = 0
-
-	if usrNet {
-		netFile, err = os.Open("/root/nsroot/test")
-		if err != nil {
-			return err
-		}
-		container.NetNsFd = netFile.Fd()
-	}
-
-	self, err := exec_.LookPath(os.Args[0])
-	if err != nil {
-		return err
-	}
-	if output, err := exec_.Command("cp", self, path.Join(container.RootFs, ".nsinit")).CombinedOutput(); err != nil {
-		return fmt.Errorf("Error exec cp: %s, (%s)", err, output)
-	} else {
-		println(self, container.RootFs)
-		fmt.Printf("-----> %s\n", output)
-	}
-	println("----")
-
-	pid, err := namespaces.ExecContainer(container)
-	if err != nil {
-		return fmt.Errorf("error exec container %s", err)
-	}
-
-	if displayPid {
-		fmt.Println(pid)
-	}
-
-	exitcode, err := utils.WaitOnPid(pid)
-	if err != nil {
-		return fmt.Errorf("error waiting on child %s", err)
-	}
-	fmt.Println(exitcode)
-	if usrNet {
-		netFile.Close()
-		if err := network.DeleteNetworkNamespace("/root/nsroot/test"); err != nil {
-			return err
-		}
-	}
-	os.Exit(exitcode)
-	return nil
-}
-
-func execIn(container *libcontainer.Container) error {
-	// f, err := os.Open("/root/nsroot/test")
-	// if err != nil {
-	// 	return err
-	// }
-	// container.NetNsFd = f.Fd()
-	// pid, err := namespaces.ExecIn(container, &libcontainer.Command{
-	// 	Env: container.Command.Env,
-	// 	Args: []string{
-	// 		newCommand,
-	// 	},
-	// })
-	// if err != nil {
-	// 	return fmt.Errorf("error exexin container %s", err)
-	// }
-	// exitcode, err := utils.WaitOnPid(pid)
-	// if err != nil {
-	// 	return fmt.Errorf("error waiting on child %s", err)
-	// }
-	// os.Exit(exitcode)
-	return nil
-}
-
-func createNet(config *libcontainer.Network) error {
-	/*
-		root := "/root/nsroot"
-		if err := network.SetupNamespaceMountDir(root); err != nil {
-			return err
-		}
-
-		nspath := root + "/test"
-		if err := network.CreateNetworkNamespace(nspath); err != nil {
-			return nil
-		}
-		if err := network.CreateVethPair("veth0", config.TempVethName); err != nil {
-			return err
-		}
-		if err := network.SetInterfaceMaster("veth0", config.Bridge); err != nil {
-			return err
-		}
-		if err := network.InterfaceUp("veth0"); err != nil {
-			return err
-		}
-
-		f, err := os.Open(nspath)
-		if err != nil {
-			return err
-		}
-		defer f.Close()
-
-		if err := network.SetInterfaceInNamespaceFd("veth1", int(f.Fd())); err != nil {
-			return err
-		}
-
-			if err := network.SetupVethInsideNamespace(f.Fd(), config); err != nil {
-				return err
-			}
-	*/
-	return nil
-}
-
-func printErr(err error) {
-	fmt.Fprintln(os.Stderr, err)
-	os.Exit(1)
-}
-
-func main() {
-	cliCmd := flag.Arg(0)
-
-	config, err := filepath.Abs(flag.Arg(1))
-	if err != nil {
-		printErr(err)
-	}
-	println("cli:", cliCmd, "config:", config)
-	f, err := os.Open(config)
-	if err != nil {
-		printErr(err)
-	}
-
-	dec := json.NewDecoder(f)
-	var container *libcontainer.Container
-
-	if err := dec.Decode(&container); err != nil {
-		printErr(err)
-	}
-	f.Close()
-
-	switch cliCmd {
-	case "init":
-		err = nsinitFunc(container)
-	case "exec":
-		err = exec(container)
-	case "execin":
-		err = execIn(container)
-	case "net":
-		err = createNet(&libcontainer.Network{
-			TempVethName: "veth1",
-			IP:           "172.17.0.100/16",
-			Gateway:      "172.17.42.1",
-			Mtu:          1500,
-			Bridge:       "docker0",
-		})
-	default:
-		err = fmt.Errorf("command not supported: %s", cliCmd)
-	}
-
-	if err != nil {
-		printErr(err)
-	}
-}

+ 0 - 48
pkg/libcontainer/namespaces/utils.go

@@ -1,48 +0,0 @@
-package namespaces
-
-import (
-	"fmt"
-	"github.com/dotcloud/docker/pkg/libcontainer"
-	"os"
-	"path/filepath"
-	"strconv"
-	"strings"
-)
-
-func addEnvIfNotSet(container *libcontainer.Container, key, value string) {
-	jv := fmt.Sprintf("%s=%s", key, value)
-	if len(container.Command.Env) == 0 {
-		container.Command.Env = []string{jv}
-		return
-	}
-
-	for _, v := range container.Command.Env {
-		parts := strings.Split(v, "=")
-		if parts[0] == key {
-			return
-		}
-	}
-	container.Command.Env = append(container.Command.Env, jv)
-}
-
-// getNsFd returns the fd for a specific pid and namespace option
-func getNsFd(pid int, ns string) (uintptr, error) {
-	nspath := filepath.Join("/proc", strconv.Itoa(pid), "ns", ns)
-	// OpenFile adds closOnExec
-	f, err := os.OpenFile(nspath, os.O_RDONLY, 0666)
-	if err != nil {
-		return 0, err
-	}
-	return f.Fd(), nil
-}
-
-// setupEnvironment adds additional environment variables to the container's
-// Command such as USER, LOGNAME, container, and TERM
-func setupEnvironment(container *libcontainer.Container) {
-	addEnvIfNotSet(container, "container", "docker")
-	// TODO: check if pty
-	addEnvIfNotSet(container, "TERM", "xterm")
-	// TODO: get username from container
-	addEnvIfNotSet(container, "USER", "root")
-	addEnvIfNotSet(container, "LOGNAME", "root")
-}

+ 15 - 11
pkg/libcontainer/namespaces/exec.go → pkg/libcontainer/nsinit/exec.go

@@ -1,4 +1,4 @@
-package namespaces
+package main
 
 
 import (
 import (
 	"github.com/dotcloud/docker/pkg/libcontainer"
 	"github.com/dotcloud/docker/pkg/libcontainer"
@@ -11,15 +11,7 @@ import (
 	"syscall"
 	"syscall"
 )
 )
 
 
-// ExecContainer will spawn new namespaces with the specified Container configuration
-// in the RootFs path and return the pid of the new containerized process.
-//
-// If an existing network namespace is specified the container
-// will join that namespace.  If an existing network namespace is not specified but CLONE_NEWNET is,
-// the container will be spawned with a new network namespace with no configuration.  Omiting an
-// existing network namespace and the CLONE_NEWNET option in the container configuration will allow
-// the container to the the host's networking options and configuration.
-func ExecContainer(container *libcontainer.Container) (pid int, err error) {
+func execCommand(container *libcontainer.Container) (pid int, err error) {
 	master, console, err := createMasterAndConsole()
 	master, console, err := createMasterAndConsole()
 	if err != nil {
 	if err != nil {
 		return -1, err
 		return -1, err
@@ -50,7 +42,19 @@ func ExecContainer(container *libcontainer.Container) (pid int, err error) {
 		}
 		}
 	}()
 	}()
 
 
-	term.SetRawTerminal(os.Stdin.Fd())
+	ws, err := term.GetWinsize(os.Stdin.Fd())
+	if err != nil {
+		return -1, err
+	}
+	if err := term.SetWinsize(master.Fd(), ws); err != nil {
+		return -1, err
+	}
+	state, err := term.SetRawTerminal(os.Stdin.Fd())
+	if err != nil {
+		command.Process.Kill()
+		return -1, err
+	}
+	defer term.RestoreTerminal(os.Stdin.Fd(), state)
 
 
 	if err := command.Wait(); err != nil {
 	if err := command.Wait(); err != nil {
 		return pid, err
 		return pid, err

+ 7 - 6
pkg/libcontainer/namespaces/nsinit/init.go → pkg/libcontainer/nsinit/init.go

@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"fmt"
 	"github.com/dotcloud/docker/pkg/libcontainer"
 	"github.com/dotcloud/docker/pkg/libcontainer"
 	"github.com/dotcloud/docker/pkg/libcontainer/capabilities"
 	"github.com/dotcloud/docker/pkg/libcontainer/capabilities"
-	"github.com/dotcloud/docker/pkg/libcontainer/namespaces"
 	"github.com/dotcloud/docker/pkg/system"
 	"github.com/dotcloud/docker/pkg/system"
 	"log"
 	"log"
 	"os"
 	"os"
@@ -34,7 +33,7 @@ func main() {
 	}
 	}
 
 
 	if os.Args[1] == "exec" {
 	if os.Args[1] == "exec" {
-		_, err := namespaces.ExecContainer(container)
+		_, err := execCommand(container)
 		if err != nil {
 		if err != nil {
 			log.Fatal(err)
 			log.Fatal(err)
 		}
 		}
@@ -157,11 +156,13 @@ func openTerminal(name string, flag int) (*os.File, error) {
 }
 }
 
 
 func setLogFile(container *libcontainer.Container) error {
 func setLogFile(container *libcontainer.Container) error {
-	f, err := os.OpenFile(container.LogFile, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0655)
-	if err != nil {
-		return err
+	if container.LogFile != "" {
+		f, err := os.OpenFile(container.LogFile, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0655)
+		if err != nil {
+			return err
+		}
+		log.SetOutput(f)
 	}
 	}
-	log.SetOutput(f)
 	return nil
 	return nil
 }
 }
 
 

+ 0 - 0
pkg/libcontainer/namespaces/nsinit/mount.go → pkg/libcontainer/nsinit/mount.go


+ 1 - 10
pkg/libcontainer/namespaces/ns_linux.go → pkg/libcontainer/nsinit/ns_linux.go

@@ -1,4 +1,4 @@
-package namespaces
+package main
 
 
 import (
 import (
 	"github.com/dotcloud/docker/pkg/libcontainer"
 	"github.com/dotcloud/docker/pkg/libcontainer"
@@ -25,15 +25,6 @@ var namespaceMap = map[libcontainer.Namespace]int{
 	libcontainer.CLONE_NEWNET:  CLONE_NEWNET,
 	libcontainer.CLONE_NEWNET:  CLONE_NEWNET,
 }
 }
 
 
-var namespaceFileMap = map[libcontainer.Namespace]string{
-	libcontainer.CLONE_NEWNS:   "mnt",
-	libcontainer.CLONE_NEWUTS:  "uts",
-	libcontainer.CLONE_NEWIPC:  "ipc",
-	libcontainer.CLONE_NEWUSER: "user",
-	libcontainer.CLONE_NEWPID:  "pid",
-	libcontainer.CLONE_NEWNET:  "net",
-}
-
 // getNamespaceFlags parses the container's Namespaces options to set the correct
 // getNamespaceFlags parses the container's Namespaces options to set the correct
 // flags on clone, unshare, and setns
 // flags on clone, unshare, and setns
 func getNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
 func getNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {