Bladeren bron

Merge pull request #12829 from Microsoft/10662-execdriver-driver-refactor

Windows: Start refactor execdriver/driver.go
Tibor Vass 10 jaren geleden
bovenliggende
commit
e9c9682333
2 gewijzigde bestanden met toevoegingen van 161 en 148 verwijderingen
  1. 5 148
      daemon/execdriver/driver.go
  2. 156 0
      daemon/execdriver/driver_linux.go

+ 5 - 148
daemon/execdriver/driver.go

@@ -1,21 +1,14 @@
 package execdriver
 package execdriver
 
 
 import (
 import (
-	"encoding/json"
 	"errors"
 	"errors"
 	"io"
 	"io"
-	"io/ioutil"
-	"os"
 	"os/exec"
 	"os/exec"
-	"path/filepath"
-	"strconv"
-	"strings"
 	"time"
 	"time"
 
 
-	"github.com/docker/docker/daemon/execdriver/native/template"
+	// TODO Windows: Factor out ulimit
 	"github.com/docker/docker/pkg/ulimit"
 	"github.com/docker/docker/pkg/ulimit"
 	"github.com/docker/libcontainer"
 	"github.com/docker/libcontainer"
-	"github.com/docker/libcontainer/cgroups/fs"
 	"github.com/docker/libcontainer/configs"
 	"github.com/docker/libcontainer/configs"
 )
 )
 
 
@@ -105,6 +98,7 @@ type NetworkInterface struct {
 	IPv6Gateway          string `json:"ipv6_gateway"`
 	IPv6Gateway          string `json:"ipv6_gateway"`
 }
 }
 
 
