Add SessionProvisioner and InstanceProvisionerFactory

Remove AllowedImages and IsDockerHost as it is not really being used for
anything useful
This commit is contained in:
Jonathan Leibiusky @xetorthio
2017-08-24 15:36:59 -03:00
parent 11d9d59975
commit 438fe9f6e7
15 changed files with 187 additions and 131 deletions

6
api.go
View File

@@ -8,6 +8,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/handlers" "github.com/play-with-docker/play-with-docker/handlers"
"github.com/play-with-docker/play-with-docker/provisioner"
"github.com/play-with-docker/play-with-docker/pwd" "github.com/play-with-docker/play-with-docker/pwd"
"github.com/play-with-docker/play-with-docker/scheduler" "github.com/play-with-docker/play-with-docker/scheduler"
"github.com/play-with-docker/play-with-docker/scheduler/task" "github.com/play-with-docker/play-with-docker/scheduler/task"
@@ -21,7 +22,10 @@ func main() {
s := initStorage() s := initStorage()
f := initFactory(s) f := initFactory(s)
core := pwd.NewPWD(f, e, s) ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(f, s), provisioner.NewDinD(f))
sp := provisioner.NewOverlaySessionProvisioner(f)
core := pwd.NewPWD(f, e, s, sp, ipf)
sch, err := scheduler.NewScheduler(s, e, core) sch, err := scheduler.NewScheduler(s, e, core)
if err != nil { if err != nil {

View File

@@ -3,9 +3,15 @@ package handlers
import ( import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"github.com/play-with-docker/play-with-docker/config"
) )
func GetInstanceImages(rw http.ResponseWriter, req *http.Request) { func GetInstanceImages(rw http.ResponseWriter, req *http.Request) {
instanceImages := core.InstanceAllowedImages() instanceImages := []string{
config.GetDindImageName(),
"franela/dind:overlay2-dev",
"franela/ucp:2.4.1",
}
json.NewEncoder(rw).Encode(instanceImages) json.NewEncoder(rw).Encode(instanceImages)
} }

View File

@@ -36,14 +36,6 @@ func checkHostnameExists(session *types.Session, hostname string) bool {
return exists return exists
} }
func (d *DinD) InstanceAllowedImages() []string {
return []string{
config.GetDindImageName(),
"franela/dind:overlay2-dev",
"franela/ucp:2.4.1",
}
}
func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (*types.Instance, error) { func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (*types.Instance, error) {
if conf.ImageName == "" { if conf.ImageName == "" {
conf.ImageName = config.GetDindImageName() conf.ImageName = config.GetDindImageName()
@@ -70,15 +62,8 @@ func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (*
ServerCert: conf.ServerCert, ServerCert: conf.ServerCert,
ServerKey: conf.ServerKey, ServerKey: conf.ServerKey,
CACert: conf.CACert, CACert: conf.CACert,
Privileged: false,
HostFQDN: conf.Host, HostFQDN: conf.Host,
} Privileged: true,
for _, imageName := range d.InstanceAllowedImages() {
if conf.ImageName == imageName {
opts.Privileged = true
break
}
} }
dockerClient, err := d.factory.GetForSession(session.Id) dockerClient, err := d.factory.GetForSession(session.Id)
@@ -104,8 +89,6 @@ func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (*
instance.Session = session instance.Session = session
instance.ProxyHost = router.EncodeHost(session.Id, ip, router.HostOpts{}) instance.ProxyHost = router.EncodeHost(session.Id, ip, router.HostOpts{})
instance.SessionHost = session.Host instance.SessionHost = session.Host
// For now this condition holds through. In the future we might need a more complex logic.
instance.IsDockerHost = opts.Privileged
return instance, nil return instance, nil
} }

18
provisioner/factory.go Normal file
View File

@@ -0,0 +1,18 @@
package provisioner
type instanceProvisionerFactory struct {
windows InstanceProvisionerApi
dind InstanceProvisionerApi
}
func NewInstanceProvisionerFactory(w InstanceProvisionerApi, d InstanceProvisionerApi) InstanceProvisionerFactoryApi {
return &instanceProvisionerFactory{windows: w, dind: d}
}
func (p *instanceProvisionerFactory) GetProvisioner(instanceType string) (InstanceProvisionerApi, error) {
if instanceType == "windows" {
return p.windows, nil
} else {
return p.dind, nil
}
}

50
provisioner/overlay.go Normal file
View File

@@ -0,0 +1,50 @@
package provisioner
import (
"fmt"
"log"
"net/url"
"strings"
"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/pwd/types"
)
type overlaySessionProvisioner struct {
dockerFactory docker.FactoryApi
}
func NewOverlaySessionProvisioner(df docker.FactoryApi) SessionProvisionerApi {
return &overlaySessionProvisioner{dockerFactory: df}
}
func (p *overlaySessionProvisioner) SessionNew(s *types.Session) error {
dockerClient, err := p.dockerFactory.GetForSession(s.Id)
if err != nil {
// We assume we are out of capacity
return fmt.Errorf("Out of capacity")
}
u, _ := url.Parse(dockerClient.GetDaemonHost())
if u.Host == "" {
s.Host = "localhost"
} else {
chunks := strings.Split(u.Host, ":")
s.Host = chunks[0]
}
if err := dockerClient.CreateNetwork(s.Id); err != nil {
log.Println("ERROR NETWORKING", err)
return err
}
log.Printf("Network [%s] created for session [%s]\n", s.Id, s.Id)
ip, err := dockerClient.ConnectNetwork(config.L2ContainerName, s.Id, s.PwdIpAddress)
if err != nil {
log.Println(err)
return err
}
s.PwdIpAddress = ip
log.Printf("Connected %s to network [%s]\n", config.PWDContainerName, s.Id)
return nil
}

View File

@@ -7,7 +7,7 @@ import (
"github.com/play-with-docker/play-with-docker/pwd/types" "github.com/play-with-docker/play-with-docker/pwd/types"
) )
type ProvisionerApi interface { type InstanceProvisionerApi interface {
InstanceNew(session *types.Session, conf types.InstanceConfig) (*types.Instance, error) InstanceNew(session *types.Session, conf types.InstanceConfig) (*types.Instance, error)
InstanceDelete(session *types.Session, instance *types.Instance) error InstanceDelete(session *types.Session, instance *types.Instance) error
@@ -17,3 +17,11 @@ type ProvisionerApi interface {
InstanceUploadFromUrl(instance *types.Instance, fileName, dest, url string) error InstanceUploadFromUrl(instance *types.Instance, fileName, dest, url string) error
InstanceUploadFromReader(instance *types.Instance, fileName, dest string, reader io.Reader) error InstanceUploadFromReader(instance *types.Instance, fileName, dest string, reader io.Reader) error
} }
type SessionProvisionerApi interface {
SessionNew(session *types.Session) error
}
type InstanceProvisionerFactoryApi interface {
GetProvisioner(instanceType string) (InstanceProvisionerApi, error)
}

View File

@@ -110,8 +110,6 @@ func (d *windows) InstanceNew(session *types.Session, conf types.InstanceConfig)
instance.Session = session instance.Session = session
instance.ProxyHost = router.EncodeHost(session.Id, instance.IP, router.HostOpts{}) instance.ProxyHost = router.EncodeHost(session.Id, instance.IP, router.HostOpts{})
instance.SessionHost = session.Host instance.SessionHost = session.Host
// For now this condition holds through. In the future we might need a more complex logic.
instance.IsDockerHost = opts.Privileged
if cli, err := d.factory.GetForInstance(instance); err != nil { if cli, err := d.factory.GetForInstance(instance); err != nil {
if derr := d.InstanceDelete(session, instance); derr != nil { if derr := d.InstanceDelete(session, instance); derr != nil {

View File

@@ -7,6 +7,7 @@ import (
"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/event" "github.com/play-with-docker/play-with-docker/event"
"github.com/play-with-docker/play-with-docker/provisioner"
"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/play-with-docker/play-with-docker/storage"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -20,6 +21,9 @@ func TestClientNew(t *testing.T) {
_d := &docker.Mock{} _d := &docker.Mock{}
_e := &event.Mock{} _e := &event.Mock{}
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_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", "aaaabbbbcccc").Return(_d, nil)
_d.On("CreateNetwork", "aaaabbbbcccc").Return(nil) _d.On("CreateNetwork", "aaaabbbbcccc").Return(nil)
@@ -32,7 +36,7 @@ func TestClientNew(t *testing.T) {
var nilArgs []interface{} var nilArgs []interface{}
_e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return() _e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return()
p := NewPWD(_f, _e, _s) p := NewPWD(_f, _e, _s, sp, ipf)
p.generator = _g p.generator = _g
session, err := p.SessionNew(time.Hour, "", "", "") session, err := p.SessionNew(time.Hour, "", "", "")
@@ -56,6 +60,8 @@ func TestClientCount(t *testing.T) {
_g := &mockGenerator{} _g := &mockGenerator{}
_d := &docker.Mock{} _d := &docker.Mock{}
_e := &event.Mock{} _e := &event.Mock{}
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_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", "aaaabbbbcccc").Return(_d, nil)
@@ -68,7 +74,7 @@ func TestClientCount(t *testing.T) {
var nilArgs []interface{} var nilArgs []interface{}
_e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return() _e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return()
p := NewPWD(_f, _e, _s) p := NewPWD(_f, _e, _s, sp, ipf)
p.generator = _g p.generator = _g
session, err := p.SessionNew(time.Hour, "", "", "") session, err := p.SessionNew(time.Hour, "", "", "")
@@ -91,6 +97,8 @@ func TestClientResizeViewPort(t *testing.T) {
_g := &mockGenerator{} _g := &mockGenerator{}
_d := &docker.Mock{} _d := &docker.Mock{}
_e := &event.Mock{} _e := &event.Mock{}
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_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", "aaaabbbbcccc").Return(_d, nil)
@@ -104,7 +112,7 @@ func TestClientResizeViewPort(t *testing.T) {
_e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return() _e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return()
_e.M.On("Emit", event.INSTANCE_VIEWPORT_RESIZE, "aaaabbbbcccc", []interface{}{uint(80), uint(24)}).Return() _e.M.On("Emit", event.INSTANCE_VIEWPORT_RESIZE, "aaaabbbbcccc", []interface{}{uint(80), uint(24)}).Return()
p := NewPWD(_f, _e, _s) p := NewPWD(_f, _e, _s, sp, ipf)
p.generator = _g p.generator = _g
session, err := p.SessionNew(time.Hour, "", "", "") session, err := p.SessionNew(time.Hour, "", "", "")

View File

@@ -7,7 +7,6 @@ import (
"time" "time"
"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/provisioner"
"github.com/play-with-docker/play-with-docker/pwd/types" "github.com/play-with-docker/play-with-docker/pwd/types"
) )
@@ -137,9 +136,3 @@ func (p *pwd) InstanceExec(instance *types.Instance, cmd []string) (int, error)
} }
return dockerClient.Exec(instance.Name, cmd) return dockerClient.Exec(instance.Name, cmd)
} }
func (p *pwd) InstanceAllowedImages() []string {
defer observeAction("InstanceAllowedImages", time.Now())
return p.dindProvisioner.(*provisioner.DinD).InstanceAllowedImages()
}

View File

@@ -8,6 +8,7 @@ import (
"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/event" "github.com/play-with-docker/play-with-docker/event"
"github.com/play-with-docker/play-with-docker/provisioner"
"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" "github.com/play-with-docker/play-with-docker/storage"
@@ -21,11 +22,13 @@ func TestInstanceResizeTerminal(t *testing.T) {
_s := &storage.Mock{} _s := &storage.Mock{}
_g := &mockGenerator{} _g := &mockGenerator{}
_e := &event.Mock{} _e := &event.Mock{}
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_f))
sp := provisioner.NewOverlaySessionProvisioner(_f)
_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) _f.On("GetForSession", "aaaabbbbcccc").Return(_d, nil)
p := NewPWD(_f, _e, _s) p := NewPWD(_f, _e, _s, sp, ipf)
err := p.InstanceResizeTerminal(&types.Instance{Name: "foobar", SessionId: "aaaabbbbcccc"}, 24, 80) err := p.InstanceResizeTerminal(&types.Instance{Name: "foobar", SessionId: "aaaabbbbcccc"}, 24, 80)
assert.Nil(t, err) assert.Nil(t, err)
@@ -43,6 +46,8 @@ func TestInstanceNew(t *testing.T) {
_s := &storage.Mock{} _s := &storage.Mock{}
_g := &mockGenerator{} _g := &mockGenerator{}
_e := &event.Mock{} _e := &event.Mock{}
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_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", "aaaabbbbcccc").Return(_d, nil)
@@ -56,22 +61,21 @@ func TestInstanceNew(t *testing.T) {
var nilArgs []interface{} var nilArgs []interface{}
_e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return() _e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return()
p := NewPWD(_f, _e, _s) p := NewPWD(_f, _e, _s, sp, ipf)
p.generator = _g p.generator = _g
session, err := p.SessionNew(time.Hour, "", "", "") session, err := p.SessionNew(time.Hour, "", "", "")
assert.Nil(t, err) assert.Nil(t, err)
expectedInstance := types.Instance{ expectedInstance := types.Instance{
Name: fmt.Sprintf("%s_node1", session.Id[:8]), Name: fmt.Sprintf("%s_node1", session.Id[:8]),
Hostname: "node1", Hostname: "node1",
IP: "10.0.0.1", IP: "10.0.0.1",
Image: config.GetDindImageName(), Image: config.GetDindImageName(),
IsDockerHost: true, SessionId: session.Id,
SessionId: session.Id, Session: session,
Session: session, SessionHost: session.Host,
SessionHost: session.Host, ProxyHost: router.EncodeHost(session.Id, "10.0.0.1", router.HostOpts{}),
ProxyHost: router.EncodeHost(session.Id, "10.0.0.1", router.HostOpts{}),
} }
expectedContainerOpts := docker.CreateContainerOpts{ expectedContainerOpts := docker.CreateContainerOpts{
Image: expectedInstance.Image, Image: expectedInstance.Image,
@@ -107,6 +111,8 @@ func TestInstanceNew_WithNotAllowedImage(t *testing.T) {
_s := &storage.Mock{} _s := &storage.Mock{}
_g := &mockGenerator{} _g := &mockGenerator{}
_e := &event.Mock{} _e := &event.Mock{}
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_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", "aaaabbbbcccc").Return(_d, nil)
@@ -120,7 +126,7 @@ func TestInstanceNew_WithNotAllowedImage(t *testing.T) {
var nilArgs []interface{} var nilArgs []interface{}
_e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return() _e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return()
p := NewPWD(_f, _e, _s) p := NewPWD(_f, _e, _s, sp, ipf)
p.generator = _g p.generator = _g
session, err := p.SessionNew(time.Hour, "", "", "") session, err := p.SessionNew(time.Hour, "", "", "")
@@ -128,15 +134,14 @@ func TestInstanceNew_WithNotAllowedImage(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
expectedInstance := types.Instance{ expectedInstance := types.Instance{
Name: fmt.Sprintf("%s_node1", session.Id[:8]), Name: fmt.Sprintf("%s_node1", session.Id[:8]),
Hostname: "node1", Hostname: "node1",
IP: "10.0.0.1", IP: "10.0.0.1",
Image: "redis", Image: "redis",
SessionId: session.Id, SessionId: session.Id,
IsDockerHost: false, Session: session,
Session: session, SessionHost: session.Host,
SessionHost: session.Host, ProxyHost: router.EncodeHost(session.Id, "10.0.0.1", router.HostOpts{}),
ProxyHost: router.EncodeHost(session.Id, "10.0.0.1", router.HostOpts{}),
} }
expectedContainerOpts := docker.CreateContainerOpts{ expectedContainerOpts := docker.CreateContainerOpts{
Image: expectedInstance.Image, Image: expectedInstance.Image,
@@ -147,7 +152,7 @@ func TestInstanceNew_WithNotAllowedImage(t *testing.T) {
ServerCert: nil, ServerCert: nil,
ServerKey: nil, ServerKey: nil,
CACert: nil, CACert: nil,
Privileged: false, Privileged: true,
} }
_d.On("CreateContainer", expectedContainerOpts).Return("10.0.0.1", nil) _d.On("CreateContainer", expectedContainerOpts).Return("10.0.0.1", nil)
_s.On("InstanceCreate", "aaaabbbbcccc", mock.AnythingOfType("*types.Instance")).Return(nil) _s.On("InstanceCreate", "aaaabbbbcccc", mock.AnythingOfType("*types.Instance")).Return(nil)
@@ -172,6 +177,9 @@ func TestInstanceNew_WithCustomHostname(t *testing.T) {
_g := &mockGenerator{} _g := &mockGenerator{}
_e := &event.Mock{} _e := &event.Mock{}
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_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", "aaaabbbbcccc").Return(_d, nil)
_d.On("CreateNetwork", "aaaabbbbcccc").Return(nil) _d.On("CreateNetwork", "aaaabbbbcccc").Return(nil)
@@ -184,22 +192,21 @@ func TestInstanceNew_WithCustomHostname(t *testing.T) {
var nilArgs []interface{} var nilArgs []interface{}
_e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return() _e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return()
p := NewPWD(_f, _e, _s) p := NewPWD(_f, _e, _s, sp, ipf)
p.generator = _g p.generator = _g
session, err := p.SessionNew(time.Hour, "", "", "") session, err := p.SessionNew(time.Hour, "", "", "")
assert.Nil(t, err) assert.Nil(t, err)
expectedInstance := types.Instance{ expectedInstance := types.Instance{
Name: fmt.Sprintf("%s_redis-master", session.Id[:8]), Name: fmt.Sprintf("%s_redis-master", session.Id[:8]),
Hostname: "redis-master", Hostname: "redis-master",
IP: "10.0.0.1", IP: "10.0.0.1",
Image: "redis", Image: "redis",
IsDockerHost: false, Session: session,
Session: session, SessionHost: session.Host,
SessionHost: session.Host, SessionId: session.Id,
SessionId: session.Id, ProxyHost: router.EncodeHost(session.Id, "10.0.0.1", router.HostOpts{}),
ProxyHost: router.EncodeHost(session.Id, "10.0.0.1", router.HostOpts{}),
} }
expectedContainerOpts := docker.CreateContainerOpts{ expectedContainerOpts := docker.CreateContainerOpts{
Image: expectedInstance.Image, Image: expectedInstance.Image,
@@ -210,7 +217,7 @@ func TestInstanceNew_WithCustomHostname(t *testing.T) {
ServerCert: nil, ServerCert: nil,
ServerKey: nil, ServerKey: nil,
CACert: nil, CACert: nil,
Privileged: false, Privileged: true,
} }
_d.On("CreateContainer", expectedContainerOpts).Return("10.0.0.1", nil) _d.On("CreateContainer", expectedContainerOpts).Return("10.0.0.1", nil)

View File

@@ -88,11 +88,6 @@ func (m *Mock) InstanceExec(instance *types.Instance, cmd []string) (int, error)
return args.Int(0), args.Error(1) return args.Int(0), args.Error(1)
} }
func (m *Mock) InstanceAllowedImages() []string {
args := m.Called()
return args.Get(0).([]string)
}
func (m *Mock) ClientNew(id string, session *types.Session) *types.Client { func (m *Mock) ClientNew(id string, session *types.Session) *types.Client {
args := m.Called(id, session) args := m.Called(id, session)
return args.Get(0).(*types.Client) return args.Get(0).(*types.Client)

View File

@@ -48,13 +48,15 @@ func init() {
} }
type pwd struct { type pwd struct {
dockerFactory docker.FactoryApi dockerFactory docker.FactoryApi
event event.EventApi event event.EventApi
storage storage.StorageApi storage storage.StorageApi
generator IdGenerator generator IdGenerator
clientCount int32 clientCount int32
windowsProvisioner provisioner.ProvisionerApi sessionProvisioner provisioner.SessionProvisionerApi
dindProvisioner provisioner.ProvisionerApi instanceProvisionerFactory provisioner.InstanceProvisionerFactoryApi
windowsProvisioner provisioner.InstanceProvisionerApi
dindProvisioner provisioner.InstanceProvisionerApi
} }
type IdGenerator interface { type IdGenerator interface {
@@ -94,7 +96,6 @@ type PWDApi interface {
InstanceFindByIP(sessionId, ip string) *types.Instance InstanceFindByIP(sessionId, ip string) *types.Instance
InstanceDelete(session *types.Session, instance *types.Instance) error InstanceDelete(session *types.Session, instance *types.Instance) error
InstanceExec(instance *types.Instance, cmd []string) (int, error) InstanceExec(instance *types.Instance, cmd []string) (int, error)
InstanceAllowedImages() []string
ClientNew(id string, session *types.Session) *types.Client ClientNew(id string, session *types.Session) *types.Client
ClientResizeViewPort(client *types.Client, cols, rows uint) ClientResizeViewPort(client *types.Client, cols, rows uint)
@@ -102,16 +103,20 @@ type PWDApi interface {
ClientCount() int ClientCount() int
} }
func NewPWD(f docker.FactoryApi, e event.EventApi, s storage.StorageApi) *pwd { func NewPWD(f docker.FactoryApi, e event.EventApi, s storage.StorageApi, sp provisioner.SessionProvisionerApi, ipf provisioner.InstanceProvisionerFactoryApi) *pwd {
return &pwd{dockerFactory: f, event: e, storage: s, generator: xidGenerator{}, windowsProvisioner: provisioner.NewWindowsASG(f, s), dindProvisioner: provisioner.NewDinD(f)} // windowsProvisioner: provisioner.NewWindowsASG(f, s), dindProvisioner: provisioner.NewDinD(f)
return &pwd{dockerFactory: f, event: e, storage: s, generator: xidGenerator{}, sessionProvisioner: sp, instanceProvisionerFactory: ipf}
} }
func (p *pwd) getProvisioner(t string) (provisioner.ProvisionerApi, error) { func (p *pwd) getProvisioner(t string) (provisioner.InstanceProvisionerApi, error) {
if t == "windows" { return p.instanceProvisionerFactory.GetProvisioner(t)
return p.windowsProvisioner, nil /*
} else { if t == "windows" {
return p.dindProvisioner, nil return p.windowsProvisioner, nil
} } else {
return p.dindProvisioner, nil
}
*/
} }
func (p *pwd) setGauges() { func (p *pwd) setGauges() {

View File

@@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"log" "log"
"math" "math"
"net/url"
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -65,33 +64,10 @@ func (p *pwd) SessionNew(duration time.Duration, stack, stackName, imageName str
s.ImageName = imageName s.ImageName = imageName
log.Printf("NewSession id=[%s]\n", s.Id) log.Printf("NewSession id=[%s]\n", s.Id)
if err := p.sessionProvisioner.SessionNew(s); err != nil {
dockerClient, err := p.dockerFactory.GetForSession(s.Id)
if err != nil {
// We assume we are out of capacity
return nil, fmt.Errorf("Out of capacity")
}
u, _ := url.Parse(dockerClient.GetDaemonHost())
if u.Host == "" {
s.Host = "localhost"
} else {
chunks := strings.Split(u.Host, ":")
s.Host = chunks[0]
}
if err := dockerClient.CreateNetwork(s.Id); err != nil {
log.Println("ERROR NETWORKING", err)
return nil, err
}
log.Printf("Network [%s] created for session [%s]\n", s.Id, s.Id)
ip, err := dockerClient.ConnectNetwork(config.L2ContainerName, s.Id, s.PwdIpAddress)
if err != nil {
log.Println(err) log.Println(err)
return nil, err return nil, err
} }
s.PwdIpAddress = ip
log.Printf("Connected %s to network [%s]\n", config.PWDContainerName, s.Id)
if err := p.storage.SessionPut(s); err != nil { if err := p.storage.SessionPut(s); err != nil {
log.Println(err) log.Println(err)

View File

@@ -7,6 +7,7 @@ import (
"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/event" "github.com/play-with-docker/play-with-docker/event"
"github.com/play-with-docker/play-with-docker/provisioner"
"github.com/play-with-docker/play-with-docker/storage" "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"
@@ -21,6 +22,9 @@ func TestSessionNew(t *testing.T) {
_g := &mockGenerator{} _g := &mockGenerator{}
_e := &event.Mock{} _e := &event.Mock{}
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_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", "aaaabbbbcccc").Return(_d, nil)
_d.On("CreateNetwork", "aaaabbbbcccc").Return(nil) _d.On("CreateNetwork", "aaaabbbbcccc").Return(nil)
@@ -33,7 +37,7 @@ func TestSessionNew(t *testing.T) {
var nilArgs []interface{} var nilArgs []interface{}
_e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return() _e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return()
p := NewPWD(_f, _e, _s) p := NewPWD(_f, _e, _s, sp, ipf)
p.generator = _g p.generator = _g
before := time.Now() before := time.Now()
@@ -72,6 +76,8 @@ func TestSessionSetup(t *testing.T) {
_s := &storage.Mock{} _s := &storage.Mock{}
_g := &mockGenerator{} _g := &mockGenerator{}
_e := &event.Mock{} _e := &event.Mock{}
ipf := provisioner.NewInstanceProvisionerFactory(provisioner.NewWindowsASG(_f, _s), provisioner.NewDinD(_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", "aaaabbbbcccc").Return(_d, nil)
@@ -109,7 +115,7 @@ func TestSessionSetup(t *testing.T) {
var nilArgs []interface{} var nilArgs []interface{}
_e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return() _e.M.On("Emit", event.SESSION_NEW, "aaaabbbbcccc", nilArgs).Return()
p := NewPWD(_f, _e, _s) p := NewPWD(_f, _e, _s, sp, ipf)
p.generator = _g p.generator = _g
s, e := p.SessionNew(time.Hour, "", "", "") s, e := p.SessionNew(time.Hour, "", "", "")
assert.Nil(t, e) assert.Nil(t, e)

View File

@@ -3,23 +3,22 @@ package types
import "context" import "context"
type Instance struct { type Instance struct {
Image string `json:"image" bson:"image"` Image string `json:"image" bson:"image"`
Name string `json:"name" bson:"name"` Name string `json:"name" bson:"name"`
Hostname string `json:"hostname" bson:"hostname"` Hostname string `json:"hostname" bson:"hostname"`
IP string `json:"ip" bson:"ip"` IP string `json:"ip" bson:"ip"`
ServerCert []byte `json:"server_cert" bson:"server_cert"` ServerCert []byte `json:"server_cert" bson:"server_cert"`
ServerKey []byte `json:"server_key" bson:"server_key"` ServerKey []byte `json:"server_key" bson:"server_key"`
CACert []byte `json:"ca_cert" bson:"ca_cert"` CACert []byte `json:"ca_cert" bson:"ca_cert"`
Cert []byte `json:"cert" bson:"cert"` Cert []byte `json:"cert" bson:"cert"`
Key []byte `json:"key" bson:"key"` Key []byte `json:"key" bson:"key"`
IsDockerHost bool `json:"is_docker_host" bson:"is_docker_host"` SessionId string `json:"session_id" bson:"session_id"`
SessionId string `json:"session_id" bson:"session_id"` ProxyHost string `json:"proxy_host" bson:"proxy_host"`
ProxyHost string `json:"proxy_host" bson:"proxy_host"` SessionHost string `json:"session_host" bson:"session_host"`
SessionHost string `json:"session_host" bson:"session_host"` Type string `json:"type" bson:"type"`
Type string `json:"type" bson:"type"` Session *Session `json:"-" bson:"-"`
Session *Session `json:"-" bson:"-"` ctx context.Context `json:"-" bson:"-"`
ctx context.Context `json:"-" bson:"-"` WindowsId string `json:"-" bson:"windows_id"`
WindowsId string `json:"-" bson:"windows_id"`
} }
type WindowsInstance struct { type WindowsInstance struct {