package reposervice import ( "os" "path" "strconv" "gorm.io/gorm" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/logger" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/models" ) type Config interface { GetUploadDir() string } type Service struct { db *gorm.DB config Config } func New(db *gorm.DB, cfg Config) *Service { return &Service{ db: db, config: cfg, } } func (s *Service) futureRepoPathPrefix() string { return path.Join( s.config.GetUploadDir(), ".future_repo", ) } func (s *Service) currentRepoPathPrefix() string { return path.Join( s.config.GetUploadDir(), "repo", ) } func (s *Service) oldRepoPathPrefix() string { return path.Join( s.config.GetUploadDir(), ".old_repo", ) } func (s *Service) ForceUpdate() error { const REPO_NAME = "aides" architectures := []string{ "x86_64", "noarch", } repos := []string{ "Sisyphus", } log := logger.GetLogger() log.Info("Start repo update") err := os.MkdirAll(s.futureRepoPathPrefix(), os.ModePerm) if err != nil { return err } defer os.RemoveAll(s.futureRepoPathPrefix()) err = os.MkdirAll(s.oldRepoPathPrefix(), os.ModePerm) if err != nil { return err } defer os.RemoveAll(s.oldRepoPathPrefix()) err = os.MkdirAll(s.currentRepoPathPrefix(), os.ModePerm) if err != nil { return err } for _, r := range repos { var tasks []models.Task altRepo := models.ALTRepo{ Name: r, } s.db. Where(&altRepo). First(&altRepo) s.db. Model(&models.GitRepoAltRepoTask{}). Select("tasks.*"). Joins("JOIN tasks ON tasks.id = git_repo_alt_repo_tasks.last_task_id"). Where(&models.GitRepoAltRepoTask{ ALTRepoID: altRepo.ID, }). Preload("Files"). Find(&tasks) futureRepoPath := path.Join( s.futureRepoPathPrefix(), altRepo.Name, ) err := os.MkdirAll( futureRepoPath, os.ModePerm, ) if err != nil { return err } for _, arch := range architectures { err = createRepoDirs(futureRepoPath, REPO_NAME, arch) if err != nil { return err } } for _, el := range tasks { for _, fileInfo := range el.Files { localFilePath := path.Join( strconv.FormatUint(uint64(el.ID), 10), fileInfo.Filename, ) symLink := path.Join( futureRepoPath, fileInfo.Arch, "RPMS.aides", fileInfo.Filename, ) targetPath := path.Join("../../../../tasks/", localFilePath) err := createSymlink(targetPath, symLink) if err != nil { return err } } } for _, arch := range architectures { err = runGenbasedir(futureRepoPath, arch, REPO_NAME) if err != nil { return err } } s.db. Model(&models.GitRepoAltRepoTask{}). Where(&models.GitRepoAltRepoTask{ ALTRepoID: altRepo.ID, }). Update( "current_task_id", gorm.Expr("last_task_id"), ) currentRepoPath := path.Join( s.currentRepoPathPrefix(), altRepo.Name, ) oldRepoPath := path.Join( s.oldRepoPathPrefix(), altRepo.Name, ) if err := renameIfExists( currentRepoPath, oldRepoPath, ); err != nil { return err } if err := os.Rename( futureRepoPath, currentRepoPath, ); err != nil { return err } } log.Info("Successful repo update") return nil }