feat: add resource_sync_all and resource_sync_one task types

This commit is contained in:
tian 2026-05-06 12:34:50 +08:00
parent 559fd2c85c
commit 1ff391f055
2 changed files with 88 additions and 0 deletions

View File

@ -36,6 +36,7 @@ type TaskService struct {
repo TaskRepository
models *storage.ModelsRepo
modelsDir string
resources *storage.ResourcesRepo
stateRepo DeviceConfigStateRepository
auditRepo AuditLogRepository
tasks map[string]*models.Task
@ -66,6 +67,13 @@ func (s *TaskService) SetStandardModels(models *storage.ModelsRepo, dir string)
s.modelsDir = filepath.Clean(dir)
}
func (s *TaskService) SetStandardResources(repo *storage.ResourcesRepo) {
if s == nil {
return
}
s.resources = repo
}
func NewTaskService(cfg *config.Config, agent *AgentClient, registry *RegistryService, repo ...TaskRepository) *TaskService {
var taskRepo TaskRepository
if len(repo) > 0 {
@ -399,6 +407,22 @@ func (s *TaskService) executeOnDevice(task *models.Task, did string) {
s.updateDeviceStatus(task.ID, did, models.TaskSuccess, 1.0, "")
s.appendAuditLog(task, did, models.TaskSuccess, "")
case "resource_sync_one":
if err := s.syncResourceToDevice(task, dev, did, false); err != nil {
s.updateDeviceStatus(task.ID, did, models.TaskFailed, 0, err.Error())
return
}
s.updateDeviceStatus(task.ID, did, models.TaskSuccess, 1.0, "")
s.appendAuditLog(task, did, models.TaskSuccess, "")
case "resource_sync_all":
if err := s.syncResourceToDevice(task, dev, did, true); err != nil {
s.updateDeviceStatus(task.ID, did, models.TaskFailed, 0, err.Error())
return
}
s.updateDeviceStatus(task.ID, did, models.TaskSuccess, 1.0, "")
s.appendAuditLog(task, did, models.TaskSuccess, "")
default:
s.updateDeviceStatus(task.ID, did, models.TaskFailed, 0, "unsupported task type")
}
@ -460,6 +484,62 @@ func (s *TaskService) syncModelToDevice(task *models.Task, dev *models.Device, d
return nil
}
func (s *TaskService) syncResourceToDevice(task *models.Task, dev *models.Device, did string, syncAll bool) error {
if s.resources == nil {
return fmt.Errorf("resources repo is not configured")
}
items, err := s.resources.List()
if err != nil {
return err
}
if len(items) == 0 {
return fmt.Errorf("no standard resources configured")
}
targets := items[:0]
if syncAll {
targets = append(targets, items...)
} else {
payload, _ := task.Payload.(map[string]any)
targetName := strings.TrimSpace(stringAny(payload["resource_name"]))
if targetName == "" {
return fmt.Errorf("resource_name is required")
}
for _, item := range items {
if strings.TrimSpace(item.Name) == targetName {
targets = append(targets, item)
break
}
}
if len(targets) == 0 {
return fmt.Errorf("standard resource %q not found", targetName)
}
}
for _, item := range targets {
if strings.TrimSpace(item.FilePath) == "" {
continue // metadata-only resource, nothing to push
}
file, err := os.Open(item.FilePath)
if err != nil {
return err
}
stat, err := file.Stat()
if err != nil {
file.Close()
return err
}
agentPath := fmt.Sprintf("/v1/resources/%s/%s", item.ResourceType, item.Name)
resp, code, err := s.agent.DoStream("PUT", dev.IP, dev.AgentPort, agentPath, file, "application/octet-stream", stat.Size())
file.Close()
if err != nil {
return err
}
if code >= 400 {
return fmt.Errorf("agent error: %d %s", code, strings.TrimSpace(string(resp)))
}
}
return nil
}
func (s *TaskService) updateDeviceStatus(taskID, did string, status models.TaskStatus, progress float64, errStr string) {
s.mu.RLock()
task, ok := s.tasks[taskID]

View File

@ -252,6 +252,8 @@ func NewUI(discovery *service.DiscoveryService, registry *service.RegistryServic
return "批量服务"
case "reload", "rollback":
return "设备操作"
case "resource_sync_one", "resource_sync_all":
return "资源同步"
default:
return "其他任务"
}
@ -264,6 +266,10 @@ func NewUI(discovery *service.DiscoveryService, registry *service.RegistryServic
return "更新单个模型"
case "model_sync_all":
return "更新全部模型"
case "resource_sync_one":
return "同步单个资源"
case "resource_sync_all":
return "同步全部资源"
case "reload":
return "重载识别服务"
case "rollback":
@ -284,6 +290,8 @@ func NewUI(discovery *service.DiscoveryService, registry *service.RegistryServic
return "pill run"
case "model_sync_one", "model_sync_all":
return "pill warn"
case "resource_sync_one", "resource_sync_all":
return "pill warn"
case "media_start", "media_restart", "media_stop":
return "pill ok"
case "reload", "rollback":