1
0
mirror of https://github.com/docker/cli.git synced 2026-01-23 15:21:32 +03:00
Files
cli/components/engine/pkg/libcontainer/nsinit/execin.go
Michael Crosby e501c61ed3 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)
Upstream-commit: d84feb8fe5e40838c81321249189f1f0a02825bb
Component: engine
2014-02-21 14:56:16 -08:00

98 lines
2.4 KiB
Go

package main
import (
"fmt"
"github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/libcontainer/capabilities"
"github.com/dotcloud/docker/pkg/system"
"os"
"path/filepath"
"strconv"
"syscall"
)
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
}
}
fds, err := getNsFds(nspid, container)
closeFds := func() {
for _, f := range fds {
system.Closefd(f)
}
}
if err != nil {
closeFds()
return -1, err
}
for _, fd := range fds {
if fd > 0 {
if err := system.Setns(fd, 0); err != nil {
closeFds()
return -1, fmt.Errorf("setns %s", err)
}
}
system.Closefd(fd)
}
// if the container has a new pid and mount namespace we need to
// remount proc and sys to pick up the changes
if container.Namespaces.Contains(libcontainer.CLONE_NEWNS) &&
container.Namespaces.Contains(libcontainer.CLONE_NEWPID) {
pid, err := system.Fork()
if err != nil {
return -1, err
}
if pid == 0 {
// TODO: make all raw syscalls to be fork safe
if err := system.Unshare(syscall.CLONE_NEWNS); err != nil {
return -1, err
}
if err := remountProc(); err != nil {
return -1, fmt.Errorf("remount proc %s", err)
}
if err := remountSys(); err != nil {
return -1, fmt.Errorf("remount sys %s", err)
}
if err := capabilities.DropCapabilities(container); err != nil {
return -1, fmt.Errorf("drop capabilities %s", err)
}
if err := system.Exec(args[0], args[0:], container.Env); err != nil {
return -1, err
}
}
proc, err := os.FindProcess(pid)
if err != nil {
return -1, err
}
state, err := proc.Wait()
if err != nil {
return -1, err
}
os.Exit(state.Sys().(syscall.WaitStatus).ExitStatus())
}
if err := capabilities.DropCapabilities(container); err != nil {
return -1, fmt.Errorf("drop capabilities %s", err)
}
if err := system.Exec(args[0], args[0:], container.Env); err != nil {
return -1, err
}
panic("unreachable")
}
func getNsFds(pid int, container *libcontainer.Container) ([]uintptr, error) {
fds := make([]uintptr, len(container.Namespaces))
for i, ns := range container.Namespaces {
f, err := os.OpenFile(filepath.Join("/proc/", strconv.Itoa(pid), "ns", namespaceFileMap[ns]), os.O_RDONLY, 0)
if err != nil {
return fds, err
}
fds[i] = f.Fd()
}
return fds, nil
}