70 lines
2.2 KiB
Go
70 lines
2.2 KiB
Go
|
|
package admin
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"net/http"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
const CurrentAppVersion = "v1.0.0"
|
||
|
|
|
||
|
|
type UpdateCheckResponse struct {
|
||
|
|
Status string `json:"status"`
|
||
|
|
CurrentVersion string `json:"current_version"`
|
||
|
|
LatestVersion string `json:"latest_version,omitempty"`
|
||
|
|
UpdateAvailable bool `json:"update_available"`
|
||
|
|
Message string `json:"message"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// HandleCheckUpdates pings gitea. If air-gapped, it returns manual instructions.
|
||
|
|
func (h *Handler) HandleCheckUpdates(w http.ResponseWriter, r *http.Request) {
|
||
|
|
respPayload := UpdateCheckResponse{
|
||
|
|
CurrentVersion: CurrentAppVersion,
|
||
|
|
}
|
||
|
|
|
||
|
|
client := http.Client{Timeout: 3 * time.Second}
|
||
|
|
|
||
|
|
giteaURL := "https://epigas.gitea.cloud/api/v1/repos/RiskRancher/core/releases/latest"
|
||
|
|
resp, err := client.Get(giteaURL)
|
||
|
|
|
||
|
|
if err != nil || resp.StatusCode != http.StatusOK {
|
||
|
|
respPayload.Status = "offline"
|
||
|
|
respPayload.Message = "No internet connection detected. To update an air-gapped server: Download the latest RiskRancher binary on a connected machine, transfer it via rsync or scp to this server, and restart the service."
|
||
|
|
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
json.NewEncoder(w).Encode(respPayload)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
defer resp.Body.Close()
|
||
|
|
|
||
|
|
var ghRelease struct {
|
||
|
|
TagName string `json:"tag_name"`
|
||
|
|
}
|
||
|
|
if err := json.NewDecoder(resp.Body).Decode(&ghRelease); err == nil {
|
||
|
|
respPayload.Status = "online"
|
||
|
|
respPayload.LatestVersion = ghRelease.TagName
|
||
|
|
respPayload.UpdateAvailable = (ghRelease.TagName != CurrentAppVersion)
|
||
|
|
|
||
|
|
if respPayload.UpdateAvailable {
|
||
|
|
respPayload.Message = "A new version is available! Please trigger a graceful shutdown and swap the binary."
|
||
|
|
} else {
|
||
|
|
respPayload.Message = "You are running the latest version."
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
json.NewEncoder(w).Encode(respPayload)
|
||
|
|
}
|
||
|
|
|
||
|
|
// HandleShutdown signals the application to close connections and exit cleanly
|
||
|
|
func (h *Handler) HandleShutdown(w http.ResponseWriter, r *http.Request) {
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
w.Write([]byte(`{"message": "Initiating graceful shutdown. The server will exit in 2 seconds..."}`))
|
||
|
|
go func() {
|
||
|
|
time.Sleep(2 * time.Second)
|
||
|
|
}()
|
||
|
|
}
|