summaryrefslogtreecommitdiffstats
path: root/web/handler/deploy.go
blob: 24e0f9540caa61aec81028fe3e71b8918ae9af5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package handler

import (
	"fmt"
	"html/template"
	"net/http"

	"git.leonardobishop.net/instancer/pkg/deployer"
	"git.leonardobishop.net/instancer/pkg/registry"
	"git.leonardobishop.net/instancer/pkg/session"
)

func PostDeploy(tmpl *template.Template, dockerDeployer *deployer.DockerDeployer) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if err := r.ParseForm(); err != nil {
			http.Error(w, "Invalid form data", http.StatusBadRequest)
			return
		}

		challenge := r.FormValue("challenge")
		if challenge == "" {
			http.Error(w, "No challenge selected", http.StatusBadRequest)
			return
		}

		session := r.Context().Value("session").(*session.UserSession)
		deployKey := dockerDeployer.StartDeploy(challenge, session.Team)

		tmpl.ExecuteTemplate(w, "f_deploy.html", struct {
			DeployKey string
			Challenge string
		}{
			DeployKey: deployKey,
			Challenge: challenge,
		})
	}
}

func DeploySSE(tmpl *template.Template, registryClient *registry.RegistryClient, dockerDeployer *deployer.DockerDeployer) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		flusher, ok := w.(http.Flusher)
		if !ok {
			http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
			return
		}

		deployKey := r.URL.Query().Get("deploy")
		if deployKey == "" {
			http.Error(w, "No deployment specified", http.StatusBadRequest)
			return
		}

		w.Header().Set("Content-Type", "text/event-stream")
		w.Header().Set("Cache-Control", "no-cache")
		w.Header().Set("Connection", "keep-alive")

		clientGone := r.Context().Done()
		job := dockerDeployer.GetJob(deployKey)

		if job == nil || job.DeployChan == nil {
			fmt.Fprintf(w, "event: %s\ndata: %s\n\n", "close", "Invalid deployment key")
			flusher.Flush()
			return
		}

		for {
			select {
			case <-clientGone:
				return
			case update, ok := <-job.DeployChan:
				if !ok {
					return
				}

				fmt.Fprintf(w, "event: %s\ndata: %s\n\n", update.Status, update.Message)
				flusher.Flush()
			}
		}

	}
}