Агенты подхватывают изменения с сервера: каталог и самообновление
CI / test (push) Successful in 1m29s
CI / test (push) Successful in 1m29s
- сервер отдаёт агенту итоговый каталог (встроенный каталог сервера + переопределения клиента); если каталог не подходит версии агента — встроенный каталог агента и предупреждение - самообновление перед бэкапом: версия сервера новее → скачивание с того же сервера (только /dl/...), проверка sha256 и запуска новой версии, подмена с откатом, перезапуск через exec; при ошибке бэкап идёт текущей версией - галочка «Автообновление» у клиента (по умолчанию включена), версия агента в списке и карточке, отставшие подсвечены; версия сервера в шапке - миграция существующей базы: колонки auto_update и agent_version - backupctl backup --no-update Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1947b26913
commit
488abc2d34
21 files changed
+674
-51
No files matched your search
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
"gitea.hsrv.site/mrleo1nid/backup-master/internal/catalog"
|
||||
"gitea.hsrv.site/mrleo1nid/backup-master/internal/manifest"
|
||||
"gitea.hsrv.site/mrleo1nid/backup-master/internal/version"
|
||||
)
|
||||
|
||||
//go:embed templates/*.html
|
||||
@@ -95,6 +96,7 @@ func (s *Server) render(w http.ResponseWriter, r *http.Request, page string, dat
|
||||
data["CSRF"] = csrfFrom(r)
|
||||
data["Page"] = page
|
||||
data["PublicURL"] = s.cfg.PublicURL
|
||||
data["ServerVersion"] = s.cfg.Version
|
||||
var buf bytes.Buffer
|
||||
if err := t.Execute(&buf, data); err != nil {
|
||||
log.Printf("render %s: %v", page, err)
|
||||
@@ -127,6 +129,7 @@ type clientRow struct {
|
||||
*Client
|
||||
StatusClass, StatusText string
|
||||
LastSize int64
|
||||
Outdated bool // агент старее сервера
|
||||
}
|
||||
|
||||
func (s *Server) webClientNew(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -196,7 +199,8 @@ func (s *Server) renderClient(w http.ResponseWriter, r *http.Request, c *Client,
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
data := map[string]any{"Client": c, "Backups": backups, "Error": formErr}
|
||||
data := map[string]any{"Client": c, "Backups": backups, "Error": formErr,
|
||||
"AgentOutdated": c.AgentVersion != "" && version.ShouldUpdate(s.cfg.Version, c.AgentVersion)}
|
||||
data["StatusClass"], data["StatusText"] = clientStatus(c)
|
||||
if latest, err := s.st.LatestComplete(c.ID); err == nil {
|
||||
var m manifest.Manifest
|
||||
@@ -230,6 +234,7 @@ func (s *Server) webClientSettings(w http.ResponseWriter, r *http.Request) {
|
||||
c.HeavyEveryDays = formInt(r, "heavy_every_days", c.HeavyEveryDays)
|
||||
c.StaleHours = formInt(r, "stale_hours", c.StaleHours)
|
||||
c.Disabled = r.FormValue("disabled") == "1"
|
||||
c.AutoUpdate = r.FormValue("auto_update") == "1"
|
||||
if strings.TrimSpace(c.ConfigYAML) != "" {
|
||||
base, err := catalog.Default()
|
||||
if err == nil {
|
||||
|
||||
Reference in new issue
Block a user