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 = `` + instance.Address + `` } else { address = `` + instance.Address + `` } 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", }) } }