Fix cross compile for make cross

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-02-25 15:19:13 -08:00
parent 2acaf7ca82
commit f85823b53d
11 changed files with 107 additions and 52 deletions

View file

@ -3,9 +3,9 @@ package nsinit
import ( import (
"fmt" "fmt"
"github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/system"
"os" "os"
"os/exec" "os/exec"
"syscall"
) )
// CommandFactory takes the container's configuration and options passed by the // 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 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 // 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 // defined on the container's configuration and use the current binary as the init with the
// args provided // args provided
func (c *DefaultCommandFactory) Create(container *libcontainer.Container, console string, pipe uintptr, args []string) *exec.Cmd { 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 // get our binary name from arg0 so we can always reexec ourself
name := os.Args[0] command := exec.Command(os.Args[0], append([]string{
command := exec.Command(name, append([]string{
"-console", console, "-console", console,
"-pipe", fmt.Sprint(pipe), "-pipe", fmt.Sprint(pipe),
"-root", c.Root,
"init"}, args...)...) "init"}, args...)...)
command.SysProcAttr = &syscall.SysProcAttr{ system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces)))
Cloneflags: uintptr(GetNamespaceFlags(container.Namespaces)),
}
command.Env = container.Env command.Env = container.Env
return command 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
}

View file

@ -1,3 +1,5 @@
// +build linux
package nsinit package nsinit
import ( import (

View file

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

View file

@ -2,7 +2,6 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors"
"flag" "flag"
"github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/libcontainer/nsinit" "github.com/dotcloud/docker/pkg/libcontainer/nsinit"
@ -18,11 +17,6 @@ var (
pipeFd int pipeFd int
) )
var (
ErrUnsupported = errors.New("Unsupported method")
ErrWrongArguments = errors.New("Wrong argument count")
)
func registerFlags() { func registerFlags() {
flag.StringVar(&console, "console", "", "console (pty slave) path") flag.StringVar(&console, "console", "", "console (pty slave) path")
flag.IntVar(&pipeFd, "pipe", 0, "sync pipe fd") flag.IntVar(&pipeFd, "pipe", 0, "sync pipe fd")
@ -35,7 +29,7 @@ func main() {
registerFlags() registerFlags()
if flag.NArg() < 1 { if flag.NArg() < 1 {
log.Fatal(ErrWrongArguments) log.Fatalf("wrong number of argments %d", flag.NArg())
} }
container, err := loadContainer() container, err := loadContainer()
if err != nil { if err != nil {
@ -71,7 +65,7 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
if flag.NArg() < 2 { if flag.NArg() < 2 {
log.Fatal(ErrWrongArguments) log.Fatalf("wrong number of argments %d", flag.NArg())
} }
syncPipe, err := nsinit.NewSyncPipeFromFd(0, uintptr(pipeFd)) syncPipe, err := nsinit.NewSyncPipeFromFd(0, uintptr(pipeFd))
if err != nil { if err != nil {
@ -112,5 +106,5 @@ func readPid() (int, error) {
} }
func newNsInit() (nsinit.NsInit, 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
} }

View file

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

View file

@ -5,25 +5,20 @@ import (
"errors" "errors"
"github.com/syndtr/gocapability/capability" "github.com/syndtr/gocapability/capability"
"os" "os"
"syscall"
) )
var ( 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 // namespaceList is used to convert the libcontainer types
// into the names of the files located in /proc/<pid>/ns/* for // into the names of the files located in /proc/<pid>/ns/* for
// each namespace // each namespace
var ( var (
namespaceList = Namespaces{ 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"},
}
capabilityList = Capabilities{ capabilityList = Capabilities{
{Key: "SETPCAP", Value: capability.CAP_SETPCAP}, {Key: "SETPCAP", Value: capability.CAP_SETPCAP},
{Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE}, {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE},
@ -52,6 +47,10 @@ type (
Namespaces []*Namespace Namespaces []*Namespace
) )
func (ns *Namespace) String() string {
return ns.Key
}
func (ns *Namespace) MarshalJSON() ([]byte, error) { func (ns *Namespace) MarshalJSON() ([]byte, error) {
return json.Marshal(ns.Key) return json.Marshal(ns.Key)
} }
@ -95,20 +94,24 @@ type (
Capabilities []*Capability Capabilities []*Capability
) )
func (ns *Capability) MarshalJSON() ([]byte, error) { func (c *Capability) String() string {
return json.Marshal(ns.Key) 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 var capName string
if err := json.Unmarshal(src, &capName); err != nil { if err := json.Unmarshal(src, &capName); err != nil {
return err return err
} }
ret := GetCapability(capName) ret := GetCapability(capName)
if ret == nil { if ret == nil {
return ErrUnkownNamespace return ErrUnkownCapability
} }
*ns = *ret *c = *ret
return nil return nil
} }
@ -119,7 +122,7 @@ func GetCapability(key string) *Capability {
} }
} }
if os.Getenv("DEBUG") != "" { if os.Getenv("DEBUG") != "" {
panic("Unreachable: Namespace not found") panic("Unreachable: Capability not found")
} }
return nil return nil
} }

View file

@ -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"},
}
}

View file

@ -136,3 +136,10 @@ func Mkfifo(name string, mode uint32) error {
func Umask(mask int) int { func Umask(mask int) int {
return syscall.Umask(mask) return syscall.Umask(mask)
} }
func SetCloneFlags(cmd *exec.Cmd, flag uintptr) {
if cmd.SysProcAttr == nil {
cmd.SysProcAttr = &syscall.SysProcAttr{}
}
cmd.SysProcAttr.Cloneflags = flag
}

9
system/errors.go Normal file
View file

@ -0,0 +1,9 @@
package system
import (
"errors"
)
var (
ErrNotSupportedPlatform = errors.New("platform and architecture is not supported")
)

View file

@ -1,16 +1,11 @@
package system package system
import ( import (
"errors"
"fmt" "fmt"
"runtime" "runtime"
"syscall" "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 // 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 // We need different setns values for the different platforms and arch

15
system/unsupported.go Normal file
View file

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