WIP moving to nsini
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
parent
c98df9e60a
commit
d2612d7018
78
cli/main.go
78
cli/main.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dotcloud/docker/pkg/libcontainer"
|
"github.com/dotcloud/docker/pkg/libcontainer"
|
||||||
"github.com/dotcloud/docker/pkg/libcontainer/namespaces"
|
"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/network"
|
||||||
"github.com/dotcloud/docker/pkg/libcontainer/utils"
|
"github.com/dotcloud/docker/pkg/libcontainer/utils"
|
||||||
"os"
|
"os"
|
||||||
|
@ -15,15 +16,26 @@ var (
|
||||||
displayPid bool
|
displayPid bool
|
||||||
newCommand string
|
newCommand string
|
||||||
usrNet bool
|
usrNet bool
|
||||||
|
masterFd int
|
||||||
|
console string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.BoolVar(&displayPid, "pid", false, "display the pid before waiting")
|
flag.BoolVar(&displayPid, "pid", false, "display the pid before waiting")
|
||||||
flag.StringVar(&newCommand, "cmd", "/bin/bash", "command to run in the existing namespace")
|
flag.StringVar(&newCommand, "cmd", "/bin/bash", "command to run in the existing namespace")
|
||||||
flag.BoolVar(&usrNet, "net", false, "user a net 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()
|
flag.Parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func nsinitFunc(container *libcontainer.Container) error {
|
||||||
|
container.Master = uintptr(masterFd)
|
||||||
|
container.Console = console
|
||||||
|
|
||||||
|
return nsinit.InitNamespace(container)
|
||||||
|
}
|
||||||
|
|
||||||
func exec(container *libcontainer.Container) error {
|
func exec(container *libcontainer.Container) error {
|
||||||
var (
|
var (
|
||||||
netFile *os.File
|
netFile *os.File
|
||||||
|
@ -39,7 +51,7 @@ func exec(container *libcontainer.Container) error {
|
||||||
container.NetNsFd = netFile.Fd()
|
container.NetNsFd = netFile.Fd()
|
||||||
}
|
}
|
||||||
|
|
||||||
pid, err := namespaces.Exec(container)
|
pid, err := namespaces.ExecContainer(container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error exec container %s", err)
|
return fmt.Errorf("error exec container %s", err)
|
||||||
}
|
}
|
||||||
|
@ -87,39 +99,39 @@ func execIn(container *libcontainer.Container) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNet(config *libcontainer.Network) error {
|
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 {
|
root := "/root/nsroot"
|
||||||
|
if err := network.SetupNamespaceMountDir(root); err != nil {
|
||||||
return err
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -133,7 +145,7 @@ func main() {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
cliCmd = flag.Arg(0)
|
cliCmd = flag.Arg(0)
|
||||||
config = flag.Arg(1)
|
config = "/root/development/gocode/src/github.com/dotcloud/docker/pkg/libcontainer/container.json" //flag.Arg(1)
|
||||||
)
|
)
|
||||||
f, err := os.Open(config)
|
f, err := os.Open(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -149,6 +161,8 @@ func main() {
|
||||||
f.Close()
|
f.Close()
|
||||||
|
|
||||||
switch cliCmd {
|
switch cliCmd {
|
||||||
|
case "init":
|
||||||
|
err = nsinitFunc(container)
|
||||||
case "exec":
|
case "exec":
|
||||||
err = exec(container)
|
err = exec(container)
|
||||||
case "execin":
|
case "execin":
|
||||||
|
|
|
@ -12,6 +12,8 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,16 +39,15 @@ func ExecContainer(container *libcontainer.Container) (pid int, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
container.Console = console
|
nsinit := filepath.Join(container.RootFs, ".nsinit")
|
||||||
container.Master = master.Fd()
|
|
||||||
|
|
||||||
// we need CLONE_VFORK so we can wait on the child
|
// we need CLONE_VFORK so we can wait on the child
|
||||||
flag := uintptr(getNamespaceFlags(container.Namespaces) | CLONE_VFORK)
|
flag := uintptr(getNamespaceFlags(container.Namespaces) | CLONE_VFORK)
|
||||||
|
|
||||||
command := exec.Command("/.nsinit")
|
command := exec.Command(nsinit, "init", "-master", strconv.Itoa(int(master.Fd())), "-console", console)
|
||||||
command.SysProcAttr = &syscall.SysProcAttr{}
|
command.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
command.SysProcAttr.Cloneflags = flag
|
command.SysProcAttr.Cloneflags = flag
|
||||||
command.SysProcAttr.Setctty = true
|
// command.SysProcAttr.Setctty = true
|
||||||
|
|
||||||
if err := command.Start(); err != nil {
|
if err := command.Start(); err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
|
@ -63,6 +64,7 @@ func ExecContainer(container *libcontainer.Container) (pid int, err error) {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
command.Wait()
|
||||||
return pid, nil
|
return pid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package network
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dotcloud/docker/pkg/libcontainer"
|
"github.com/dotcloud/docker/pkg/libcontainer"
|
||||||
"github.com/dotcloud/docker/pkg/libcontainer/namespaces"
|
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
@ -59,21 +58,6 @@ func SetupNamespaceMountDir(root string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateNetworkNamespace creates a new network namespace and binds it's fd
|
|
||||||
// at the binding path
|
|
||||||
func CreateNetworkNamespace(bindingPath string) error {
|
|
||||||
f, err := os.OpenFile(bindingPath, os.O_RDONLY|os.O_CREATE|os.O_EXCL, 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
|
|
||||||
if err := namespaces.CreateNewNamespace(libcontainer.CLONE_NEWNET, bindingPath); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteNetworkNamespace unmounts the binding path and removes the
|
// DeleteNetworkNamespace unmounts the binding path and removes the
|
||||||
// file so that no references to the fd are present and the network
|
// file so that no references to the fd are present and the network
|
||||||
// namespace is automatically cleaned up
|
// namespace is automatically cleaned up
|
||||||
|
|
Loading…
Reference in New Issue