Merge branch 'next' of github.com:xetorthio/play-with-docker into next
This commit is contained in:
2
api.go
2
api.go
@@ -32,7 +32,7 @@ func main() {
|
|||||||
task.NewCheckPorts(e, f),
|
task.NewCheckPorts(e, f),
|
||||||
task.NewCheckSwarmPorts(e, f),
|
task.NewCheckSwarmPorts(e, f),
|
||||||
task.NewCheckSwarmStatus(e, f),
|
task.NewCheckSwarmStatus(e, f),
|
||||||
task.NewCollectStats(e, f),
|
task.NewCollectStats(e, f, s),
|
||||||
}
|
}
|
||||||
sch, err := scheduler.NewScheduler(tasks, s, e, core)
|
sch, err := scheduler.NewScheduler(tasks, s, e, core)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type FactoryApi interface {
|
type FactoryApi interface {
|
||||||
GetForSession(sessionId string) (DockerApi, error)
|
GetForSession(session *types.Session) (DockerApi, error)
|
||||||
GetForInstance(instance *types.Instance) (DockerApi, error)
|
GetForInstance(instance *types.Instance) (DockerApi, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ type FactoryMock struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *FactoryMock) GetForSession(sessionId string) (DockerApi, error) {
|
func (m *FactoryMock) GetForSession(session *types.Session) (DockerApi, error) {
|
||||||
args := m.Called(sessionId)
|
args := m.Called(session)
|
||||||
return args.Get(0).(DockerApi), args.Error(1)
|
return args.Get(0).(DockerApi), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ type instanceEntry struct {
|
|||||||
client DockerApi
|
client DockerApi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *localCachedFactory) GetForSession(sessionId string) (DockerApi, error) {
|
func (f *localCachedFactory) GetForSession(session *types.Session) (DockerApi, error) {
|
||||||
f.rw.Lock()
|
f.rw.Lock()
|
||||||
defer f.rw.Unlock()
|
defer f.rw.Unlock()
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
lru "github.com/hashicorp/golang-lru"
|
||||||
"github.com/play-with-docker/play-with-docker/config"
|
"github.com/play-with-docker/play-with-docker/config"
|
||||||
"github.com/play-with-docker/play-with-docker/docker"
|
"github.com/play-with-docker/play-with-docker/docker"
|
||||||
"github.com/play-with-docker/play-with-docker/id"
|
"github.com/play-with-docker/play-with-docker/id"
|
||||||
@@ -22,10 +23,12 @@ type DinD struct {
|
|||||||
factory docker.FactoryApi
|
factory docker.FactoryApi
|
||||||
storage storage.StorageApi
|
storage storage.StorageApi
|
||||||
generator id.Generator
|
generator id.Generator
|
||||||
|
cache *lru.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDinD(generator id.Generator, f docker.FactoryApi, s storage.StorageApi) *DinD {
|
func NewDinD(generator id.Generator, f docker.FactoryApi, s storage.StorageApi) *DinD {
|
||||||
return &DinD{generator: generator, factory: f, storage: s}
|
c, _ := lru.New(5000)
|
||||||
|
return &DinD{generator: generator, factory: f, storage: s, cache: c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkHostnameExists(sessionId, hostname string, instances []*types.Instance) bool {
|
func checkHostnameExists(sessionId, hostname string, instances []*types.Instance) bool {
|
||||||
@@ -73,7 +76,7 @@ func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (*
|
|||||||
Networks: []string{session.Id},
|
Networks: []string{session.Id},
|
||||||
}
|
}
|
||||||
|
|
||||||
dockerClient, err := d.factory.GetForSession(session.Id)
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -105,8 +108,23 @@ func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (*
|
|||||||
return instance, nil
|
return instance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *DinD) getSession(sessionId string) (*types.Session, error) {
|
||||||
|
var session *types.Session
|
||||||
|
if s, found := d.cache.Get(sessionId); !found {
|
||||||
|
s, err := d.storage.SessionGet(sessionId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
session = s
|
||||||
|
d.cache.Add(sessionId, s)
|
||||||
|
} else {
|
||||||
|
session = s.(*types.Session)
|
||||||
|
}
|
||||||
|
return session, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *DinD) InstanceDelete(session *types.Session, instance *types.Instance) error {
|
func (d *DinD) InstanceDelete(session *types.Session, instance *types.Instance) error {
|
||||||
dockerClient, err := d.factory.GetForSession(session.Id)
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -118,7 +136,11 @@ func (d *DinD) InstanceDelete(session *types.Session, instance *types.Instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DinD) InstanceExec(instance *types.Instance, cmd []string) (int, error) {
|
func (d *DinD) InstanceExec(instance *types.Instance, cmd []string) (int, error) {
|
||||||
dockerClient, err := d.factory.GetForSession(instance.SessionId)
|
session, err := d.getSession(instance.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
@@ -126,7 +148,11 @@ func (d *DinD) InstanceExec(instance *types.Instance, cmd []string) (int, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DinD) InstanceResizeTerminal(instance *types.Instance, rows, cols uint) error {
|
func (d *DinD) InstanceResizeTerminal(instance *types.Instance, rows, cols uint) error {
|
||||||
dockerClient, err := d.factory.GetForSession(instance.SessionId)
|
session, err := d.getSession(instance.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -134,7 +160,11 @@ func (d *DinD) InstanceResizeTerminal(instance *types.Instance, rows, cols uint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DinD) InstanceGetTerminal(instance *types.Instance) (net.Conn, error) {
|
func (d *DinD) InstanceGetTerminal(instance *types.Instance) (net.Conn, error) {
|
||||||
dockerClient, err := d.factory.GetForSession(instance.SessionId)
|
session, err := d.getSession(instance.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -151,7 +181,11 @@ func (d *DinD) InstanceUploadFromUrl(instance *types.Instance, fileName, dest, u
|
|||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
return fmt.Errorf("Could not download file [%s]. Status code: %d\n", url, resp.StatusCode)
|
return fmt.Errorf("Could not download file [%s]. Status code: %d\n", url, resp.StatusCode)
|
||||||
}
|
}
|
||||||
dockerClient, err := d.factory.GetForSession(instance.SessionId)
|
session, err := d.getSession(instance.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -166,7 +200,11 @@ func (d *DinD) InstanceUploadFromUrl(instance *types.Instance, fileName, dest, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DinD) getInstanceCWD(instance *types.Instance) (string, error) {
|
func (d *DinD) getInstanceCWD(instance *types.Instance) (string, error) {
|
||||||
dockerClient, err := d.factory.GetForSession(instance.SessionId)
|
session, err := d.getSession(instance.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -184,7 +222,11 @@ func (d *DinD) getInstanceCWD(instance *types.Instance) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DinD) InstanceUploadFromReader(instance *types.Instance, fileName, dest string, reader io.Reader) error {
|
func (d *DinD) InstanceUploadFromReader(instance *types.Instance, fileName, dest string, reader io.Reader) error {
|
||||||
dockerClient, err := d.factory.GetForSession(instance.SessionId)
|
session, err := d.getSession(instance.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func NewOverlaySessionProvisioner(df docker.FactoryApi) SessionProvisionerApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *overlaySessionProvisioner) SessionNew(s *types.Session) error {
|
func (p *overlaySessionProvisioner) SessionNew(s *types.Session) error {
|
||||||
dockerClient, err := p.dockerFactory.GetForSession(s.Id)
|
dockerClient, err := p.dockerFactory.GetForSession(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// We assume we are out of capacity
|
// We assume we are out of capacity
|
||||||
return fmt.Errorf("Out of capacity")
|
return fmt.Errorf("Out of capacity")
|
||||||
@@ -52,7 +52,7 @@ func (p *overlaySessionProvisioner) SessionNew(s *types.Session) error {
|
|||||||
}
|
}
|
||||||
func (p *overlaySessionProvisioner) SessionClose(s *types.Session) error {
|
func (p *overlaySessionProvisioner) SessionClose(s *types.Session) error {
|
||||||
// Disconnect L2 router from the network
|
// Disconnect L2 router from the network
|
||||||
dockerClient, err := p.dockerFactory.GetForSession(s.Id)
|
dockerClient, err := p.dockerFactory.GetForSession(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ func (d *windows) InstanceNew(session *types.Session, conf types.InstanceConfig)
|
|||||||
}
|
}
|
||||||
instanceName := fmt.Sprintf("%s_%s", session.Id[:8], winfo.id)
|
instanceName := fmt.Sprintf("%s_%s", session.Id[:8], winfo.id)
|
||||||
|
|
||||||
dockerClient, err := d.factory.GetForSession(session.Id)
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.releaseInstance(winfo.id)
|
d.releaseInstance(winfo.id)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -94,7 +94,7 @@ func (d *windows) InstanceNew(session *types.Session, conf types.InstanceConfig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *windows) InstanceDelete(session *types.Session, instance *types.Instance) error {
|
func (d *windows) InstanceDelete(session *types.Session, instance *types.Instance) error {
|
||||||
dockerClient, err := d.factory.GetForSession(session.Id)
|
dockerClient, err := d.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func TestClientNew(t *testing.T) {
|
|||||||
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
||||||
|
|
||||||
_g.On("NewId").Return("aaaabbbbcccc")
|
_g.On("NewId").Return("aaaabbbbcccc")
|
||||||
_f.On("GetForSession", "aaaabbbbcccc").Return(_d, nil)
|
_f.On("GetForSession", mock.AnythingOfType("*types.Session")).Return(_d, nil)
|
||||||
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
||||||
_d.On("GetDaemonHost").Return("localhost")
|
_d.On("GetDaemonHost").Return("localhost")
|
||||||
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
||||||
@@ -67,7 +67,7 @@ func TestClientCount(t *testing.T) {
|
|||||||
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
||||||
|
|
||||||
_g.On("NewId").Return("aaaabbbbcccc")
|
_g.On("NewId").Return("aaaabbbbcccc")
|
||||||
_f.On("GetForSession", "aaaabbbbcccc").Return(_d, nil)
|
_f.On("GetForSession", mock.AnythingOfType("*types.Session")).Return(_d, nil)
|
||||||
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
||||||
_d.On("GetDaemonHost").Return("localhost")
|
_d.On("GetDaemonHost").Return("localhost")
|
||||||
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
||||||
@@ -106,7 +106,7 @@ func TestClientResizeViewPort(t *testing.T) {
|
|||||||
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
||||||
|
|
||||||
_g.On("NewId").Return("aaaabbbbcccc")
|
_g.On("NewId").Return("aaaabbbbcccc")
|
||||||
_f.On("GetForSession", "aaaabbbbcccc").Return(_d, nil)
|
_f.On("GetForSession", mock.AnythingOfType("*types.Session")).Return(_d, nil)
|
||||||
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
||||||
_d.On("GetDaemonHost").Return("localhost")
|
_d.On("GetDaemonHost").Return("localhost")
|
||||||
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ func TestInstanceResizeTerminal(t *testing.T) {
|
|||||||
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_g, _f, _s))
|
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_g, _f, _s))
|
||||||
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
||||||
|
|
||||||
|
s := &types.Session{Id: "aaaabbbbcccc"}
|
||||||
_d.On("ContainerResize", "foobar", uint(24), uint(80)).Return(nil)
|
_d.On("ContainerResize", "foobar", uint(24), uint(80)).Return(nil)
|
||||||
_f.On("GetForSession", "aaaabbbbcccc").Return(_d, nil)
|
_s.On("SessionGet", "aaaabbbbcccc").Return(s, nil)
|
||||||
|
_f.On("GetForSession", s).Return(_d, nil)
|
||||||
|
|
||||||
p := NewPWD(_f, _e, _s, sp, ipf)
|
p := NewPWD(_f, _e, _s, sp, ipf)
|
||||||
|
|
||||||
@@ -52,7 +54,7 @@ func TestInstanceNew(t *testing.T) {
|
|||||||
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
||||||
|
|
||||||
_g.On("NewId").Return("aaaabbbbcccc")
|
_g.On("NewId").Return("aaaabbbbcccc")
|
||||||
_f.On("GetForSession", "aaaabbbbcccc").Return(_d, nil)
|
_f.On("GetForSession", mock.AnythingOfType("*types.Session")).Return(_d, nil)
|
||||||
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
||||||
_d.On("GetDaemonHost").Return("localhost")
|
_d.On("GetDaemonHost").Return("localhost")
|
||||||
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
||||||
@@ -120,7 +122,7 @@ func TestInstanceNew_WithNotAllowedImage(t *testing.T) {
|
|||||||
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
||||||
|
|
||||||
_g.On("NewId").Return("aaaabbbbcccc")
|
_g.On("NewId").Return("aaaabbbbcccc")
|
||||||
_f.On("GetForSession", "aaaabbbbcccc").Return(_d, nil)
|
_f.On("GetForSession", mock.AnythingOfType("*types.Session")).Return(_d, nil)
|
||||||
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
||||||
_d.On("GetDaemonHost").Return("localhost")
|
_d.On("GetDaemonHost").Return("localhost")
|
||||||
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
||||||
@@ -189,7 +191,7 @@ func TestInstanceNew_WithCustomHostname(t *testing.T) {
|
|||||||
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
||||||
|
|
||||||
_g.On("NewId").Return("aaaabbbbcccc")
|
_g.On("NewId").Return("aaaabbbbcccc")
|
||||||
_f.On("GetForSession", "aaaabbbbcccc").Return(_d, nil)
|
_f.On("GetForSession", mock.AnythingOfType("*types.Session")).Return(_d, nil)
|
||||||
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
||||||
_d.On("GetDaemonHost").Return("localhost")
|
_d.On("GetDaemonHost").Return("localhost")
|
||||||
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ func (p *pwd) SessionDeployStack(s *types.Session) error {
|
|||||||
|
|
||||||
w := sessionBuilderWriter{sessionId: s.Id, event: p.event}
|
w := sessionBuilderWriter{sessionId: s.Id, event: p.event}
|
||||||
|
|
||||||
dockerClient, err := p.dockerFactory.GetForSession(s.Id)
|
dockerClient, err := p.dockerFactory.GetForSession(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func TestSessionNew(t *testing.T) {
|
|||||||
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
sp := provisioner.NewOverlaySessionProvisioner(_f)
|
||||||
|
|
||||||
_g.On("NewId").Return("aaaabbbbcccc")
|
_g.On("NewId").Return("aaaabbbbcccc")
|
||||||
_f.On("GetForSession", "aaaabbbbcccc").Return(_d, nil)
|
_f.On("GetForSession", mock.AnythingOfType("*types.Session")).Return(_d, nil)
|
||||||
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
_d.On("CreateNetwork", "aaaabbbbcccc", dtypes.NetworkCreate{Attachable: true, Driver: "overlay"}).Return(nil)
|
||||||
_d.On("GetDaemonHost").Return("localhost")
|
_d.On("GetDaemonHost").Return("localhost")
|
||||||
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
_d.On("ConnectNetwork", config.L2ContainerName, "aaaabbbbcccc", "").Return("10.0.0.1", nil)
|
||||||
|
|||||||
@@ -329,12 +329,15 @@ func (r *proxyRouter) ListenSshAddress() string {
|
|||||||
func (r *proxyRouter) handleConnection(c net.Conn) {
|
func (r *proxyRouter) handleConnection(c net.Conn) {
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
// first try tls
|
// first try tls
|
||||||
|
start := time.Now()
|
||||||
vhostConn, err := vhost.TLS(c)
|
vhostConn, err := vhost.TLS(c)
|
||||||
|
discoverElapsed := time.Since(start)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// It is a TLS connection
|
// It is a TLS connection
|
||||||
defer vhostConn.Close()
|
defer vhostConn.Close()
|
||||||
host := vhostConn.ClientHelloMsg.ServerName
|
host := vhostConn.ClientHelloMsg.ServerName
|
||||||
|
log.Printf("Proxying TLS connection to %s. Discover took %s\n", host, discoverElapsed)
|
||||||
dstHost, err := r.director(ProtocolHTTPS, host)
|
dstHost, err := r.director(ProtocolHTTPS, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error directing request: %v\n", err)
|
log.Printf("Error directing request: %v\n", err)
|
||||||
@@ -351,7 +354,9 @@ func (r *proxyRouter) handleConnection(c net.Conn) {
|
|||||||
// it is not TLS
|
// it is not TLS
|
||||||
// treat it as an http connection
|
// treat it as an http connection
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
req, err := http.ReadRequest(bufio.NewReader(vhostConn))
|
req, err := http.ReadRequest(bufio.NewReader(vhostConn))
|
||||||
|
httpReadElapsed := time.Since(start)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// It is not http neither. So just close the connection.
|
// It is not http neither. So just close the connection.
|
||||||
return
|
return
|
||||||
@@ -360,6 +365,7 @@ func (r *proxyRouter) handleConnection(c net.Conn) {
|
|||||||
if host == "" {
|
if host == "" {
|
||||||
host = req.Host
|
host = req.Host
|
||||||
}
|
}
|
||||||
|
log.Printf("Proxying http connection to %s. Discover took %s. Http read took %s\n", host, discoverElapsed, httpReadElapsed)
|
||||||
dstHost, err := r.director(ProtocolHTTP, host)
|
dstHost, err := r.director(ProtocolHTTP, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error directing request: %v\n", err)
|
log.Printf("Error directing request: %v\n", err)
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ func TestCheckSwarmPorts_RunWhenManager(t *testing.T) {
|
|||||||
IP: "10.0.0.1",
|
IP: "10.0.0.1",
|
||||||
Name: "aaaabbbb_node1",
|
Name: "aaaabbbb_node1",
|
||||||
SessionId: "aaaabbbbcccc",
|
SessionId: "aaaabbbbcccc",
|
||||||
|
Hostname: "node1",
|
||||||
}
|
}
|
||||||
info := dockerTypes.Info{
|
info := dockerTypes.Info{
|
||||||
Swarm: swarm.Info{
|
Swarm: swarm.Info{
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ import (
|
|||||||
|
|
||||||
dockerTypes "github.com/docker/docker/api/types"
|
dockerTypes "github.com/docker/docker/api/types"
|
||||||
units "github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
|
lru "github.com/hashicorp/golang-lru"
|
||||||
"github.com/play-with-docker/play-with-docker/docker"
|
"github.com/play-with-docker/play-with-docker/docker"
|
||||||
"github.com/play-with-docker/play-with-docker/event"
|
"github.com/play-with-docker/play-with-docker/event"
|
||||||
"github.com/play-with-docker/play-with-docker/pwd/types"
|
"github.com/play-with-docker/play-with-docker/pwd/types"
|
||||||
"github.com/play-with-docker/play-with-docker/router"
|
"github.com/play-with-docker/play-with-docker/router"
|
||||||
|
"github.com/play-with-docker/play-with-docker/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InstanceStats struct {
|
type InstanceStats struct {
|
||||||
@@ -28,6 +30,8 @@ type collectStats struct {
|
|||||||
event event.EventApi
|
event event.EventApi
|
||||||
factory docker.FactoryApi
|
factory docker.FactoryApi
|
||||||
cli *http.Client
|
cli *http.Client
|
||||||
|
cache *lru.Cache
|
||||||
|
storage storage.StorageApi
|
||||||
}
|
}
|
||||||
|
|
||||||
var CollectStatsEvent event.EventType
|
var CollectStatsEvent event.EventType
|
||||||
@@ -71,7 +75,18 @@ func (t *collectStats) Run(ctx context.Context, instance *types.Instance) error
|
|||||||
t.event.Emit(CollectStatsEvent, instance.SessionId, stats)
|
t.event.Emit(CollectStatsEvent, instance.SessionId, stats)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
dockerClient, err := t.factory.GetForSession(instance.SessionId)
|
var session *types.Session
|
||||||
|
if sess, found := t.cache.Get(instance.SessionId); !found {
|
||||||
|
s, err := t.storage.SessionGet(instance.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.cache.Add(s.Id, s)
|
||||||
|
session = s
|
||||||
|
} else {
|
||||||
|
session = sess.(*types.Session)
|
||||||
|
}
|
||||||
|
dockerClient, err := t.factory.GetForSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return err
|
return err
|
||||||
@@ -119,7 +134,7 @@ func proxyHost(r *http.Request) (*url.URL, error) {
|
|||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCollectStats(e event.EventApi, f docker.FactoryApi) *collectStats {
|
func NewCollectStats(e event.EventApi, f docker.FactoryApi, s storage.StorageApi) *collectStats {
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
DialContext: (&net.Dialer{
|
DialContext: (&net.Dialer{
|
||||||
Timeout: 1 * time.Second,
|
Timeout: 1 * time.Second,
|
||||||
@@ -131,7 +146,8 @@ func NewCollectStats(e event.EventApi, f docker.FactoryApi) *collectStats {
|
|||||||
cli := &http.Client{
|
cli := &http.Client{
|
||||||
Transport: transport,
|
Transport: transport,
|
||||||
}
|
}
|
||||||
return &collectStats{event: e, factory: f, cli: cli}
|
c, _ := lru.New(5000)
|
||||||
|
return &collectStats{event: e, factory: f, cli: cli, cache: c, storage: s}
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *dockerTypes.StatsJSON) float64 {
|
func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *dockerTypes.StatsJSON) float64 {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/play-with-docker/play-with-docker/docker"
|
"github.com/play-with-docker/play-with-docker/docker"
|
||||||
"github.com/play-with-docker/play-with-docker/event"
|
"github.com/play-with-docker/play-with-docker/event"
|
||||||
"github.com/play-with-docker/play-with-docker/pwd/types"
|
"github.com/play-with-docker/play-with-docker/pwd/types"
|
||||||
|
"github.com/play-with-docker/play-with-docker/storage"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
)
|
)
|
||||||
@@ -19,8 +20,8 @@ type mockSessionProvider struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockSessionProvider) GetDocker(sessionId string) (docker.DockerApi, error) {
|
func (m *mockSessionProvider) GetDocker(session *types.Session) (docker.DockerApi, error) {
|
||||||
args := m.Called(sessionId)
|
args := m.Called(session)
|
||||||
|
|
||||||
return args.Get(0).(docker.DockerApi), args.Error(1)
|
return args.Get(0).(docker.DockerApi), args.Error(1)
|
||||||
}
|
}
|
||||||
@@ -34,8 +35,9 @@ func (nopCloser) Close() error { return nil }
|
|||||||
func TestCollectStats_Name(t *testing.T) {
|
func TestCollectStats_Name(t *testing.T) {
|
||||||
e := &event.Mock{}
|
e := &event.Mock{}
|
||||||
f := &docker.FactoryMock{}
|
f := &docker.FactoryMock{}
|
||||||
|
s := &storage.Mock{}
|
||||||
|
|
||||||
task := NewCollectStats(e, f)
|
task := NewCollectStats(e, f, s)
|
||||||
|
|
||||||
assert.Equal(t, "CollectStats", task.Name())
|
assert.Equal(t, "CollectStats", task.Name())
|
||||||
e.M.AssertExpectations(t)
|
e.M.AssertExpectations(t)
|
||||||
@@ -46,6 +48,7 @@ func TestCollectStats_Run(t *testing.T) {
|
|||||||
d := &docker.Mock{}
|
d := &docker.Mock{}
|
||||||
e := &event.Mock{}
|
e := &event.Mock{}
|
||||||
f := &docker.FactoryMock{}
|
f := &docker.FactoryMock{}
|
||||||
|
s := &storage.Mock{}
|
||||||
|
|
||||||
stats := dockerTypes.StatsJSON{}
|
stats := dockerTypes.StatsJSON{}
|
||||||
b, _ := json.Marshal(stats)
|
b, _ := json.Marshal(stats)
|
||||||
@@ -53,13 +56,19 @@ func TestCollectStats_Run(t *testing.T) {
|
|||||||
IP: "10.0.0.1",
|
IP: "10.0.0.1",
|
||||||
Name: "aaaabbbb_node1",
|
Name: "aaaabbbb_node1",
|
||||||
SessionId: "aaaabbbbcccc",
|
SessionId: "aaaabbbbcccc",
|
||||||
|
Hostname: "node1",
|
||||||
}
|
}
|
||||||
|
|
||||||
f.On("GetForSession", i.SessionId).Return(d, nil)
|
sess := &types.Session{
|
||||||
|
Id: "aaaabbbbcccc",
|
||||||
|
}
|
||||||
|
|
||||||
|
s.On("SessionGet", i.SessionId).Return(sess, nil)
|
||||||
|
f.On("GetForSession", sess).Return(d, nil)
|
||||||
d.On("GetContainerStats", i.Name).Return(nopCloser{bytes.NewReader(b)}, nil)
|
d.On("GetContainerStats", i.Name).Return(nopCloser{bytes.NewReader(b)}, nil)
|
||||||
e.M.On("Emit", CollectStatsEvent, "aaaabbbbcccc", []interface{}{InstanceStats{Instance: i.Name, Mem: "0.00% (0B / 0B)", Cpu: "0.00%"}}).Return()
|
e.M.On("Emit", CollectStatsEvent, "aaaabbbbcccc", []interface{}{InstanceStats{Instance: i.Name, Mem: "0.00% (0B / 0B)", Cpu: "0.00%"}}).Return()
|
||||||
|
|
||||||
task := NewCollectStats(e, f)
|
task := NewCollectStats(e, f, s)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
err := task.Run(ctx, i)
|
err := task.Run(ctx, i)
|
||||||
|
|||||||
Reference in New Issue
Block a user