fix system update current version display

This commit is contained in:
ShukeBta
2026-07-02 00:04:04 +08:00
parent 3bea1ca276
commit 5ecb5e2144
7 changed files with 63 additions and 21 deletions
+1 -1
View File
@@ -77,7 +77,7 @@ func main() {
repos := repository.New(db) repos := repository.New(db)
service.ApplyRuntimeSettings(context.Background(), cfg, repos, logger) service.ApplyRuntimeSettings(context.Background(), cfg, repos, logger)
applyCPUThreadLimit(cfg, logger) applyCPUThreadLimit(cfg, logger)
services := service.New(cfg, logger, repos) services := service.NewWithVersion(cfg, logger, repos, version)
if repaired, err := services.RepairCloudPathMetadata(context.Background()); err != nil { if repaired, err := services.RepairCloudPathMetadata(context.Background()); err != nil {
logger.Warn("cloud path metadata repair failed", zap.Error(err)) logger.Warn("cloud path metadata repair failed", zap.Error(err))
+6 -1
View File
@@ -82,7 +82,12 @@ type Container struct {
// New 构建服务容器。 // New 构建服务容器。
func New(cfg *config.Config, log *zap.Logger, repos *repository.Container) *Container { func New(cfg *config.Config, log *zap.Logger, repos *repository.Container) *Container {
return newServiceContainer(cfg, log, repos) return NewWithVersion(cfg, log, repos, "dev")
}
// NewWithVersion 构建带应用版本信息的服务容器。
func NewWithVersion(cfg *config.Config, log *zap.Logger, repos *repository.Container, version string) *Container {
return newServiceContainer(cfg, log, repos, version)
} }
// Boot 启动后台工作进程(watcher, downloads poller, subscription scheduler)。 // Boot 启动后台工作进程(watcher, downloads poller, subscription scheduler)。
+11 -9
View File
@@ -11,19 +11,21 @@ import (
) )
type serviceContainerBuilder struct { type serviceContainerBuilder struct {
cfg *config.Config cfg *config.Config
log *zap.Logger log *zap.Logger
repos *repository.Container repos *repository.Container
c *Container version string
c *Container
} }
func newServiceContainer(cfg *config.Config, log *zap.Logger, repos *repository.Container) *Container { func newServiceContainer(cfg *config.Config, log *zap.Logger, repos *repository.Container, version string) *Container {
ApplyRuntimeSettings(context.Background(), cfg, repos, log) ApplyRuntimeSettings(context.Background(), cfg, repos, log)
builder := &serviceContainerBuilder{ builder := &serviceContainerBuilder{
cfg: cfg, cfg: cfg,
log: log, log: log,
repos: repos, repos: repos,
version: normalizeSystemUpdateVersion(version),
c: &Container{ c: &Container{
Cfg: cfg, Cfg: cfg,
Log: log, Log: log,
@@ -45,7 +47,7 @@ func (b *serviceContainerBuilder) startRealtimeServices() {
b.c.WSHub = NewHub(b.log) b.c.WSHub = NewHub(b.log)
go b.c.WSHub.Run() go b.c.WSHub.Run()
b.c.Tasks = NewTaskTrackerService(b.log, b.c.WSHub) b.c.Tasks = NewTaskTrackerService(b.log, b.c.WSHub)
b.c.SystemUpdate = NewSystemUpdateService(b.cfg, b.log, b.repos, b.c.Tasks) b.c.SystemUpdate = NewSystemUpdateService(b.cfg, b.log, b.repos, b.c.Tasks, b.version)
b.c.SSEHub = NewSSEHub(b.log) b.c.SSEHub = NewSSEHub(b.log)
go b.c.SSEHub.Run() go b.c.SSEHub.Run()
+23 -9
View File
@@ -33,6 +33,7 @@ var ErrSystemUpdateRunning = errors.New("system update already running")
type SystemUpdateStatus struct { type SystemUpdateStatus struct {
Image string `json:"image"` Image string `json:"image"`
CurrentVersion string `json:"current_version,omitempty"`
WatchtowerImage string `json:"watchtower_image,omitempty"` WatchtowerImage string `json:"watchtower_image,omitempty"`
UpdateMode string `json:"update_mode,omitempty"` UpdateMode string `json:"update_mode,omitempty"`
ComposeDir string `json:"compose_dir,omitempty"` ComposeDir string `json:"compose_dir,omitempty"`
@@ -55,18 +56,19 @@ type SystemUpdateStatus struct {
} }
type SystemUpdateService struct { type SystemUpdateService struct {
cfg *config.Config cfg *config.Config
log *zap.Logger log *zap.Logger
repo *repository.Container repo *repository.Container
tasks *TaskTrackerService tasks *TaskTrackerService
version string
mu sync.Mutex mu sync.Mutex
running bool running bool
last *SystemUpdateStatus last *SystemUpdateStatus
} }
func NewSystemUpdateService(cfg *config.Config, log *zap.Logger, repo *repository.Container, tasks *TaskTrackerService) *SystemUpdateService { func NewSystemUpdateService(cfg *config.Config, log *zap.Logger, repo *repository.Container, tasks *TaskTrackerService, version string) *SystemUpdateService {
return &SystemUpdateService{cfg: cfg, log: log, repo: repo, tasks: tasks} return &SystemUpdateService{cfg: cfg, log: log, repo: repo, tasks: tasks, version: normalizeSystemUpdateVersion(version)}
} }
func (s *SystemUpdateService) Status(ctx context.Context) SystemUpdateStatus { func (s *SystemUpdateService) Status(ctx context.Context) SystemUpdateStatus {
@@ -98,12 +100,15 @@ func (s *SystemUpdateService) Check(ctx context.Context) SystemUpdateStatus {
func (s *SystemUpdateService) Apply(ctx context.Context) (SystemUpdateStatus, error) { func (s *SystemUpdateService) Apply(ctx context.Context) (SystemUpdateStatus, error) {
s.mu.Lock() s.mu.Lock()
if s.running { if s.running {
status := SystemUpdateStatus{}
if s.last != nil { if s.last != nil {
status = cloneSystemUpdateStatus(*s.last) status := cloneSystemUpdateStatus(*s.last)
status.Running = true
s.mu.Unlock()
return status, ErrSystemUpdateRunning
} }
status.Running = true
s.mu.Unlock() s.mu.Unlock()
status := s.baseStatus(ctx)
status.Running = true
return status, ErrSystemUpdateRunning return status, ErrSystemUpdateRunning
} }
s.running = true s.running = true
@@ -203,12 +208,21 @@ func (s *SystemUpdateService) baseStatus(ctx context.Context) SystemUpdateStatus
} }
return SystemUpdateStatus{ return SystemUpdateStatus{
Image: image, Image: image,
CurrentVersion: s.version,
WatchtowerImage: watchtowerImage, WatchtowerImage: watchtowerImage,
UpdateMode: "compose", UpdateMode: "compose",
ContainerID: currentContainerID(), ContainerID: currentContainerID(),
} }
} }
func normalizeSystemUpdateVersion(version string) string {
version = strings.TrimSpace(version)
if version == "" {
return "dev"
}
return version
}
func (s *SystemUpdateService) setting(ctx context.Context, key, fallback string) string { func (s *SystemUpdateService) setting(ctx context.Context, key, fallback string) string {
if s == nil || s.repo == nil || s.repo.Setting == nil { if s == nil || s.repo == nil || s.repo.Setting == nil {
return strings.TrimSpace(fallback) return strings.TrimSpace(fallback)
+19
View File
@@ -1,6 +1,7 @@
package service package service
import ( import (
"context"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -152,3 +153,21 @@ func TestSystemUpdateOutputDetailsKeepsTail(t *testing.T) {
t.Fatalf("details length = %d, want 12", len(got)) t.Fatalf("details length = %d, want 12", len(got))
} }
} }
func TestSystemUpdateStatusIncludesCurrentVersion(t *testing.T) {
svc := NewSystemUpdateService(nil, nil, nil, nil, "MediaStationGo-v0.0.99")
status := svc.Status(context.Background())
if status.CurrentVersion != "MediaStationGo-v0.0.99" {
t.Fatalf("current_version = %q, want MediaStationGo-v0.0.99", status.CurrentVersion)
}
}
func TestSystemUpdateStatusDefaultsCurrentVersion(t *testing.T) {
svc := NewSystemUpdateService(nil, nil, nil, nil, "")
status := svc.Status(context.Background())
if status.CurrentVersion != "dev" {
t.Fatalf("current_version = %q, want dev", status.CurrentVersion)
}
}
+1
View File
@@ -3,6 +3,7 @@ import type { AccessLog, Setting, User } from '../types'
export interface SystemUpdateStatus { export interface SystemUpdateStatus {
image: string image: string
current_version?: string
watchtower_image?: string watchtower_image?: string
update_mode?: string update_mode?: string
compose_dir?: string compose_dir?: string
+2 -1
View File
@@ -139,7 +139,8 @@ export function SystemUpdatePanel() {
</div> </div>
</div> </div>
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4"> <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-5">
<UpdateFact label="当前版本" value={status?.current_version || 'dev'} mono />
<UpdateFact icon={Server} label="更新方式" value={status?.update_mode === 'compose' ? 'Docker Compose' : '自定义命令'} /> <UpdateFact icon={Server} label="更新方式" value={status?.update_mode === 'compose' ? 'Docker Compose' : '自定义命令'} />
<UpdateFact label="Compose 目录" value={status?.compose_dir || '自动识别'} mono /> <UpdateFact label="Compose 目录" value={status?.compose_dir || '自动识别'} mono />
<UpdateFact label="应用镜像" value={status?.image || '-'} mono /> <UpdateFact label="应用镜像" value={status?.image || '-'} mono />