summaryrefslogtreecommitdiffstats
path: root/web/handler/deploy.go
diff options
context:
space:
mode:
authorLeonardo Bishop <me@leonardobishop.net>2026-01-07 23:39:53 +0000
committerLeonardo Bishop <me@leonardobishop.net>2026-01-07 23:39:53 +0000
commit03cd6bdfbd473dba3f3dc50a1b15e389aac5bc70 (patch)
tree5fea2b1840e298aaab953add749fb9226bd4a710 /web/handler/deploy.go
Initial commit
Diffstat (limited to 'web/handler/deploy.go')
-rw-r--r--web/handler/deploy.go81
1 files changed, 81 insertions, 0 deletions
diff --git a/web/handler/deploy.go b/web/handler/deploy.go
new file mode 100644
index 0000000..24e0f95
--- /dev/null
+++ b/web/handler/deploy.go
@@ -0,0 +1,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()
+ }
+ }
+
+ }
+}