From f85823b53de774a6d690832b8f27bc1bde0f01bc Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 25 Feb 2014 15:19:13 -0800 Subject: [PATCH] Fix cross compile for make cross Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- libcontainer/nsinit/command.go | 25 ++++++++++++++------- libcontainer/nsinit/execin.go | 2 ++ libcontainer/nsinit/ns_linux.go | 14 ------------ libcontainer/nsinit/nsinit/main.go | 12 +++------- libcontainer/nsinit/unsupported.go | 19 ++++++++++++++++ libcontainer/types.go | 35 ++++++++++++++++-------------- libcontainer/types_linux.go | 16 ++++++++++++++ system/calls_linux.go | 7 ++++++ system/errors.go | 9 ++++++++ system/setns_linux.go | 5 ----- system/unsupported.go | 15 +++++++++++++ 11 files changed, 107 insertions(+), 52 deletions(-) delete mode 100644 libcontainer/nsinit/ns_linux.go create mode 100644 libcontainer/nsinit/unsupported.go create mode 100644 libcontainer/types_linux.go create mode 100644 system/errors.go create mode 100644 system/unsupported.go diff --git a/libcontainer/nsinit/command.go b/libcontainer/nsinit/command.go index 5eb378a..8ddf1e7 100644 --- a/libcontainer/nsinit/command.go +++ b/libcontainer/nsinit/command.go @@ -3,9 +3,9 @@ package nsinit import ( "fmt" "github.com/dotcloud/docker/pkg/libcontainer" + "github.com/dotcloud/docker/pkg/system" "os" "os/exec" - "syscall" ) // CommandFactory takes the container's configuration and options passed by the @@ -15,22 +15,31 @@ type CommandFactory interface { Create(container *libcontainer.Container, console string, syncFd uintptr, args []string) *exec.Cmd } -type DefaultCommandFactory struct{} +type DefaultCommandFactory struct { + Root string +} // Create will return an exec.Cmd with the Cloneflags set to the proper namespaces // defined on the container's configuration and use the current binary as the init with the // args provided func (c *DefaultCommandFactory) Create(container *libcontainer.Container, console string, pipe uintptr, args []string) *exec.Cmd { - // get our binary name so we can always reexec ourself - name := os.Args[0] - command := exec.Command(name, append([]string{ + // get our binary name from arg0 so we can always reexec ourself + command := exec.Command(os.Args[0], append([]string{ "-console", console, "-pipe", fmt.Sprint(pipe), + "-root", c.Root, "init"}, args...)...) - command.SysProcAttr = &syscall.SysProcAttr{ - Cloneflags: uintptr(GetNamespaceFlags(container.Namespaces)), - } + system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces))) command.Env = container.Env return command } + +// GetNamespaceFlags parses the container's Namespaces options to set the correct +// flags on clone, unshare, and setns +func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) { + for _, ns := range namespaces { + flag |= ns.Value + } + return flag +} diff --git a/libcontainer/nsinit/execin.go b/libcontainer/nsinit/execin.go index 253fbdc..55f7b96 100644 --- a/libcontainer/nsinit/execin.go +++ b/libcontainer/nsinit/execin.go @@ -1,3 +1,5 @@ +// +build linux + package nsinit import ( diff --git a/libcontainer/nsinit/ns_linux.go b/libcontainer/nsinit/ns_linux.go deleted file mode 100644 index ab6322e..0000000 --- a/libcontainer/nsinit/ns_linux.go +++ /dev/null @@ -1,14 +0,0 @@ -package nsinit - -import ( - "github.com/dotcloud/docker/pkg/libcontainer" -) - -// getNamespaceFlags parses the container's Namespaces options to set the correct -// flags on clone, unshare, and setns -func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) { - for _, ns := range namespaces { - flag |= ns.Value - } - return flag -} diff --git a/libcontainer/nsinit/nsinit/main.go b/libcontainer/nsinit/nsinit/main.go index e6b020b..61921c5 100644 --- a/libcontainer/nsinit/nsinit/main.go +++ b/libcontainer/nsinit/nsinit/main.go @@ -2,7 +2,6 @@ package main import ( "encoding/json" - "errors" "flag" "github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer/nsinit" @@ -18,11 +17,6 @@ var ( pipeFd int ) -var ( - ErrUnsupported = errors.New("Unsupported method") - ErrWrongArguments = errors.New("Wrong argument count") -) - func registerFlags() { flag.StringVar(&console, "console", "", "console (pty slave) path") flag.IntVar(&pipeFd, "pipe", 0, "sync pipe fd") @@ -35,7 +29,7 @@ func main() { registerFlags() if flag.NArg() < 1 { - log.Fatal(ErrWrongArguments) + log.Fatalf("wrong number of argments %d", flag.NArg()) } container, err := loadContainer() if err != nil { @@ -71,7 +65,7 @@ func main() { log.Fatal(err) } if flag.NArg() < 2 { - log.Fatal(ErrWrongArguments) + log.Fatalf("wrong number of argments %d", flag.NArg()) } syncPipe, err := nsinit.NewSyncPipeFromFd(0, uintptr(pipeFd)) if err != nil { @@ -112,5 +106,5 @@ func readPid() (int, error) { } func newNsInit() (nsinit.NsInit, error) { - return nsinit.NewNsInit(&nsinit.DefaultCommandFactory{}, &nsinit.DefaultStateWriter{root}), nil + return nsinit.NewNsInit(&nsinit.DefaultCommandFactory{root}, &nsinit.DefaultStateWriter{root}), nil } diff --git a/libcontainer/nsinit/unsupported.go b/libcontainer/nsinit/unsupported.go new file mode 100644 index 0000000..2412223 --- /dev/null +++ b/libcontainer/nsinit/unsupported.go @@ -0,0 +1,19 @@ +// +build !linux + +package nsinit + +import ( + "github.com/dotcloud/docker/pkg/libcontainer" +) + +func (ns *linuxNs) Exec(container *libcontainer.Container, term Terminal, args []string) (int, error) { + return -1, libcontainer.ErrUnsupported +} + +func (ns *linuxNs) ExecIn(container *libcontainer.Container, nspid int, args []string) (int, error) { + return -1, libcontainer.ErrUnsupported +} + +func (ns *linuxNs) Init(container *libcontainer.Container, uncleanRootfs, console string, syncPipe *SyncPipe, args []string) error { + return libcontainer.ErrUnsupported +} diff --git a/libcontainer/types.go b/libcontainer/types.go index cb64db1..8c28530 100644 --- a/libcontainer/types.go +++ b/libcontainer/types.go @@ -5,25 +5,20 @@ import ( "errors" "github.com/syndtr/gocapability/capability" "os" - "syscall" ) var ( - ErrUnkownNamespace error = errors.New("Unkown namespace") + ErrUnkownNamespace = errors.New("Unknown namespace") + ErrUnkownCapability = errors.New("Unknown capability") + ErrUnsupported = errors.New("Unsupported method") ) // namespaceList is used to convert the libcontainer types // into the names of the files located in /proc//ns/* for // each namespace var ( - namespaceList = Namespaces{ - {Key: "NEWNS", Value: syscall.CLONE_NEWNS, File: "mnt"}, - {Key: "NEWUTS", Value: syscall.CLONE_NEWUTS, File: "uts"}, - {Key: "NEWIPC", Value: syscall.CLONE_NEWIPC, File: "ipc"}, - {Key: "NEWUSER", Value: syscall.CLONE_NEWUSER, File: "user"}, - {Key: "NEWPID", Value: syscall.CLONE_NEWPID, File: "pid"}, - {Key: "NEWNET", Value: syscall.CLONE_NEWNET, File: "net"}, - } + namespaceList = Namespaces{} + capabilityList = Capabilities{ {Key: "SETPCAP", Value: capability.CAP_SETPCAP}, {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE}, @@ -52,6 +47,10 @@ type ( Namespaces []*Namespace ) +func (ns *Namespace) String() string { + return ns.Key +} + func (ns *Namespace) MarshalJSON() ([]byte, error) { return json.Marshal(ns.Key) } @@ -95,20 +94,24 @@ type ( Capabilities []*Capability ) -func (ns *Capability) MarshalJSON() ([]byte, error) { - return json.Marshal(ns.Key) +func (c *Capability) String() string { + return c.Key } -func (ns *Capability) UnmarshalJSON(src []byte) error { +func (c *Capability) MarshalJSON() ([]byte, error) { + return json.Marshal(c.Key) +} + +func (c *Capability) UnmarshalJSON(src []byte) error { var capName string if err := json.Unmarshal(src, &capName); err != nil { return err } ret := GetCapability(capName) if ret == nil { - return ErrUnkownNamespace + return ErrUnkownCapability } - *ns = *ret + *c = *ret return nil } @@ -119,7 +122,7 @@ func GetCapability(key string) *Capability { } } if os.Getenv("DEBUG") != "" { - panic("Unreachable: Namespace not found") + panic("Unreachable: Capability not found") } return nil } diff --git a/libcontainer/types_linux.go b/libcontainer/types_linux.go new file mode 100644 index 0000000..c14531d --- /dev/null +++ b/libcontainer/types_linux.go @@ -0,0 +1,16 @@ +package libcontainer + +import ( + "syscall" +) + +func init() { + namespaceList = Namespaces{ + {Key: "NEWNS", Value: syscall.CLONE_NEWNS, File: "mnt"}, + {Key: "NEWUTS", Value: syscall.CLONE_NEWUTS, File: "uts"}, + {Key: "NEWIPC", Value: syscall.CLONE_NEWIPC, File: "ipc"}, + {Key: "NEWUSER", Value: syscall.CLONE_NEWUSER, File: "user"}, + {Key: "NEWPID", Value: syscall.CLONE_NEWPID, File: "pid"}, + {Key: "NEWNET", Value: syscall.CLONE_NEWNET, File: "net"}, + } +} diff --git a/system/calls_linux.go b/system/calls_linux.go index b7a8f14..bf667c5 100644 --- a/system/calls_linux.go +++ b/system/calls_linux.go @@ -136,3 +136,10 @@ func Mkfifo(name string, mode uint32) error { func Umask(mask int) int { return syscall.Umask(mask) } + +func SetCloneFlags(cmd *exec.Cmd, flag uintptr) { + if cmd.SysProcAttr == nil { + cmd.SysProcAttr = &syscall.SysProcAttr{} + } + cmd.SysProcAttr.Cloneflags = flag +} diff --git a/system/errors.go b/system/errors.go new file mode 100644 index 0000000..6304518 --- /dev/null +++ b/system/errors.go @@ -0,0 +1,9 @@ +package system + +import ( + "errors" +) + +var ( + ErrNotSupportedPlatform = errors.New("platform and architecture is not supported") +) diff --git a/system/setns_linux.go b/system/setns_linux.go index 07b1c93..2b6f9e7 100644 --- a/system/setns_linux.go +++ b/system/setns_linux.go @@ -1,16 +1,11 @@ package system import ( - "errors" "fmt" "runtime" "syscall" ) -var ( - ErrNotSupportedPlatform = errors.New("platform and architecture is not supported") -) - // Via http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b21fddd087678a70ad64afc0f632e0f1071b092 // // We need different setns values for the different platforms and arch diff --git a/system/unsupported.go b/system/unsupported.go new file mode 100644 index 0000000..eb3ec7e --- /dev/null +++ b/system/unsupported.go @@ -0,0 +1,15 @@ +// +build !linux + +package system + +import ( + "os/exec" +) + +func SetCloneFlags(cmd *exec.Cmd, flag uintptr) { + +} + +func UsetCloseOnExec(fd uintptr) error { + return ErrNotSupportedPlatform +}