0.2.45 - Server side git commits

This commit is contained in:
ponzischeme89
2026-08-10 20:54:00 +12:00
parent 4c47a5f8a0
commit dd2dd497f2
11 changed files with 170 additions and 63 deletions
+27 -7
View File
@@ -521,6 +521,12 @@ type updatePolicyRequest struct {
// toggle rather than exposing "minimum version" directly, because "force this
// update" is the decision an operator actually wants to make.
Required bool `json:"required"`
// Destructive removes sessions for clients below this release. It implies Required,
// but remains separate so a required update can keep viewers signed in.
Destructive bool `json:"destructive"`
// RetireBelowVersion exposes the exact destructive compatibility floor for releases
// where the operator needs to retire only part of the installed fleet.
RetireBelowVersion string `json:"retireBelowVersion"`
// MinimumVersion is honoured when set explicitly, for staged rollouts where the
// forced floor is older than the latest build.
MinimumVersion string `json:"minimumVersion"`
@@ -533,14 +539,15 @@ func (s *Server) handleAdminUpdatePolicy(w http.ResponseWriter, r *http.Request)
return
}
policy := appupdate.Policy{
Enabled: req.Enabled,
LatestVersion: strings.TrimSpace(req.LatestVersion),
MinimumVersion: strings.TrimSpace(req.MinimumVersion),
DownloadURL: strings.TrimSpace(req.DownloadURL),
Notes: strings.TrimSpace(req.Notes),
}
current := s.updatePolicy.get()
policy := appupdate.Policy{
Enabled: req.Enabled,
LatestVersion: strings.TrimSpace(req.LatestVersion),
MinimumVersion: strings.TrimSpace(req.MinimumVersion),
RetireBelowVersion: strings.TrimSpace(req.RetireBelowVersion),
DownloadURL: strings.TrimSpace(req.DownloadURL),
Notes: strings.TrimSpace(req.Notes),
}
if policy.LatestVersion == current.LatestVersion && policy.DownloadURL == current.DownloadURL {
// Changing "required" or release notes must not silently discard integrity
// metadata added by the signed release publisher.
@@ -554,6 +561,10 @@ func (s *Server) handleAdminUpdatePolicy(w http.ResponseWriter, r *http.Request)
// Un-ticking the box must actually release the floor.
policy.MinimumVersion = ""
}
if req.Destructive {
policy.MinimumVersion = policy.LatestVersion
policy.RetireBelowVersion = policy.LatestVersion
}
if policy.Enabled && policy.LatestVersion == "" {
writeError(w, http.StatusBadRequest, "set the latest version before enabling update prompts")
@@ -563,6 +574,15 @@ func (s *Server) handleAdminUpdatePolicy(w http.ResponseWriter, r *http.Request)
writeError(w, http.StatusBadRequest, "set the APK download URL before enabling update prompts")
return
}
if policy.RetireBelowVersion != "" && !releaseVersionPattern.MatchString(policy.RetireBelowVersion) {
writeError(w, http.StatusBadRequest, "the destructive update floor must look like 0.2.44")
return
}
if policy.Enabled && policy.RetireBelowVersion != "" &&
appupdate.CompareVersions(policy.RetireBelowVersion, policy.LatestVersion) > 0 {
writeError(w, http.StatusBadRequest, "the destructive update floor cannot be newer than the latest version")
return
}
if err := s.store.SetUpdatePolicy(r.Context(), policy); err != nil {
s.loggerFor(r.Context()).Error("update policy write failed", "error", err)