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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
package handler
import (
"fmt"
"html/template"
"log/slog"
"net/http"
"time"
"git.leonardobishop.net/instancer/pkg/deployer"
"git.leonardobishop.net/instancer/pkg/session"
)
func GetInstances(tmpl *template.Template, dockerDeployer *deployer.DockerDeployer) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*session.UserSession)
instances, err := dockerDeployer.GetTeamInstances(r.Context(), session.Team)
if err != nil {
slog.Error("could not get team instances", "team", session.Team, "error", err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
type instanceView struct {
ChallengeName string
DeployKey string
Address template.HTML
ExpiresIn string
}
var instanceViews []instanceView
for _, instance := range instances {
var expiresIn string
timeLeft := time.Until(instance.ExpiresAt)
if timeLeft <= 0 {
expiresIn = "now"
} else {
expiresIn = fmt.Sprintf("%dm %ds", int(timeLeft.Minutes()), int(timeLeft.Seconds())%60)
}
var address string
if instance.AddressFormat == "http" || instance.AddressFormat == "https" {
address = `<a target="_blank" href="` + instance.AddressFormat + "://" + instance.Address + `">` + instance.Address + `</a>`
} else {
address = `<code>` + instance.Address + `</code>`
}
instanceViews = append(instanceViews, instanceView{
ChallengeName: instance.ChallengeName,
DeployKey: instance.DeployKey,
Address: template.HTML(address),
ExpiresIn: expiresIn,
})
}
if err := tmpl.ExecuteTemplate(w, "f_instance.html", struct {
Instances []instanceView
}{
Instances: instanceViews,
}); err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
}
}
func PostStopInstance(tmpl *template.Template, dockerDeployer *deployer.DockerDeployer) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*session.UserSession)
deployKey := r.PathValue("deployKey")
err := dockerDeployer.StopInstance(r.Context(), deployKey, session.Team)
if err != nil {
tmpl.ExecuteTemplate(w, "f_instance_result.html", struct {
State string
Message string
}{
State: "danger",
Message: "Could not stop instance" + err.Error(),
})
return
}
w.Header().Set("HX-Trigger", "poll-instances-now")
tmpl.ExecuteTemplate(w, "f_deploy_result.html", struct {
State string
Message string
}{
State: "success",
Message: "Instance " + deployKey + " stopped",
})
}
}
|