127 lines
2.6 KiB
Go
127 lines
2.6 KiB
Go
|
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.app.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.app.Config.UploadDir, "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.app.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
|
||
|
}
|