Making it not crash on Windows
Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -3,3 +3,4 @@ containerd-shim/containerd-shim | |||||||
| bin/ | bin/ | ||||||
| ctr/ctr | ctr/ctr | ||||||
| hack/benchmark | hack/benchmark | ||||||
|  | *.exe | ||||||
|   | |||||||
| @@ -1,25 +1,19 @@ | |||||||
| package main | package main | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"log" |  | ||||||
| 	"net" | 	"net" | ||||||
| 	"os" | 	"os" | ||||||
| 	"runtime" |  | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"google.golang.org/grpc" | 	"google.golang.org/grpc" | ||||||
|  |  | ||||||
| 	"github.com/Sirupsen/logrus" | 	"github.com/Sirupsen/logrus" | ||||||
| 	"github.com/cloudfoundry/gosigar" |  | ||||||
| 	"github.com/codegangsta/cli" | 	"github.com/codegangsta/cli" | ||||||
| 	"github.com/cyberdelia/go-metrics-graphite" |  | ||||||
| 	"github.com/docker/containerd" | 	"github.com/docker/containerd" | ||||||
| 	"github.com/docker/containerd/api/grpc/server" | 	"github.com/docker/containerd/api/grpc/server" | ||||||
| 	"github.com/docker/containerd/api/grpc/types" | 	"github.com/docker/containerd/api/grpc/types" | ||||||
| 	"github.com/docker/containerd/osutils" |  | ||||||
| 	"github.com/docker/containerd/supervisor" | 	"github.com/docker/containerd/supervisor" | ||||||
| 	"github.com/rcrowley/go-metrics" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -34,7 +28,7 @@ var daemonFlags = []cli.Flag{ | |||||||
| 	}, | 	}, | ||||||
| 	cli.StringFlag{ | 	cli.StringFlag{ | ||||||
| 		Name:  "state-dir", | 		Name:  "state-dir", | ||||||
| 		Value: "/run/containerd", | 		Value: defaultStateDir, | ||||||
| 		Usage: "runtime state directory", | 		Usage: "runtime state directory", | ||||||
| 	}, | 	}, | ||||||
| 	cli.DurationFlag{ | 	cli.DurationFlag{ | ||||||
| @@ -44,43 +38,26 @@ var daemonFlags = []cli.Flag{ | |||||||
| 	}, | 	}, | ||||||
| 	cli.StringFlag{ | 	cli.StringFlag{ | ||||||
| 		Name:  "listen,l", | 		Name:  "listen,l", | ||||||
| 		Value: "/run/containerd/containerd.sock", | 		Value: defaultGRPCEndpoint, | ||||||
| 		Usage: "Address on which GRPC API will listen", | 		Usage: "Address on which GRPC API will listen", | ||||||
| 	}, | 	}, | ||||||
| 	cli.BoolFlag{ |  | ||||||
| 		Name:  "oom-notify", |  | ||||||
| 		Usage: "enable oom notifications for containers", |  | ||||||
| 	}, |  | ||||||
| 	cli.StringFlag{ |  | ||||||
| 		Name:  "graphite-address", |  | ||||||
| 		Usage: "Address of graphite server", |  | ||||||
| 	}, |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func main() { | func main() { | ||||||
|  | 	appendPlatformFlags() | ||||||
| 	app := cli.NewApp() | 	app := cli.NewApp() | ||||||
| 	app.Name = "containerd" | 	app.Name = "containerd" | ||||||
| 	app.Version = containerd.Version | 	app.Version = containerd.Version | ||||||
| 	app.Usage = usage | 	app.Usage = usage | ||||||
| 	app.Flags = daemonFlags | 	app.Flags = daemonFlags | ||||||
| 	app.Before = func(context *cli.Context) error { | 	setAppBefore(app) | ||||||
| 		if context.GlobalBool("debug") { |  | ||||||
| 			logrus.SetLevel(logrus.DebugLevel) |  | ||||||
| 			if err := debugMetrics(context.GlobalDuration("metrics-interval"), context.GlobalString("graphite-address")); err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if err := checkLimits(); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	app.Action = func(context *cli.Context) { | 	app.Action = func(context *cli.Context) { | ||||||
| 		if err := daemon( | 		if err := daemon( | ||||||
| 			context.String("listen"), | 			context.String("listen"), | ||||||
| 			context.String("state-dir"), | 			context.String("state-dir"), | ||||||
| 			10, | 			10, | ||||||
| 			context.Bool("oom-notify"), | 			context.Bool("oom-notify"), // TODO Windows: Remove oom-notify | ||||||
| 		); err != nil { | 		); err != nil { | ||||||
| 			logrus.Fatal(err) | 			logrus.Fatal(err) | ||||||
| 		} | 		} | ||||||
| @@ -90,59 +67,6 @@ func main() { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func debugMetrics(interval time.Duration, graphiteAddr string) error { |  | ||||||
| 	for name, m := range supervisor.Metrics() { |  | ||||||
| 		if err := metrics.DefaultRegistry.Register(name, m); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	processMetrics() |  | ||||||
| 	if graphiteAddr != "" { |  | ||||||
| 		addr, err := net.ResolveTCPAddr("tcp", graphiteAddr) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		go graphite.Graphite(metrics.DefaultRegistry, 10e9, "metrics", addr) |  | ||||||
| 	} else { |  | ||||||
| 		l := log.New(os.Stdout, "[containerd] ", log.LstdFlags) |  | ||||||
| 		go metrics.Log(metrics.DefaultRegistry, interval, l) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func processMetrics() { |  | ||||||
| 	var ( |  | ||||||
| 		g    = metrics.NewGauge() |  | ||||||
| 		fg   = metrics.NewGauge() |  | ||||||
| 		memg = metrics.NewGauge() |  | ||||||
| 	) |  | ||||||
| 	metrics.DefaultRegistry.Register("goroutines", g) |  | ||||||
| 	metrics.DefaultRegistry.Register("fds", fg) |  | ||||||
| 	metrics.DefaultRegistry.Register("memory-used", memg) |  | ||||||
| 	collect := func() { |  | ||||||
| 		// update number of goroutines |  | ||||||
| 		g.Update(int64(runtime.NumGoroutine())) |  | ||||||
| 		// collect the number of open fds |  | ||||||
| 		fds, err := osutils.GetOpenFds(os.Getpid()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			logrus.WithField("error", err).Error("containerd: get open fd count") |  | ||||||
| 		} |  | ||||||
| 		fg.Update(int64(fds)) |  | ||||||
| 		// get the memory used |  | ||||||
| 		m := sigar.ProcMem{} |  | ||||||
| 		if err := m.Get(os.Getpid()); err != nil { |  | ||||||
| 			logrus.WithField("error", err).Error("containerd: get pid memory information") |  | ||||||
| 		} |  | ||||||
| 		memg.Update(int64(m.Size)) |  | ||||||
| 	} |  | ||||||
| 	go func() { |  | ||||||
| 		collect() |  | ||||||
| 		for range time.Tick(30 * time.Second) { |  | ||||||
| 			collect() |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func daemon(address, stateDir string, concurrency int, oom bool) error { | func daemon(address, stateDir string, concurrency int, oom bool) error { | ||||||
| 	// setup a standard reaper so that we don't leave any zombies if we are still alive | 	// setup a standard reaper so that we don't leave any zombies if we are still alive | ||||||
| 	// this is just good practice because we are spawning new processes | 	// this is just good practice because we are spawning new processes | ||||||
| @@ -163,7 +87,7 @@ func daemon(address, stateDir string, concurrency int, oom bool) error { | |||||||
| 	if err := os.RemoveAll(address); err != nil { | 	if err := os.RemoveAll(address); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	l, err := net.Listen("unix", address) | 	l, err := net.Listen(defaultListenType, address) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -1,14 +1,55 @@ | |||||||
| package main | package main | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"log" | ||||||
|  | 	"net" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/signal" | 	"os/signal" | ||||||
|  | 	"runtime" | ||||||
| 	"syscall" | 	"syscall" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/Sirupsen/logrus" | 	"github.com/Sirupsen/logrus" | ||||||
|  | 	"github.com/cloudfoundry/gosigar" | ||||||
|  | 	"github.com/codegangsta/cli" | ||||||
|  | 	"github.com/cyberdelia/go-metrics-graphite" | ||||||
| 	"github.com/docker/containerd/osutils" | 	"github.com/docker/containerd/osutils" | ||||||
|  | 	"github.com/docker/containerd/supervisor" | ||||||
|  | 	"github.com/rcrowley/go-metrics" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	defaultStateDir     = "/run/containerd" | ||||||
|  | 	defaultListenType   = "unix" | ||||||
|  | 	defaultGRPCEndpoint = "/run/containerd/containerd.sock" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func appendPlatformFlags() { | ||||||
|  | 	daemonFlags = append(daemonFlags, cli.BoolFlag{ | ||||||
|  | 		Name:  "oom-notify", | ||||||
|  | 		Usage: "enable oom notifications for containers", | ||||||
|  | 	}) | ||||||
|  | 	daemonFlags = append(daemonFlags, cli.StringFlag{ | ||||||
|  | 		Name:  "graphite-address", | ||||||
|  | 		Usage: "Address of graphite server", | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func setAppBefore(app *cli.App) { | ||||||
|  | 	app.Before = func(context *cli.Context) error { | ||||||
|  | 		if context.GlobalBool("debug") { | ||||||
|  | 			logrus.SetLevel(logrus.DebugLevel) | ||||||
|  | 			if err := debugMetrics(context.GlobalDuration("metrics-interval"), context.GlobalString("graphite-address")); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if err := checkLimits(); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func checkLimits() error { | func checkLimits() error { | ||||||
| 	var l syscall.Rlimit | 	var l syscall.Rlimit | ||||||
| 	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l); err != nil { | 	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l); err != nil { | ||||||
| @@ -37,3 +78,56 @@ func reapProcesses() { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func processMetrics() { | ||||||
|  | 	var ( | ||||||
|  | 		g    = metrics.NewGauge() | ||||||
|  | 		fg   = metrics.NewGauge() | ||||||
|  | 		memg = metrics.NewGauge() | ||||||
|  | 	) | ||||||
|  | 	metrics.DefaultRegistry.Register("goroutines", g) | ||||||
|  | 	metrics.DefaultRegistry.Register("fds", fg) | ||||||
|  | 	metrics.DefaultRegistry.Register("memory-used", memg) | ||||||
|  | 	collect := func() { | ||||||
|  | 		// update number of goroutines | ||||||
|  | 		g.Update(int64(runtime.NumGoroutine())) | ||||||
|  | 		// collect the number of open fds | ||||||
|  | 		fds, err := osutils.GetOpenFds(os.Getpid()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			logrus.WithField("error", err).Error("containerd: get open fd count") | ||||||
|  | 		} | ||||||
|  | 		fg.Update(int64(fds)) | ||||||
|  | 		// get the memory used | ||||||
|  | 		m := sigar.ProcMem{} | ||||||
|  | 		if err := m.Get(os.Getpid()); err != nil { | ||||||
|  | 			logrus.WithField("error", err).Error("containerd: get pid memory information") | ||||||
|  | 		} | ||||||
|  | 		memg.Update(int64(m.Size)) | ||||||
|  | 	} | ||||||
|  | 	go func() { | ||||||
|  | 		collect() | ||||||
|  | 		for range time.Tick(30 * time.Second) { | ||||||
|  | 			collect() | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func debugMetrics(interval time.Duration, graphiteAddr string) error { | ||||||
|  | 	for name, m := range supervisor.Metrics() { | ||||||
|  | 		if err := metrics.DefaultRegistry.Register(name, m); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	processMetrics() | ||||||
|  | 	if graphiteAddr != "" { | ||||||
|  | 		addr, err := net.ResolveTCPAddr("tcp", graphiteAddr) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		go graphite.Graphite(metrics.DefaultRegistry, 10e9, "metrics", addr) | ||||||
|  | 	} else { | ||||||
|  | 		l := log.New(os.Stdout, "[containerd] ", log.LstdFlags) | ||||||
|  | 		go metrics.Log(metrics.DefaultRegistry, interval, l) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,5 +1,21 @@ | |||||||
| package main | package main | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  |  | ||||||
|  | 	"github.com/codegangsta/cli" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var defaultStateDir = os.Getenv("PROGRAMDATA") + `\docker\containerd` | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	defaultListenType   = "tcp" | ||||||
|  | 	defaultGRPCEndpoint = "localhost:2377" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func appendPlatformFlags() { | ||||||
|  | } | ||||||
|  |  | ||||||
| // TODO Windows: May be able to factor out entirely | // TODO Windows: May be able to factor out entirely | ||||||
| func checkLimits() error { | func checkLimits() error { | ||||||
| 	return nil | 	return nil | ||||||
| @@ -8,3 +24,6 @@ func checkLimits() error { | |||||||
| // No idea how to implement this on Windows. | // No idea how to implement this on Windows. | ||||||
| func reapProcesses() { | func reapProcesses() { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func setAppBefore(app *cli.App) { | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,23 +1,6 @@ | |||||||
| package supervisor | package supervisor | ||||||
|  |  | ||||||
| import "github.com/cloudfoundry/gosigar" |  | ||||||
|  |  | ||||||
| type Machine struct { | type Machine struct { | ||||||
| 	Cpus   int | 	Cpus   int | ||||||
| 	Memory int64 | 	Memory int64 | ||||||
| } | } | ||||||
|  |  | ||||||
| func CollectMachineInformation() (Machine, error) { |  | ||||||
| 	m := Machine{} |  | ||||||
| 	cpu := sigar.CpuList{} |  | ||||||
| 	if err := cpu.Get(); err != nil { |  | ||||||
| 		return m, err |  | ||||||
| 	} |  | ||||||
| 	m.Cpus = len(cpu.List) |  | ||||||
| 	mem := sigar.Mem{} |  | ||||||
| 	if err := mem.Get(); err != nil { |  | ||||||
| 		return m, err |  | ||||||
| 	} |  | ||||||
| 	m.Memory = int64(mem.Total / 1024 / 1024) |  | ||||||
| 	return m, nil |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								supervisor/machine_linux.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								supervisor/machine_linux.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | package supervisor | ||||||
|  |  | ||||||
|  | import "github.com/cloudfoundry/gosigar" | ||||||
|  |  | ||||||
|  | func CollectMachineInformation() (Machine, error) { | ||||||
|  | 	m := Machine{} | ||||||
|  | 	cpu := sigar.CpuList{} | ||||||
|  | 	if err := cpu.Get(); err != nil { | ||||||
|  | 		return m, err | ||||||
|  | 	} | ||||||
|  | 	m.Cpus = len(cpu.List) | ||||||
|  | 	mem := sigar.Mem{} | ||||||
|  | 	if err := mem.Get(); err != nil { | ||||||
|  | 		return m, err | ||||||
|  | 	} | ||||||
|  | 	m.Memory = int64(mem.Total / 1024 / 1024) | ||||||
|  | 	return m, nil | ||||||
|  | } | ||||||
							
								
								
									
										5
									
								
								supervisor/machine_windows.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								supervisor/machine_windows.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | package supervisor | ||||||
|  |  | ||||||
|  | func CollectMachineInformation() (Machine, error) { | ||||||
|  | 	return Machine{}, nil | ||||||
|  | } | ||||||
| @@ -11,7 +11,8 @@ import ( | |||||||
| // Linux implementation. @crosbymichael - Help needed. | // Linux implementation. @crosbymichael - Help needed. | ||||||
|  |  | ||||||
| func NewMonitor() (*Monitor, error) { | func NewMonitor() (*Monitor, error) { | ||||||
| 	return nil, errors.New("NewMonitor not implemented on Windows") | 	// During Windows bring-up, don't error out other binary bombs immediately. | ||||||
|  | 	return &Monitor{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| type Monitor struct { | type Monitor struct { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 John Howard
					John Howard