diff --git a/agent/internal/config/config.go b/agent/internal/config/config.go index 34ca814..f83017d 100644 --- a/agent/internal/config/config.go +++ b/agent/internal/config/config.go @@ -23,6 +23,7 @@ type AgentConfig struct { DeviceName string `json:"device_name"` DeviceIDPath string `json:"device_id_path"` ModelsDir string `json:"models_dir"` + ResourcesDir string `json:"resources_dir"` MaxUploadMB int `json:"max_upload_mb"` ConfigPath string `json:"config_path"` MediaServerProcess MediaServerProcessConfig `json:"media_server_process"` @@ -54,6 +55,7 @@ func Default() Config { DiscoveryPort: 35688, DeviceIDPath: "/var/lib/rk3588-agent/device_id", ModelsDir: "/opt/rk3588sys/models", + ResourcesDir: "/opt/rk3588sys/resources", MaxUploadMB: 200, ConfigPath: "/etc/rk3588sys/config.json", MediaServerProcess: MediaServerProcessConfig{ @@ -106,6 +108,9 @@ func (c Config) Validate() error { if strings.TrimSpace(a.ModelsDir) == "" { return errors.New("agent.models_dir is required") } + if strings.TrimSpace(a.ResourcesDir) == "" { + return errors.New("agent.resources_dir is required") + } if strings.TrimSpace(a.ConfigPath) == "" { return errors.New("agent.config_path is required") } diff --git a/agent/internal/httpapi/face_gallery.go b/agent/internal/httpapi/face_gallery.go index c9d3fea..4c425cb 100644 --- a/agent/internal/httpapi/face_gallery.go +++ b/agent/internal/httpapi/face_gallery.go @@ -22,7 +22,7 @@ type faceGalleryInfo struct { } func (s *Server) faceGalleryPath() string { - return filepath.Join(s.agentCfg.ModelsDir, "face_gallery.db") + return filepath.Join(s.resourcesDir, "face_gallery", "face_gallery.db") } func (s *Server) handleFaceGallery(w http.ResponseWriter, r *http.Request) { diff --git a/agent/internal/httpapi/resources.go b/agent/internal/httpapi/resources.go index a52bb91..584be64 100644 --- a/agent/internal/httpapi/resources.go +++ b/agent/internal/httpapi/resources.go @@ -21,10 +21,6 @@ type installedResource struct { UpdatedAt int64 `json:"updated_at"` } -func (s *Server) resourcesDir() string { - return filepath.Join(s.agentCfg.ModelsDir, "resources") -} - // handleResourcesStatus returns all installed resources on this device. // GET /v1/resources/status func (s *Server) handleResourcesStatus(w http.ResponseWriter, r *http.Request) { @@ -39,22 +35,8 @@ func (s *Server) handleResourcesStatus(w http.ResponseWriter, r *http.Request) { resources := make([]installedResource, 0) - // 1. Face gallery (stored at modelsDir/face_gallery.db) - fgPath := filepath.Join(s.agentCfg.ModelsDir, "face_gallery.db") - if st, err := os.Stat(fgPath); err == nil { - sha, _ := fileSHA256HTTP(fgPath) - name := strings.TrimSuffix(filepath.Base(fgPath), filepath.Ext(fgPath)) - resources = append(resources, installedResource{ - Name: name, - ResourceType: "face_gallery", - SHA256: sha, - SizeBytes: st.Size(), - UpdatedAt: st.ModTime().Unix(), - }) - } - - // 2. Resources directory — scan each type subdirectory - resDir := s.resourcesDir() + // Scan resourcesDir — each subdirectory is a resource_type + resDir := s.resourcesDir entries, err := os.ReadDir(resDir) if err == nil { for _, entry := range entries { @@ -96,18 +78,7 @@ func (s *Server) handleResourcesStatus(w http.ResponseWriter, r *http.Request) { return resources[i].Name < resources[j].Name }) - // dedup by resource_type + name (face_gallery.db may appear both in modelsDir and resources/) - seen := make(map[string]bool, len(resources)) - deduped := make([]installedResource, 0, len(resources)) - for _, r := range resources { - key := r.ResourceType + "/" + r.Name - if !seen[key] { - seen[key] = true - deduped = append(deduped, r) - } - } - - writeJSON(w, http.StatusOK, map[string]any{"resources": deduped}) + writeJSON(w, http.StatusOK, map[string]any{"resources": resources}) } // handleResourceUpload accepts a resource file upload. @@ -147,7 +118,7 @@ func (s *Server) handleResourceUpload(w http.ResponseWriter, r *http.Request) { maxBytes := int64(s.agentCfg.MaxUploadMB) * 1024 * 1024 r.Body = http.MaxBytesReader(w, r.Body, maxBytes) - typeDir := filepath.Join(s.resourcesDir(), resourceType) + typeDir := filepath.Join(s.resourcesDir, resourceType) if err := files.EnsureDir(typeDir, 0o755); err != nil { errorJSON(w, http.StatusInternalServerError, "internal error: "+err.Error()) return diff --git a/agent/internal/httpapi/server.go b/agent/internal/httpapi/server.go index 8b75c03..9df3a3d 100644 --- a/agent/internal/httpapi/server.go +++ b/agent/internal/httpapi/server.go @@ -37,6 +37,7 @@ type Server struct { tasks *tasks.Registry baseDir string execPath string + resourcesDir string deviceID string hostname string agentPort int @@ -95,6 +96,10 @@ func New(agentCfg config.AgentConfig, baseDir string, ms *mediaserver.Client, st execPath = resolved } } + resourcesDir := strings.TrimSpace(agentCfg.ResourcesDir) + if resourcesDir == "" { + resourcesDir = filepath.Join(baseDir, "resources") + } s := &Server{ agentCfg: agentCfg, ms: ms, @@ -104,6 +109,7 @@ func New(agentCfg config.AgentConfig, baseDir string, ms *mediaserver.Client, st tasks: tasks.NewRegistry(), baseDir: baseDir, execPath: execPath, + resourcesDir: resourcesDir, deviceID: deviceID, hostname: sysinfo.Hostname(), agentPort: agentPort, @@ -150,6 +156,18 @@ func New(agentCfg config.AgentConfig, baseDir string, ms *mediaserver.Client, st mux.HandleFunc("/v1/assets", s.handleAssets) mux.HandleFunc("/v1/tasks/", s.handleTask) + // Migrate face_gallery.db from old location (modelsDir) to new location (resourcesDir) + oldFG := filepath.Join(agentCfg.ModelsDir, "face_gallery.db") + newFGDir := filepath.Join(resourcesDir, "face_gallery") + newFG := filepath.Join(newFGDir, "face_gallery.db") + if _, err := os.Stat(oldFG); err == nil { + if _, err := os.Stat(newFG); os.IsNotExist(err) { + _ = files.EnsureDir(newFGDir, 0o755) + if data, rerr := os.ReadFile(oldFG); rerr == nil { + _ = files.WriteFileAtomic(newFG, data, 0o644) + } + } + } s.handler = mux return s } diff --git a/agent/rk3588-agent_linux_arm64 b/agent/rk3588-agent_linux_arm64 index 66e513c..355814c 100755 Binary files a/agent/rk3588-agent_linux_arm64 and b/agent/rk3588-agent_linux_arm64 differ