This commit is contained in:
Jonathan Leibiusky @xetorthio
2017-05-23 19:29:36 -03:00
parent 911d56bc49
commit 3d96760a98
41 changed files with 1454 additions and 1329 deletions

118
pwd/tasks.go Normal file
View File

@@ -0,0 +1,118 @@
package pwd
import (
"crypto/tls"
"fmt"
"log"
"net"
"net/http"
"sort"
"strings"
"sync"
"time"
"github.com/docker/docker/api"
"github.com/docker/docker/client"
"github.com/docker/go-connections/tlsconfig"
"github.com/play-with-docker/play-with-docker/docker"
)
type periodicTask interface {
Run(i *Instance) error
}
type SchedulerApi interface {
Schedule(session *Session)
Unschedule(session *Session)
}
type scheduler struct {
broadcast BroadcastApi
periodicTasks []periodicTask
}
func (sch *scheduler) Schedule(s *Session) {
if s.scheduled {
return
}
go func() {
s.scheduled = true
s.ticker = time.NewTicker(1 * time.Second)
for range s.ticker.C {
var wg = sync.WaitGroup{}
wg.Add(len(s.Instances))
for _, ins := range s.Instances {
var i *Instance = ins
if i.docker == nil {
// Need to create client to the DinD docker daemon
// We check if the client needs to use TLS
var tlsConfig *tls.Config
if len(i.Cert) > 0 && len(i.Key) > 0 {
tlsConfig = tlsconfig.ClientDefault()
tlsConfig.InsecureSkipVerify = true
tlsCert, err := tls.X509KeyPair(i.Cert, i.Key)
if err != nil {
log.Println("Could not load X509 key pair: %v. Make sure the key is not encrypted", err)
continue
}
tlsConfig.Certificates = []tls.Certificate{tlsCert}
}
transport := &http.Transport{
DialContext: (&net.Dialer{
Timeout: 1 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext}
if tlsConfig != nil {
transport.TLSClientConfig = tlsConfig
}
cli := &http.Client{
Transport: transport,
}
c, err := client.NewClient(fmt.Sprintf("http://%s:2375", i.IP), api.DefaultVersion, cli, nil)
if err != nil {
log.Println("Could not connect to DinD docker daemon", err)
} else {
i.docker = docker.NewDocker(c)
}
}
go func() {
defer wg.Done()
for _, t := range sch.periodicTasks {
err := t.Run(i)
if err != nil {
if strings.Contains(err.Error(), "No such container") {
log.Printf("Container for instance [%s] doesn't exist any more.\n", i.IP)
//DeleteInstance(i.session, i)
} else {
log.Println(err)
}
break
}
}
}()
}
wg.Wait()
// broadcast all information
for _, ins := range s.Instances {
ins.Ports = UInt16Slice(ins.tempPorts)
sort.Sort(ins.Ports)
ins.tempPorts = []uint16{}
sch.broadcast.BroadcastTo(ins.session.Id, "instance stats", ins.Name, ins.Mem, ins.Cpu, ins.IsManager, ins.Ports)
}
}
}()
}
func (sch *scheduler) Unschedule(s *Session) {
}
func NewScheduler(b BroadcastApi, d docker.DockerApi) *scheduler {
s := &scheduler{broadcast: b}
s.periodicTasks = []periodicTask{&collectStatsTask{docker: d}, &checkSwarmStatusTask{}, &checkUsedPortsTask{}, &checkSwarmUsedPortsTask{}}
return s
}