+// TODO Windows: Factor out ulimit.Rlimit
 type Resources struct {
 type Resources struct {
 	Memory     int64            `json:"memory"`
 	Memory     int64            `json:"memory"`
 	MemorySwap int64            `json:"memory_swap"`
 	MemorySwap int64            `json:"memory_swap"`
@@ -143,6 +137,9 @@ type ProcessConfig struct {
 	Console    string   `json:"-"` // dev/console path
 	Console    string   `json:"-"` // dev/console path
 }
 }
 
 
+// TODO Windows: Factor out unused fields such as LxcConfig, AppArmorProfile,
+// and CgroupParent.
+//
 // Process wrapps an os/exec.Cmd to add more metadata
 // Process wrapps an os/exec.Cmd to add more metadata
 type Command struct {
 type Command struct {
 	ID                 string            `json:"id"`
 	ID                 string            `json:"id"`
@@ -168,143 +165,3 @@ type Command struct {
 	AppArmorProfile    string            `json:"apparmor_profile"`
 	AppArmorProfile    string            `json:"apparmor_profile"`
 	CgroupParent       string            `json:"cgroup_parent"` // The parent cgroup for this command.
 	CgroupParent       string            `json:"cgroup_parent"` // The parent cgroup for this command.
 }
 }
-
-func InitContainer(c *Command) *configs.Config {
-	container := template.New()
-
-	container.Hostname = getEnv("HOSTNAME", c.ProcessConfig.Env)
-	container.Cgroups.Name = c.ID
-	container.Cgroups.AllowedDevices = c.AllowedDevices
-	container.Devices = c.AutoCreatedDevices
-	container.Rootfs = c.Rootfs
-	container.Readonlyfs = c.ReadonlyRootfs
-
-	// check to see if we are running in ramdisk to disable pivot root
-	container.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != ""
-
-	// Default parent cgroup is "docker". Override if required.
-	if c.CgroupParent != "" {
-		container.Cgroups.Parent = c.CgroupParent
-	}
-	return container
-}
-
-func getEnv(key string, env []string) string {
-	for _, pair := range env {
-		parts := strings.Split(pair, "=")
-		if parts[0] == key {
-			return parts[1]
-		}
-	}
-	return ""
-}
-
-func SetupCgroups(container *configs.Config, c *Command) error {
-	if c.Resources != nil {
-		container.Cgroups.CpuShares = c.Resources.CpuShares
-		container.Cgroups.Memory = c.Resources.Memory
-		container.Cgroups.MemoryReservation = c.Resources.Memory
-		container.Cgroups.MemorySwap = c.Resources.MemorySwap
-		container.Cgroups.CpusetCpus = c.Resources.CpusetCpus
-		container.Cgroups.CpusetMems = c.Resources.CpusetMems
-		container.Cgroups.CpuQuota = c.Resources.CpuQuota
-	}
-
-	return nil
-}
-
-// Returns the network statistics for the network interfaces represented by the NetworkRuntimeInfo.
-func getNetworkInterfaceStats(interfaceName string) (*libcontainer.NetworkInterface, error) {
-	out := &libcontainer.NetworkInterface{Name: interfaceName}
-	// This can happen if the network runtime information is missing - possible if the
-	// container was created by an old version of libcontainer.
-	if interfaceName == "" {
-		return out, nil
-	}
-	type netStatsPair struct {
-		// Where to write the output.
-		Out *uint64
-		// The network stats file to read.
-		File string
-	}
-	// Ingress for host veth is from the container. Hence tx_bytes stat on the host veth is actually number of bytes received by the container.
-	netStats := []netStatsPair{
-		{Out: &out.RxBytes, File: "tx_bytes"},
-		{Out: &out.RxPackets, File: "tx_packets"},
-		{Out: &out.RxErrors, File: "tx_errors"},
-		{Out: &out.RxDropped, File: "tx_dropped"},
-
-		{Out: &out.TxBytes, File: "rx_bytes"},
-		{Out: &out.TxPackets, File: "rx_packets"},
-		{Out: &out.TxErrors, File: "rx_errors"},
-		{Out: &out.TxDropped, File: "rx_dropped"},
-	}
-	for _, netStat := range netStats {
-		data, err := readSysfsNetworkStats(interfaceName, netStat.File)
-		if err != nil {
-			return nil, err
-		}
-		*(netStat.Out) = data
-	}
-	return out, nil
-}
-
-// Reads the specified statistics available under /sys/class/net/<EthInterface>/statistics
-func readSysfsNetworkStats(ethInterface, statsFile string) (uint64, error) {
-	data, err := ioutil.ReadFile(filepath.Join("/sys/class/net", ethInterface, "statistics", statsFile))
-	if err != nil {
-		return 0, err
-	}
-	return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
-}
-
-func Stats(containerDir string, containerMemoryLimit int64, machineMemory int64) (*ResourceStats, error) {
-	f, err := os.Open(filepath.Join(containerDir, "state.json"))
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-
-	type network struct {
-		Type              string
-		HostInterfaceName string
-	}
-
-	state := struct {
-		CgroupPaths map[string]string `json:"cgroup_paths"`
-		Networks    []network
-	}{}
-
-	if err := json.NewDecoder(f).Decode(&state); err != nil {
-		return nil, err
-	}
-	now := time.Now()
-
-	mgr := fs.Manager{Paths: state.CgroupPaths}
-	cstats, err := mgr.GetStats()
-	if err != nil {
-		return nil, err
-	}
-	stats := &libcontainer.Stats{CgroupStats: cstats}
-	// if the container does not have any memory limit specified set the
-	// limit to the machines memory
-	memoryLimit := containerMemoryLimit
-	if memoryLimit == 0 {
-		memoryLimit = machineMemory
-	}
-	for _, iface := range state.Networks {
-		switch iface.Type {
-		case "veth":
-			istats, err := getNetworkInterfaceStats(iface.HostInterfaceName)
-			if err != nil {
-				return nil, err
-			}
-			stats.Interfaces = append(stats.Interfaces, istats)
-		}
-	}
-	return &ResourceStats{
-		Stats:       stats,
-		Read:        now,
-		MemoryLimit: memoryLimit,
-	}, nil
-}

+ 156 - 0
daemon/execdriver/driver_linux.go

@@ -0,0 +1,156 @@
+package execdriver
+
+import (
+	"encoding/json"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/docker/docker/daemon/execdriver/native/template"
+	"github.com/docker/libcontainer"
+	"github.com/docker/libcontainer/cgroups/fs"
+	"github.com/docker/libcontainer/configs"
+)
+
+func InitContainer(c *Command) *configs.Config {
+	container := template.New()
+
+	container.Hostname = getEnv("HOSTNAME", c.ProcessConfig.Env)
+	container.Cgroups.Name = c.ID
+	container.Cgroups.AllowedDevices = c.AllowedDevices
+	container.Devices = c.AutoCreatedDevices
+	container.Rootfs = c.Rootfs
+	container.Readonlyfs = c.ReadonlyRootfs
+
+	// check to see if we are running in ramdisk to disable pivot root
+	container.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != ""
+
+	// Default parent cgroup is "docker". Override if required.
+	if c.CgroupParent != "" {
+		container.Cgroups.Parent = c.CgroupParent
+	}
+	return container
+}
+
+func getEnv(key string, env []string) string {
+	for _, pair := range env {
+		parts := strings.Split(pair, "=")
+		if parts[0] == key {
+			return parts[1]
+		}
+	}
+	return ""
+}
+
+func SetupCgroups(container *configs.Config, c *Command) error {
+	if c.Resources != nil {
+		container.Cgroups.CpuShares = c.Resources.CpuShares
+		container.Cgroups.Memory = c.Resources.Memory
+		container.Cgroups.MemoryReservation = c.Resources.Memory
+		container.Cgroups.MemorySwap = c.Resources.MemorySwap
+		container.Cgroups.CpusetCpus = c.Resources.CpusetCpus
+		container.Cgroups.CpusetMems = c.Resources.CpusetMems
+		container.Cgroups.CpuQuota = c.Resources.CpuQuota
+	}
+
+	return nil
+}
+
+// Returns the network statistics for the network interfaces represented by the NetworkRuntimeInfo.
+func getNetworkInterfaceStats(interfaceName string) (*libcontainer.NetworkInterface, error) {
+	out := &libcontainer.NetworkInterface{Name: interfaceName}
+	// This can happen if the network runtime information is missing - possible if the
+	// container was created by an old version of libcontainer.
+	if interfaceName == "" {
+		return out, nil
+	}
+	type netStatsPair struct {
+		// Where to write the output.
+		Out *uint64
+		// The network stats file to read.
+		File string
+	}
+	// Ingress for host veth is from the container. Hence tx_bytes stat on the host veth is actually number of bytes received by the container.
+	netStats := []netStatsPair{
+		{Out: &out.RxBytes, File: "tx_bytes"},
+		{Out: &out.RxPackets, File: "tx_packets"},
+		{Out: &out.RxErrors, File: "tx_errors"},
+		{Out: &out.RxDropped, File: "tx_dropped"},
+
+		{Out: &out.TxBytes, File: "rx_bytes"},
+		{Out: &out.TxPackets, File: "rx_packets"},
+		{Out: &out.TxErrors, File: "rx_errors"},
+		{Out: &out.TxDropped, File: "rx_dropped"},
+	}
+	for _, netStat := range netStats {
+		data, err := readSysfsNetworkStats(interfaceName, netStat.File)
+		if err != nil {
+			return nil, err
+		}
+		*(netStat.Out) = data
+	}
+	return out, nil
+}
+
+// Reads the specified statistics available under /sys/class/net/<EthInterface>/statistics
+func readSysfsNetworkStats(ethInterface, statsFile string) (uint64, error) {
+	data, err := ioutil.ReadFile(filepath.Join("/sys/class/net", ethInterface, "statistics", statsFile))
+	if err != nil {
+		return 0, err
+	}
+	return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
+}
+
+func Stats(containerDir string, containerMemoryLimit int64, machineMemory int64) (*ResourceStats, error) {
+	f, err := os.Open(filepath.Join(containerDir, "state.json"))
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	type network struct {
+		Type              string
+		HostInterfaceName string
+	}
+
+	state := struct {
+		CgroupPaths map[string]string `json:"cgroup_paths"`
+		Networks    []network
+	}{}
+
+	if err := json.NewDecoder(f).Decode(&state); err != nil {
+		return nil, err
+	}
+	now := time.Now()
+
+	mgr := fs.Manager{Paths: state.CgroupPaths}
+	cstats, err := mgr.GetStats()
+	if err != nil {
+		return nil, err
+	}
+	stats := &libcontainer.Stats{CgroupStats: cstats}
+	// if the container does not have any memory limit specified set the
+	// limit to the machines memory
+	memoryLimit := containerMemoryLimit
+	if memoryLimit == 0 {
+		memoryLimit = machineMemory
+	}
+	for _, iface := range state.Networks {
+		switch iface.Type {
+		case "veth":
+			istats, err := getNetworkInterfaceStats(iface.HostInterfaceName)
+			if err != nil {
+				return nil, err
+			}
+			stats.Interfaces = append(stats.Interfaces, istats)
+		}
+	}
+	return &ResourceStats{
+		Stats:       stats,
+		Read:        now,
+		MemoryLimit: memoryLimit,
+	}, nil
+}