feat(controller): Hub asset syncer for logos and screenshots
Add internal/assets package that downloads and caches app assets from Hub API with SHA-256 change detection. Assets resolve from synced cache first, falling back to baked-in directory. Daily sync schedule + on-demand POST /api/assets/sync endpoint. Config: assets.sync_enabled + assets.sync_schedule (default 05:00) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/assets"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/backup"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/config"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/monitor"
|
||||
@@ -61,6 +62,9 @@ type Server struct {
|
||||
|
||||
// Hub push status callback — set via SetHubPushStatus for monitoring page
|
||||
hubPushStatusFn func() HubPushStatusData
|
||||
|
||||
// Asset syncer for Hub-managed assets (optional)
|
||||
assetsSyncer *assets.Syncer
|
||||
}
|
||||
|
||||
func NewServer(cfg *config.Config, stackMgr *stacks.Manager, cpuCollector *system.CPUCollector, backupMgr *backup.Manager, crossDrive *backup.CrossDriveRunner, sched *scheduler.Scheduler, sett *settings.Settings, alertMgr *AlertManager, notif *notify.Notifier, updater *selfupdate.Updater, logger *log.Logger, version string) *Server {
|
||||
@@ -134,6 +138,11 @@ func (s *Server) SetHubPushStatus(fn func() HubPushStatusData) {
|
||||
s.hubPushStatusFn = fn
|
||||
}
|
||||
|
||||
// SetAssetsSyncer sets the Hub asset syncer for resolving app assets.
|
||||
func (s *Server) SetAssetsSyncer(as *assets.Syncer) {
|
||||
s.assetsSyncer = as
|
||||
}
|
||||
|
||||
// InRestoreMode returns true if the server is in DR restore mode.
|
||||
func (s *Server) InRestoreMode() bool {
|
||||
s.restoreMu.RLock()
|
||||
@@ -286,7 +295,13 @@ const assetsDir = "/usr/share/felhom/assets"
|
||||
|
||||
func (s *Server) serveAsset(w http.ResponseWriter, r *http.Request, filename string) {
|
||||
filename = filepath.Base(filename)
|
||||
path := filepath.Join(assetsDir, filename)
|
||||
|
||||
var path string
|
||||
if s.assetsSyncer != nil {
|
||||
path = s.assetsSyncer.Resolve(filename)
|
||||
} else {
|
||||
path = filepath.Join(assetsDir, filename)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
http.NotFound(w, r)
|
||||
|
||||
Reference in New Issue
Block a user