Cgroups allow devices for privileged containers
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
parent
a6e5e18511
commit
a76407ac61
3 changed files with 40 additions and 11 deletions
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/dotcloud/docker/execdriver"
|
||||
"github.com/dotcloud/docker/execdriver/lxc"
|
||||
"github.com/dotcloud/docker/pkg/cgroups"
|
||||
"github.com/dotcloud/docker/pkg/libcontainer"
|
||||
"github.com/dotcloud/docker/pkg/libcontainer/nsinit"
|
||||
"io"
|
||||
|
@ -13,6 +14,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
@ -125,7 +127,40 @@ func (d *driver) Name() string {
|
|||
}
|
||||
|
||||
func (d *driver) GetPidsForContainer(id string) ([]int, error) {
|
||||
return nil, ErrNotSupported
|
||||
pids := []int{}
|
||||
|
||||
subsystem := "cpu"
|
||||
cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem)
|
||||
if err != nil {
|
||||
return pids, err
|
||||
}
|
||||
cgroupRoot = filepath.Dir(cgroupRoot)
|
||||
|
||||
cgroupDir, err := cgroups.GetThisCgroupDir(subsystem)
|
||||
if err != nil {
|
||||
return pids, err
|
||||
}
|
||||
|
||||
filename := filepath.Join(cgroupRoot, cgroupDir, id, "tasks")
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
filename = filepath.Join(cgroupRoot, cgroupDir, "docker", id, "tasks")
|
||||
}
|
||||
|
||||
output, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return pids, err
|
||||
}
|
||||
for _, p := range strings.Split(string(output), "\n") {
|
||||
if len(p) == 0 {
|
||||
continue
|
||||
}
|
||||
pid, err := strconv.Atoi(p)
|
||||
if err != nil {
|
||||
return pids, fmt.Errorf("Invalid pid '%s': %s", p, err)
|
||||
}
|
||||
pids = append(pids, pid)
|
||||
}
|
||||
return pids, nil
|
||||
}
|
||||
|
||||
func writeContainerFile(container *libcontainer.Container, rootfs string) error {
|
||||
|
@ -219,6 +254,7 @@ func createContainer(c *execdriver.Command) *libcontainer.Container {
|
|||
}
|
||||
if c.Privileged {
|
||||
container.Capabilities = nil
|
||||
container.Cgroups.DeviceAccess = true
|
||||
}
|
||||
if c.Resources != nil {
|
||||
container.Cgroups.CpuShares = c.Resources.CpuShares
|
||||
|
|
|
@ -1581,8 +1581,8 @@ func TestPrivilegedCanMknod(t *testing.T) {
|
|||
eng := NewTestEngine(t)
|
||||
runtime := mkRuntimeFromEngine(eng, t)
|
||||
defer runtime.Nuke()
|
||||
if output, _ := runContainer(eng, runtime, []string{"-privileged", "_", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok"}, t); output != "ok\n" {
|
||||
t.Fatal("Could not mknod into privileged container")
|
||||
if output, err := runContainer(eng, runtime, []string{"-privileged", "_", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok"}, t); output != "ok\n" {
|
||||
t.Fatalf("Could not mknod into privileged container %s %v", output, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/dotcloud/docker/pkg/libcontainer/network"
|
||||
"github.com/dotcloud/docker/pkg/system"
|
||||
"github.com/dotcloud/docker/pkg/user"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
@ -23,7 +22,6 @@ func Init(container *libcontainer.Container, uncleanRootfs, console string, sync
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("initializing namespace at %s", rootfs)
|
||||
|
||||
// We always read this as it is a way to sync with the parent as well
|
||||
context, err := syncPipe.ReadFromParent()
|
||||
|
@ -32,10 +30,8 @@ func Init(container *libcontainer.Container, uncleanRootfs, console string, sync
|
|||
return err
|
||||
}
|
||||
syncPipe.Close()
|
||||
log.Printf("received context from parent %v", context)
|
||||
|
||||
if console != "" {
|
||||
log.Printf("setting up console for %s", console)
|
||||
// close pipes so that we can replace it with the pty
|
||||
closeStdPipes()
|
||||
slave, err := openTerminal(console, syscall.O_RDWR)
|
||||
|
@ -66,11 +62,9 @@ func Init(container *libcontainer.Container, uncleanRootfs, console string, sync
|
|||
if err := system.Sethostname(container.Hostname); err != nil {
|
||||
return fmt.Errorf("sethostname %s", err)
|
||||
}
|
||||
log.Printf("dropping capabilities")
|
||||
if err := capabilities.DropCapabilities(container); err != nil {
|
||||
return fmt.Errorf("drop capabilities %s", err)
|
||||
}
|
||||
log.Printf("setting user in namespace")
|
||||
if err := setupUser(container); err != nil {
|
||||
return fmt.Errorf("setup user %s", err)
|
||||
}
|
||||
|
@ -87,7 +81,6 @@ func execArgs(args []string, env []string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("execing %s goodbye", name)
|
||||
if err := system.Exec(name, args[0:], env); err != nil {
|
||||
return fmt.Errorf("exec %s", err)
|
||||
}
|
||||
|
@ -111,7 +104,7 @@ func resolveRootfs(uncleanRootfs string) (string, error) {
|
|||
}
|
||||
|
||||
func setupUser(container *libcontainer.Container) error {
|
||||
if container.User != "" {
|
||||
if container.User != "" && container.User != "root" {
|
||||
uid, gid, suppGids, err := user.GetUserGroupSupplementary(container.User, syscall.Getuid(), syscall.Getgid())
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in a new issue