Compare commits
3 Commits
8a9ec59134
...
c5f3e1a009
| Author | SHA1 | Date | |
|---|---|---|---|
| c5f3e1a009 | |||
| 4dd0335e55 | |||
| daa5da3b85 |
@ -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")
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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,21 +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)
|
||||
resources = append(resources, installedResource{
|
||||
Name: "face_gallery_v1",
|
||||
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 {
|
||||
@ -135,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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Binary file not shown.
@ -290,11 +290,24 @@ cmd_install_media_server() {
|
||||
echo -e "${GREEN}✓${NC} 已复制 web 静态文件 ($WEB_FILES 个文件)"
|
||||
fi
|
||||
|
||||
# 复制模型文件(包括 .rknn 模型和 .db 人脸库)
|
||||
# 复制模型文件(仅 .rknn)
|
||||
if [ -d "$PROJECT_DIR/models" ]; then
|
||||
cp -r "$PROJECT_DIR/models"/* "$INSTALL_DIR/models/" 2>/dev/null || true
|
||||
MODEL_COUNT=$(find "$INSTALL_DIR/models" -type f \( -name "*.rknn" -o -name "*.db" \) | wc -l)
|
||||
echo -e "${GREEN}✓${NC} 已复制模型文件 ($MODEL_COUNT 个模型/人脸库)"
|
||||
mkdir -p "$INSTALL_DIR/models"
|
||||
if ls "$PROJECT_DIR"/models/*.rknn 1>/dev/null 2>&1; then
|
||||
cp "$PROJECT_DIR"/models/*.rknn "$INSTALL_DIR/models/" 2>/dev/null || true
|
||||
fi
|
||||
MODEL_COUNT=$(find "$INSTALL_DIR/models" -type f -name "*.rknn" | wc -l)
|
||||
echo -e "${GREEN}✓${NC} 已复制模型文件 ($MODEL_COUNT 个)"
|
||||
fi
|
||||
|
||||
# 复制资源文件(.db 人脸库等)
|
||||
if [ -d "$PROJECT_DIR/models" ]; then
|
||||
mkdir -p "$INSTALL_DIR/resources/face_gallery"
|
||||
if ls "$PROJECT_DIR"/models/*.db 1>/dev/null 2>&1; then
|
||||
cp "$PROJECT_DIR"/models/*.db "$INSTALL_DIR/resources/face_gallery/" 2>/dev/null || true
|
||||
fi
|
||||
RES_COUNT=$(find "$INSTALL_DIR/resources" -type f -name "*.db" | wc -l)
|
||||
echo -e "${GREEN}✓${NC} 已复制资源文件 ($RES_COUNT 个)"
|
||||
fi
|
||||
|
||||
# 选择并复制配置文件
|
||||
@ -410,6 +423,10 @@ def fix_path(path):
|
||||
if not path or not isinstance(path, str):
|
||||
return path
|
||||
|
||||
# 人脸库/资源文件 -> 安装目录的 resources
|
||||
if '.db' in path:
|
||||
return os.path.join(install_dir, 'resources', 'face_gallery', os.path.basename(path))
|
||||
|
||||
# 模型路径 -> 安装目录的 models
|
||||
if 'third_party/rknpu2' in path or '.rknn' in path:
|
||||
return os.path.join(install_dir, 'models', os.path.basename(path))
|
||||
@ -538,6 +555,7 @@ cmd_install_agent() {
|
||||
"device_name": "rk3588_$(hostname)",
|
||||
"device_id_path": "/var/lib/rk3588-agent/device_id",
|
||||
"models_dir": "$INSTALL_DIR/models",
|
||||
"resources_dir": "$INSTALL_DIR/resources",
|
||||
"max_upload_mb": 200,
|
||||
"config_path": "$INSTALL_DIR/etc/media-server.json",
|
||||
"media_server_process": {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user