diff --git a/config/config.go b/config/config.go index 30e30c4..15f9f79 100644 --- a/config/config.go +++ b/config/config.go @@ -2,6 +2,7 @@ package config import ( "flag" + "os" "regexp" "github.com/gorilla/securecookie" @@ -30,6 +31,11 @@ var ForceTLS bool var SecureCookie *securecookie.SecureCookie var AdminToken string +// Unsafe enables a number of unsafe features when set. It is principally +// intended to be used in development. For example, it allows the caller to +// specify the Docker networks to join. +var Unsafe bool + var PlaygroundDomain string var SegmentId string @@ -60,6 +66,8 @@ func ParseFlags() { flag.StringVar(&SegmentId, "segment-id", "", "Segment id to post metrics") + flag.BoolVar(&Unsafe, "unsafe", os.Getenv("PWD_UNSAFE") == "true", "Operate in unsafe mode") + flag.Parse() SecureCookie = securecookie.New([]byte(CookieHashKey), []byte(CookieBlockKey)) diff --git a/provisioner/dind.go b/provisioner/dind.go index a63daee..cdec3b1 100644 --- a/provisioner/dind.go +++ b/provisioner/dind.go @@ -11,6 +11,7 @@ import ( "strings" lru "github.com/hashicorp/golang-lru" + "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/id" "github.com/play-with-docker/play-with-docker/pwd/types" @@ -65,6 +66,12 @@ func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (* } conf.Hostname = nodeName } + + networks := []string{session.Id} + if config.Unsafe { + networks = append(networks, conf.Networks...) + } + containerName := fmt.Sprintf("%s_%s", session.Id[:8], d.generator.NewId()) opts := docker.CreateContainerOpts{ Image: conf.ImageName, @@ -76,7 +83,7 @@ func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (* CACert: conf.CACert, HostFQDN: conf.PlaygroundFQDN, Privileged: true, - Networks: []string{session.Id}, + Networks: networks, DindVolumeSize: conf.DindVolumeSize, Envs: conf.Envs, } diff --git a/pwd/instance_test.go b/pwd/instance_test.go index 2513894..5bc7133 100644 --- a/pwd/instance_test.go +++ b/pwd/instance_test.go @@ -152,6 +152,15 @@ func TestInstanceNew_WithNotAllowedImage(t *testing.T) { assert.Nil(t, err) + // Switch to unsafe mode in order to test custom networks below + // + // TODO: move config away from being a global in order that we don't + // have to hack setting the context in this way. + config.Unsafe = true + defer func() { + config.Unsafe = false + }() + expectedInstance := types.Instance{ Name: fmt.Sprintf("%s_aaaabbbbcccc", session.Id[:8]), Hostname: "node1", @@ -172,14 +181,14 @@ func TestInstanceNew_WithNotAllowedImage(t *testing.T) { CACert: nil, Privileged: true, Envs: []string{"HELLO=WORLD"}, - Networks: []string{session.Id}, + Networks: []string{session.Id, "arpanet"}, } _d.On("ContainerCreate", expectedContainerOpts).Return(nil) _d.On("ContainerIPs", expectedInstance.Name).Return(map[string]string{session.Id: "10.0.0.1"}, nil) _s.On("InstancePut", mock.AnythingOfType("*types.Instance")).Return(nil) _e.M.On("Emit", event.INSTANCE_NEW, "aaaabbbbcccc", []interface{}{"aaaabbbb_aaaabbbbcccc", "10.0.0.1", "node1", "ip10-0-0-1-aaaabbbbcccc"}).Return() - instance, err := p.InstanceNew(session, types.InstanceConfig{ImageName: "redis", Envs: []string{"HELLO=WORLD"}}) + instance, err := p.InstanceNew(session, types.InstanceConfig{ImageName: "redis", Envs: []string{"HELLO=WORLD"}, Networks: []string{"arpanet"}}) assert.Nil(t, err) assert.Equal(t, expectedInstance, *instance) diff --git a/pwd/types/instance.go b/pwd/types/instance.go index 4f84ed1..5b6c33c 100644 --- a/pwd/types/instance.go +++ b/pwd/types/instance.go @@ -40,4 +40,5 @@ type InstanceConfig struct { Type string DindVolumeSize string Envs []string + Networks []string }