diff --git a/Dockerfile.dind b/Dockerfile.dind index c1c46a1..25d3614 100644 --- a/Dockerfile.dind +++ b/Dockerfile.dind @@ -1,4 +1,4 @@ -FROM docker:1.13.0-rc1-dind +FROM docker:1.13.0-rc2-dind ENV DOCKER_STORAGE_DRIVER=overlay2 diff --git a/docker-compose.yml b/docker-compose.yml index 5545a8a..17329e4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,4 +14,4 @@ services: # since this app creates networks and launches containers, we need to talk to docker daemon - /var/run/docker.sock:/var/run/docker.sock # mount the box mounted shared folder to the container - - /go/src:/go/src + - $GOPATH/src:/go/src diff --git a/services/docker.go b/services/docker.go index 39c576c..f7c6b52 100644 --- a/services/docker.go +++ b/services/docker.go @@ -4,6 +4,9 @@ import ( "fmt" "io" "log" + "net" + "net/http" + "time" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" @@ -40,6 +43,22 @@ func GetContainerInfo(id string) (types.ContainerJSON, error) { return c.ContainerInspect(context.Background(), id) } +func GetDaemonInfo(host string) (types.Info, error) { + transport := &http.Transport{ + DialContext: (&net.Dialer{ + Timeout: 1 * time.Second, + KeepAlive: 30 * time.Second, + }).DialContext} + cli := &http.Client{ + Transport: transport, + } + c, err := client.NewClient(host, client.DefaultVersion, cli, nil) + if err != nil { + return types.Info{}, err + } + return c.Info(context.Background()) +} + func CreateNetwork(name string) error { opts := types.NetworkCreate{Driver: "overlay", Attachable: true} _, err := c.NetworkCreate(context.Background(), name, opts) diff --git a/services/instance.go b/services/instance.go index 9ce093d..e0a0614 100644 --- a/services/instance.go +++ b/services/instance.go @@ -12,6 +12,7 @@ import ( "golang.org/x/text/encoding" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" units "github.com/docker/go-units" ) @@ -90,6 +91,7 @@ func (s *sessionWriter) Write(p []byte) (n int, err error) { } func (o *Instance) CollectStats() { + reader, err := GetContainerStats(o.Name) if err != nil { log.Println("Error while trying to collect instance stats", err) @@ -115,6 +117,15 @@ func (o *Instance) CollectStats() { break } + var isManager *bool + if info, err := GetDaemonInfo(fmt.Sprintf("http://%s:2375", o.IP)); err == nil { + if info.Swarm.LocalNodeState != swarm.LocalNodeStateInactive && info.Swarm.LocalNodeState != swarm.LocalNodeStateLocked { + isManager = &info.Swarm.ControlAvailable + } + } else { + fmt.Println(info, err) + } + // Memory if v.MemoryStats.Limit != 0 { memPercent = float64(v.MemoryStats.Usage) / float64(v.MemoryStats.Limit) * 100.0 @@ -130,7 +141,7 @@ func (o *Instance) CollectStats() { cpuPercent = calculateCPUPercentUnix(previousCPU, previousSystem, v) cpuFormatted = fmt.Sprintf("%.2f%%", cpuPercent) - wsServer.BroadcastTo(o.session.Id, "instance stats", o.Name, memFormatted, cpuFormatted) + wsServer.BroadcastTo(o.session.Id, "instance stats", o.Name, memFormatted, cpuFormatted, isManager) } } diff --git a/www/assets/app.js b/www/assets/app.js index 477608b..9f384e0 100644 --- a/www/assets/app.js +++ b/www/assets/app.js @@ -3,6 +3,7 @@ var app = angular.module('DockerPlay', ['ngMaterial']); + app.controller('PlayController', ['$scope', '$log', '$http', '$location', '$timeout', '$mdDialog', '$window', function($scope, $log, $http, $location, $timeout, $mdDialog, $window) { $scope.sessionId = window.location.pathname.replace('/p/', ''); $scope.instances = []; @@ -132,9 +133,10 @@ $scope.connected = true; }); - socket.on('instance stats', function(name, mem, cpu) { + socket.on('instance stats', function(name, mem, cpu, isManager) { $scope.idx[name].mem = mem; $scope.idx[name].cpu = cpu; + $scope.idx[name].isManager = isManager; $scope.$apply(); }); @@ -210,7 +212,7 @@ }); term.open(terminalContainer); - + // Set geometry during the next tick, to avoid race conditions. setTimeout(function() { $scope.resize(term.proposeGeometry()); @@ -231,5 +233,9 @@ cb(); } } - }]); + }]) + + .config(['$mdIconProvider', function($mdIconProvider) { + $mdIconProvider.defaultIconSet('../assets/social-icons.svg', 24); + }]); })(); diff --git a/www/assets/social-icons.svg b/www/assets/social-icons.svg new file mode 100644 index 0000000..3b39255 --- /dev/null +++ b/www/assets/social-icons.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/index.html b/www/index.html index 47eabeb..d47330d 100644 --- a/www/index.html +++ b/www/index.html @@ -40,8 +40,10 @@ + Add new instance - - {{instance.name}} ({{instance.hostname}}) + + + + {{instance.name}}
{{instance.name}}