pkg/libcontainer/cli/main.go
Michael Crosby 81d2c67492 Initial commit of libcontainer
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
2014-02-21 14:56:15 -08:00

171 lines
3.3 KiB
Go

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/network"
"github.com/dotcloud/docker/pkg/libcontainer/utils"
"os"
)
var (
displayPid bool
newCommand string
usrNet bool
)
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.Parse()
}
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()
}
pid, err := namespaces.Exec(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() {
var (
err error
cliCmd = flag.Arg(0)
config = flag.Arg(1)
)
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 "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)
}
}