package main import ( "encoding/json" "fmt" "os" "path/filepath" "time" ) const defaultUpdateStatusPath = "/var/lib/proxmox-dashboard/update-status.json" const defaultUpdateRequestPath = "/var/lib/proxmox-dashboard/update-request" type UpdateStatus struct { CurrentVersion string `json:"currentVersion"` AvailableVersion string `json:"availableVersion"` State string `json:"state"` Mode string `json:"mode"` Message string `json:"message"` ReleaseURL string `json:"releaseUrl"` CheckedAt time.Time `json:"checkedAt"` } func readUpdateStatus() UpdateStatus { status := UpdateStatus{CurrentVersion: version, State: "unknown", Mode: "notify"} path := os.Getenv("DASHBOARD_UPDATE_STATUS_PATH") if path == "" { path = defaultUpdateStatusPath } data, err := os.ReadFile(path) if err != nil || json.Unmarshal(data, &status) != nil { return status } status.CurrentVersion = version return status } func requestUpdate() (UpdateStatus, error) { requestPath := os.Getenv("DASHBOARD_UPDATE_REQUEST_PATH") if requestPath == "" { requestPath = defaultUpdateRequestPath } if err := os.MkdirAll(filepath.Dir(requestPath), 0o750); err != nil { return UpdateStatus{}, err } status := readUpdateStatus() status.State = "queued" status.Message = "Обновление поставлено в очередь." status.CheckedAt = time.Now() statusPath := os.Getenv("DASHBOARD_UPDATE_STATUS_PATH") if statusPath == "" { statusPath = defaultUpdateStatusPath } data, _ := json.Marshal(status) temporary, err := os.CreateTemp(filepath.Dir(statusPath), ".update-status-") if err != nil { return UpdateStatus{}, err } temporaryPath := temporary.Name() defer os.Remove(temporaryPath) if _, err = temporary.Write(data); err == nil { err = temporary.Chmod(0o644) } if closeErr := temporary.Close(); err == nil { err = closeErr } if err == nil { err = os.Rename(temporaryPath, statusPath) } if err != nil { return UpdateStatus{}, fmt.Errorf("не удалось сохранить запрос обновления: %w", err) } if err := os.WriteFile(requestPath, []byte(time.Now().Format(time.RFC3339Nano)), 0o640); err != nil { return UpdateStatus{}, err } return status, nil }