Windows: Initial compilation enablement

Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
John Howard 2015-05-13 15:42:16 -07:00
parent a37b2a4f15
commit c712fa0814
46 changed files with 281 additions and 146 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,3 @@
// +build !linux
package cgroups

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,3 @@
// +build !linux
package fs

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,5 @@
// +build linux
/* /*
Utility for testing cgroup operations. Utility for testing cgroup operations.

View File

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

View File

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

View File

@ -1,3 +1,5 @@
// +build linux
package cgroups package cgroups
type ThrottlingData struct { type ThrottlingData struct {

View File

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

View File

@ -8,6 +8,9 @@ const (
Thawed FreezerState = "THAWED" Thawed FreezerState = "THAWED"
) )
// TODO Windows: This can be factored out in the future as Cgroups are not
// supported on the Windows platform.
type Cgroup struct { type Cgroup struct {
Name string `json:"name"` Name string `json:"name"`

View File

@ -1,7 +1,5 @@
package configs package configs
import "fmt"
type Rlimit struct { type Rlimit struct {
Type int `json:"type"` Type int `json:"type"`
Hard uint64 `json:"hard"` Hard uint64 `json:"hard"`
@ -15,6 +13,9 @@ type IDMap struct {
Size int `json:"size"` Size int `json:"size"`
} }
// TODO Windows. Many of these fields should be factored out into those parts
// which are common across platforms, and those which are platform specific.
// Config defines configuration options for executing a process inside a contained environment. // Config defines configuration options for executing a process inside a contained environment.
type Config struct { type Config struct {
// NoPivotRoot will use MS_MOVE and a chroot to jail the process into the container's rootfs // NoPivotRoot will use MS_MOVE and a chroot to jail the process into the container's rootfs
@ -104,49 +105,3 @@ type Config struct {
// sysctl -w my.property.name value in Linux. // sysctl -w my.property.name value in Linux.
SystemProperties map[string]string `json:"system_properties"` SystemProperties map[string]string `json:"system_properties"`
} }
// Gets the root uid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostUID() (int, error) {
if c.Namespaces.Contains(NEWUSER) {
if c.UidMappings == nil {
return -1, fmt.Errorf("User namespaces enabled, but no user mappings found.")
}
id, found := c.hostIDFromMapping(0, c.UidMappings)
if !found {
return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
}
return id, nil
}
// Return default root uid 0
return 0, nil
}
// Gets the root uid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostGID() (int, error) {
if c.Namespaces.Contains(NEWUSER) {
if c.GidMappings == nil {
return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.")
}
id, found := c.hostIDFromMapping(0, c.GidMappings)
if !found {
return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
}
return id, nil
}
// Return default root uid 0
return 0, nil
}
// Utility function that gets a host ID for a container ID from user namespace map
// if that ID is present in the map.
func (c Config) hostIDFromMapping(containerID int, uMap []IDMap) (int, bool) {
for _, m := range uMap {
if (containerID >= m.ContainerID) && (containerID <= (m.ContainerID + m.Size - 1)) {
hostID := m.HostID + (containerID - m.ContainerID)
return hostID, true
}
}
return -1, false
}

49
configs/config_linux.go Normal file
View File

@ -0,0 +1,49 @@
package configs
import "fmt"
// Gets the root uid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostUID() (int, error) {
if c.Namespaces.Contains(NEWUSER) {
if c.UidMappings == nil {
return -1, fmt.Errorf("User namespaces enabled, but no user mappings found.")
}
id, found := c.hostIDFromMapping(0, c.UidMappings)
if !found {
return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
}
return id, nil
}
// Return default root uid 0
return 0, nil
}
// Gets the root uid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostGID() (int, error) {
if c.Namespaces.Contains(NEWUSER) {
if c.GidMappings == nil {
return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.")
}
id, found := c.hostIDFromMapping(0, c.GidMappings)
if !found {
return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
}
return id, nil
}
// Return default root uid 0
return 0, nil
}
// Utility function that gets a host ID for a container ID from user namespace map
// if that ID is present in the map.
func (c Config) hostIDFromMapping(containerID int, uMap []IDMap) (int, bool) {
for _, m := range uMap {
if (containerID >= m.ContainerID) && (containerID <= (m.ContainerID + m.Size - 1)) {
hostID := m.HostID + (containerID - m.ContainerID)
return hostID, true
}
}
return -1, false
}

View File

@ -9,6 +9,8 @@ const (
Wildcard = -1 Wildcard = -1
) )
// TODO Windows: This can be factored out in the future
type Device struct { type Device struct {
// Device type, block, char, etc. // Device type, block, char, etc.
Type rune `json:"type"` Type rune `json:"type"`

View File

@ -1,3 +1,5 @@
// +build linux
package configs package configs
var ( var (

View File

@ -1,91 +1,5 @@
package configs package configs
import "fmt"
type NamespaceType string type NamespaceType string
const (
NEWNET NamespaceType = "NEWNET"
NEWPID NamespaceType = "NEWPID"
NEWNS NamespaceType = "NEWNS"
NEWUTS NamespaceType = "NEWUTS"
NEWIPC NamespaceType = "NEWIPC"
NEWUSER NamespaceType = "NEWUSER"
)
func NamespaceTypes() []NamespaceType {
return []NamespaceType{
NEWNET,
NEWPID,
NEWNS,
NEWUTS,
NEWIPC,
NEWUSER,
}
}
// Namespace defines configuration for each namespace. It specifies an
// alternate path that is able to be joined via setns.
type Namespace struct {
Type NamespaceType `json:"type"`
Path string `json:"path"`
}
func (n *Namespace) GetPath(pid int) string {
if n.Path != "" {
return n.Path
}
return fmt.Sprintf("/proc/%d/ns/%s", pid, n.file())
}
func (n *Namespace) file() string {
file := ""
switch n.Type {
case NEWNET:
file = "net"
case NEWNS:
file = "mnt"
case NEWPID:
file = "pid"
case NEWIPC:
file = "ipc"
case NEWUSER:
file = "user"
case NEWUTS:
file = "uts"
}
return file
}
type Namespaces []Namespace type Namespaces []Namespace
func (n *Namespaces) Remove(t NamespaceType) bool {
i := n.index(t)
if i == -1 {
return false
}
*n = append((*n)[:i], (*n)[i+1:]...)
return true
}
func (n *Namespaces) Add(t NamespaceType, path string) {
i := n.index(t)
if i == -1 {
*n = append(*n, Namespace{Type: t, Path: path})
return
}
(*n)[i].Path = path
}
func (n *Namespaces) index(t NamespaceType) int {
for i, ns := range *n {
if ns.Type == t {
return i
}
}
return -1
}
func (n *Namespaces) Contains(t NamespaceType) bool {
return n.index(t) != -1
}

View File

@ -0,0 +1,89 @@
// +build linux
package configs
import "fmt"
const (
NEWNET NamespaceType = "NEWNET"
NEWPID NamespaceType = "NEWPID"
NEWNS NamespaceType = "NEWNS"
NEWUTS NamespaceType = "NEWUTS"
NEWIPC NamespaceType = "NEWIPC"
NEWUSER NamespaceType = "NEWUSER"
)
func NamespaceTypes() []NamespaceType {
return []NamespaceType{
NEWNET,
NEWPID,
NEWNS,
NEWUTS,
NEWIPC,
NEWUSER,
}
}
// Namespace defines configuration for each namespace. It specifies an
// alternate path that is able to be joined via setns.
type Namespace struct {
Type NamespaceType `json:"type"`
Path string `json:"path"`
}
func (n *Namespace) GetPath(pid int) string {
if n.Path != "" {
return n.Path
}
return fmt.Sprintf("/proc/%d/ns/%s", pid, n.file())
}
func (n *Namespace) file() string {
file := ""
switch n.Type {
case NEWNET:
file = "net"
case NEWNS:
file = "mnt"
case NEWPID:
file = "pid"
case NEWIPC:
file = "ipc"
case NEWUSER:
file = "user"
case NEWUTS:
file = "uts"
}
return file
}
func (n *Namespaces) Remove(t NamespaceType) bool {
i := n.index(t)
if i == -1 {
return false
}
*n = append((*n)[:i], (*n)[i+1:]...)
return true
}
func (n *Namespaces) Add(t NamespaceType, path string) {
i := n.index(t)
if i == -1 {
*n = append(*n, Namespace{Type: t, Path: path})
return
}
(*n)[i].Path = path
}
func (n *Namespaces) index(t NamespaceType) int {
for i, ns := range *n {
if ns.Type == t {
return i
}
}
return -1
}
func (n *Namespaces) Contains(t NamespaceType) bool {
return n.index(t) != -1
}

View File

@ -1,4 +1,4 @@
// +build !linux // +build !linux,!windows
package configs package configs

View File

@ -0,0 +1,6 @@
package configs
// Namespace defines configuration for each namespace. It specifies an
// alternate path that is able to be joined via setns.
type Namespace struct {
}

View File

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

30
console_windows.go Normal file
View File

@ -0,0 +1,30 @@
package libcontainer
// newConsole returns an initalized console that can be used within a container
func newConsole(uid, gid int) (Console, error) {
return &windowsConsole{}, nil
}
// windowsConsole is a Windows psuedo TTY for use within a container.
type windowsConsole struct {
}
func (c *windowsConsole) Fd() uintptr {
return 0
}
func (c *windowsConsole) Path() string {
return ""
}
func (c *windowsConsole) Read(b []byte) (int, error) {
return 0, nil
}
func (c *windowsConsole) Write(b []byte) (int, error) {
return 0, nil
}
func (c *windowsConsole) Close() error {
return nil
}

View File

@ -0,0 +1,16 @@
package devices
import (
"github.com/docker/libcontainer/configs"
)
// TODO Windows. This can be factored out further - Devices are not supported
// by Windows Containers.
func DeviceFromPath(path, permissions string) (*configs.Device, error) {
return nil, nil
}
func HostDevices() ([]*configs.Device, error) {
return nil, nil
}

View File

@ -1,3 +1,5 @@
// +build linux
package devices package devices
/* /*

View File

@ -1,12 +1,5 @@
package libcontainer package libcontainer
import "github.com/docker/libcontainer/cgroups"
type Stats struct {
Interfaces []*NetworkInterface
CgroupStats *cgroups.Stats
}
type NetworkInterface struct { type NetworkInterface struct {
// Name is the name of the network interface. // Name is the name of the network interface.
Name string Name string

8
stats_linux.go Normal file
View File

@ -0,0 +1,8 @@
package libcontainer
import "github.com/docker/libcontainer/cgroups"
type Stats struct {
Interfaces []*NetworkInterface
CgroupStats *cgroups.Stats
}

5
stats_windows.go Normal file
View File

@ -0,0 +1,5 @@
package libcontainer
type Stats struct {
Interfaces []*NetworkInterface
}

View File

@ -1,4 +1,4 @@
// +build cgo // +build cgo,linux
package system package system

View File

@ -1,8 +1,15 @@
// +build !cgo // +build !cgo windows
package system package system
func GetClockTicks() int { func GetClockTicks() int {
// TODO figure out a better alternative for platforms where we're missing cgo // TODO figure out a better alternative for platforms where we're missing cgo
//
// TODO Windows. This could be implemented using Win32 QueryPerformanceFrequency().
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx
//
// An example of its usage can be found here.
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
return 100 return 100
} }