pkg/libcontainer/cli/main.go

204 lines
4.3 KiB
Go
Raw Normal View History

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