aides-repo-api/internal/services/reposervice/service.go

198 lines
4 KiB
Go

package reposervice
import (
"fmt"
"os"
"os/exec"
"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 createSymlink(target, link string) error {
if _, err := os.Lstat(link); err == nil {
if err := os.Remove(link); err != nil {
return fmt.Errorf("failed to remove existing file or symlink: %w", err)
}
}
if err := os.Symlink(target, link); err != nil {
return fmt.Errorf("failed to create symlink: %w", err)
}
return nil
}
func runGenbasedir(repoDir, arch, repoName string) {
log := logger.GetLogger()
cmd := exec.Command(
"genbasedir",
"--bloat",
"--progress",
fmt.Sprintf("--topdir=%s", repoDir),
arch,
repoName,
)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
log.Error(
"Failed to run genbasedir",
map[string]interface{}{
"arch": arch,
"error": err,
},
)
os.Exit(1)
}
log.Info("Successfully ran genbasedir", map[string]interface{}{
"arch": arch,
})
}
func createRepoDirs(repoDir, repoName, arch string) {
log := logger.GetLogger()
// Create the 'base' directory
baseDir := path.Join(repoDir, arch, "base")
err := os.MkdirAll(baseDir, os.ModePerm)
if err != nil {
log.Error("Failed to create directory", map[string]interface{}{
"directory": baseDir,
"err": err,
})
os.Exit(1)
}
// Create the 'RPMS.<REPO_NAME>' directory
rpmsDir := path.Join(repoDir, arch, fmt.Sprintf("RPMS.%s", repoName))
err = os.MkdirAll(rpmsDir, os.ModePerm)
if err != nil {
log.Error("Failed to create directory", map[string]interface{}{
"directory": rpmsDir,
"err": err,
})
os.Exit(1)
}
}
func (s *Service) ForceUpdate() {
var tasks []models.Task
altRepo := models.ALTRepo{
Name: "Sisyphus",
}
s.db.
Where(&altRepo).
First(&altRepo)
s.db.Debug().
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)
repoPath := path.Join(s.config.GetUploadDir(), "future_repo", "Sisyphus")
err := os.MkdirAll(
repoPath,
os.ModePerm,
)
if err != nil {
panic(err)
}
repoName := "aides"
architectures := []string{"x86_64", "noarch"}
for _, arch := range architectures {
createRepoDirs(repoPath, repoName, arch)
}
for _, el := range tasks {
for _, fileInfo := range el.Files {
localFilePath := path.Join(
strconv.FormatUint(uint64(el.ID), 10), fileInfo.Name,
)
symLink := path.Join(
s.config.GetUploadDir(),
"future_repo",
"Sisyphus",
fileInfo.Arch,
"RPMS.aides",
fileInfo.Name,
)
targetPath := path.Join("../../../../tasks/", localFilePath)
err := createSymlink(targetPath, symLink)
if err != nil {
panic(err)
}
}
}
for _, arch := range architectures {
runGenbasedir(repoPath, arch, repoName)
}
s.db.Debug().
Model(&models.GitRepoAltRepoTask{}).
Where(&models.GitRepoAltRepoTask{
ALTRepoID: altRepo.ID,
}).
Update(
"current_task_id", gorm.Expr("last_task_id"),
)
err = os.MkdirAll(path.Join(s.config.GetUploadDir(), "repo"), os.ModePerm)
if err != nil {
panic(err)
}
aPath := path.Join(s.config.GetUploadDir(), "future_repo", "Sisyphus")
bPath := path.Join(s.config.GetUploadDir(), "repo", "Sisyphus")
cPath := path.Join(s.config.GetUploadDir(), "repo", ".Sisyphus")
if _, err := os.Stat(bPath); err == nil {
if err := os.Rename(bPath, cPath); err != nil {
panic(err)
}
} else if !os.IsNotExist(err) {
panic(err)
}
if err := os.Rename(aPath, bPath); err != nil {
panic(err)
}
if err := os.RemoveAll(cPath); err != nil {
panic(err)
}
if err := os.RemoveAll(path.Join(s.config.GetUploadDir(), "future_repo")); err != nil {
panic(err)
}
}