From 5ecb5e2144520971ed7f58462eea8ef6e1deeb77 Mon Sep 17 00:00:00 2001 From: ShukeBta <272197458+ShukeBta@users.noreply.github.com> Date: Thu, 2 Jul 2026 00:04:04 +0800 Subject: [PATCH] fix system update current version display --- cmd/server/main.go | 2 +- internal/service/service.go | 7 +++++- internal/service/service_builder.go | 20 ++++++++-------- internal/service/system_update.go | 32 ++++++++++++++++++-------- internal/service/system_update_test.go | 19 +++++++++++++++ web/src/api/admin.ts | 1 + web/src/pages/SystemUpdatePanel.tsx | 3 ++- 7 files changed, 63 insertions(+), 21 deletions(-) diff --git a/cmd/server/main.go b/cmd/server/main.go index 1c13b7b..6b8dd70 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -77,7 +77,7 @@ func main() { repos := repository.New(db) service.ApplyRuntimeSettings(context.Background(), cfg, repos, 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 { logger.Warn("cloud path metadata repair failed", zap.Error(err)) diff --git a/internal/service/service.go b/internal/service/service.go index 5c020e3..ab2288e 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -82,7 +82,12 @@ type Container struct { // New 构建服务容器。 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)。 diff --git a/internal/service/service_builder.go b/internal/service/service_builder.go index 461163e..b7606c6 100644 --- a/internal/service/service_builder.go +++ b/internal/service/service_builder.go @@ -11,19 +11,21 @@ import ( ) type serviceContainerBuilder struct { - cfg *config.Config - log *zap.Logger - repos *repository.Container - c *Container + cfg *config.Config + log *zap.Logger + repos *repository.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) builder := &serviceContainerBuilder{ - cfg: cfg, - log: log, - repos: repos, + cfg: cfg, + log: log, + repos: repos, + version: normalizeSystemUpdateVersion(version), c: &Container{ Cfg: cfg, Log: log, @@ -45,7 +47,7 @@ func (b *serviceContainerBuilder) startRealtimeServices() { b.c.WSHub = NewHub(b.log) go b.c.WSHub.Run() 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) go b.c.SSEHub.Run() diff --git a/internal/service/system_update.go b/internal/service/system_update.go index 10bca98..ef6c68a 100644 --- a/internal/service/system_update.go +++ b/internal/service/system_update.go @@ -33,6 +33,7 @@ var ErrSystemUpdateRunning = errors.New("system update already running") type SystemUpdateStatus struct { Image string `json:"image"` + CurrentVersion string `json:"current_version,omitempty"` WatchtowerImage string `json:"watchtower_image,omitempty"` UpdateMode string `json:"update_mode,omitempty"` ComposeDir string `json:"compose_dir,omitempty"` @@ -55,18 +56,19 @@ type SystemUpdateStatus struct { } type SystemUpdateService struct { - cfg *config.Config - log *zap.Logger - repo *repository.Container - tasks *TaskTrackerService + cfg *config.Config + log *zap.Logger + repo *repository.Container + tasks *TaskTrackerService + version string mu sync.Mutex running bool last *SystemUpdateStatus } -func NewSystemUpdateService(cfg *config.Config, log *zap.Logger, repo *repository.Container, tasks *TaskTrackerService) *SystemUpdateService { - return &SystemUpdateService{cfg: cfg, log: log, repo: repo, tasks: tasks} +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, version: normalizeSystemUpdateVersion(version)} } 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) { s.mu.Lock() if s.running { - status := SystemUpdateStatus{} 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() + status := s.baseStatus(ctx) + status.Running = true return status, ErrSystemUpdateRunning } s.running = true @@ -203,12 +208,21 @@ func (s *SystemUpdateService) baseStatus(ctx context.Context) SystemUpdateStatus } return SystemUpdateStatus{ Image: image, + CurrentVersion: s.version, WatchtowerImage: watchtowerImage, UpdateMode: "compose", 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 { if s == nil || s.repo == nil || s.repo.Setting == nil { return strings.TrimSpace(fallback) diff --git a/internal/service/system_update_test.go b/internal/service/system_update_test.go index 0e72923..ddcf576 100644 --- a/internal/service/system_update_test.go +++ b/internal/service/system_update_test.go @@ -1,6 +1,7 @@ package service import ( + "context" "os" "path/filepath" "strings" @@ -152,3 +153,21 @@ func TestSystemUpdateOutputDetailsKeepsTail(t *testing.T) { 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) + } +} diff --git a/web/src/api/admin.ts b/web/src/api/admin.ts index 1d5e59c..6763f93 100644 --- a/web/src/api/admin.ts +++ b/web/src/api/admin.ts @@ -3,6 +3,7 @@ import type { AccessLog, Setting, User } from '../types' export interface SystemUpdateStatus { image: string + current_version?: string watchtower_image?: string update_mode?: string compose_dir?: string diff --git a/web/src/pages/SystemUpdatePanel.tsx b/web/src/pages/SystemUpdatePanel.tsx index a05cb94..a0c7a0d 100644 --- a/web/src/pages/SystemUpdatePanel.tsx +++ b/web/src/pages/SystemUpdatePanel.tsx @@ -139,7 +139,8 @@ export function SystemUpdatePanel() { -