1
0
mirror of https://github.com/bingohuang/docker-labs.git synced 2025-07-14 18:27:25 +08:00

Merge pull request #68 from franela/show_swarm_ports

Show docker swarm used ports
This commit is contained in:
Jonathan Leibiusky 2016-12-13 08:03:41 -06:00 committed by GitHub
commit c0a4553a69
10 changed files with 110 additions and 15 deletions

View File

@ -1,6 +1,8 @@
FROM docker:1.13.0-rc2-dind
ENV DOCKER_STORAGE_DRIVER=overlay2
ARG docker_storage_driver=overlay2
ENV DOCKER_STORAGE_DRIVER=${docker-storage-driver}
RUN apk add --no-cache git tmux py-pip apache2-utils vim build-base gettext-dev curl bash

View File

@ -6,7 +6,7 @@ services:
# use the latest golang image
image: golang
# go to the right place and starts the app
command: /bin/sh -c 'cd /go/src/github.com/franela/play-with-docker; go run -race api.go'
command: /bin/sh -c 'cd /go/src/github.com/franela/play-with-docker; go run api.go'
ports:
# app exposes port 3000
- "3000:3000"

View File

@ -1,8 +0,0 @@
package services
type broadcastInfoTask struct {
}
func (c *broadcastInfoTask) Run(i *Instance) {
wsServer.BroadcastTo(i.session.Id, "instance stats", i.Name, i.Mem, i.Cpu, i.IsManager, i.Ports)
}

View File

@ -1,6 +1,10 @@
package services
import "github.com/docker/docker/api/types/swarm"
import (
"log"
"github.com/docker/docker/api/types/swarm"
)
type checkSwarmStatusTask struct {
}
@ -12,6 +16,8 @@ func (c checkSwarmStatusTask) Run(i *Instance) {
} else {
i.IsManager = nil
}
} else {
log.Println(err)
}
}

View File

@ -0,0 +1,15 @@
package services
import "log"
type checkSwarmUsedPortsTask struct {
}
func (c checkSwarmUsedPortsTask) Run(i *Instance) {
if i.IsManager != nil && *i.IsManager {
// This is a swarm manager instance, then check for ports
if err := SetInstanceSwarmPorts(i); err != nil {
log.Println(err)
}
}
}

View File

@ -5,6 +5,8 @@ type checkUsedPortsTask struct {
func (c checkUsedPortsTask) Run(i *Instance) {
if ports, err := GetUsedPorts(i); err == nil {
i.Ports = ports
for _, p := range ports {
i.setUsedPort(p)
}
}
}

View File

@ -4,6 +4,7 @@ import (
"fmt"
"io"
"log"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
@ -46,6 +47,55 @@ func GetDaemonInfo(i *Instance) (types.Info, error) {
}
return i.dockerClient.Info(context.Background())
}
func SetInstanceSwarmPorts(i *Instance) error {
if i.dockerClient == nil {
return fmt.Errorf("Docker client for DinD (%s) is not ready", i.IP)
}
hostnamesIdx := map[string]*Instance{}
for _, ins := range i.session.Instances {
hostnamesIdx[ins.Hostname] = ins
}
nodesIdx := map[string]*Instance{}
nodes, nodesErr := i.dockerClient.NodeList(context.Background(), types.NodeListOptions{})
if nodesErr != nil {
return nodesErr
}
for _, n := range nodes {
nodesIdx[n.ID] = hostnamesIdx[n.Description.Hostname]
}
tasks, err := i.dockerClient.TaskList(context.Background(), types.TaskListOptions{})
if err != nil {
return err
}
services := map[string][]uint16{}
for _, t := range tasks {
services[t.ServiceID] = []uint16{}
}
for serviceID, _ := range services {
s, _, err := i.dockerClient.ServiceInspectWithRaw(context.Background(), serviceID)
if err != nil {
return err
}
for _, p := range s.Endpoint.Ports {
services[serviceID] = append(services[serviceID], uint16(p.PublishedPort))
}
}
for _, t := range tasks {
for _, n := range nodes {
ins := nodesIdx[n.ID]
for _, p := range services[t.ServiceID] {
ins.setUsedPort(p)
}
}
}
return nil
}
func GetUsedPorts(i *Instance) ([]uint16, error) {
if i.dockerClient == nil {
return nil, fmt.Errorf("Docker client for DinD (%s) is not ready", i.IP)
@ -84,7 +134,7 @@ func CreateNetwork(name string) error {
func ConnectNetwork(containerId, networkId string) error {
err := c.NetworkConnect(context.Background(), networkId, containerId, &network.EndpointSettings{})
if err != nil {
if err != nil && !strings.Contains(err.Error(), "already exists") {
log.Printf("Connection container to network err [%s]\n", err)
return err

View File

@ -28,6 +28,19 @@ type Instance struct {
Mem string `json:"mem"`
Cpu string `json:"cpu"`
Ports []uint16 `json:"ports"`
tempPorts []uint16 `json:"-"`
}
func (i *Instance) setUsedPort(port uint16) {
rw.Lock()
defer rw.Unlock()
for _, p := range i.tempPorts {
if p == port {
return
}
}
i.tempPorts = append(i.tempPorts, port)
}
func (i *Instance) IsConnected() bool {

View File

@ -94,6 +94,12 @@ func (s *Session) SchedulePeriodicTasks() {
}()
}
wg.Wait()
// broadcast all information
for _, ins := range s.Instances {
ins.Ports = ins.tempPorts
ins.tempPorts = []uint16{}
wsServer.BroadcastTo(ins.session.Id, "instance stats", ins.Name, ins.Mem, ins.Cpu, ins.IsManager, ins.Ports)
}
}
}()
}
@ -123,7 +129,9 @@ func CloseSession(s *Session) error {
s.rw.Lock()
defer s.rw.Unlock()
s.ticker.Stop()
if s.ticker != nil {
s.ticker.Stop()
}
wsServer.BroadcastTo(s.Id, "session end")
log.Printf("Starting clean up of session [%s]\n", s.Id)
for _, i := range s.Instances {
@ -238,6 +246,13 @@ func LoadSessionsFromDisk() error {
}
// Connect PWD daemon to the new network
if err := ConnectNetwork("pwd", s.Id); err != nil {
log.Println("ERROR NETWORKING")
return err
}
log.Printf("Connected pwd to network [%s]\n", s.Id)
// Schedule peridic tasks execution
s.SchedulePeriodicTasks()
}

View File

@ -7,5 +7,5 @@ type periodicTask interface {
var periodicTasks []periodicTask
func init() {
periodicTasks = append(periodicTasks, &collectStatsTask{}, &checkSwarmStatusTask{}, &checkUsedPortsTask{}, &broadcastInfoTask{})
periodicTasks = append(periodicTasks, &collectStatsTask{}, &checkSwarmStatusTask{}, &checkUsedPortsTask{}, &checkSwarmUsedPortsTask{})
}