package taskservice import ( "errors" "fmt" "io" "mime/multipart" "os" "os/exec" "path" "strconv" "strings" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/models" "gorm.io/gorm" ) type TaskUploadInput struct { TaskID string Files []*multipart.FileHeader } func getRPMArchitecture(filePath string) (string, error) { cmd := exec.Command("rpm", "-qp", "--queryformat", "%{ARCH}", filePath) output, err := cmd.Output() if err != nil { return "", fmt.Errorf("ошибка при выполнении команды rpm: %v", err) } arch := strings.TrimSpace(string(output)) return arch, nil } func (s *Service) Upload(input *TaskUploadInput) error { taskID, err := strconv.Atoi(input.TaskID) if err != nil { return err } files := input.Files task := models.Task{} result := s.db.Preload("Repo").Where( "id = ?", taskID, ).First(&task) /*.Where( "status = ?", models.StatusPending, )*/ if errors.Is(result.Error, gorm.ErrRecordNotFound) { return result.Error } if result.Error != nil { return result.Error } localPath := path.Join(input.TaskID) taskFolderPath := path.Join(s.config.GetUploadDir(), "tasks", localPath) os.MkdirAll(taskFolderPath, os.ModePerm) for _, fileHeader := range files { file, err := fileHeader.Open() if err != nil { return err } defer file.Close() if !strings.HasSuffix(fileHeader.Filename, ".rpm") { return fmt.Errorf("invalid file type: only .rpm files are allowed") } // Полный путь для файла filePath := path.Join(taskFolderPath, fileHeader.Filename) //Удаляем файл если такой уже существует if _, err := os.Stat(filePath); err == nil { err = os.Remove(filePath) if err != nil { return err } } // Сохранение файла на сервере outFile, err := os.Create(filePath) if err != nil { return err } defer outFile.Close() _, err = io.Copy(outFile, file) if err != nil { return err } arch, err := getRPMArchitecture(filePath) if err != nil { return err } f := models.RPMFile{ Name: fileHeader.Filename, Arch: arch, Task: task, } if err := s.db.Save(&f).Error; err != nil { return err } // Символическая ссылка /* targetPath := path.Join("../../../../tasks/", localPath, fileHeader.Filename) symLink := path.Join(s.app.Config.UploadDir, "repo/Sisyphus", arch, "RPMS.aides", fileHeader.Filename) err = createSymlink(targetPath, symLink) if err != nil { return err } */ } task.Status = models.StatusCompleted s.onTaskComplete(&task) return nil }