Files
ProxmoxDash/update.go
2026-07-31 22:32:20 +03:00

78 lines
2.2 KiB
Go

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
}