1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Refactor to remove cmd from container

Pass the container's command via args
Remove execin function and just look for an
existing nspid file to join the namespace
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-02-19 20:35:04 -08:00
parent 420b5eb211
commit d84feb8fe5
6 changed files with 55 additions and 55 deletions

View file

@ -5,17 +5,12 @@ type Container struct {
ReadonlyFs bool `json:"readonly_fs,omitempty"`
User string `json:"user,omitempty"`
WorkingDir string `json:"working_dir,omitempty"`
Command *Command `json:"command,omitempty"`
Env []string `json:"environment,omitempty"`
Namespaces Namespaces `json:"namespaces,omitempty"`
Capabilities Capabilities `json:"capabilities,omitempty"`
Network *Network `json:"network,omitempty"`
}
type Command struct {
Args []string `json:"args,omitempty"`
Env []string `json:"environment,omitempty"`
}
type Network struct {
IP string `json:"ip,omitempty"`
Gateway string `json:"gateway,omitempty"`

View file

@ -1,16 +1,11 @@
{
"hostname": "koye",
"command": {
"args": [
"/bin/bash"
],
"environment": [
"HOME=/",
"PATH=PATH=$PATH:/bin:/usr/bin:/sbin:/usr/sbin",
"container=docker",
"TERM=xterm-256color"
]
},
],
"namespaces": [
"NEWIPC",
"NEWNS",

View file

@ -16,17 +16,13 @@ import (
"syscall"
)
func execCommand(container *libcontainer.Container) (int, error) {
func execCommand(container *libcontainer.Container, args []string) (int, error) {
master, console, err := createMasterAndConsole()
if err != nil {
return -1, err
}
command := exec.Command("nsinit", "init", console)
command.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: uintptr(getNamespaceFlags(container.Namespaces) | syscall.CLONE_VFORK), // we need CLONE_VFORK so we can wait on the child
}
command := createCommand(container, console, args)
// create a pipe so that we can syncronize with the namespaced process and
// pass the veth name to the child
inPipe, err := command.StdinPipe()
@ -39,6 +35,7 @@ func execCommand(container *libcontainer.Container) (int, error) {
if err := writePidFile(command); err != nil {
return -1, err
}
defer deletePidFile()
if container.Network != nil {
vethPair, err := setupVeth(container.Network.Bridge, command.Process.Pid)
@ -134,3 +131,15 @@ func createVethPair() (name1 string, name2 string, err error) {
func writePidFile(command *exec.Cmd) error {
return ioutil.WriteFile(".nspid", []byte(fmt.Sprint(command.Process.Pid)), 0655)
}
func deletePidFile() error {
return os.Remove(".nspid")
}
func createCommand(container *libcontainer.Container, console string, args []string) *exec.Cmd {
command := exec.Command("nsinit", append([]string{"init", console}, args...)...)
command.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: uintptr(getNamespaceFlags(container.Namespaces) | syscall.CLONE_VFORK), // we need CLONE_VFORK so we can wait on the child
}
return command
}

View file

@ -5,19 +5,13 @@ import (
"github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/libcontainer/capabilities"
"github.com/dotcloud/docker/pkg/system"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"syscall"
)
func execinCommand(container *libcontainer.Container) (int, error) {
nspid, err := readPid()
if err != nil {
return -1, err
}
func execinCommand(container *libcontainer.Container, nspid int, args []string) (int, error) {
for _, ns := range container.Namespaces {
if err := system.Unshare(namespaceMap[ns]); err != nil {
return -1, err
@ -67,7 +61,7 @@ func execinCommand(container *libcontainer.Container) (int, error) {
if err := capabilities.DropCapabilities(container); err != nil {
return -1, fmt.Errorf("drop capabilities %s", err)
}
if err := system.Exec(container.Command.Args[0], container.Command.Args[0:], container.Command.Env); err != nil {
if err := system.Exec(args[0], args[0:], container.Env); err != nil {
return -1, err
}
}
@ -84,24 +78,12 @@ func execinCommand(container *libcontainer.Container) (int, error) {
if err := capabilities.DropCapabilities(container); err != nil {
return -1, fmt.Errorf("drop capabilities %s", err)
}
if err := system.Exec(container.Command.Args[0], container.Command.Args[0:], container.Command.Env); err != nil {
if err := system.Exec(args[0], args[0:], container.Env); err != nil {
return -1, err
}
panic("unreachable")
}
func readPid() (int, error) {
data, err := ioutil.ReadFile(".nspid")
if err != nil {
return -1, err
}
pid, err := strconv.Atoi(string(data))
if err != nil {
return -1, err
}
return pid, nil
}
func getNsFds(pid int, container *libcontainer.Container) ([]uintptr, error) {
fds := make([]uintptr, len(container.Namespaces))
for i, ns := range container.Namespaces {

View file

@ -14,7 +14,7 @@ import (
"syscall"
)
func initCommand(container *libcontainer.Container, console string) error {
func initCommand(container *libcontainer.Container, console string, args []string) error {
rootfs, err := resolveRootfs()
if err != nil {
return err
@ -72,7 +72,7 @@ func initCommand(container *libcontainer.Container, console string) error {
return fmt.Errorf("chdir to %s %s", container.WorkingDir, err)
}
}
if err := system.Exec(container.Command.Args[0], container.Command.Args[0:], container.Command.Env); err != nil {
if err := system.Exec(args[0], args[0:], container.Env); err != nil {
return fmt.Errorf("exec %s", err)
}
panic("unreachable")

View file

@ -4,8 +4,10 @@ import (
"encoding/json"
"errors"
"github.com/dotcloud/docker/pkg/libcontainer"
"io/ioutil"
"log"
"os"
"strconv"
)
var (
@ -25,24 +27,29 @@ func main() {
}
switch os.Args[1] {
case "exec":
exitCode, err := execCommand(container)
var exitCode int
nspid, err := readPid()
if err != nil {
if !os.IsNotExist(err) {
log.Fatal(err)
}
}
if nspid > 0 {
exitCode, err = execinCommand(container, nspid, os.Args[2:])
} else {
exitCode, err = execCommand(container, os.Args[2:])
}
if err != nil {
log.Fatal(err)
}
os.Exit(exitCode)
case "init":
if argc != 3 {
if argc < 3 {
log.Fatal(ErrWrongArguments)
}
if err := initCommand(container, os.Args[2]); err != nil {
if err := initCommand(container, os.Args[2], os.Args[3:]); err != nil {
log.Fatal(err)
}
case "execin":
exitCode, err := execinCommand(container)
if err != nil {
log.Fatal(err)
}
os.Exit(exitCode)
default:
log.Fatalf("command not supported for nsinit %s", os.Args[1])
}
@ -61,3 +68,15 @@ func loadContainer() (*libcontainer.Container, error) {
}
return container, nil
}
func readPid() (int, error) {
data, err := ioutil.ReadFile(".nspid")
if err != nil {
return -1, err
}
pid, err := strconv.Atoi(string(data))
if err != nil {
return -1, err
}
return pid, nil
}