diff --git a/api.go b/api.go index 7ec2981..277ea0c 100644 --- a/api.go +++ b/api.go @@ -73,11 +73,7 @@ func main() { corsRouter.HandleFunc("/sessions/{sessionId}/instances/{instanceName}", handlers.DeleteInstance).Methods("DELETE") corsRouter.HandleFunc("/sessions/{sessionId}/instances/{instanceName}/exec", handlers.Exec).Methods("POST") - h := func(w http.ResponseWriter, r *http.Request) { - http.ServeFile(w, r, "./www/index.html") - } - - r.HandleFunc("/p/{sessionId}", h).Methods("GET") + r.HandleFunc("/p/{sessionId}", handlers.Home).Methods("GET") r.PathPrefix("/assets").Handler(http.FileServer(http.Dir("./www"))) r.HandleFunc("/robots.txt", func(rw http.ResponseWriter, r *http.Request) { http.ServeFile(rw, r, "www/robots.txt") diff --git a/handlers/home.go b/handlers/home.go new file mode 100644 index 0000000..b3bd008 --- /dev/null +++ b/handlers/home.go @@ -0,0 +1,41 @@ +package handlers + +import ( + "log" + "net/http" + "path" + + "github.com/gorilla/mux" + "github.com/play-with-docker/play-with-docker/services" +) + +func Home(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + sessionId := vars["sessionId"] + + stack := r.URL.Query().Get("stack") + s := services.GetSession(sessionId) + if stack != "" { + go deployStack(s, stack) + } + http.ServeFile(w, r, "./www/index.html") +} + +func deployStack(s *services.Session, stack string) { + i, err := services.NewInstance(s, services.InstanceConfig{}) + if err != nil { + log.Printf("Error creating instance for stack [%s]: %s\n", stack, err) + } + err = i.UploadFromURL("https://raw.githubusercontent.com/play-with-docker/stacks/master" + stack) + if err != nil { + log.Printf("Error uploading stack file [%s]: %s\n", stack, err) + } + + fileName := path.Base(stack) + code, err := services.Exec(i.Name, []string{"docker-compose", "-f", "/var/run/pwd/uploads/" + fileName, "up", "-d"}) + if err != nil { + log.Printf("Error executing stack [%s]: %s\n", stack, err) + } + + log.Printf("Stack execution finished with code %d\n", code) +} diff --git a/handlers/new_session.go b/handlers/new_session.go index 52d34bc..cf79084 100644 --- a/handlers/new_session.go +++ b/handlers/new_session.go @@ -5,7 +5,6 @@ import ( "fmt" "log" "net/http" - "path" "github.com/play-with-docker/play-with-docker/config" "github.com/play-with-docker/play-with-docker/services" @@ -27,16 +26,24 @@ func NewSession(rw http.ResponseWriter, req *http.Request) { reqDur := req.Form.Get("session-duration") stack := req.Form.Get("stack") + if stack != "" { + if ok, err := stackExists(stack); err != nil { + log.Printf("Error retrieving stack: %s", err) + rw.WriteHeader(http.StatusInternalServerError) + return + } else if !ok { + log.Printf("Stack [%s] could not be found", stack) + rw.WriteHeader(http.StatusBadRequest) + return + } + + } duration := services.GetDuration(reqDur) s, err := services.NewSession(duration) if err != nil { log.Println(err) //TODO: Return some error code } else { - s.StackFile = stack - if stack != "" { - go deployStack(s) - } hostname := fmt.Sprintf("%s.%s", config.PWDCName, req.Host) // If request is not a form, return sessionId in the body if req.Header.Get("X-Requested-With") == "XMLHttpRequest" { @@ -45,25 +52,22 @@ func NewSession(rw http.ResponseWriter, req *http.Request) { json.NewEncoder(rw).Encode(resp) return } + + if stack != "" { + http.Redirect(rw, req, fmt.Sprintf("http://%s/p/%s?stack=%s", hostname, s.Id, stack), http.StatusFound) + return + } http.Redirect(rw, req, fmt.Sprintf("http://%s/p/%s", hostname, s.Id), http.StatusFound) } } -func deployStack(s *services.Session) { - i, err := services.NewInstance(s, services.InstanceConfig{}) +func stackExists(stack string) (bool, error) { + resp, err := http.Head("https://raw.githubusercontent.com/play-with-docker/stacks/master" + stack) if err != nil { - log.Printf("Error creating instance for stack [%s]: %s\n", s.StackFile, err) - } - err = i.UploadFromURL("https://raw.githubusercontent.com/play-with-docker/stacks/master" + s.StackFile) - if err != nil { - log.Printf("Error uploading stack file [%s]: %s\n", s.StackFile, err) + return false, err } + defer resp.Body.Close() - fileName := path.Base(s.StackFile) - code, err := services.Exec(i.Name, []string{"docker-compose", "-f", "/var/run/pwd/uploads/" + fileName, "up", "-d"}) - if err != nil { - log.Printf("Error executing stack [%s]: %s\n", s.StackFile, err) - } + return resp.StatusCode == 200, nil - log.Printf("Stack execution finished with code %d\n", code) } diff --git a/services/session.go b/services/session.go index b52c2d2..61babac 100644 --- a/services/session.go +++ b/services/session.go @@ -56,7 +56,6 @@ type Session struct { scheduled bool `json:"-"` ticker *time.Ticker `json:"-"` PwdIpAddress string `json:"pwd_ip_address"` - StackFile string `json:"-"` } func (s *Session) Lock() {