|
@@ -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)
|
|
|
|
- }
|
|
|
|
-}
|
|
|