Move DindVolumeSize to playground opts

This commit is contained in:
Marcos Lilljedahl
2019-04-23 01:47:06 -03:00
parent 1bee95e862
commit 4b1dc52c59
11 changed files with 65 additions and 41 deletions

6
api.go
View File

@@ -47,12 +47,12 @@ func main() {
sch.Start() sch.Start()
d, err := time.ParseDuration(config.DefaultSessionDuration) d, err := time.ParseDuration("4h")
if err != nil { if err != nil {
log.Fatalf("Cannot parse duration %s. Got: %v", config.DefaultSessionDuration, err) log.Fatalf("Cannot parse duration Got: %v", err)
} }
playground := types.Playground{Domain: config.PlaygroundDomain, DefaultDinDInstanceImage: config.DefaultDinDImage, AllowWindowsInstances: config.NoWindows, DefaultSessionDuration: d, AvailableDinDInstanceImages: []string{config.DefaultDinDImage}, Tasks: []string{".*"}} playground := types.Playground{Domain: config.PlaygroundDomain, DefaultDinDInstanceImage: "franela/dind", AllowWindowsInstances: config.NoWindows, DefaultSessionDuration: d, Tasks: []string{".*"}, DockerClientID: "cec293c0-f9dd-4f0b-8c3e-e29df7b956b7", DockerClientSecret: "fdf6f091-3766-44ef-b0be-ab3946e45ec3", DockerHost: "id-stage.docker.com", Extras: map[string]interface{}{"LoginRedirect": "http://localhost:3000"}}
if _, err := core.PlaygroundNew(playground); err != nil { if _, err := core.PlaygroundNew(playground); err != nil {
log.Fatalf("Cannot create default playground. Got: %v", err) log.Fatalf("Cannot create default playground. Got: %v", err)
} }

View File

@@ -22,7 +22,7 @@ const (
var NameFilter = regexp.MustCompile(PWDHostPortGroupRegex) var NameFilter = regexp.MustCompile(PWDHostPortGroupRegex)
var AliasFilter = regexp.MustCompile(AliasPortGroupRegex) var AliasFilter = regexp.MustCompile(AliasPortGroupRegex)
var PortNumber, SessionsFile, PWDContainerName, L2ContainerName, L2Subdomain, HashKey, SSHKeyPath, L2RouterIP, DindVolumeSize, CookieHashKey, CookieBlockKey, DefaultDinDImage, DefaultSessionDuration string var PortNumber, SessionsFile, PWDContainerName, L2ContainerName, L2Subdomain, HashKey, SSHKeyPath, L2RouterIP, CookieHashKey, CookieBlockKey string
var UseLetsEncrypt, ExternalDindVolume, NoWindows bool var UseLetsEncrypt, ExternalDindVolume, NoWindows bool
var LetsEncryptCertsDir string var LetsEncryptCertsDir string
var MaxLoadAvg float64 var MaxLoadAvg float64
@@ -48,15 +48,12 @@ func ParseFlags() {
flag.StringVar(&L2RouterIP, "l2-ip", "", "Host IP address for L2 router ping response") flag.StringVar(&L2RouterIP, "l2-ip", "", "Host IP address for L2 router ping response")
flag.StringVar(&L2Subdomain, "l2-subdomain", "direct", "Subdomain to the L2 Router") flag.StringVar(&L2Subdomain, "l2-subdomain", "direct", "Subdomain to the L2 Router")
flag.StringVar(&HashKey, "hash_key", "salmonrosado", "Hash key to use for cookies") flag.StringVar(&HashKey, "hash_key", "salmonrosado", "Hash key to use for cookies")
flag.StringVar(&DindVolumeSize, "dind-volume-size", "5G", "Dind volume folder size")
flag.BoolVar(&NoWindows, "win-disable", false, "Disable windows instances") flag.BoolVar(&NoWindows, "win-disable", false, "Disable windows instances")
flag.BoolVar(&ExternalDindVolume, "dind-external-volume", false, "Use external dind volume though XFS volume driver") flag.BoolVar(&ExternalDindVolume, "dind-external-volume", false, "Use external dind volume though XFS volume driver")
flag.Float64Var(&MaxLoadAvg, "maxload", 100, "Maximum allowed load average before failing ping requests") flag.Float64Var(&MaxLoadAvg, "maxload", 100, "Maximum allowed load average before failing ping requests")
flag.StringVar(&SSHKeyPath, "ssh_key_path", "", "SSH Private Key to use") flag.StringVar(&SSHKeyPath, "ssh_key_path", "", "SSH Private Key to use")
flag.StringVar(&CookieHashKey, "cookie-hash-key", "", "Hash key to use to validate cookies") flag.StringVar(&CookieHashKey, "cookie-hash-key", "", "Hash key to use to validate cookies")
flag.StringVar(&CookieBlockKey, "cookie-block-key", "", "Block key to use to encrypt cookies") flag.StringVar(&CookieBlockKey, "cookie-block-key", "", "Block key to use to encrypt cookies")
flag.StringVar(&DefaultDinDImage, "default-dind-image", "franela/dind", "Default DinD image to use if not specified otherwise")
flag.StringVar(&DefaultSessionDuration, "default-session-duration", "4h", "Default session duration if not specified otherwise")
flag.StringVar(&PlaygroundDomain, "playground-domain", "localhost", "Domain to use for the playground") flag.StringVar(&PlaygroundDomain, "playground-domain", "localhost", "Domain to use for the playground")
flag.StringVar(&AdminToken, "admin-token", "", "Token to validate admin user for admin endpoints") flag.StringVar(&AdminToken, "admin-token", "", "Token to validate admin user for admin endpoints")

View File

@@ -250,17 +250,18 @@ func (d *docker) ContainerDelete(name string) error {
} }
type CreateContainerOpts struct { type CreateContainerOpts struct {
Image string Image string
SessionId string SessionId string
ContainerName string ContainerName string
Hostname string Hostname string
ServerCert []byte ServerCert []byte
ServerKey []byte ServerKey []byte
CACert []byte CACert []byte
Privileged bool Privileged bool
HostFQDN string HostFQDN string
Labels map[string]string Labels map[string]string
Networks []string Networks []string
DindVolumeSize string
} }
func (d *docker) ContainerCreate(opts CreateContainerOpts) (err error) { func (d *docker) ContainerCreate(opts CreateContainerOpts) (err error) {
@@ -342,7 +343,7 @@ func (d *docker) ContainerCreate(opts CreateContainerOpts) (err error) {
_, err = d.c.VolumeCreate(context.Background(), volume.VolumesCreateBody{ _, err = d.c.VolumeCreate(context.Background(), volume.VolumesCreateBody{
Driver: "xfsvol", Driver: "xfsvol",
DriverOpts: map[string]string{ DriverOpts: map[string]string{
"size": config.DindVolumeSize, "size": opts.DindVolumeSize,
}, },
Name: opts.ContainerName, Name: opts.ContainerName,
}) })

View File

@@ -240,10 +240,8 @@ func initOauthProviders(p *types.Playground) {
config.Providers[p.Id]["facebook"] = conf config.Providers[p.Id]["facebook"] = conf
} }
if p.DockerClientID != "" && p.DockerClientSecret != "" { if p.DockerClientID != "" && p.DockerClientSecret != "" {
endpoint := "id.docker.com"
if len(p.DockerHost) > 0 { endpoint := getDockerEndpoint(p)
endpoint = p.DockerHost
}
oauth2.RegisterBrokenAuthHeaderProvider(fmt.Sprintf(".%s", endpoint)) oauth2.RegisterBrokenAuthHeaderProvider(fmt.Sprintf(".%s", endpoint))
conf := &oauth2.Config{ conf := &oauth2.Config{
ClientID: p.DockerClientID, ClientID: p.DockerClientID,

View File

@@ -12,11 +12,12 @@ type CookieID struct {
UserAvatar string `json:"user_avatar"` UserAvatar string `json:"user_avatar"`
} }
func (c *CookieID) SetCookie(rw http.ResponseWriter) error { func (c *CookieID) SetCookie(rw http.ResponseWriter, host string) error {
if encoded, err := config.SecureCookie.Encode("id", c); err == nil { if encoded, err := config.SecureCookie.Encode("id", c); err == nil {
cookie := &http.Cookie{ cookie := &http.Cookie{
Name: "id", Name: "id",
Value: encoded, Value: encoded,
Domain: host,
Path: "/", Path: "/",
Secure: config.UseLetsEncrypt, Secure: config.UseLetsEncrypt,
HttpOnly: true, HttpOnly: true,

View File

@@ -166,7 +166,9 @@ func LoginCallback(rw http.ResponseWriter, req *http.Request) {
&oauth2.Token{AccessToken: tok.AccessToken}, &oauth2.Token{AccessToken: tok.AccessToken},
) )
tc := oauth2.NewClient(ctx, ts) tc := oauth2.NewClient(ctx, ts)
resp, err := tc.Get("https://id.docker.com/api/id/v1/openid/userinfo")
endpoint := getDockerEndpoint(playground)
resp, err := tc.Get(fmt.Sprintf("https://%s/api/id/v1/openid/userinfo", endpoint))
if err != nil { if err != nil {
log.Printf("Could not get user from docker. Got: %v\n", err) log.Printf("Could not get user from docker. Got: %v\n", err)
rw.WriteHeader(http.StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)
@@ -197,26 +199,42 @@ func LoginCallback(rw http.ResponseWriter, req *http.Request) {
cookieData := CookieID{Id: user.Id, UserName: user.Name, UserAvatar: user.Avatar} cookieData := CookieID{Id: user.Id, UserName: user.Name, UserAvatar: user.Avatar}
if err := cookieData.SetCookie(rw); err != nil { host := "localhost"
if req.Host != "" {
host = req.Host
}
if err := cookieData.SetCookie(rw, host); err != nil {
log.Printf("Could not encode cookie. Got: %v\n", err) log.Printf("Could not encode cookie. Got: %v\n", err)
rw.WriteHeader(http.StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)
return return
} }
r, _ := playground.Extras.GetString("LoginRedirect")
fmt.Fprintf(rw, ` fmt.Fprintf(rw, `
<html> <html>
<head> <head>
<script> <script>
if (window.opener && !window.opener.closed) { if (window.opener && !window.opener.closed) {
try { try {
window.opener.postMessage('done','*') window.opener.postMessage('done','*');
} }
catch(e) { } catch(e) { }
window.close(); window.close();
} else {
window.location = '%s';
} }
</script> </script>
</head> </head>
<body> <body>
</body> </body>
</html>`) </html>`, r)
}
func getDockerEndpoint(p *types.Playground) string {
if len(p.DockerHost) > 0 {
return p.DockerHost
}
return "id.docker.com"
} }

View File

@@ -15,7 +15,7 @@ func NewInstance(rw http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req) vars := mux.Vars(req)
sessionId := vars["sessionId"] sessionId := vars["sessionId"]
body := types.InstanceConfig{PlaygroundFQDN: req.Host} body := types.InstanceConfig{PlaygroundFQDN: req.Host, DindVolumeSize: "5G"}
json.NewDecoder(req.Body).Decode(&body) json.NewDecoder(req.Body).Decode(&body)
@@ -51,6 +51,10 @@ func NewInstance(rw http.ResponseWriter, req *http.Request) {
return return
} }
if len(playground.DindVolumeSize) > 0 {
body.DindVolumeSize = playground.DindVolumeSize
}
i, err := core.InstanceNew(s, body) i, err := core.InstanceNew(s, body)
if err != nil { if err != nil {
if provisioner.OutOfCapacity(err) { if provisioner.OutOfCapacity(err) {

View File

@@ -59,6 +59,7 @@ type PlaygroundConfigurationResponse struct {
AvailableDinDInstanceImages []string `json:"available_dind_instance_images"` AvailableDinDInstanceImages []string `json:"available_dind_instance_images"`
AllowWindowsInstances bool `json:"allow_windows_instances"` AllowWindowsInstances bool `json:"allow_windows_instances"`
DefaultSessionDuration time.Duration `json:"default_session_duration"` DefaultSessionDuration time.Duration `json:"default_session_duration"`
DindVolumeSize string `json:"dind_volume_size"`
} }
func GetCurrentPlayground(rw http.ResponseWriter, req *http.Request) { func GetCurrentPlayground(rw http.ResponseWriter, req *http.Request) {
@@ -69,12 +70,13 @@ func GetCurrentPlayground(rw http.ResponseWriter, req *http.Request) {
return return
} }
json.NewEncoder(rw).Encode(PlaygroundConfigurationResponse{ json.NewEncoder(rw).Encode(PlaygroundConfigurationResponse{
Id: playground.Id, Id: playground.Id,
Domain: playground.Domain, Domain: playground.Domain,
DefaultDinDInstanceImage: playground.DefaultDinDInstanceImage, DefaultDinDInstanceImage: playground.DefaultDinDInstanceImage,
AvailableDinDInstanceImages: playground.AvailableDinDInstanceImages, AvailableDinDInstanceImages: playground.AvailableDinDInstanceImages,
AllowWindowsInstances: playground.AllowWindowsInstances, AllowWindowsInstances: playground.AllowWindowsInstances,
DefaultSessionDuration: playground.DefaultSessionDuration, DefaultSessionDuration: playground.DefaultSessionDuration,
DindVolumeSize: playground.DindVolumeSize,
}) })
} }

View File

@@ -67,16 +67,17 @@ func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (*
} }
containerName := fmt.Sprintf("%s_%s", session.Id[:8], d.generator.NewId()) containerName := fmt.Sprintf("%s_%s", session.Id[:8], d.generator.NewId())
opts := docker.CreateContainerOpts{ opts := docker.CreateContainerOpts{
Image: conf.ImageName, Image: conf.ImageName,
SessionId: session.Id, SessionId: session.Id,
ContainerName: containerName, ContainerName: containerName,
Hostname: conf.Hostname, Hostname: conf.Hostname,
ServerCert: conf.ServerCert, ServerCert: conf.ServerCert,
ServerKey: conf.ServerKey, ServerKey: conf.ServerKey,
CACert: conf.CACert, CACert: conf.CACert,
HostFQDN: conf.PlaygroundFQDN, HostFQDN: conf.PlaygroundFQDN,
Privileged: true, Privileged: true,
Networks: []string{session.Id}, Networks: []string{session.Id},
DindVolumeSize: conf.DindVolumeSize,
} }
dockerClient, err := d.factory.GetForSession(session) dockerClient, err := d.factory.GetForSession(session)

View File

@@ -38,4 +38,5 @@ type InstanceConfig struct {
Tls bool Tls bool
PlaygroundFQDN string PlaygroundFQDN string
Type string Type string
DindVolumeSize string
} }

View File

@@ -78,6 +78,7 @@ type Playground struct {
AvailableDinDInstanceImages []string `json:"available_dind_instance_images" bson:"available_dind_instance_images"` AvailableDinDInstanceImages []string `json:"available_dind_instance_images" bson:"available_dind_instance_images"`
AllowWindowsInstances bool `json:"allow_windows_instances" bson:"allow_windows_instances"` AllowWindowsInstances bool `json:"allow_windows_instances" bson:"allow_windows_instances"`
DefaultSessionDuration time.Duration `json:"default_session_duration" bson:"default_session_duration"` DefaultSessionDuration time.Duration `json:"default_session_duration" bson:"default_session_duration"`
DindVolumeSize string `json:"dind_volume_size" bson:"dind_volume_size"`
Extras PlaygroundExtras `json:"extras" bson:"extras"` Extras PlaygroundExtras `json:"extras" bson:"extras"`
AssetsDir string `json:"assets_dir" bson:"assets_dir"` AssetsDir string `json:"assets_dir" bson:"assets_dir"`
Tasks []string `json:"tasks" bson:"tasks"` Tasks []string `json:"tasks" bson:"tasks"`