Add SessionProvisioner and InstanceProvisionerFactory
Remove AllowedImages and IsDockerHost as it is not really being used for anything useful
This commit is contained in:
6
api.go
6
api.go
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
18
provisioner/factory.go
Normal 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
50
provisioner/overlay.go
Normal 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
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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, "", "", "")
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
37
pwd/pwd.go
37
pwd/pwd.go
@@ -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() {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user